detached d6ec785

refactor(drm): drop the unreachable own-separator overlay check

A float's own lines lie inside its rect and only exist with borders on, where the inset check already refuses it. Tests now cover stacking: a window under or over the candidate, popups after it, hidden and touching popups.
commit
d6ec785f0ad373545f431515c3482944d34e7c30
author
brice · · 2026-10-08 05:12 UTC
parent
892d98e
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +30 -6
M internal/adapters/drm/overlay.go +1 -1
@@ -141,7 +141,7 @@ func overlayCandidate(s ports.Scene, surfaces map[ports.WindowID]ports.SurfaceCo
141141 return ports.SceneWindow{}, ports.SurfaceContent{}, colorBypass, "border"
142142 }
143143 for _, sep := range s.Separators {
144- if sep.Window == pick.ID || sep.Rect.Overlaps(pick.Rect) {
144+ if sep.Rect.Overlaps(pick.Rect) {
145145 // The overlay shows the buffer alone; the lines would go
146146 // under it.
147147 return ports.SceneWindow{}, ports.SurfaceContent{}, colorBypass, "border"
@@ -141,7 +141,7 @@ func overlayCandidate(s ports.Scene, surfaces map[ports.WindowID]ports.SurfaceCo
141 return ports.SceneWindow{}, ports.SurfaceContent{}, colorBypass, "border"141 return ports.SceneWindow{}, ports.SurfaceContent{}, colorBypass, "border"
142 }142 }
143 for _, sep := range s.Separators {143 for _, sep := range s.Separators {
144- if sep.Window == pick.ID || sep.Rect.Overlaps(pick.Rect) {144+ if sep.Rect.Overlaps(pick.Rect) {
145 // The overlay shows the buffer alone; the lines would go145 // The overlay shows the buffer alone; the lines would go
146 // under it.146 // under it.
147 return ports.SceneWindow{}, ports.SurfaceContent{}, colorBypass, "border"147 return ports.SceneWindow{}, ports.SurfaceContent{}, colorBypass, "border"
M internal/adapters/drm/overlay_test.go +29 -5
@@ -233,11 +233,6 @@ func TestOverlayPopupAndBorder(t *testing.T) {
233233 t.Fatalf("border: %q", reason)
234234 }
235235 s, _ = overlayScene()
236- s.Separators = []ports.Separator{{Rect: ports.Rect{X: 300, W: 2, H: 2}, Window: 2}}
237- if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != "border" {
238- t.Fatalf("own border: %q", reason)
239- }
240- s, _ = overlayScene()
241236 s.Border.Width = 2
242237 s.Windows[1].Inset = ports.SideLeft
243238 if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != "border" {
@@ -269,6 +264,35 @@ func TestOverlayIgnoresWhatDoesNotCoverIt(t *testing.T) {
269264 }
270265 }
271266
267+// Draw order decides: a window listed before the candidate is under it, one
268+// after is over it; a popup is over it wherever it is listed, unless hidden.
269+func TestOverlayStackingOrder(t *testing.T) {
270+ under := ports.SceneWindow{ID: 8, Floating: true, Below: true, Rect: ports.Rect{X: 120, W: 20, H: 20}}
271+ over := under
272+ over.Below = false
273+ popup := ports.SceneWindow{ID: 7, Popup: true, Rect: ports.Rect{X: 120, W: 20, H: 20}}
274+ for name, tc := range map[string]struct {
275+ edit func(*ports.Scene)
276+ want string
277+ }{
278+ "window under": {func(s *ports.Scene) { s.Windows = append([]ports.SceneWindow{under}, s.Windows...) }, ""},
279+ "window over": {func(s *ports.Scene) { s.Windows = append(s.Windows, over) }, "window_above"},
280+ "popup after": {func(s *ports.Scene) { s.Windows = append(s.Windows, popup) }, "window_above"},
281+ "hidden popup": {func(s *ports.Scene) { p := popup; p.Hidden = true; s.Windows = append(s.Windows, p) }, ""},
282+ "popup touching": {func(s *ports.Scene) {
283+ p := popup
284+ p.Rect.X = 80
285+ s.Windows = append(s.Windows, p)
286+ }, ""},
287+ } {
288+ s, c := overlayScene()
289+ tc.edit(&s)
290+ if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != tc.want {
291+ t.Errorf("%s: reason %q, want %q", name, reason, tc.want)
292+ }
293+ }
294+}
295+
272296 // A cursor commit refused with the overlay on drops the overlay: the
273297 // next frame is composed.
274298 func TestOverlayCursorConflictDropsOverlay(t *testing.T) {
@@ -233,11 +233,6 @@ func TestOverlayPopupAndBorder(t *testing.T) {
233 t.Fatalf("border: %q", reason)233 t.Fatalf("border: %q", reason)
234 }234 }
235 s, _ = overlayScene()235 s, _ = overlayScene()
236- s.Separators = []ports.Separator{{Rect: ports.Rect{X: 300, W: 2, H: 2}, Window: 2}}
237- if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != "border" {
238- t.Fatalf("own border: %q", reason)
239- }
240- s, _ = overlayScene()
241 s.Border.Width = 2236 s.Border.Width = 2
242 s.Windows[1].Inset = ports.SideLeft237 s.Windows[1].Inset = ports.SideLeft
243 if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != "border" {238 if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != "border" {
@@ -269,6 +264,35 @@ func TestOverlayIgnoresWhatDoesNotCoverIt(t *testing.T) {
269 }264 }
270 }265 }
271 266
267+// Draw order decides: a window listed before the candidate is under it, one
268+// after is over it; a popup is over it wherever it is listed, unless hidden.
269+func TestOverlayStackingOrder(t *testing.T) {
270+ under := ports.SceneWindow{ID: 8, Floating: true, Below: true, Rect: ports.Rect{X: 120, W: 20, H: 20}}
271+ over := under
272+ over.Below = false
273+ popup := ports.SceneWindow{ID: 7, Popup: true, Rect: ports.Rect{X: 120, W: 20, H: 20}}
274+ for name, tc := range map[string]struct {
275+ edit func(*ports.Scene)
276+ want string
277+ }{
278+ "window under": {func(s *ports.Scene) { s.Windows = append([]ports.SceneWindow{under}, s.Windows...) }, ""},
279+ "window over": {func(s *ports.Scene) { s.Windows = append(s.Windows, over) }, "window_above"},
280+ "popup after": {func(s *ports.Scene) { s.Windows = append(s.Windows, popup) }, "window_above"},
281+ "hidden popup": {func(s *ports.Scene) { p := popup; p.Hidden = true; s.Windows = append(s.Windows, p) }, ""},
282+ "popup touching": {func(s *ports.Scene) {
283+ p := popup
284+ p.Rect.X = 80
285+ s.Windows = append(s.Windows, p)
286+ }, ""},
287+ } {
288+ s, c := overlayScene()
289+ tc.edit(&s)
290+ if _, _, _, reason := overlayCandidate(s, c, false, nil, nil); reason != tc.want {
291+ t.Errorf("%s: reason %q, want %q", name, reason, tc.want)
292+ }
293+ }
294+}
295+
272 // A cursor commit refused with the overlay on drops the overlay: the296 // A cursor commit refused with the overlay on drops the overlay: the
273 // next frame is composed.297 // next frame is composed.
274 func TestOverlayCursorConflictDropsOverlay(t *testing.T) {298 func TestOverlayCursorConflictDropsOverlay(t *testing.T) {

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