detached 4c917cf

fix(core): abort border resize when the workspace goes fullscreen

commit
4c917cfcaa22857cf9cb4f382b5f591e02d4c216
author
brice · · 2026-10-21 05:42 UTC
committer
brice · · 2026-10-21 07:11 UTC
parent
080065e
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +28 -1
M internal/core/border_resize.go +1 -1
@@ -38,7 +38,7 @@ func (g *borderResize) cursor() string {
3838
3939 func (g *borderResize) valid() bool {
4040 c, s, w := g.core, g.screen, g.ws
41- if !slices.Contains(c.screens, s) || s.mon.Current() != w || s.mon.previewing() || s.mon.ov.open || w.pinned() || len(w.Columns) != len(g.saved) {
41+ if !slices.Contains(c.screens, s) || s.mon.Current() != w || s.mon.previewing() || s.mon.ov.open || w.pinned() || w.fullscreen != 0 || len(w.Columns) != len(g.saved) {
4242 return false
4343 }
4444 for i, col := range w.Columns {
@@ -38,7 +38,7 @@ func (g *borderResize) cursor() string {
38 38
39 func (g *borderResize) valid() bool {39 func (g *borderResize) valid() bool {
40 c, s, w := g.core, g.screen, g.ws40 c, s, w := g.core, g.screen, g.ws
41- if !slices.Contains(c.screens, s) || s.mon.Current() != w || s.mon.previewing() || s.mon.ov.open || w.pinned() || len(w.Columns) != len(g.saved) {41+ if !slices.Contains(c.screens, s) || s.mon.Current() != w || s.mon.previewing() || s.mon.ov.open || w.pinned() || w.fullscreen != 0 || len(w.Columns) != len(g.saved) {
42 return false42 return false
43 }43 }
44 for i, col := range w.Columns {44 for i, col := range w.Columns {
M internal/core/pointergrab_test.go +27 -0
@@ -262,3 +262,30 @@ func TestPointerGrabValidityContract(t *testing.T) {
262262 t.Fatal("grab survived output removal")
263263 }
264264 }
265+
266+func TestBorderGrabFullscreenPublish(t *testing.T) {
267+ c, w := borderCore(t, false)
268+ w.Overflow = OverflowScroll
269+ grabButton(t, c, btnRight, true, time.Second)
270+ if c.pgrab == nil {
271+ t.Fatal("grab not started")
272+ }
273+ grabCommands(c)
274+ w.fullscreen = 1
275+ if err := c.publish(context.Background()); err != nil {
276+ t.Fatal(err)
277+ }
278+ if c.pgrab != nil || !c.swallow[btnRight] {
279+ t.Fatal("fullscreen did not abort grab and swallow release")
280+ }
281+ requireOverride(t, grabCommands(c), "")
282+ grabButton(t, c, btnRight, false, 2*time.Second)
283+ for _, cmd := range grabCommands(c) {
284+ if _, ok := cmd.(ports.PointerButtonTo); ok {
285+ t.Fatal("release forwarded")
286+ }
287+ }
288+ if c.buttons[btnRight] || c.swallow[btnRight] {
289+ t.Fatal("release still held")
290+ }
291+}
@@ -262,3 +262,30 @@ func TestPointerGrabValidityContract(t *testing.T) {
262 t.Fatal("grab survived output removal")262 t.Fatal("grab survived output removal")
263 }263 }
264 }264 }
265+
266+func TestBorderGrabFullscreenPublish(t *testing.T) {
267+ c, w := borderCore(t, false)
268+ w.Overflow = OverflowScroll
269+ grabButton(t, c, btnRight, true, time.Second)
270+ if c.pgrab == nil {
271+ t.Fatal("grab not started")
272+ }
273+ grabCommands(c)
274+ w.fullscreen = 1
275+ if err := c.publish(context.Background()); err != nil {
276+ t.Fatal(err)
277+ }
278+ if c.pgrab != nil || !c.swallow[btnRight] {
279+ t.Fatal("fullscreen did not abort grab and swallow release")
280+ }
281+ requireOverride(t, grabCommands(c), "")
282+ grabButton(t, c, btnRight, false, 2*time.Second)
283+ for _, cmd := range grabCommands(c) {
284+ if _, ok := cmd.(ports.PointerButtonTo); ok {
285+ t.Fatal("release forwarded")
286+ }
287+ }
288+ if c.buttons[btnRight] || c.swallow[btnRight] {
289+ t.Fatal("release still held")
290+ }
291+}

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 23

Tags 10

↑↓ moveenter openesc close