Fix two bugs: splits layout corruption and overlay stuck on early drop exit

splits.py: insert_window_next_to called split_and_add on self.pairs_root
instead of on the pair found by pair_for_window. split_and_add only handles
direct children, so nested dest windows fell to 'else: self.two = pair',
silently replacing an entire subtree. Lost windows were re-added by
do_layout, producing phantom panes.

tabs.py: on_window_drop returned early (window not found) before calling
_clear_force_show_title_bars, leaving the drag overlay stuck on screen.
This commit is contained in:
mcrmck
2026-03-20 01:34:01 -04:00
parent 940b8bf1d3
commit 5c0a4accb3
2 changed files with 9 additions and 1 deletions
+1 -1
View File
@@ -740,7 +740,7 @@ class Splits(Layout):
# Re-insert next to dest
pair = self.pairs_root.pair_for_window(dest_wg.id)
if pair is not None:
self.pairs_root.split_and_add(dest_wg.id, src_wg.id, horizontal, after)
pair.split_and_add(dest_wg.id, src_wg.id, horizontal, after)
else:
self.pairs_root.balanced_add(src_wg.id)
+8
View File
@@ -1858,8 +1858,10 @@ class TabManager: # {{{
self.mark_tab_bar_dirty()
def _clear_force_show_title_bars(self) -> None:
log_error('DRAG DEBUG: _clear_force_show_title_bars called')
boss = get_boss()
for tm in boss.all_tab_managers:
log_error(f'DRAG DEBUG: clearing tm={tm.os_window_id} window_being_dropped={tm.window_being_dropped}')
tm._set_drag_target_window(0)
tm._set_drag_target_tab(0)
for tab in tm:
@@ -1888,18 +1890,23 @@ class TabManager: # {{{
boss = get_boss()
prev_id = self.window_being_dropped.window_id if self.window_being_dropped else 0
prev_quadrant = self.window_being_dropped.quadrant if self.window_being_dropped else 0
log_error(f'DRAG DEBUG: _set_drag_target_window window_id={window_id} quadrant={quadrant} prev_id={prev_id} prev_quadrant={prev_quadrant}')
if prev_id == window_id and prev_quadrant == quadrant:
return
if prev_id and (prev_w := boss.window_id_map.get(prev_id)):
log_error(f'DRAG DEBUG: clearing overlay on prev_id={prev_id} tab_id={prev_w.tab_id}')
prev_w.is_drag_target = False
set_window_drag_overlay(self.os_window_id, prev_w.tab_id, prev_id, 0)
if prev_w._title_bar_screen is not None:
tab = prev_w.tabref()
prev_w.update_title_bar(is_active=tab is not None and tab.active_window is prev_w)
elif prev_id:
log_error(f'DRAG DEBUG: prev_id={prev_id} not found in window_id_map — overlay may be stuck!')
if window_id and (new_w := boss.window_id_map.get(window_id)):
if quadrant == 5:
new_w.is_drag_target = True
new_w.update_title_bar(is_active=True)
log_error(f'DRAG DEBUG: setting overlay on window_id={window_id} tab_id={new_w.tab_id} quadrant={quadrant}')
set_window_drag_overlay(self.os_window_id, new_w.tab_id, window_id, quadrant)
self.window_being_dropped = WindowBeingDropped(window_id=window_id, quadrant=quadrant)
else:
@@ -1953,6 +1960,7 @@ class TabManager: # {{{
boss = get_boss()
w = boss.window_id_map.get(window_id)
if w is None:
self._clear_force_show_title_bars()
return
self._clear_force_show_title_bars()
set_window_being_dragged()