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 Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· 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 { | |||
| 1832 | 1832 | ) | |
| 1833 | 1833 | appendFloats := func(group int) { | |
| 1834 | 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 | 1839 | // Dialogs stay over covering floats even when the latter is | |
| 1837 | 1840 | // selected. Fullscreen floats remain in the upper group. | |
| 1838 | 1841 | order := dialogs | |
| 1839 | 1842 | if below { | |
| 1840 | 1843 | order = belowTiles | |
| 1841 | - | } else if w.coversFloat(f) || w.fullscreen == f.ID { | |
| 1844 | + | } else if !dialog && (w.coversFloat(f) || w.fullscreen == f.ID) { | |
| 1842 | 1845 | order = coveringFloats | |
| 1843 | 1846 | } | |
| 1844 | 1847 | if order != group { | |
| @@ -1847,7 +1850,7 @@ func (w *Workspace) appendLayout(dst []Placement) []Placement { | |||
| 1847 | 1850 | // A covering fullscreen window hides every float but the | |
| 1848 | 1851 | // dialogs over it (overCover): the others show again when it | |
| 1849 | 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 | 1854 | if p.Hidden { | |
| 1852 | 1855 | p.Rect = Rect{} | |
| 1853 | 1856 | 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 is | 1839 | // 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 := dialogs | 1841 | order := dialogs | ||
| 1839 | if below { | 1842 | if below { | ||
| 1840 | order = belowTiles | 1843 | 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 = coveringFloats | 1845 | 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 the | 1850 | // A covering fullscreen window hides every float but the | ||
| 1848 | // dialogs over it (overCover): the others show again when it | 1851 | // 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) { | |||
| 203 | 203 | w.AddDialog(9, 2, 20, 10) | |
| 204 | 204 | return 9 | |
| 205 | 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 | 212 | {"dialog of cover", func(w *Workspace, cover WindowID) WindowID { | |
| 207 | 213 | w.AddDialog(9, cover, 20, 10) | |
| 208 | 214 | 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 9 | 204 | 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) | ||