You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
src/gtk/draw.rs was not the only thing #540's Relm4 cutover orphaned. 22 widget
handles on App are initialised None at construction and assigned nowhere in the
crate. They guard ~103 if let Some(…) / match arms that can never execute,
and — unlike draw.rs — there is no file-level #![allow(dead_code)] marking them,
so #672's "no file-level allow" acceptance criterion could not have found them.
This is the same sweep #672 did for draw.rs, applied to the widget-handle
pocket that survived it.
Why the compiler is silent
These fields are read, just never written. Rust warns on a field that is never read; it does not warn on a field that is never assigned a non-default value. So
every one of these compiles clean, reads as live code to a human, and is unreachable
at runtime. Two are already documented as dead in-file:
src/gtk/mod.rs:534-542 — "Always None under the ShellApp runner … nothing in
this file assigns this field. Every if let Some(da) = self.drawing_area… arm is
therefore dead code inherited from the Relm4 build."
src/gtk/mod.rs:2123 — "self.drawing_area is never assigned under the ShellApp
runner … so the old if let Some(da) arm never ran and this was unconditionally None."
The other 20 carry no such note.
Inventory
All declared in struct App and initialised Rc::new(RefCell::new(None)); grep for borrow_mut() = Some / .replace(Some( across src/gtk/ returns zero hits for any
of them.
Field
decl
init
refs
guarded arms
drawing_area
mod.rs:543
:1627
39
29
overlay
:575
:1646
56
7
ext_dyn_panel_da_ref
:555
:1632
14
12
settings_da_ref
:571
:1643
12
6
git_sidebar_da_ref
:552
:1630
11
8
explorer_sidebar_da_ref
:517
:1622
11
8
debug_sidebar_da_ref
:544
:1628
10
7
ext_sidebar_da_ref
:553
:1631
7
4
ai_sidebar_da_ref
:558
:1634
7
4
activity_bar_da_ref
:520
:1623
6
4
ctx_menu_overlay_da
:528
:1625
6
4
panel_hover_da
:814
:1701
6
4
search_sidebar_da_ref
:564
:1638
5
2
menu_dropdown_da
:812
:1700
5
1
sidebar_inner_sw
:559
:1635
4
2
ext_dyn_panel_box
:557
:1633
3
1
explorer_panel_box
:563
:1637
3
0
debug_panel_box
:565
:1639
3
0
git_panel_box
:566
:1640
3
0
ext_panel_box
:567
:1641
3
0
settings_panel_box
:568
:1642
3
0
ai_panel_box_ref
:572
:1644
3
0
Plus window_scrollbars (:574, init :1645), which is a HashMap rather than an Option but is populated only inside a block gated on two of the above.
This is not a hypothetical cleanup. e02a824 (2026-09-01, one week after #672)
landed the GTK half of #723 — inset the native gtk4::Scrollbar past the minimap strip
so the two stop fighting over the pane's right edge. The geometry is correct. It is also
unreachable:
create_window_scrollbars (mod.rs:2825) <- only constructor of gtk4::Scrollbar
called from mod.rs:2760, inside...
sync_scrollbar (mod.rs:2657) <- only caller
:2672 let overlay = match self.overlay.borrow().as_ref() { Some(o) => …, None => return };
:2677 let drawing_area = match self.drawing_area.borrow().as_ref() { Some(da) => …, None => return };
Both guards are permanently None, so sync_scrollbar returns before reaching either
one. window_scrollbars is populated nowhere else. No gtk4::Scrollbar is ever
constructed under the runner, so native_scrollbar_margin_start (:1438) and sync_scrollbar_positions (:1459) have no live caller, and #723's fix cannot execute.
The commit message states the premise without drawing the conclusion:
GTK widget visibility/geometry has no headless coverage (App::new_headless never
constructs a real gtk4::Scrollbar; GtkDriver only sees Cairo paint, not overlay
widgets) — hence the pure-function test plus a SMOKE_TESTS item.
Its four native_scrollbar_placement_tests all exercise native_scrollbar_margin_start
in isolation: a pure function with no caller on any live path. They pass; they prove
nothing about the screen.
So #723 needs re-verifying on a display before it is closed, and whatever is actually
drawing the scrollbar the user sees is not this code. Two candidates worth checking
first: quadraui's own gtk::draw_editor painting a scrollbar into the single DA (the
TUI-equivalent path), or the runner's ScrolledWindow policy.
Scope
Delete the 22 fields, their initialisers, and every arm they guard. Where an arm
contained the only implementation of a behaviour, that behaviour is already absent
at runtime — deleting it changes nothing on screen. Where deletion would remove the
last reference to a helper (sync_scrollbar, create_window_scrollbars, sync_scrollbar_positions, native_scrollbar_margin_start, struct WindowScrollbars),
delete the helper too.
No field in struct App is Option-typed, initialised None, and never assigned.
Add a comment to any deliberate exception saying who assigns it.
grep -rn 'gtk4::\(Box\|Overlay\|ScrolledWindow\)' src/gtk/ returns only live uses.
cargo build && cargo test && cargo clippy -- -D warnings && cargo fmt --check all
EXIT=0.
A GtkDriver black-box test covering whichever surface turns out to be the real
scrollbar painter, stated in the PR as verified RED against unfixed develop
(CLAUDE.md, "Black-box coverage is the acceptance bar", rule 2).
The PR says explicitly which of the deleted arms, if any, removed a behaviour that a
user could observe. Expected answer: none — but it must be checked, not assumed.
⚠️ Line numbers in this body drift — locate by symbol
Every line number above was measured on develop @ 4872ab9 (2026-09-01). They are
already wrong.#727 landed src/gtk/mod.rs +435/−44 within hours and moved enum Msg 1096→1131, fn dispatch 1799→1896, sync_scrollbar 2657→2754. Seven more
issues sit ahead of this one in the chain, each deleting or moving thousands of lines.
Treat the numbers as provenance — proof the claim was verified once — never as
coordinates. Locate by these anchors instead:
grep -nE "^\s+(explorer_sidebar_da_ref|activity_bar_da_ref|ctx_menu_overlay_da|drawing_area|debug_sidebar_da_ref|git_sidebar_da_ref|ext_sidebar_da_ref|ext_dyn_panel_da_ref|ext_dyn_panel_box|ai_sidebar_da_ref|sidebar_inner_sw|explorer_panel_box|search_sidebar_da_ref|debug_panel_box|git_panel_box|ext_panel_box|settings_panel_box|settings_da_ref|ai_panel_box_ref|overlay|menu_dropdown_da|panel_hover_da|window_scrollbars):" src/gtk/mod.rs
grep -nE "fn (sync_scrollbar|create_window_scrollbars|sync_scrollbar_positions|native_scrollbar_margin_start)|struct WindowScrollbars" src/gtk/mod.rs
# the inventory regenerates: for each field above, grep -c for reads, and confirm
# ZERO hits for: grep -rn "borrow_mut() = Some\|\.replace(Some(" src/gtk/
This is the same defect #734 exists to fix: src/tui_main/ carries 19 mirrors mod.rs:NNNN comments whose targets all drifted after #540, leaving the only
record of a cross-backend contract pointing at unrelated code. Do not re-point the
numbers when they rot — the anchors are the durable form.
Summary
src/gtk/draw.rswas not the only thing #540's Relm4 cutover orphaned. 22 widgethandles on
Appare initialisedNoneat construction and assigned nowhere in thecrate. They guard ~103
if let Some(…)/matcharms that can never execute,and — unlike
draw.rs— there is no file-level#![allow(dead_code)]marking them,so #672's "no file-level allow" acceptance criterion could not have found them.
This is the same sweep #672 did for
draw.rs, applied to the widget-handlepocket that survived it.
Why the compiler is silent
These fields are read, just never written. Rust warns on a field that is never
read; it does not warn on a field that is never assigned a non-default value. So
every one of these compiles clean, reads as live code to a human, and is unreachable
at runtime. Two are already documented as dead in-file:
src/gtk/mod.rs:534-542— "AlwaysNoneunder the ShellApp runner … nothing inthis file assigns this field. Every
if let Some(da) = self.drawing_area…arm istherefore dead code inherited from the Relm4 build."
src/gtk/mod.rs:2123— "self.drawing_areais never assigned under the ShellApprunner … so the old
if let Some(da)arm never ran and this was unconditionallyNone."The other 20 carry no such note.
Inventory
All declared in
struct Appand initialisedRc::new(RefCell::new(None)); grep forborrow_mut() = Some/.replace(Some(acrosssrc/gtk/returns zero hits for anyof them.
drawing_areamod.rs:543:1627overlay:575:1646ext_dyn_panel_da_ref:555:1632settings_da_ref:571:1643git_sidebar_da_ref:552:1630explorer_sidebar_da_ref:517:1622debug_sidebar_da_ref:544:1628ext_sidebar_da_ref:553:1631ai_sidebar_da_ref:558:1634activity_bar_da_ref:520:1623ctx_menu_overlay_da:528:1625panel_hover_da:814:1701search_sidebar_da_ref:564:1638menu_dropdown_da:812:1700sidebar_inner_sw:559:1635ext_dyn_panel_box:557:1633explorer_panel_box:563:1637debug_panel_box:565:1639git_panel_box:566:1640ext_panel_box:567:1641settings_panel_box:568:1642ai_panel_box_ref:572:1644Plus
window_scrollbars(:574, init:1645), which is aHashMaprather than anOptionbut is populated only inside a block gated on two of the above.The live consequence: #723's GTK half cannot run
This is not a hypothetical cleanup.
e02a824(2026-09-01, one week after #672)landed the GTK half of #723 — inset the native
gtk4::Scrollbarpast the minimap stripso the two stop fighting over the pane's right edge. The geometry is correct. It is also
unreachable:
Both guards are permanently
None, sosync_scrollbarreturns before reaching eitherone.
window_scrollbarsis populated nowhere else. Nogtk4::Scrollbaris everconstructed under the runner, so
native_scrollbar_margin_start(:1438) andsync_scrollbar_positions(:1459) have no live caller, and #723's fix cannot execute.The commit message states the premise without drawing the conclusion:
Its four
native_scrollbar_placement_testsall exercisenative_scrollbar_margin_startin isolation: a pure function with no caller on any live path. They pass; they prove
nothing about the screen.
So #723 needs re-verifying on a display before it is closed, and whatever is actually
drawing the scrollbar the user sees is not this code. Two candidates worth checking
first: quadraui's own
gtk::draw_editorpainting a scrollbar into the single DA (theTUI-equivalent path), or the runner's
ScrolledWindowpolicy.Scope
contained the only implementation of a behaviour, that behaviour is already absent
at runtime — deleting it changes nothing on screen. Where deletion would remove the
last reference to a helper (
sync_scrollbar,create_window_scrollbars,sync_scrollbar_positions,native_scrollbar_margin_start,struct WindowScrollbars),delete the helper too.
scrollbar, then either re-fix No scrollbar when the minimap is on: quadraui's MinimapLayout.scrollbar is computed and discarded, and sync_scrollbar_positions doesn't know the strip exists #723 there or reopen it with the corrected diagnosis.
Do not delete
native_scrollbar_margin_start's logic without recording where theinset decision has to move to.
grep -rn '\.ai_panel\|\.ext_panel\|\.ext_sidebar\|\.diff_toolbar\|\.tab_scroll_offset' src/gtk/returns zero — theseScreenLayoutfields have no reader anywhere in the GTK backend.screen.ai_panelwas named in #592-B: GTK live path — paint the panel surfaces (quickfix, bottom_tabs, debug_toolbar, panel_hover, ai_panel) #670's scope but its commit paints only
quickfix/bottom_tabs/debug_toolbar/panel_hover. Confirm with a
GtkDrivertestwhether the AI panel paints at all; if not, that is a GTK live render path silently drops 13 populated ScreenLayout fields (rest of #587's blast radius) #592-class gap that survived
the epic.
Out of scope
enum Msgbus (separate issue).is the signal to file a quadraui issue instead — per
CLAUDE.md's Platform-NeutralityRule, the scrollbar is a surface quadraui should own for both backends.
Acceptance criteria
struct AppisOption-typed, initialisedNone, and never assigned.Add a comment to any deliberate exception saying who assigns it.
grep -rn 'gtk4::\(Box\|Overlay\|ScrolledWindow\)' src/gtk/returns only live uses.cargo build && cargo test && cargo clippy -- -D warnings && cargo fmt --checkallEXIT=0.
GtkDriverblack-box test covering whichever surface turns out to be the realscrollbar painter, stated in the PR as verified RED against unfixed
develop(
CLAUDE.md, "Black-box coverage is the acceptance bar", rule 2).user could observe. Expected answer: none — but it must be checked, not assumed.
Files
src/gtk/mod.rs(all of the above)src/gtk/testing.rs(new driver coverage)Milestone
#7 Platform-Neutral
Every line number above was measured on
develop @ 4872ab9(2026-09-01). They arealready wrong. #727 landed
src/gtk/mod.rs+435/−44 within hours and movedenum Msg1096→1131,fn dispatch1799→1896,sync_scrollbar2657→2754. Seven moreissues sit ahead of this one in the chain, each deleting or moving thousands of lines.
Treat the numbers as provenance — proof the claim was verified once — never as
coordinates. Locate by these anchors instead:
This is the same defect #734 exists to fix:
src/tui_main/carries 19mirrors mod.rs:NNNNcomments whose targets all drifted after #540, leaving the onlyrecord of a cross-backend contract pointing at unrelated code. Do not re-point the
numbers when they rot — the anchors are the durable form.