detached 8d80ed0

fix(core): keep a full-size dialog of a stashed window over the stash

A dialog shown over the cover that fills the usable area was sorted with
the covering floats, which are drawn under the stash: its stashed parent
hid it. Dialogs over the cover now always stay in the dialog group.
commit
8d80ed062915ab11a665282da0fc38d78348b34e
author
brice · · 2026-10-14 13:31 UTC
parent
877c74b
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +12 -3
M internal/core/layout.go +6 -3
@@ -1832,13 +1832,16 @@ func (w *Workspace) appendLayout(dst []Placement) []Placement {
18321832 )
18331833 appendFloats := func(group int) {
18341834 for _, f := range w.Floats {
1835- below := f.below && w.coversFloat(f)
1835+ // A dialog shown over the cover stays a dialog whatever its
1836+ // size, so a full-size one is not drawn under the stash.
1837+ dialog := cover != 0 && w.overCover(f)
1838+ below := f.below && w.coversFloat(f) && !dialog
18361839 // Dialogs stay over covering floats even when the latter is
18371840 // selected. Fullscreen floats remain in the upper group.
18381841 order := dialogs
18391842 if below {
18401843 order = belowTiles
1841- } else if w.coversFloat(f) || w.fullscreen == f.ID {
1844+ } else if !dialog && (w.coversFloat(f) || w.fullscreen == f.ID) {
18421845 order = coveringFloats
18431846 }
18441847 if order != group {
@@ -1847,7 +1850,7 @@ func (w *Workspace) appendLayout(dst []Placement) []Placement {
18471850 // A covering fullscreen window hides every float but the
18481851 // dialogs over it (overCover): the others show again when it
18491852 // leaves fullscreen.
1850- p := Placement{ID: f.ID, Rect: w.floatRect(f), Floating: true, Below: below, Focused: f.ID == focusedID, Inset: ports.SideAll, Hidden: cover != 0 && f.ID != cover && !w.overCover(f)}
1853+ p := Placement{ID: f.ID, Rect: w.floatRect(f), Floating: true, Below: below, Focused: f.ID == focusedID, Inset: ports.SideAll, Hidden: cover != 0 && f.ID != cover && !dialog}
18511854 if p.Hidden {
18521855 p.Rect = Rect{}
18531856 result = append(result, p)
@@ -1832,13 +1832,16 @@ func (w *Workspace) appendLayout(dst []Placement) []Placement {
1832 )1832 )
1833 appendFloats := func(group int) {1833 appendFloats := func(group int) {
1834 for _, f := range w.Floats {1834 for _, f := range w.Floats {
1835- below := f.below && w.coversFloat(f)1835+ // A dialog shown over the cover stays a dialog whatever its
1836+ // size, so a full-size one is not drawn under the stash.
1837+ dialog := cover != 0 && w.overCover(f)
1838+ below := f.below && w.coversFloat(f) && !dialog
1836 // Dialogs stay over covering floats even when the latter is1839 // Dialogs stay over covering floats even when the latter is
1837 // selected. Fullscreen floats remain in the upper group.1840 // selected. Fullscreen floats remain in the upper group.
1838 order := dialogs1841 order := dialogs
1839 if below {1842 if below {
1840 order = belowTiles1843 order = belowTiles
1841- } else if w.coversFloat(f) || w.fullscreen == f.ID {1844+ } else if !dialog && (w.coversFloat(f) || w.fullscreen == f.ID) {
1842 order = coveringFloats1845 order = coveringFloats
1843 }1846 }
1844 if order != group {1847 if order != group {
@@ -1847,7 +1850,7 @@ func (w *Workspace) appendLayout(dst []Placement) []Placement {
1847 // A covering fullscreen window hides every float but the1850 // A covering fullscreen window hides every float but the
1848 // dialogs over it (overCover): the others show again when it1851 // dialogs over it (overCover): the others show again when it
1849 // leaves fullscreen.1852 // leaves fullscreen.
1850- p := Placement{ID: f.ID, Rect: w.floatRect(f), Floating: true, Below: below, Focused: f.ID == focusedID, Inset: ports.SideAll, Hidden: cover != 0 && f.ID != cover && !w.overCover(f)}1853+ p := Placement{ID: f.ID, Rect: w.floatRect(f), Floating: true, Below: below, Focused: f.ID == focusedID, Inset: ports.SideAll, Hidden: cover != 0 && f.ID != cover && !dialog}
1851 if p.Hidden {1854 if p.Hidden {
1852 p.Rect = Rect{}1855 p.Rect = Rect{}
1853 result = append(result, p)1856 result = append(result, p)
M internal/core/stash_cover_test.go +6 -0
@@ -203,6 +203,12 @@ func TestActivateOverCover(t *testing.T) {
203203 w.AddDialog(9, 2, 20, 10)
204204 return 9
205205 }, 9, true},
206+ // A dialog filling the usable area is a covering float: it stays
207+ // over the stash all the same.
208+ {"full-size dialog of stashed", func(w *Workspace, _ WindowID) WindowID {
209+ w.AddDialog(9, 2, 100, 80)
210+ return 9
211+ }, 9, true},
206212 {"dialog of cover", func(w *Workspace, cover WindowID) WindowID {
207213 w.AddDialog(9, cover, 20, 10)
208214 w.FocusID(cover)
@@ -203,6 +203,12 @@ func TestActivateOverCover(t *testing.T) {
203 w.AddDialog(9, 2, 20, 10)203 w.AddDialog(9, 2, 20, 10)
204 return 9204 return 9
205 }, 9, true},205 }, 9, true},
206+ // A dialog filling the usable area is a covering float: it stays
207+ // over the stash all the same.
208+ {"full-size dialog of stashed", func(w *Workspace, _ WindowID) WindowID {
209+ w.AddDialog(9, 2, 100, 80)
210+ return 9
211+ }, 9, true},
206 {"dialog of cover", func(w *Workspace, cover WindowID) WindowID {212 {"dialog of cover", func(w *Workspace, cover WindowID) WindowID {
207 w.AddDialog(9, cover, 20, 10)213 w.AddDialog(9, cover, 20, 10)
208 w.FocusID(cover)214 w.FocusID(cover)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 25

Tags 10

↑↓ moveenter openesc close