Skip to content

Fix whole-app crash when dragging a tab out of a window; add explicit Detach Tab action#1101

Open
henricook wants to merge 3 commits into
gnome-terminator:masterfrom
henricook:fix/1022-safe-tab-detach
Open

Fix whole-app crash when dragging a tab out of a window; add explicit Detach Tab action#1101
henricook wants to merge 3 commits into
gnome-terminator:masterfrom
henricook:fix/1022-safe-tab-detach

Conversation

@henricook

@henricook henricook commented Jul 6, 2026

Copy link
Copy Markdown

Background

Occasionally I drag a tab out of my terminator window on Gnome/Wayland and drop it, and it gets lost forever (but I think is still running!).

What

Why

The gdb log attached to #1022 shows the segfault inside GTK's own drag-end handling:

#0  gtk_notebook_drag_end (...) at ../gtk/gtk/gtknotebook.c:3743
3743      _gtk_bin_set_child (GTK_BIN (priv->dnd_window), NULL);

GTK emits create-window in the middle of its drag bookkeeping, and our handler removed the page on the spot. With exactly two tabs, hoover() then dissolved the whole notebook, freeing priv->dnd_window before GTK's drag-end handler dereferences it (hence intermittent: 3+ tabs, no collapse, no crash). One Python process hosts every window, so "all instances crash".

The explicit action matters because on Wayland GTK only emits create-window for drops on shell chrome or bare desktop (GTK#46) - dropping a tab on any window can never detach, and that's not fixable app-side.

How

  • create_window_detach now just schedules the detach with GObject.idle_add; the page is moved after the drag has fully ended, never inside the emission
  • New detach-tab terminal signal wired like move-tab, driving the keybinding and menu item
  • queue_resize after a failed tab drag so the restored label repaints (GTK#3143)
  • Verified on GNOME 50.1 Wayland via a nested compositor with injected drags: keyboard/menu/desktop-drop detach all work, drops on app windows snap back safely. Only test change is row indices in test_prefseditor_keybindings.py (the new binding sorts before edit_*)

Credit where due: Claude did the gdb spelunking and the nested-compositor testing.

henricook added 3 commits July 6, 2026 08:25
Dragging a tab out of its window could crash the whole process,
killing every window at once (issue gnome-terminator#1022). The gdb log on that issue
shows a use-after-free in gtk_notebook_drag_end (gtknotebook.c:3743):
our create-window handler removed the page while GTK was still mid-way
through its drag bookkeeping, and when the source window had exactly
two tabs, hoover() dissolved the notebook entirely, freeing the drag
state GTK touches right after the handler returns. That also explains
the intermittency: three or more tabs means no notebook collapse.

Defer the detach with GObject.idle_add until the drag has fully ended,
and queue a re-allocate after failed tab drags so the restored tab
label is not left undrawn under Wayland (GTK issue #3143).

GTK on Wayland only emits create-window for drops outside any
drop-accepting surface (GTK issue gnome-terminator#46), so dragging a tab onto another
window can never detach there. Add an explicit, DnD-free way to detach
as well: a detach_tab keybinding (Shift+Ctrl+D) and a Detach Tab
context menu item, plumbed the same way as move-tab. Tabs containing
splits detach with all their panes.

The keybinding prefs tests hardcode row indices of the sorted
keybinding list; the new binding sorts before edit_* and zoom_in, so
those indices shift by one.
@henricook henricook marked this pull request as ready for review July 6, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant