Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add continuous scrolling speed adjustment #1649

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cbabb6f
Add continuous scrolling speed adjustment
FireChickenProductivity Dec 21, 2024
8a50d43
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 21, 2024
128a4f5
Add ability to set speed with scrolling commands
FireChickenProductivity Dec 21, 2024
1f3c8fb
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 21, 2024
eaf2df4
Remove unneeded context
FireChickenProductivity Dec 29, 2024
f27b7ad
Create default factor constant
FireChickenProductivity Dec 29, 2024
fd66564
Use optional integers
FireChickenProductivity Dec 29, 2024
9f451a7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 29, 2024
e10b3a6
Make alternate version of commands without argument
FireChickenProductivity Dec 31, 2024
a008edd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 31, 2024
9b5d0da
Merge branch 'main' into adjustable-scrolling-speed
nriley Jan 11, 2025
3ed0a38
Update mouse.py
knausj85 Jan 12, 2025
7ac5ecd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 12, 2025
a413cff
Revert "Update mouse.py"
knausj85 Jan 12, 2025
957d200
Merge branch 'adjustable-scrolling-speed' of https://github.com/FireC…
knausj85 Jan 12, 2025
fb3d71a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 12, 2025
25d164f
Update mouse_scroll.py
knausj85 Jan 12, 2025
0151e70
Merge branch 'adjustable-scrolling-speed' of https://github.com/FireC…
knausj85 Jan 12, 2025
c2ba66e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 12, 2025
078e207
Make speed quotient a setting
FireChickenProductivity Jan 16, 2025
ce2a48d
Address scrolling mode inconsistency
FireChickenProductivity Jan 16, 2025
5747535
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to ensure this coexists well with the tag user.numbers_unprefixed. Since the talon files have the same specificity, it's ambiguous which one talon will choose. Probably just add not tag: user.continuous_scrolling to that file

Copy link
Collaborator

@lunixbochs lunixbochs Jan 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specificity doesn't work on commands right now besides exact matches. it's pretty complicated to factor in .talon specificity in the command parser. action-level overrides are much easier to reason about

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, the commands are not an exact match. unprefixed numbers use a different capture, so I don't think an action really nets us anything in this context either.

-
<number_small>: user.mouse_scroll_set_speed(number_small)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the community backlog session we recommended that you add a graphical display of the presence of this feature.

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
76 changes: 62 additions & 14 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,6 +52,18 @@
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):
Expand Down Expand Up @@ -83,13 +95,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 +127,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, ctx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need ctx here unless you're writing directly to it.


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 +152,24 @@ 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"""
if continuous_scroll_mode:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider return continuous_scroll_mode != ""

return True
return False

def hiss_scroll_up():
"""Change mouse hiss scroll direction to up"""
global hiss_scroll_up
Expand All @@ -162,38 +194,54 @@ 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, ctx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove ctx as above

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
actions.mouse_scroll(y)

Expand Down
Loading