init commit

This commit is contained in:
unknown
2025-08-19 08:06:37 -04:00
commit 2957b5515a
743 changed files with 45495 additions and 0 deletions
+7
View File
@@ -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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

@@ -0,0 +1,8 @@
tag: user.continuous_scrolling
-
<number_small>: user.mouse_scroll_set_speed(number_small)
[wheel] stop: user.mouse_scroll_stop()
[wheel] stop here:
user.mouse_move_center_active_window()
user.mouse_scroll_stop()
@@ -0,0 +1,6 @@
list: user.continuous_scrolling_direction
-
upper: UP
downer: DOWN
righter: RIGHT
lefter: LEFT
+135
View File
@@ -0,0 +1,135 @@
from talon import Context, Module, actions, ctrl, settings, ui
mod = Module()
ctx = Context()
mod.list(
"mouse_button",
desc="List of mouse button words to mouse_click index parameter",
)
mod.setting(
"mouse_enable_pop_click",
type=int,
default=0,
desc="Pop noise clicks left mouse button. 0 = off, 1 = on with eyetracker but not with zoom mouse mode, 2 = on but not with zoom mouse mode",
)
mod.setting(
"mouse_enable_pop_stops_scroll",
type=bool,
default=False,
desc="When enabled, pop stops continuous scroll modes (wheel upper/downer/gaze)",
)
mod.setting(
"mouse_enable_pop_stops_drag",
type=bool,
default=False,
desc="When enabled, pop stops mouse drag",
)
mod.setting(
"mouse_wake_hides_cursor",
type=bool,
default=False,
desc="When enabled, mouse wake will hide the cursor. mouse_wake enables zoom mouse.",
)
@mod.action_class
class Actions:
def zoom_close():
"""Closes an in-progress zoom. Talon will move the cursor position but not click."""
actions.user.deprecate_action(
"2024-12-26",
"user.zoom_close",
"tracking.zoom_cancel",
)
actions.tracking.zoom_cancel()
def mouse_wake():
"""Enable control mouse, zoom mouse, and disables cursor"""
actions.tracking.control_zoom_toggle(True)
if settings.get("user.mouse_wake_hides_cursor"):
actions.user.mouse_cursor_hide()
def mouse_drag(button: int):
"""Press and hold/release a specific mouse button for dragging"""
# Clear any existing drags
actions.user.mouse_drag_end()
# Start drag
actions.mouse_drag(button)
def mouse_drag_end() -> bool:
"""Releases any held mouse buttons"""
buttons = ctrl.mouse_buttons_down()
if buttons:
for button in buttons:
actions.mouse_release(button)
return True
return False
def mouse_drag_toggle(button: int):
"""If the button is held down, release the button, else start dragging"""
if button in ctrl.mouse_buttons_down():
actions.mouse_release(button)
else:
actions.mouse_drag(button)
def mouse_sleep():
"""Disables control mouse, zoom mouse, and re-enables cursor"""
actions.tracking.control_zoom_toggle(False)
actions.tracking.control_toggle(False)
actions.tracking.control1_toggle(False)
actions.user.mouse_cursor_show()
actions.user.mouse_scroll_stop()
actions.user.mouse_drag_end()
def copy_mouse_position():
"""Copy the current mouse position coordinates"""
x, y = actions.mouse_x(), actions.mouse_y()
actions.clip.set_text(f"{x}, {y}")
def mouse_move_center_active_window():
"""Move the mouse cursor to the center of the currently active window"""
rect = ui.active_window().rect
actions.mouse_move(rect.center.x, rect.center.y)
@ctx.action_class("user")
class UserActions:
def noise_trigger_pop():
dont_click = False
# Allow pop to stop drag
if settings.get("user.mouse_enable_pop_stops_drag"):
if actions.user.mouse_drag_end():
dont_click = True
# Allow pop to stop scroll
if settings.get("user.mouse_enable_pop_stops_scroll"):
if actions.user.mouse_scroll_stop():
dont_click = True
if dont_click:
return
# Otherwise respect the mouse_enable_pop_click setting
setting_val = settings.get("user.mouse_enable_pop_click")
is_using_eye_tracker = (
actions.tracking.control_zoom_enabled()
or actions.tracking.control_enabled()
or actions.tracking.control1_enabled()
)
should_click = (
setting_val == 2 and not actions.tracking.control_zoom_enabled()
) or (
setting_val == 1
and is_using_eye_tracker
and not actions.tracking.control_zoom_enabled()
)
if should_click:
ctrl.mouse_click(button=0, hold=16000)
+134
View File
@@ -0,0 +1,134 @@
control mouse: tracking.control_toggle()
control off: user.mouse_sleep()
zoom mouse: tracking.control_zoom_toggle()
camera overlay: tracking.control_debug_toggle()
run calibration: tracking.calibrate()
touch:
# close zoom if open
tracking.zoom_cancel()
mouse_click(0)
# close the mouse grid if open
user.grid_close()
# End any open drags
# Touch automatically ends left drags so this is for right drags specifically
user.mouse_drag_end()
righty:
# close zoom if open
tracking.zoom_cancel()
mouse_click(1)
# close the mouse grid if open
user.grid_close()
mid click:
# close zoom if open
tracking.zoom_cancel()
mouse_click(2)
# close the mouse grid
user.grid_close()
#see keys.py for modifiers.
#defaults
#command
#control
#option = alt
#shift
#super = windows key
<user.modifiers> touch:
# close zoom if open
tracking.zoom_cancel()
key("{modifiers}:down")
mouse_click(0)
key("{modifiers}:up")
# close the mouse grid
user.grid_close()
<user.modifiers> righty:
# close zoom if open
tracking.zoom_cancel()
key("{modifiers}:down")
mouse_click(1)
key("{modifiers}:up")
# close the mouse grid
user.grid_close()
(dub click | duke):
# close zoom if open
tracking.zoom_cancel()
mouse_click()
mouse_click()
# close the mouse grid
user.grid_close()
(trip click | trip lick):
# close zoom if open
tracking.zoom_cancel()
mouse_click()
mouse_click()
mouse_click()
# close the mouse grid
user.grid_close()
left drag | drag | drag start:
# close zoom if open
tracking.zoom_cancel()
user.mouse_drag(0)
# close the mouse grid
user.grid_close()
right drag | righty drag:
# close zoom if open
tracking.zoom_cancel()
user.mouse_drag(1)
# close the mouse grid
user.grid_close()
end drag | drag end: user.mouse_drag_end()
wheel down: user.mouse_scroll_down()
wheel down here:
user.mouse_move_center_active_window()
user.mouse_scroll_down()
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 up: user.mouse_scroll_up()
wheel up here:
user.mouse_move_center_active_window()
user.mouse_scroll_up()
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 gaze: user.mouse_gaze_scroll()
wheel gaze here:
user.mouse_move_center_active_window()
user.mouse_gaze_scroll()
wheel left: user.mouse_scroll_left()
wheel left here:
user.mouse_move_center_active_window()
user.mouse_scroll_left()
wheel tiny left: user.mouse_scroll_left(0.5)
wheel tiny left here:
user.mouse_move_center_active_window()
user.mouse_scroll_left(0.5)
wheel right: user.mouse_scroll_right()
wheel right here:
user.mouse_move_center_active_window()
user.mouse_scroll_right()
wheel tiny right: user.mouse_scroll_right(0.5)
wheel tiny right here:
user.mouse_move_center_active_window()
user.mouse_scroll_right(0.5)
wheel {user.continuous_scrolling_direction}:
user.mouse_scroll_continuous(continuous_scrolling_direction)
wheel {user.continuous_scrolling_direction} here:
user.mouse_move_center_active_window()
user.mouse_scroll_continuous(continuous_scrolling_direction)
wheel {user.continuous_scrolling_direction} <number_small>:
user.mouse_scroll_continuous(continuous_scrolling_direction, number_small)
wheel {user.continuous_scrolling_direction} here <number_small>:
user.mouse_move_center_active_window()
user.mouse_scroll_continuous(continuous_scrolling_direction, number_small)
copy mouse position: user.copy_mouse_position()
curse no:
# Command added 2021-12-13, can remove after 2022-06-01
app.notify("Please activate the user.mouse_cursor_commands_enable tag to enable this command")
# To scroll with a hiss sound, set mouse_enable_hiss_scroll to true in settings.talon
mouse hiss up: user.hiss_scroll_up()
mouse hiss down: user.hiss_scroll_down()
+81
View File
@@ -0,0 +1,81 @@
import os
from talon import Module, app, ctrl
default_cursor = {
"AppStarting": r"%SystemRoot%\Cursors\aero_working.ani",
"Arrow": r"%SystemRoot%\Cursors\aero_arrow.cur",
"Hand": r"%SystemRoot%\Cursors\aero_link.cur",
"Help": r"%SystemRoot%\Cursors\aero_helpsel.cur",
"No": r"%SystemRoot%\Cursors\aero_unavail.cur",
"NWPen": r"%SystemRoot%\Cursors\aero_pen.cur",
"Person": r"%SystemRoot%\Cursors\aero_person.cur",
"Pin": r"%SystemRoot%\Cursors\aero_pin.cur",
"SizeAll": r"%SystemRoot%\Cursors\aero_move.cur",
"SizeNESW": r"%SystemRoot%\Cursors\aero_nesw.cur",
"SizeNS": r"%SystemRoot%\Cursors\aero_ns.cur",
"SizeNWSE": r"%SystemRoot%\Cursors\aero_nwse.cur",
"SizeWE": r"%SystemRoot%\Cursors\aero_ew.cur",
"UpArrow": r"%SystemRoot%\Cursors\aero_up.cur",
"Wait": r"%SystemRoot%\Cursors\aero_busy.ani",
"Crosshair": "",
"IBeam": "",
}
# todo figure out why notepad++ still shows the cursor sometimes.
hidden_cursor = os.path.join(
os.path.dirname(os.path.realpath(__file__)), r"Resources\HiddenCursor.cur"
)
mod = Module()
mod.tag(
"mouse_cursor_commands_enable",
desc="Tag enables hide/show mouse cursor commands",
)
@mod.action_class
class Actions:
def mouse_cursor_show():
"""Shows the cursor"""
show_cursor_helper(True)
def mouse_cursor_hide():
"""Hides the cursor"""
show_cursor_helper(False)
def show_cursor_helper(show: bool):
"""Show/hide the cursor"""
if app.platform == "windows":
import ctypes
import winreg
import win32con
try:
Registrykey = winreg.OpenKey(
winreg.HKEY_CURRENT_USER, r"Control Panel\Cursors", 0, winreg.KEY_WRITE
)
for value_name, value in default_cursor.items():
if show:
winreg.SetValueEx(
Registrykey, value_name, 0, winreg.REG_EXPAND_SZ, value
)
else:
winreg.SetValueEx(
Registrykey, value_name, 0, winreg.REG_EXPAND_SZ, hidden_cursor
)
winreg.CloseKey(Registrykey)
ctypes.windll.user32.SystemParametersInfoA(
win32con.SPI_SETCURSORS, 0, None, 0
)
except OSError:
print(f"Unable to show_cursor({show})")
else:
ctrl.cursor_visible(show)
@@ -0,0 +1,4 @@
tag: user.mouse_cursor_commands_enable
-
curse yes: user.mouse_cursor_show()
curse no: user.mouse_cursor_hide()
+326
View File
@@ -0,0 +1,326 @@
import time
from typing import Literal, Optional
from talon import Context, Module, actions, app, cron, ctrl, imgui, settings, ui
continuous_scroll_mode = ""
scroll_job = None
gaze_job = None
scroll_dir: Literal[-1, 1] = 1
scroll_start_ts: float = 0
hiss_scroll_up = False
control_mouse_forced = False
continuous_scrolling_speed_factor: float = 1.0
is_continuous_scrolling_vertical: bool = True
mod = Module()
ctx = Context()
mod.list(
"continuous_scrolling_direction",
desc="Defines names for directions used with continuous scrolling",
)
mod.setting(
"mouse_wheel_down_amount",
type=int,
default=120,
desc="The amount to scroll up/down (equivalent to mouse wheel on Windows by default)",
)
mod.setting(
"mouse_wheel_horizontal_amount",
type=int,
default=40,
desc="The amount to scroll left/right",
)
mod.setting(
"mouse_continuous_scroll_amount",
type=int,
default=8,
desc="The default amount used when scrolling continuously",
)
mod.setting(
"mouse_continuous_scroll_acceleration",
type=float,
default=1,
desc="The maximum (linear) acceleration factor when scrolling continuously. 1=constant speed/no acceleration",
)
mod.setting(
"mouse_enable_hiss_scroll",
type=bool,
default=False,
desc="Hiss noise scrolls down when enabled",
)
mod.setting(
"mouse_hide_mouse_gui",
type=bool,
default=False,
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.setting(
"mouse_gaze_scroll_speed_multiplier",
type=float,
default=1.0,
desc="This multiplies the gaze scroll speed",
)
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"):
actions.user.mouse_scroll_stop()
@mod.action_class
class Actions:
def mouse_scroll_up(amount: float = 1):
"""Scrolls up"""
y = amount * settings.get("user.mouse_wheel_down_amount")
actions.mouse_scroll(-y)
def mouse_scroll_down(amount: float = 1):
"""Scrolls down"""
y = amount * settings.get("user.mouse_wheel_down_amount")
actions.mouse_scroll(y)
def mouse_scroll_left(amount: float = 1):
"""Scrolls left"""
x = amount * settings.get("user.mouse_wheel_horizontal_amount")
actions.mouse_scroll(0, -x)
def mouse_scroll_right(amount: float = 1):
"""Scrolls right"""
x = amount * settings.get("user.mouse_wheel_horizontal_amount")
actions.mouse_scroll(0, x)
def mouse_scroll_continuous(direction: str, speed_factor: Optional[int] = None):
"""Scrolls continuously in the given direction"""
match direction:
case "UP":
actions.user.mouse_scroll_up_continuous(speed_factor)
case "DOWN":
actions.user.mouse_scroll_down_continuous(speed_factor)
case "LEFT":
actions.user.mouse_scroll_left_continuous(speed_factor)
case "RIGHT":
actions.user.mouse_scroll_right_continuous(speed_factor)
case _:
raise ValueError(f"Invalid continuous scrolling direction: {direction}")
def mouse_scroll_up_continuous(speed_factor: Optional[int] = None):
"""Scrolls up continuously"""
mouse_scroll_continuous(-1, speed_factor)
def mouse_scroll_down_continuous(speed_factor: Optional[int] = None):
"""Scrolls down continuously"""
mouse_scroll_continuous(1, speed_factor)
def mouse_scroll_right_continuous(speed_factor: Optional[int] = None):
"""Scrolls right continuously"""
mouse_scroll_continuous(1, speed_factor, is_vertical=False)
def mouse_scroll_left_continuous(speed_factor: Optional[int] = None):
"""Scrolls left continuously"""
mouse_scroll_continuous(-1, speed_factor, is_vertical=False)
def mouse_gaze_scroll():
"""Starts gaze scroll"""
global gaze_job, continuous_scroll_mode, control_mouse_forced
ctx.tags = ["user.continuous_scrolling"]
continuous_scroll_mode = "gaze scroll"
gaze_job = cron.interval("16ms", scroll_gaze_helper)
if not settings.get("user.mouse_hide_mouse_gui"):
gui_wheel.show()
# enable 'control mouse' if eye tracker is present and not enabled already
if not actions.tracking.control_enabled():
actions.tracking.control_toggle(True)
control_mouse_forced = True
def mouse_gaze_scroll_toggle():
"""If not scrolling, start gaze scroll, else stop scrolling."""
if continuous_scroll_mode == "":
actions.user.mouse_gaze_scroll()
else:
actions.user.mouse_scroll_stop()
def mouse_scroll_stop() -> bool:
"""Stops scrolling"""
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)
scroll_job = None
return_value = True
if gaze_job:
cron.cancel(gaze_job)
gaze_job = None
return_value = True
if control_mouse_forced:
actions.tracking.control_toggle(False)
control_mouse_forced = False
gui_wheel.hide()
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
hiss_scroll_up = True
def hiss_scroll_down():
"""Change mouse hiss scroll direction to down"""
global hiss_scroll_up
hiss_scroll_up = False
@ctx.action_class("user")
class UserActions:
def noise_trigger_hiss(active: bool):
if settings.get("user.mouse_enable_hiss_scroll"):
if active:
if hiss_scroll_up:
actions.user.mouse_scroll_up_continuous()
else:
actions.user.mouse_scroll_down_continuous()
else:
actions.user.mouse_scroll_stop()
def mouse_scroll_continuous(
new_scroll_dir: Literal[-1, 1],
speed_factor: Optional[int] = None,
is_vertical: bool = True,
):
global scroll_job, scroll_dir, scroll_start_ts, is_continuous_scrolling_vertical
actions.user.mouse_scroll_set_speed(speed_factor)
was_vertical = is_continuous_scrolling_vertical
is_continuous_scrolling_vertical = is_vertical
update_continuous_scrolling_mode(new_scroll_dir, is_vertical)
if scroll_job:
# Issuing a scroll in the same direction aborts scrolling
if scroll_dir == new_scroll_dir and was_vertical == is_vertical:
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()
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], is_vertical: bool):
global continuous_scroll_mode
if new_scroll_dir == -1:
if is_vertical:
continuous_scroll_mode = "scroll up continuous"
else:
continuous_scroll_mode = "scroll left continuous"
else:
if is_vertical:
continuous_scroll_mode = "scroll down continuous"
else:
continuous_scroll_mode = "scroll right continuous"
def scroll_continuous_helper():
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
)
scroll_delta = round(scroll_amount * acceleration_speed * scroll_dir)
if scroll_delta == 0:
scroll_delta = scroll_dir
if is_continuous_scrolling_vertical:
actions.mouse_scroll(scroll_delta)
else:
actions.mouse_scroll(0, scroll_delta)
def scroll_gaze_helper():
x, y = ctrl.mouse_pos()
# The window containing the mouse
window = get_window_containing(x, y)
if window is None:
return
rect = window.rect
midpoint = rect.center.y
factor = continuous_scrolling_speed_factor * settings.get(
"user.mouse_gaze_scroll_speed_multiplier"
)
amount = factor * (((y - midpoint) / (rect.height / 10)) ** 3)
actions.mouse_scroll(amount)
def get_window_containing(x: float, y: float):
# on windows, check the active_window first since ui.windows() is not z-ordered
if app.platform == "windows" and ui.active_window().rect.contains(x, y):
return ui.active_window()
for window in ui.windows():
if window.rect.contains(x, y):
return window
return None