Skip to content

Commit

Permalink
Add continuous scrolling speed adjustment (#1649)
Browse files Browse the repository at this point in the history
Add the ability to adjust continuous scrolling speed while scrolling by
dictating a number_small. The speed becomes the speed setting multiplied
by the dictated number divided by ten. The acceleration gets reset every
time the speed gets changed. The scrolling speed reverts to the default
after the current scroll is finished.
closes #1648

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Nicholas Riley <[email protected]>
Co-authored-by: Jeff Knaus <[email protected]>
  • Loading branch information
4 people authored Jan 26, 2025
1 parent 1775118 commit 16adf1c
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 15 deletions.
1 change: 1 addition & 0 deletions core/numbers/numbers_unprefixed.talon
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
tag: user.unprefixed_numbers
and not tag: user.continuous_scrolling
-

<user.number_prose_unprefixed>: "{number_prose_unprefixed}"
7 changes: 7 additions & 0 deletions plugin/mouse/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Mouse

## Continuous Scrolling

You can start continuous scrolling by saying "wheel upper" or "wheel downer" and stop by saying "wheel stop". Saying "here" after one of the scrolling commands first moves the cursor to the middle of the window. A number between 1 and 99 can be dictated at the end of a scrolling command to set the scrolling speed. Dictating a continuous scrolling command in the same direction twice stops the scrolling.

During continuous scrolling, you can dictate a number between 0 and 99 to change the scrolling speed. The resulting speed is the user.mouse_continuous_scroll_amount setting multiplied by the number you dictated divided by the user.mouse_continuous_scroll_speed_quotient setting (which defaults to 10). With default settings, dictating 5 gives you half speed and dictating 20 gives you double speed. Note: Because the scrolling speed has to be an integer number, changing the speed by a small amount like 1 might not change how fast scrolling actually happens depending on your settings. The final scrolling speed is chosen by rounding and enforcing a minimum speed of 1.
3 changes: 3 additions & 0 deletions plugin/mouse/continuous_scrolling.talon
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tag: user.continuous_scrolling
-
<number_small>: user.mouse_scroll_set_speed(number_small)
8 changes: 8 additions & 0 deletions plugin/mouse/mouse.talon
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ wheel tiny [down]: user.mouse_scroll_down(0.2)
wheel tiny [down] here:
user.mouse_move_center_active_window()
user.mouse_scroll_down(0.2)
wheel downer <number_small>: user.mouse_scroll_down_continuous(number_small)
wheel downer: user.mouse_scroll_down_continuous()
wheel downer here <number_small>:
user.mouse_move_center_active_window()
user.mouse_scroll_down_continuous(number_small)
wheel downer here:
user.mouse_move_center_active_window()
user.mouse_scroll_down_continuous()
Expand All @@ -98,7 +102,11 @@ wheel tiny up: user.mouse_scroll_up(0.2)
wheel tiny up here:
user.mouse_move_center_active_window()
user.mouse_scroll_up(0.2)
wheel upper <number_small>: user.mouse_scroll_up_continuous(number_small)
wheel upper: user.mouse_scroll_up_continuous()
wheel upper here <number_small>:
user.mouse_move_center_active_window()
user.mouse_scroll_up_continuous(number_small)
wheel upper here:
user.mouse_move_center_active_window()
user.mouse_scroll_up_continuous()
Expand Down
79 changes: 64 additions & 15 deletions plugin/mouse/mouse_scroll.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import time
from typing import Literal
from typing import Literal, Optional

from talon import Context, Module, actions, app, cron, ctrl, imgui, settings, ui

Expand All @@ -10,11 +10,11 @@
scroll_start_ts: float = 0
hiss_scroll_up = False
control_mouse_forced = False
continuous_scrolling_speed_factor: float = 1.0

mod = Module()
ctx = Context()


mod.setting(
"mouse_wheel_down_amount",
type=int,
Expand Down Expand Up @@ -52,10 +52,23 @@
desc="When enabled, the 'Scroll Mouse' GUI will not be shown.",
)

mod.setting(
"mouse_continuous_scroll_speed_quotient",
type=float,
default=10.0,
desc="When adjusting the continuous scrolling speed through voice commands, the result is that the speed is multiplied by the dictated number divided by this number.",
)

mod.tag(
"continuous_scrolling",
desc="Allows commands for adjusting continuous scrolling behavior",
)


@imgui.open(x=700, y=0)
def gui_wheel(gui: imgui.GUI):
gui.text(f"Scroll mode: {continuous_scroll_mode}")
gui.text(f"say a number between 0 and 99 to set scrolling speed")
gui.line()
if gui.button("Wheel Stop [stop scrolling]"):
actions.user.mouse_scroll_stop()
Expand Down Expand Up @@ -83,13 +96,13 @@ def mouse_scroll_right(amount: float = 1):
x = amount * settings.get("user.mouse_wheel_horizontal_amount")
actions.mouse_scroll(0, x)

def mouse_scroll_up_continuous():
def mouse_scroll_up_continuous(speed_factor: Optional[int] = None):
"""Scrolls up continuously"""
mouse_scroll_continuous(-1)
mouse_scroll_continuous(-1, speed_factor)

def mouse_scroll_down_continuous():
def mouse_scroll_down_continuous(speed_factor: Optional[int] = None):
"""Scrolls down continuously"""
mouse_scroll_continuous(1)
mouse_scroll_continuous(1, speed_factor)

def mouse_gaze_scroll():
"""Starts gaze scroll"""
Expand All @@ -115,10 +128,12 @@ def mouse_gaze_scroll_toggle():

def mouse_scroll_stop() -> bool:
"""Stops scrolling"""
global scroll_job, gaze_job, continuous_scroll_mode, control_mouse_forced
global scroll_job, gaze_job, continuous_scroll_mode, control_mouse_forced, continuous_scrolling_speed_factor

continuous_scroll_mode = ""
continuous_scrolling_speed_factor = 1.0
return_value = False
ctx.tags = []

if scroll_job:
cron.cancel(scroll_job)
Expand All @@ -138,6 +153,22 @@ def mouse_scroll_stop() -> bool:

return return_value

def mouse_scroll_set_speed(speed: Optional[int]):
"""Sets the continuous scrolling speed for the current scrolling"""
global continuous_scrolling_speed_factor, scroll_start_ts
if scroll_start_ts:
scroll_start_ts = time.perf_counter()
if speed is None:
continuous_scrolling_speed_factor = 1.0
else:
continuous_scrolling_speed_factor = speed / settings.get(
"user.mouse_continuous_scroll_speed_quotient"
)

def mouse_is_continuous_scrolling():
"""Returns whether continuous scroll is in progress"""
return len(continuous_scroll_mode) > 0

def hiss_scroll_up():
"""Change mouse hiss scroll direction to up"""
global hiss_scroll_up
Expand All @@ -162,39 +193,57 @@ def noise_trigger_hiss(active: bool):
actions.user.mouse_scroll_stop()


def mouse_scroll_continuous(new_scroll_dir: Literal[-1, 1]):
global scroll_job, scroll_dir, scroll_start_ts, continuous_scroll_mode
def mouse_scroll_continuous(
new_scroll_dir: Literal[-1, 1],
speed_factor: Optional[int] = None,
):
global scroll_job, scroll_dir, scroll_start_ts
actions.user.mouse_scroll_set_speed(speed_factor)

update_continuous_scrolling_mode(new_scroll_dir)

if scroll_job:
# Issuing a scroll in the same direction aborts scrolling
if scroll_dir == new_scroll_dir:
cron.cancel(scroll_job)
scroll_job = None
continuous_scroll_mode = ""
actions.user.mouse_scroll_stop()
# Issuing a scroll in the reverse direction resets acceleration
else:
scroll_dir = new_scroll_dir
scroll_start_ts = time.perf_counter()
else:
scroll_dir = new_scroll_dir
scroll_start_ts = time.perf_counter()
continuous_scroll_mode = "scroll down continuous"
scroll_continuous_helper()
scroll_job = cron.interval("16ms", scroll_continuous_helper)
ctx.tags = ["user.continuous_scrolling"]

if not settings.get("user.mouse_hide_mouse_gui"):
gui_wheel.show()


def update_continuous_scrolling_mode(new_scroll_dir: Literal[-1, 1]):
global continuous_scroll_mode
if new_scroll_dir == -1:
continuous_scroll_mode = "scroll up continuous"
else:
continuous_scroll_mode = "scroll down continuous"


def scroll_continuous_helper():
scroll_amount = settings.get("user.mouse_continuous_scroll_amount")
scroll_amount = (
settings.get("user.mouse_continuous_scroll_amount")
* continuous_scrolling_speed_factor
)
acceleration_setting = settings.get("user.mouse_continuous_scroll_acceleration")
acceleration_speed = (
1 + min((time.perf_counter() - scroll_start_ts) / 0.5, acceleration_setting - 1)
if acceleration_setting > 1
else 1
)
y = scroll_amount * acceleration_speed * scroll_dir

y = round(scroll_amount * acceleration_speed * scroll_dir)
if y == 0:
y = scroll_dir
actions.mouse_scroll(y)


Expand Down

0 comments on commit 16adf1c

Please sign in to comment.