detached e5d6019

style(ui): fade touchpad navigation indicator

commit
e5d60196ab9d79fcd9ca48d4112fddd96072eabe
author
brice · · 2026-06-18 10:09 UTC
parent
0d3b8ed
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +39 -3
M internal/ui/component/touchpad_navigation_indicator.go +5 -0
@@ -120,6 +120,7 @@ func (i *TouchpadNavigationIndicator) ShowGesture(gesture port.TouchpadNavigatio
120120 }
121121 i.cancelHideTimer()
122122
123+ i.container.RemoveCssClass("hiding")
123124 i.container.RemoveCssClass("back")
124125 i.container.RemoveCssClass("forward")
125126 if gesture.Action == port.TouchpadNavigationForward {
@@ -173,6 +174,9 @@ func (i *TouchpadNavigationIndicator) scheduleHide(triggered bool) {
173174 i.hide()
174175 return
175176 }
177+ if i.container != nil {
178+ i.container.AddCssClass("hiding")
179+ }
176180 cb := glib.SourceFunc(func(_ uintptr) bool {
177181 i.hideTimer = 0
178182 i.hide()
@@ -184,6 +188,7 @@ func (i *TouchpadNavigationIndicator) scheduleHide(triggered bool) {
184188 func (i *TouchpadNavigationIndicator) hide() {
185189 i.cancelHideTimer()
186190 if i.container != nil {
191+ i.container.RemoveCssClass("hiding")
187192 i.container.RemoveCssClass("threshold-reached")
188193 i.container.RemoveCssClass("back")
189194 i.container.RemoveCssClass("forward")
@@ -120,6 +120,7 @@ func (i *TouchpadNavigationIndicator) ShowGesture(gesture port.TouchpadNavigatio
120 }120 }
121 i.cancelHideTimer()121 i.cancelHideTimer()
122 122
123+ i.container.RemoveCssClass("hiding")
123 i.container.RemoveCssClass("back")124 i.container.RemoveCssClass("back")
124 i.container.RemoveCssClass("forward")125 i.container.RemoveCssClass("forward")
125 if gesture.Action == port.TouchpadNavigationForward {126 if gesture.Action == port.TouchpadNavigationForward {
@@ -173,6 +174,9 @@ func (i *TouchpadNavigationIndicator) scheduleHide(triggered bool) {
173 i.hide()174 i.hide()
174 return175 return
175 }176 }
177+ if i.container != nil {
178+ i.container.AddCssClass("hiding")
179+ }
176 cb := glib.SourceFunc(func(_ uintptr) bool {180 cb := glib.SourceFunc(func(_ uintptr) bool {
177 i.hideTimer = 0181 i.hideTimer = 0
178 i.hide()182 i.hide()
@@ -184,6 +188,7 @@ func (i *TouchpadNavigationIndicator) scheduleHide(triggered bool) {
184 func (i *TouchpadNavigationIndicator) hide() {188 func (i *TouchpadNavigationIndicator) hide() {
185 i.cancelHideTimer()189 i.cancelHideTimer()
186 if i.container != nil {190 if i.container != nil {
191+ i.container.RemoveCssClass("hiding")
187 i.container.RemoveCssClass("threshold-reached")192 i.container.RemoveCssClass("threshold-reached")
188 i.container.RemoveCssClass("back")193 i.container.RemoveCssClass("back")
189 i.container.RemoveCssClass("forward")194 i.container.RemoveCssClass("forward")
M internal/ui/theme/css.go +16 -3
@@ -770,16 +770,22 @@ func generateTouchpadNavigationIndicatorCSS(p Palette) string {
770770 return `/* ===== Touchpad Navigation Indicator Styling ===== */
771771
772772 .touchpad-navigation-indicator {
773- background-color: alpha(var(--surface), 0.94);
773+ background-color: alpha(var(--surface), 0.90);
774774 color: var(--text);
775775 border: 0.0625em solid alpha(var(--border), 0.72);
776776 border-radius: 1.125em;
777777 padding: 0.75em 0.875em 0.8125em;
778+ opacity: 1;
779+ filter: blur(0px);
780+ backdrop-filter: blur(0.75em);
778781 box-shadow: 0 1em 2.25em alpha(black, 0.30),
779782 0 0.0625em 0 alpha(white, 0.06) inset;
780- transition: background-color 140ms ease-out,
783+ transition: opacity 220ms ease-out,
784+ filter 220ms ease-out,
785+ backdrop-filter 220ms ease-out,
786+ background-color 140ms ease-out,
781787 border-color 140ms ease-out,
782- box-shadow 140ms ease-out;
788+ box-shadow 220ms ease-out;
783789 }
784790
785791 .touchpad-navigation-indicator.back {
@@ -797,6 +803,13 @@ func generateTouchpadNavigationIndicatorCSS(p Palette) string {
797803 0 0 0 0.0625em alpha(var(--accent), 0.24) inset;
798804 }
799805
806+.touchpad-navigation-indicator.hiding {
807+ opacity: 0;
808+ filter: blur(0.0625em);
809+ box-shadow: 0 0.375em 0.875em alpha(black, 0.10),
810+ 0 0 0 0.0625em alpha(var(--accent), 0.04) inset;
811+}
812+
800813 .touchpad-navigation-header {
801814 min-width: 9.75em;
802815 }
@@ -770,16 +770,22 @@ func generateTouchpadNavigationIndicatorCSS(p Palette) string {
770 return `/* ===== Touchpad Navigation Indicator Styling ===== */770 return `/* ===== Touchpad Navigation Indicator Styling ===== */
771 771
772 .touchpad-navigation-indicator {772 .touchpad-navigation-indicator {
773- background-color: alpha(var(--surface), 0.94);773+ background-color: alpha(var(--surface), 0.90);
774 color: var(--text);774 color: var(--text);
775 border: 0.0625em solid alpha(var(--border), 0.72);775 border: 0.0625em solid alpha(var(--border), 0.72);
776 border-radius: 1.125em;776 border-radius: 1.125em;
777 padding: 0.75em 0.875em 0.8125em;777 padding: 0.75em 0.875em 0.8125em;
778+ opacity: 1;
779+ filter: blur(0px);
780+ backdrop-filter: blur(0.75em);
778 box-shadow: 0 1em 2.25em alpha(black, 0.30),781 box-shadow: 0 1em 2.25em alpha(black, 0.30),
779 0 0.0625em 0 alpha(white, 0.06) inset;782 0 0.0625em 0 alpha(white, 0.06) inset;
780- transition: background-color 140ms ease-out,783+ transition: opacity 220ms ease-out,
784+ filter 220ms ease-out,
785+ backdrop-filter 220ms ease-out,
786+ background-color 140ms ease-out,
781 border-color 140ms ease-out,787 border-color 140ms ease-out,
782- box-shadow 140ms ease-out;788+ box-shadow 220ms ease-out;
783 }789 }
784 790
785 .touchpad-navigation-indicator.back {791 .touchpad-navigation-indicator.back {
@@ -797,6 +803,13 @@ func generateTouchpadNavigationIndicatorCSS(p Palette) string {
797 0 0 0 0.0625em alpha(var(--accent), 0.24) inset;803 0 0 0 0.0625em alpha(var(--accent), 0.24) inset;
798 }804 }
799 805
806+.touchpad-navigation-indicator.hiding {
807+ opacity: 0;
808+ filter: blur(0.0625em);
809+ box-shadow: 0 0.375em 0.875em alpha(black, 0.10),
810+ 0 0 0 0.0625em alpha(var(--accent), 0.04) inset;
811+}
812+
800 .touchpad-navigation-header {813 .touchpad-navigation-header {
801 min-width: 9.75em;814 min-width: 9.75em;
802 }815 }
M internal/ui/theme/css_test.go +18 -0
@@ -235,6 +235,24 @@ func cssRuleBlock(t *testing.T, css, selector string) string {
235235 return matches[1]
236236 }
237237
238+func TestGenerateCSS_TouchpadNavigationIndicatorFadesWholeOverlay(t *testing.T) {
239+ css := GenerateCSS(DefaultDarkPalette())
240+
241+ baseBlock := cssRuleBlock(t, css, ".touchpad-navigation-indicator")
242+ assert.Contains(t, baseBlock, "opacity: 1;")
243+ assert.Contains(t, baseBlock, "filter: blur(0px);")
244+ assert.Contains(t, baseBlock, "backdrop-filter: blur(0.75em);")
245+ assert.Contains(t, baseBlock, "transition: opacity 220ms ease-out,")
246+ assert.Contains(t, baseBlock, "filter 220ms ease-out,")
247+ assert.Contains(t, baseBlock, "backdrop-filter 220ms ease-out,")
248+ assert.Contains(t, baseBlock, "box-shadow 220ms ease-out;")
249+
250+ hidingBlock := cssRuleBlock(t, css, ".touchpad-navigation-indicator.hiding")
251+ assert.Contains(t, hidingBlock, "opacity: 0;")
252+ assert.Contains(t, hidingBlock, "filter: blur(0.0625em);")
253+ assert.Contains(t, hidingBlock, "box-shadow:")
254+}
255+
238256 func TestGenerateCSS_DoesNotEmitUnsupportedGTKProperties(t *testing.T) {
239257 css := GenerateCSS(DefaultDarkPalette())
240258
@@ -235,6 +235,24 @@ func cssRuleBlock(t *testing.T, css, selector string) string {
235 return matches[1]235 return matches[1]
236 }236 }
237 237
238+func TestGenerateCSS_TouchpadNavigationIndicatorFadesWholeOverlay(t *testing.T) {
239+ css := GenerateCSS(DefaultDarkPalette())
240+
241+ baseBlock := cssRuleBlock(t, css, ".touchpad-navigation-indicator")
242+ assert.Contains(t, baseBlock, "opacity: 1;")
243+ assert.Contains(t, baseBlock, "filter: blur(0px);")
244+ assert.Contains(t, baseBlock, "backdrop-filter: blur(0.75em);")
245+ assert.Contains(t, baseBlock, "transition: opacity 220ms ease-out,")
246+ assert.Contains(t, baseBlock, "filter 220ms ease-out,")
247+ assert.Contains(t, baseBlock, "backdrop-filter 220ms ease-out,")
248+ assert.Contains(t, baseBlock, "box-shadow 220ms ease-out;")
249+
250+ hidingBlock := cssRuleBlock(t, css, ".touchpad-navigation-indicator.hiding")
251+ assert.Contains(t, hidingBlock, "opacity: 0;")
252+ assert.Contains(t, hidingBlock, "filter: blur(0.0625em);")
253+ assert.Contains(t, hidingBlock, "box-shadow:")
254+}
255+
238 func TestGenerateCSS_DoesNotEmitUnsupportedGTKProperties(t *testing.T) {256 func TestGenerateCSS_DoesNotEmitUnsupportedGTKProperties(t *testing.T) {
239 css := GenerateCSS(DefaultDarkPalette())257 css := GenerateCSS(DefaultDarkPalette())
240 258

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 8

Tags 42

↑↓ moveenter openesc close