feat(config): replace animations.slowdown with animations.speed and make normal faster
- commit
- 1c70add6c2b75447de6a2465160057e4aac2b774
- author
- brice · · 2026-10-05 07:44 UTC
- parent
- f6e232f
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
7 files · +39 -17
M README.md +1 -1
| @@ -18,7 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | I wanted a compositor I would never have to think about. It takes the newest Wayland protocols and kernel features as they land, gives games the whole GPU, and otherwise stays out of sight. | |
| 20 | 20 | ||
| 21 | - | It is small on purpose, and it will stay small. Drawing is kept to simple primitives: no blur, no shadows, no rounded corners, no themes. There is no built-in bar or wallpaper either; for those, bring your own: any layer-shell client works. Animations are experimental and off by default (`animations = on` turns them on); off, every change is instant and touchpad swipes switch on release. With them, three-finger swipes follow the fingers, windows and the view move with short springs (about 300 ms) when you scroll, switch workspaces, move columns or windows, resize them, drop a dragged tile or send a workspace to another monitor; windows fade in and out when they open, close or leave with the stash, the overview zooms its cards, and a brief pulse marks the window you just focused. They stay cheap: nothing runs while the screen is still, frames follow the display, only the region that moves is redrawn, apps are resized once, to their final size, and do not redraw during a transition, and nothing is copied or blurred. About 40–80 MB of RAM with two 4K monitors, and almost no CPU while the screen does not change. | |
| 21 | + | It is small on purpose, and it will stay small. Drawing is kept to simple primitives: no blur, no shadows, no rounded corners, no themes. There is no built-in bar or wallpaper either; for those, bring your own: any layer-shell client works. Animations are experimental and off by default (`animations = on` turns them on); off, every change is instant and touchpad swipes switch on release. With them, three-finger swipes follow the fingers, windows and the view move with short springs (about 180 ms) when you scroll, switch workspaces, move columns or windows, resize them, drop a dragged tile or send a workspace to another monitor; windows fade in and out when they open, close or leave with the stash, the overview zooms its cards, and a brief pulse marks the window you just focused. They stay cheap: nothing runs while the screen is still, frames follow the display, only the region that moves is redrawn, apps are resized once, to their final size, and do not redraw during a transition, and nothing is copied or blurred. About 40–80 MB of RAM with two 4K monitors, and almost no CPU while the screen does not change. | |
| 22 | 22 | ||
| 23 | 23 | ## OK, but why Go? | |
| 24 | 24 | ||
| @@ -18,7 +18,7 @@ | |||||
| 18 | 18 | ||||
| 19 | I wanted a compositor I would never have to think about. It takes the newest Wayland protocols and kernel features as they land, gives games the whole GPU, and otherwise stays out of sight. | 19 | I wanted a compositor I would never have to think about. It takes the newest Wayland protocols and kernel features as they land, gives games the whole GPU, and otherwise stays out of sight. | ||
| 20 | 20 | ||||
| 21 | - | It is small on purpose, and it will stay small. Drawing is kept to simple primitives: no blur, no shadows, no rounded corners, no themes. There is no built-in bar or wallpaper either; for those, bring your own: any layer-shell client works. Animations are experimental and off by default (`animations = on` turns them on); off, every change is instant and touchpad swipes switch on release. With them, three-finger swipes follow the fingers, windows and the view move with short springs (about 300 ms) when you scroll, switch workspaces, move columns or windows, resize them, drop a dragged tile or send a workspace to another monitor; windows fade in and out when they open, close or leave with the stash, the overview zooms its cards, and a brief pulse marks the window you just focused. They stay cheap: nothing runs while the screen is still, frames follow the display, only the region that moves is redrawn, apps are resized once, to their final size, and do not redraw during a transition, and nothing is copied or blurred. About 40–80 MB of RAM with two 4K monitors, and almost no CPU while the screen does not change. | 21 | + | It is small on purpose, and it will stay small. Drawing is kept to simple primitives: no blur, no shadows, no rounded corners, no themes. There is no built-in bar or wallpaper either; for those, bring your own: any layer-shell client works. Animations are experimental and off by default (`animations = on` turns them on); off, every change is instant and touchpad swipes switch on release. With them, three-finger swipes follow the fingers, windows and the view move with short springs (about 180 ms) when you scroll, switch workspaces, move columns or windows, resize them, drop a dragged tile or send a workspace to another monitor; windows fade in and out when they open, close or leave with the stash, the overview zooms its cards, and a brief pulse marks the window you just focused. They stay cheap: nothing runs while the screen is still, frames follow the display, only the region that moves is redrawn, apps are resized once, to their final size, and do not redraw during a transition, and nothing is copied or blurred. About 40–80 MB of RAM with two 4K monitors, and almost no CPU while the screen does not change. |
| 22 | 22 | ||||
| 23 | ## OK, but why Go? | 23 | ## OK, but why Go? | ||
| 24 | 24 | ||||
M docs/config.md +1 -1
| @@ -45,7 +45,7 @@ NeferWL reads `$XDG_CONFIG_HOME/neferwl/config` (or `~/.config/neferwl/config`). | |||
| 45 | 45 | | `mouse.left-handed` | `off` | Swaps the left and right mouse buttons | | |
| 46 | 46 | | `cursor.hide-after` | `5s` | Hides the pointer cursor after this long without motion; the next motion shows it. 100ms to 1h, or `off` | | |
| 47 | 47 | | `animations` | `off` | **Experimental.** `on` animates changes; `off` makes every change instant and the three-finger swipe no longer follows the fingers: swipe landings, scrolling, workspace switches, window moves and resizes, drag drops, workspaces sent to another monitor, the overview, windows opening and closing, the stash showing and hiding, the focus pulse | | |
| 48 | - | | `animations.slowdown` | `1` | Multiplies the duration of every spring (not the focus pulse), `0.1` to `10` | | |
| 48 | + | | `animations.speed` | `normal` | Speed of every spring (not the focus pulse): `slow`, `normal` or `fast` (a view move lands in about 260, 180 or 130 ms), or a number relative to `normal`, from `0.1` (10× slower) to `10` (10× faster) | | |
| 49 | 49 | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | |
| 50 | 50 | | `focus.animation` | `pulse` | Focus indicator on a window that keeps the focus for 150 ms: `pulse` (brief rise and fall) or `off`. Skipped for fullscreen windows, a window alone on screen (e.g. a maximized column), the overview and a window focused as it opens. Off while `animations = off` | | |
| 51 | 51 | | `focus.effect` | `screen` | What the focus indicator draws: `screen` brightens the window slightly, visible on black too. HDR (PQ) client content is not brightened on HDR outputs | | |
| @@ -45,7 +45,7 @@ NeferWL reads `$XDG_CONFIG_HOME/neferwl/config` (or `~/.config/neferwl/config`). | |||||
| 45 | | `mouse.left-handed` | `off` | Swaps the left and right mouse buttons | | 45 | | `mouse.left-handed` | `off` | Swaps the left and right mouse buttons | | ||
| 46 | | `cursor.hide-after` | `5s` | Hides the pointer cursor after this long without motion; the next motion shows it. 100ms to 1h, or `off` | | 46 | | `cursor.hide-after` | `5s` | Hides the pointer cursor after this long without motion; the next motion shows it. 100ms to 1h, or `off` | | ||
| 47 | | `animations` | `off` | **Experimental.** `on` animates changes; `off` makes every change instant and the three-finger swipe no longer follows the fingers: swipe landings, scrolling, workspace switches, window moves and resizes, drag drops, workspaces sent to another monitor, the overview, windows opening and closing, the stash showing and hiding, the focus pulse | | 47 | | `animations` | `off` | **Experimental.** `on` animates changes; `off` makes every change instant and the three-finger swipe no longer follows the fingers: swipe landings, scrolling, workspace switches, window moves and resizes, drag drops, workspaces sent to another monitor, the overview, windows opening and closing, the stash showing and hiding, the focus pulse | | ||
| 48 | - | | `animations.slowdown` | `1` | Multiplies the duration of every spring (not the focus pulse), `0.1` to `10` | | 48 | + | | `animations.speed` | `normal` | Speed of every spring (not the focus pulse): `slow`, `normal` or `fast` (a view move lands in about 260, 180 or 130 ms), or a number relative to `normal`, from `0.1` (10× slower) to `10` (10× faster) | |
| 49 | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | 49 | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | ||
| 50 | | `focus.animation` | `pulse` | Focus indicator on a window that keeps the focus for 150 ms: `pulse` (brief rise and fall) or `off`. Skipped for fullscreen windows, a window alone on screen (e.g. a maximized column), the overview and a window focused as it opens. Off while `animations = off` | | 50 | | `focus.animation` | `pulse` | Focus indicator on a window that keeps the focus for 150 ms: `pulse` (brief rise and fall) or `off`. Skipped for fullscreen windows, a window alone on screen (e.g. a maximized column), the overview and a window focused as it opens. Off while `animations = off` | | ||
| 51 | | `focus.effect` | `screen` | What the focus indicator draws: `screen` brightens the window slightly, visible on black too. HDR (PQ) client content is not brightened on HDR outputs | | 51 | | `focus.effect` | `screen` | What the focus indicator draws: `screen` brightens the window slightly, visible on black too. HDR (PQ) client content is not brightened on HDR outputs | | ||
M examples/config +3 -2
| @@ -77,9 +77,10 @@ focus.follow-move = off | |||
| 77 | 77 | # they open, close or leave with the stash, the overview zooms its cards; | |
| 78 | 78 | # off: every change is instant and three-finger swipes act when the | |
| 79 | 79 | # fingers lift. | |
| 80 | - | # slowdown multiplies every spring's duration (0.1 to 10). | |
| 80 | + | # speed: slow, normal, fast, or a number from 0.1 (10x slower) to 10 | |
| 81 | + | # (10x faster). | |
| 81 | 82 | animations = off | |
| 82 | - | animations.slowdown = 1 | |
| 83 | + | animations.speed = normal | |
| 83 | 84 | # Focus indicator on the newly focused window: an animation (pulse or off) | |
| 84 | 85 | # of an effect (screen: a slight brightening), peaking at strength | |
| 85 | 86 | # (0.01 to 0.2; 0.04: black reaches about 10/255). | |
| @@ -77,9 +77,10 @@ focus.follow-move = off | |||||
| 77 | # they open, close or leave with the stash, the overview zooms its cards; | 77 | # they open, close or leave with the stash, the overview zooms its cards; | ||
| 78 | # off: every change is instant and three-finger swipes act when the | 78 | # off: every change is instant and three-finger swipes act when the | ||
| 79 | # fingers lift. | 79 | # fingers lift. | ||
| 80 | - | # slowdown multiplies every spring's duration (0.1 to 10). | 80 | + | # speed: slow, normal, fast, or a number from 0.1 (10x slower) to 10 |
| 81 | + | # (10x faster). | |||
| 81 | animations = off | 82 | animations = off | ||
| 82 | - | animations.slowdown = 1 | 83 | + | animations.speed = normal |
| 83 | # Focus indicator on the newly focused window: an animation (pulse or off) | 84 | # Focus indicator on the newly focused window: an animation (pulse or off) | ||
| 84 | # of an effect (screen: a slight brightening), peaking at strength | 85 | # of an effect (screen: a slight brightening), peaking at strength | ||
| 85 | # (0.01 to 0.2; 0.04: black reaches about 10/255). | 86 | # (0.01 to 0.2; 0.04: black reaches about 10/255). | ||
M internal/adapters/config/config.go +19 -6
| @@ -171,7 +171,7 @@ func Defaults() ports.Config { | |||
| 171 | 171 | c.Cursor.HideAfter = 5 * time.Second | |
| 172 | 172 | // Animations are experimental: off unless the config turns them on. | |
| 173 | 173 | c.Animations.On = false | |
| 174 | - | c.Animations.Slowdown = 1 | |
| 174 | + | c.Animations.Slowdown = normalSlowdown | |
| 175 | 175 | c.Focus.Animation = ports.FocusAnimationPulse | |
| 176 | 176 | c.Focus.Effect = ports.FocusEffectScreen | |
| 177 | 177 | c.Focus.Strength = 0.04 | |
| @@ -758,12 +758,17 @@ func set(c *ports.Config, key, v string) error { | |||
| 758 | 758 | return err | |
| 759 | 759 | } | |
| 760 | 760 | c.Animations.On = b | |
| 761 | - | case "animations.slowdown": | |
| 762 | - | f, err := strconv.ParseFloat(v, 64) | |
| 763 | - | if err != nil || !(f >= 0.1 && f <= 10) { | |
| 764 | - | return fmt.Errorf("must be between 0.1 and 10") | |
| 761 | + | case "animations.speed": | |
| 762 | + | f, ok := animationSpeeds[v] | |
| 763 | + | if !ok { | |
| 764 | + | var err error | |
| 765 | + | f, err = strconv.ParseFloat(v, 64) | |
| 766 | + | if err != nil || !(f >= 0.1 && f <= 10) { | |
| 767 | + | return fmt.Errorf("must be slow, normal, fast or a number between 0.1 and 10") | |
| 768 | + | } | |
| 765 | 769 | } | |
| 766 | - | c.Animations.Slowdown = f | |
| 770 | + | // Core stretches springs by a duration factor: the inverse. | |
| 771 | + | c.Animations.Slowdown = normalSlowdown / f | |
| 767 | 772 | case "focus.follow-move": | |
| 768 | 773 | b, err := onOff(v) | |
| 769 | 774 | if err != nil { | |
| @@ -1022,6 +1027,14 @@ func positive(dst *int, v string, max int) error { | |||
| 1022 | 1027 | return nil | |
| 1023 | 1028 | } | |
| 1024 | 1029 | ||
| 1030 | + | // normalSlowdown is the spring duration factor of animations.speed = | |
| 1031 | + | // normal (1): a view move lands in about 180 ms. | |
| 1032 | + | const normalSlowdown = 0.7 | |
| 1033 | + | ||
| 1034 | + | // animationSpeeds are the named animations.speed values, relative to | |
| 1035 | + | // normal: a view move lands in about 260 ms at slow and 130 ms at fast. | |
| 1036 | + | var animationSpeeds = map[string]float64{"slow": 0.7, "normal": 1, "fast": 1.4} | |
| 1037 | + | ||
| 1025 | 1038 | func onOff(v string) (bool, error) { | |
| 1026 | 1039 | switch v { | |
| 1027 | 1040 | case "on": | |
| @@ -171,7 +171,7 @@ func Defaults() ports.Config { | |||||
| 171 | c.Cursor.HideAfter = 5 * time.Second | 171 | c.Cursor.HideAfter = 5 * time.Second | ||
| 172 | // Animations are experimental: off unless the config turns them on. | 172 | // Animations are experimental: off unless the config turns them on. | ||
| 173 | c.Animations.On = false | 173 | c.Animations.On = false | ||
| 174 | - | c.Animations.Slowdown = 1 | 174 | + | c.Animations.Slowdown = normalSlowdown |
| 175 | c.Focus.Animation = ports.FocusAnimationPulse | 175 | c.Focus.Animation = ports.FocusAnimationPulse | ||
| 176 | c.Focus.Effect = ports.FocusEffectScreen | 176 | c.Focus.Effect = ports.FocusEffectScreen | ||
| 177 | c.Focus.Strength = 0.04 | 177 | c.Focus.Strength = 0.04 | ||
| @@ -758,12 +758,17 @@ func set(c *ports.Config, key, v string) error { | |||||
| 758 | return err | 758 | return err | ||
| 759 | } | 759 | } | ||
| 760 | c.Animations.On = b | 760 | c.Animations.On = b | ||
| 761 | - | case "animations.slowdown": | 761 | + | case "animations.speed": |
| 762 | - | f, err := strconv.ParseFloat(v, 64) | 762 | + | f, ok := animationSpeeds[v] |
| 763 | - | if err != nil || !(f >= 0.1 && f <= 10) { | 763 | + | if !ok { |
| 764 | - | return fmt.Errorf("must be between 0.1 and 10") | 764 | + | var err error |
| 765 | + | f, err = strconv.ParseFloat(v, 64) | |||
| 766 | + | if err != nil || !(f >= 0.1 && f <= 10) { | |||
| 767 | + | return fmt.Errorf("must be slow, normal, fast or a number between 0.1 and 10") | |||
| 768 | + | } | |||
| 765 | } | 769 | } | ||
| 766 | - | c.Animations.Slowdown = f | 770 | + | // Core stretches springs by a duration factor: the inverse. |
| 771 | + | c.Animations.Slowdown = normalSlowdown / f | |||
| 767 | case "focus.follow-move": | 772 | case "focus.follow-move": | ||
| 768 | b, err := onOff(v) | 773 | b, err := onOff(v) | ||
| 769 | if err != nil { | 774 | if err != nil { | ||
| @@ -1022,6 +1027,14 @@ func positive(dst *int, v string, max int) error { | |||||
| 1022 | return nil | 1027 | return nil | ||
| 1023 | } | 1028 | } | ||
| 1024 | 1029 | ||||
| 1030 | + | // normalSlowdown is the spring duration factor of animations.speed = | |||
| 1031 | + | // normal (1): a view move lands in about 180 ms. | |||
| 1032 | + | const normalSlowdown = 0.7 | |||
| 1033 | + | ||||
| 1034 | + | // animationSpeeds are the named animations.speed values, relative to | |||
| 1035 | + | // normal: a view move lands in about 260 ms at slow and 130 ms at fast. | |||
| 1036 | + | var animationSpeeds = map[string]float64{"slow": 0.7, "normal": 1, "fast": 1.4} | |||
| 1037 | + | ||||
| 1025 | func onOff(v string) (bool, error) { | 1038 | func onOff(v string) (bool, error) { | ||
| 1026 | switch v { | 1039 | switch v { | ||
| 1027 | case "on": | 1040 | case "on": | ||
M internal/adapters/config/config_test.go +12 -5
| @@ -2,6 +2,7 @@ package config | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | + | "math" | |
| 5 | 6 | "os" | |
| 6 | 7 | "path/filepath" | |
| 7 | 8 | "reflect" | |
| @@ -80,23 +81,29 @@ func TestFollowMove(t *testing.T) { | |||
| 80 | 81 | ||
| 81 | 82 | func TestAnimations(t *testing.T) { | |
| 82 | 83 | d := Defaults().Animations | |
| 83 | - | if d.On || d.Slowdown != 1 { | |
| 84 | + | if d.On || d.Slowdown != normalSlowdown { | |
| 84 | 85 | t.Fatal("animations defaults", d) | |
| 85 | 86 | } | |
| 86 | - | c, w := parseString(t, "animations = on\nanimations.slowdown = 2\n") | |
| 87 | - | if !c.Animations.On || c.Animations.Slowdown != 2 || len(w) != 0 { | |
| 87 | + | c, w := parseString(t, "animations = on\nanimations.speed = 0.5\n") | |
| 88 | + | if !c.Animations.On || c.Animations.Slowdown != 2*normalSlowdown || len(w) != 0 { | |
| 88 | 89 | t.Fatal(c.Animations, w) | |
| 89 | 90 | } | |
| 91 | + | for v, slowdown := range map[string]float64{"slow": 1, "normal": 0.7, "fast": 0.5, "10": 0.07, "0.1": 7} { | |
| 92 | + | c, w = parseString(t, "animations.speed = "+v+"\n") | |
| 93 | + | if math.Abs(c.Animations.Slowdown-slowdown) > 1e-9 || len(w) != 0 { | |
| 94 | + | t.Fatal(v, c.Animations, w) | |
| 95 | + | } | |
| 96 | + | } | |
| 90 | 97 | c, w = parseString(t, "animations = off\n") | |
| 91 | 98 | if c.Animations.On || len(w) != 0 { | |
| 92 | 99 | t.Fatal(c.Animations, w) | |
| 93 | 100 | } | |
| 94 | - | for _, line := range []string{"animations = maybe", "animations.slowdown = 0", "animations.slowdown = 11"} { | |
| 101 | + | for _, line := range []string{"animations = maybe", "animations.speed = 0", "animations.speed = 11", "animations.speed = turbo", "animations.slowdown = 2"} { | |
| 95 | 102 | c, w = parseString(t, line+"\n") | |
| 96 | 103 | if c.Animations != d || len(w) != 1 { | |
| 97 | 104 | t.Fatal(line, c.Animations, w) | |
| 98 | 105 | } | |
| 99 | - | if strings.Contains(line, "slowdown") && !strings.Contains(w[0].Msg, "must be between 0.1 and 10") { | |
| 106 | + | if strings.Contains(line, "speed") && !strings.Contains(w[0].Msg, "must be slow, normal, fast or a number between 0.1 and 10") { | |
| 100 | 107 | t.Fatal(line, w) | |
| 101 | 108 | } | |
| 102 | 109 | } | |
| @@ -2,6 +2,7 @@ package config | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | + | "math" | |||
| 5 | "os" | 6 | "os" | ||
| 6 | "path/filepath" | 7 | "path/filepath" | ||
| 7 | "reflect" | 8 | "reflect" | ||
| @@ -80,23 +81,29 @@ func TestFollowMove(t *testing.T) { | |||||
| 80 | 81 | ||||
| 81 | func TestAnimations(t *testing.T) { | 82 | func TestAnimations(t *testing.T) { | ||
| 82 | d := Defaults().Animations | 83 | d := Defaults().Animations | ||
| 83 | - | if d.On || d.Slowdown != 1 { | 84 | + | if d.On || d.Slowdown != normalSlowdown { |
| 84 | t.Fatal("animations defaults", d) | 85 | t.Fatal("animations defaults", d) | ||
| 85 | } | 86 | } | ||
| 86 | - | c, w := parseString(t, "animations = on\nanimations.slowdown = 2\n") | 87 | + | c, w := parseString(t, "animations = on\nanimations.speed = 0.5\n") |
| 87 | - | if !c.Animations.On || c.Animations.Slowdown != 2 || len(w) != 0 { | 88 | + | if !c.Animations.On || c.Animations.Slowdown != 2*normalSlowdown || len(w) != 0 { |
| 88 | t.Fatal(c.Animations, w) | 89 | t.Fatal(c.Animations, w) | ||
| 89 | } | 90 | } | ||
| 91 | + | for v, slowdown := range map[string]float64{"slow": 1, "normal": 0.7, "fast": 0.5, "10": 0.07, "0.1": 7} { | |||
| 92 | + | c, w = parseString(t, "animations.speed = "+v+"\n") | |||
| 93 | + | if math.Abs(c.Animations.Slowdown-slowdown) > 1e-9 || len(w) != 0 { | |||
| 94 | + | t.Fatal(v, c.Animations, w) | |||
| 95 | + | } | |||
| 96 | + | } | |||
| 90 | c, w = parseString(t, "animations = off\n") | 97 | c, w = parseString(t, "animations = off\n") | ||
| 91 | if c.Animations.On || len(w) != 0 { | 98 | if c.Animations.On || len(w) != 0 { | ||
| 92 | t.Fatal(c.Animations, w) | 99 | t.Fatal(c.Animations, w) | ||
| 93 | } | 100 | } | ||
| 94 | - | for _, line := range []string{"animations = maybe", "animations.slowdown = 0", "animations.slowdown = 11"} { | 101 | + | for _, line := range []string{"animations = maybe", "animations.speed = 0", "animations.speed = 11", "animations.speed = turbo", "animations.slowdown = 2"} { |
| 95 | c, w = parseString(t, line+"\n") | 102 | c, w = parseString(t, line+"\n") | ||
| 96 | if c.Animations != d || len(w) != 1 { | 103 | if c.Animations != d || len(w) != 1 { | ||
| 97 | t.Fatal(line, c.Animations, w) | 104 | t.Fatal(line, c.Animations, w) | ||
| 98 | } | 105 | } | ||
| 99 | - | if strings.Contains(line, "slowdown") && !strings.Contains(w[0].Msg, "must be between 0.1 and 10") { | 106 | + | if strings.Contains(line, "speed") && !strings.Contains(w[0].Msg, "must be slow, normal, fast or a number between 0.1 and 10") { |
| 100 | t.Fatal(line, w) | 107 | t.Fatal(line, w) | ||
| 101 | } | 108 | } | ||
| 102 | } | 109 | } | ||
M internal/core/gesture.go +1 -1
| @@ -359,7 +359,7 @@ func (c *Core) hasScreen(s *screen) bool { | |||
| 359 | 359 | // animOn reports whether transitions run (animations = on). | |
| 360 | 360 | func (c *Core) animOn() bool { return c.cfg.Animations.On } | |
| 361 | 361 | ||
| 362 | - | // spring starts s at now, slowed down by animations.slowdown. Every motion | |
| 362 | + | // spring starts s at now, stretched by animations.speed (Slowdown). Every motion | |
| 363 | 363 | // core creates goes through it, except a retarget, which keeps the slowdown | |
| 364 | 364 | // of the motion it replaces. | |
| 365 | 365 | func (c *Core) spring(s spring, now time.Time) motion { | |
| @@ -359,7 +359,7 @@ func (c *Core) hasScreen(s *screen) bool { | |||||
| 359 | // animOn reports whether transitions run (animations = on). | 359 | // animOn reports whether transitions run (animations = on). | ||
| 360 | func (c *Core) animOn() bool { return c.cfg.Animations.On } | 360 | func (c *Core) animOn() bool { return c.cfg.Animations.On } | ||
| 361 | 361 | ||||
| 362 | - | // spring starts s at now, slowed down by animations.slowdown. Every motion | 362 | + | // spring starts s at now, stretched by animations.speed (Slowdown). Every motion |
| 363 | // core creates goes through it, except a retarget, which keeps the slowdown | 363 | // core creates goes through it, except a retarget, which keeps the slowdown | ||
| 364 | // of the motion it replaces. | 364 | // of the motion it replaces. | ||
| 365 | func (c *Core) spring(s spring, now time.Time) motion { | 365 | func (c *Core) spring(s spring, now time.Time) motion { | ||
M internal/ports/config.go +2 -1
| @@ -144,7 +144,8 @@ type Config struct { | |||
| 144 | 144 | // motion; the next motion shows it. 0 never hides it. | |
| 145 | 145 | Cursor struct{ HideAfter time.Duration } | |
| 146 | 146 | // Animations: On enables motion (off lands everything instantly); | |
| 147 | - | // Slowdown scales every spring's duration (not the focus pulse), 0.1 to 10. | |
| 147 | + | // Slowdown scales every spring's duration (not the focus pulse), 0.1 to | |
| 148 | + | // 10 (the config's animations.speed maps to it). | |
| 148 | 149 | Animations struct { | |
| 149 | 150 | On bool | |
| 150 | 151 | Slowdown float64 | |
| @@ -144,7 +144,8 @@ type Config struct { | |||||
| 144 | // motion; the next motion shows it. 0 never hides it. | 144 | // motion; the next motion shows it. 0 never hides it. | ||
| 145 | Cursor struct{ HideAfter time.Duration } | 145 | Cursor struct{ HideAfter time.Duration } | ||
| 146 | // Animations: On enables motion (off lands everything instantly); | 146 | // Animations: On enables motion (off lands everything instantly); | ||
| 147 | - | // Slowdown scales every spring's duration (not the focus pulse), 0.1 to 10. | 147 | + | // Slowdown scales every spring's duration (not the focus pulse), 0.1 to |
| 148 | + | // 10 (the config's animations.speed maps to it). | |||
| 148 | Animations struct { | 149 | Animations struct { | ||
| 149 | On bool | 150 | On bool | ||
| 150 | Slowdown float64 | 151 | Slowdown float64 | ||