detached a46ff66

fix(core): skip position hint band walk when disabled and document hint fade scheduling

commit
a46ff66551c2aa890d28d0cc0672c723f31f36c6
author
brice · · 2026-10-20 01:49 UTC
parent
392b5b6
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
4 files · +16 -8
M internal/core/gesture.go +4 -2
@@ -586,13 +586,15 @@ func (c *Core) animate(now time.Time, only *screen) {
586586 }
587587 }
588588
589-// sliding reports whether a spring or focus flash runs on the named output.
589+// sliding reports whether a spring, focus flash or position hint fade runs
590+// on the named output.
590591 func (c *Core) sliding(output string) bool {
591592 i := c.screenIndex(output)
592593 return i >= 0 && (c.screens[i].springing() || c.flashing(c.screens[i]) || c.positionHintFading(c.screens[i]))
593594 }
594595
595-// animating reports whether a spring or focus flash runs on any output.
596+// animating reports whether a spring, focus flash or position hint fade
597+// runs on any output.
596598 func (c *Core) animating() bool {
597599 if c.flash.running != nil {
598600 return true
@@ -586,13 +586,15 @@ func (c *Core) animate(now time.Time, only *screen) {
586 }586 }
587 }587 }
588 588
589-// sliding reports whether a spring or focus flash runs on the named output.589+// sliding reports whether a spring, focus flash or position hint fade runs
590+// on the named output.
590 func (c *Core) sliding(output string) bool {591 func (c *Core) sliding(output string) bool {
591 i := c.screenIndex(output)592 i := c.screenIndex(output)
592 return i >= 0 && (c.screens[i].springing() || c.flashing(c.screens[i]) || c.positionHintFading(c.screens[i]))593 return i >= 0 && (c.screens[i].springing() || c.flashing(c.screens[i]) || c.positionHintFading(c.screens[i]))
593 }594 }
594 595
595-// animating reports whether a spring or focus flash runs on any output.596+// animating reports whether a spring, focus flash or position hint fade
597+// runs on any output.
596 func (c *Core) animating() bool {598 func (c *Core) animating() bool {
597 if c.flash.running != nil {599 if c.flash.running != nil {
598 return true600 return true
M internal/core/position_hint.go +7 -1
@@ -41,6 +41,12 @@ func (c *Core) updatePositionHints(only *screen) {
4141 h.live, h.sample = false, ports.PositionHint{}
4242 continue
4343 }
44+ // Disabled hints skip the band walk; dropping the baseline keeps a
45+ // later re-enable from announcing the position it finds.
46+ if !c.cfg.Focus.PositionHint {
47+ *h = positionHintState{}
48+ continue
49+ }
4450 w := sc.mon.Current()
4551 band := 0
4652 if w.Overflow == OverflowCascade {
@@ -59,7 +65,7 @@ func (c *Core) updatePositionHints(only *screen) {
5965 }
6066 }
6167 h.workspace, h.band, h.focused, h.initialized = w, band, focused, true
62- if !c.cfg.Focus.PositionHint || c.protectionRequested() || w.cover() != 0 {
68+ if c.protectionRequested() || w.cover() != 0 {
6369 h.live, h.sample = false, ports.PositionHint{}
6470 continue
6571 }
@@ -41,6 +41,12 @@ func (c *Core) updatePositionHints(only *screen) {
41 h.live, h.sample = false, ports.PositionHint{}41 h.live, h.sample = false, ports.PositionHint{}
42 continue42 continue
43 }43 }
44+ // Disabled hints skip the band walk; dropping the baseline keeps a
45+ // later re-enable from announcing the position it finds.
46+ if !c.cfg.Focus.PositionHint {
47+ *h = positionHintState{}
48+ continue
49+ }
44 w := sc.mon.Current()50 w := sc.mon.Current()
45 band := 051 band := 0
46 if w.Overflow == OverflowCascade {52 if w.Overflow == OverflowCascade {
@@ -59,7 +65,7 @@ func (c *Core) updatePositionHints(only *screen) {
59 }65 }
60 }66 }
61 h.workspace, h.band, h.focused, h.initialized = w, band, focused, true67 h.workspace, h.band, h.focused, h.initialized = w, band, focused, true
62- if !c.cfg.Focus.PositionHint || c.protectionRequested() || w.cover() != 0 {68+ if c.protectionRequested() || w.cover() != 0 {
63 h.live, h.sample = false, ports.PositionHint{}69 h.live, h.sample = false, ports.PositionHint{}
64 continue70 continue
65 }71 }
M internal/core/position_hint_test.go +1 -1
@@ -55,7 +55,7 @@ func TestPositionHintChangesAndTiming(t *testing.T) {
5555 }
5656
5757 func TestPositionHintWorkspaceAndSuppression(t *testing.T) {
58- for _, mode := range []string{"workspace", "overview", "fullscreen", "off", "no-animation"} {
58+ for _, mode := range []string{"overview", "fullscreen", "off", "no-animation"} {
5959 t.Run(mode, func(t *testing.T) {
6060 c, clock := indicatorCore(t)
6161 c.cfg.Focus.PositionHint = true
@@ -55,7 +55,7 @@ func TestPositionHintChangesAndTiming(t *testing.T) {
55 }55 }
56 56
57 func TestPositionHintWorkspaceAndSuppression(t *testing.T) {57 func TestPositionHintWorkspaceAndSuppression(t *testing.T) {
58- for _, mode := range []string{"workspace", "overview", "fullscreen", "off", "no-animation"} {58+ for _, mode := range []string{"overview", "fullscreen", "off", "no-animation"} {
59 t.Run(mode, func(t *testing.T) {59 t.Run(mode, func(t *testing.T) {
60 c, clock := indicatorCore(t)60 c, clock := indicatorCore(t)
61 c.cfg.Focus.PositionHint = true61 c.cfg.Focus.PositionHint = true
M internal/ports/scene.go +4 -4
@@ -79,10 +79,10 @@ type Scene struct {
7979 Flash *FocusFlash
8080 // PositionHint is drawn on the physical output only, never in captures.
8181 PositionHint PositionHint
82- // Animating is set by core when a spring or a focus flash runs on
83- // this output after this frame was computed: the output reports the
84- // flip of the scene to core (OutputFrame), which moves the animation to
85- // the next frame. A scene of a settled output carries false, so a flip
82+ // Animating is set by core when a spring, a focus flash or a position
83+ // hint fade runs on this output after this frame was computed: the
84+ // output reports the flip of the scene to core (OutputFrame), which
85+ // moves the animation to the next frame. A scene of a settled output carries false, so a flip
8686 // of it wakes nobody. It describes scheduling, not drawing: SameAs and
8787 // the renderer ignore it.
8888 Animating bool
@@ -79,10 +79,10 @@ type Scene struct {
79 Flash *FocusFlash79 Flash *FocusFlash
80 // PositionHint is drawn on the physical output only, never in captures.80 // PositionHint is drawn on the physical output only, never in captures.
81 PositionHint PositionHint81 PositionHint PositionHint
82- // Animating is set by core when a spring or a focus flash runs on82+ // Animating is set by core when a spring, a focus flash or a position
83- // this output after this frame was computed: the output reports the83+ // hint fade runs on this output after this frame was computed: the
84- // flip of the scene to core (OutputFrame), which moves the animation to84+ // output reports the flip of the scene to core (OutputFrame), which
85- // the next frame. A scene of a settled output carries false, so a flip85+ // moves the animation to the next frame. A scene of a settled output carries false, so a flip
86 // of it wakes nobody. It describes scheduling, not drawing: SameAs and86 // of it wakes nobody. It describes scheduling, not drawing: SameAs and
87 // the renderer ignore it.87 // the renderer ignore it.
88 Animating bool88 Animating bool

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