Summary
In the GTK ShellApp path (the Relm4→ShellApp flip, #540), dialogs and
context menus are never rendered and cannot be dismissed by clicking. Their
draw code and click-region caches are populated only by the now-dead legacy
draw_editor Cairo path, so in the live ShellApp build they are effectively
broken.
This was uncovered while finishing #515 (editor-group drag-and-drop). It is
ShellApp-port fallout, not a #515 regression — filing separately.
User-visible symptoms (GTK)
- Right-click does nothing — the editor/tab/explorer context menus never
appear.
- Closing a tab (×) on a modified buffer hangs the UI — it fires
Msg::ShowCloseTabConfirm → engine.dialog = Some(...), but the
"Unsaved Changes" dialog is invisible (never drawn) and undismissable by
click. dialog.is_some() stays true and the dialog block in
handle_mouse_click_msg then swallows all subsequent clicks, so the editor
appears frozen to the mouse. Only Esc (keyboard) clears it.
- Any other
show_dialog(...) caller (:about, extension-remove confirm,
buffer prompts, etc.) is likewise invisible/stuck.
Root cause
The rendering + hit-region caches live in the dead path:
src/gtk/draw.rs — draw_dialog_popup(...) and the context-menu draw set
dialog_btn_rects, dialog_popup_rect, and the context-menu layout. These run
only inside draw_editor, which is not called under the ShellApp runner.
render_content (the live path) draws neither dialogs nor context menus.
handle_mouse_click_msg still has the dialog block (and the context-menu
block) that read those now-empty caches:
- dialog:
dialog_btn_rects empty → no button is ever hit; dialog_popup_rect
None → never pushed to the modal stack → dispatch_mouse_down reports
outside == false → the dismiss branch never runs → the dialog is stuck.
- context menu:
context_menu is set by right-click but never drawn, and the
inner ContextMenuLayout hit-test has no geometry.
Fix
Migrate both surfaces into the ShellApp render + event path, mirroring the
explorer/tab-bar work already done for #515/#540:
- Render in
render_content — draw the dialog popup and the context-menu
popup via quadraui primitives (Dialog/DialogTable, ContextMenu) on top of
the frame, and cache their resolved click geometry from the same layout the
renderer uses (no per-backend pixel maps).
- Wire clicks — route dialog-button / context-menu-item clicks (and
outside-click dismissal) through that cached layout in handle_mouse_click_msg,
the same way tab-bar/tree hit-testing now flows through shared hit_regions /
TreeController.
- Verify right-click menus appear and act; tab-close-on-dirty shows a
visible, clickable confirm; :about and other dialogs render and dismiss.
Acceptance
- Right-click in editor / tab bar / explorer opens a working context menu.
- Closing a modified tab shows a visible Unsaved-Changes dialog whose
Save/Discard/Cancel buttons work by click (and Esc/Enter still work).
- No stuck-invisible-dialog state; clicks are not swallowed after a dialog opens.
Notes
- Platform-neutral: reuse the shared quadraui Dialog/ContextMenu primitives; the
GTK side should be thin event→engine wiring only.
- Keyboard handling already works (engine handles dialog/menu keys) — this is
specifically the render + mouse gap.
Summary
In the GTK ShellApp path (the Relm4→ShellApp flip, #540), dialogs and
context menus are never rendered and cannot be dismissed by clicking. Their
draw code and click-region caches are populated only by the now-dead legacy
draw_editorCairo path, so in the live ShellApp build they are effectivelybroken.
This was uncovered while finishing #515 (editor-group drag-and-drop). It is
ShellApp-port fallout, not a #515 regression — filing separately.
User-visible symptoms (GTK)
appear.
Msg::ShowCloseTabConfirm→engine.dialog = Some(...), but the"Unsaved Changes" dialog is invisible (never drawn) and undismissable by
click.
dialog.is_some()stays true and the dialog block inhandle_mouse_click_msgthen swallows all subsequent clicks, so the editorappears frozen to the mouse. Only Esc (keyboard) clears it.
show_dialog(...)caller (:about, extension-remove confirm,buffer prompts, etc.) is likewise invisible/stuck.
Root cause
The rendering + hit-region caches live in the dead path:
src/gtk/draw.rs—draw_dialog_popup(...)and the context-menu draw setdialog_btn_rects,dialog_popup_rect, and the context-menu layout. These runonly inside
draw_editor, which is not called under the ShellApp runner.render_content(the live path) draws neither dialogs nor context menus.handle_mouse_click_msgstill has the dialog block (and the context-menublock) that read those now-empty caches:
dialog_btn_rectsempty → no button is ever hit;dialog_popup_rectNone→ never pushed to the modal stack →dispatch_mouse_downreportsoutside == false→ the dismiss branch never runs → the dialog is stuck.context_menuis set by right-click but never drawn, and theinner
ContextMenuLayouthit-test has no geometry.Fix
Migrate both surfaces into the ShellApp render + event path, mirroring the
explorer/tab-bar work already done for #515/#540:
render_content— draw the dialog popup and the context-menupopup via quadraui primitives (Dialog/
DialogTable, ContextMenu) on top ofthe frame, and cache their resolved click geometry from the same layout the
renderer uses (no per-backend pixel maps).
outside-click dismissal) through that cached layout in
handle_mouse_click_msg,the same way tab-bar/tree hit-testing now flows through shared
hit_regions/TreeController.visible, clickable confirm;
:aboutand other dialogs render and dismiss.Acceptance
Save/Discard/Cancel buttons work by click (and Esc/Enter still work).
Notes
GTK side should be thin event→engine wiring only.
specifically the render + mouse gap.