From 45165028a6114f93fb520a134887fb61ac28af93 Mon Sep 17 00:00:00 2001 From: Colton <70598503+C-Loftus@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:18:53 -0500 Subject: [PATCH] quickstart and misc fixes --- .../cursorless-sightless.talon | 1 - application-integration/gpt-utils.talon | 5 ++++ core/core-integration.py | 2 +- core/overrides.py | 6 ++--- core/settings.py | 6 +++-- docs/src/philosophy.md | 10 ++++---- docs/src/quickstart.md | 8 +++++-- nvda/nvda.talon | 2 ++ nvda/overrides.talon | 8 ++++--- pedal/nvda-pedal.talon | 8 +------ sight-free-global.talon | 2 +- sight-free-settings.talon | 3 ++- utils/timer.py | 23 ++++++++++++++----- 13 files changed, 51 insertions(+), 33 deletions(-) diff --git a/application-integration/cursorless-sightless.talon b/application-integration/cursorless-sightless.talon index 47ed3c5..6580111 100644 --- a/application-integration/cursorless-sightless.talon +++ b/application-integration/cursorless-sightless.talon @@ -1,7 +1,6 @@ tag: user.cursorless - - speak : txt = user.cursorless_get_text(cursorless_target) user.tts(txt) diff --git a/application-integration/gpt-utils.talon b/application-integration/gpt-utils.talon index 50e9d8a..6aa5e80 100644 --- a/application-integration/gpt-utils.talon +++ b/application-integration/gpt-utils.talon @@ -10,5 +10,10 @@ tag: user.openai_defined user.cancel_current_speaker() user.tts(result) +echo ask : + result = user.gpt_answer_question(text) + user.cancel_current_speaker() + user.tts(result) + describe image: user.describe_image() diff --git a/core/core-integration.py b/core/core-integration.py index 1b80a9e..0fd1973 100644 --- a/core/core-integration.py +++ b/core/core-integration.py @@ -1,7 +1,7 @@ from typing import Optional from talon import Module, actions, Context, settings, cron, ui, registry, scope, clip, app import os, subprocess -from ..lib.utils import remove_special +from ..utils.utils import remove_special from .sapi import SAPI5 if os.name == 'nt': diff --git a/core/overrides.py b/core/overrides.py index 22deb03..4e0e7cb 100644 --- a/core/overrides.py +++ b/core/overrides.py @@ -23,7 +23,7 @@ def key(key: str): return elif settings.get("user.sound_on_keypress", False) or sound_on_keypress: - actions.user.beep(freq = 440, duration = 100) + actions.user.beep(freq = 180, duration = 100) actions.next(key) @@ -36,12 +36,12 @@ def toggle_keypress_sound(): """Toggles whether or not to play a sound on keypress""" global sound_on_keypress sound_on_keypress = not sound_on_keypress - message = f"Keypress sound is now {'on' if sound_on_keypress else 'off'}" + message = f"Keypress sound {'on' if sound_on_keypress else 'off'}" actions.user.tts(message) def toggle_keypresses(): """Toggles whether or not to pass keypresses through to the OS""" global sound_on_keypress sound_on_keypress = not sound_on_keypress - message = f"Keypresses are now {'enabled' if sound_on_keypress else 'disabled'}" + message = f"Keypresses {'enabled' if sound_on_keypress else 'disabled'}" actions.user.tts(message) \ No newline at end of file diff --git a/core/settings.py b/core/settings.py index 264994b..f03a8ad 100644 --- a/core/settings.py +++ b/core/settings.py @@ -86,6 +86,8 @@ mod.setting("disable_keypresses", type=bool, default=False) mod.setting("sound_on_keypress", type=bool, default=False) +mod.setting("min_until_break", type=int, default=10) +# mod.setting("break_length", type=int, default=10) -mod.mode("strict_dictation", desc="Dictation mode with only a subset of dictation commands") -mod.mode('strict_command', desc='Command mode with only a subset of command commands') \ No newline at end of file +# mod.mode("strict_dictation", desc="Dictation mode with only a subset of dictation commands") +# mod.mode('strict_command', desc='Command mode with only a subset of command commands') \ No newline at end of file diff --git a/docs/src/philosophy.md b/docs/src/philosophy.md index 59b30e8..bad5d1f 100644 --- a/docs/src/philosophy.md +++ b/docs/src/philosophy.md @@ -1,14 +1,12 @@ -# Designing around Chronic Pain +# Accessibility Design alongside Chronic Pain -Within digital accessibility designers often assume conditions that are static binaries. for instance either a user is either blind or sighted. If a user has a vision impairment, it is implicitly expected to be a tournament condition, not one that might fluctuate based on pain levels +Within digital accessibility, designers often assume conditions that are static binaries. for instance either a user is either blind or sighted. If a user has a vision impairment, designers often implicitly expect it to be a permanent condition, not one that might fluctuate based on pain levels. When designing around chronic pain, all of these assumptions are knocked down. for instance in the case of carpal tunnel, the user can easily decide to simply type and work through the pain. in such a case accessibility is no longer about a binary of whether or not a product or service can be physically accessed. rather it becomes about whether or not the level of friction in the solution incentivizes its use instead of simply working with the standard option. -the unconscious mind is not rational in the long term and it will easily pick a moderately uncomfortable solution in the short term if it can be done quickly with little friction. however as anyone with chronic pain knows, enough of these moderately uncomfortable actions can quickly accumulate two a flare up of significant pain. +The unconscious mind is often not rational in the long term and it will easily pick a moderately uncomfortable solution if it can be done quickly with little friction. however as anyone with chronic pain knows, enough of these moderately uncomfortable actions can quickly accumulate two a flare up of significant pain. -as such when we are designing around chronic pain we can't simply look at baseline accessibility. we need to have designs that are such low friction and in some way do something totally unique that the old way of computer interaction couldn't do. - -that is why cursorless is so successful as a product to reduce chronic hand pain. +As such when we are designing around chronic pain we can't simply look at baseline accessibility. we need to have designs that are such low friction and in some way do something totally unique that the old way of computer interaction couldn't do. # For Better Accessibility, Do Less diff --git a/docs/src/quickstart.md b/docs/src/quickstart.md index 70e754c..a866dd2 100644 --- a/docs/src/quickstart.md +++ b/docs/src/quickstart.md @@ -1,3 +1,7 @@ +# Demo Video and General Introduction + + + # Installing This repository is in frequent development. I suggest using git to clone the repository into your user directory by running the following, @@ -8,10 +12,10 @@ git clone https://github.com/C-Loftus/sight-free-talon and then updating it frequently with `git pull`. On Windows your user directory is located at `%APPDATA%\Talon\user`. On MacOS and Linux your user directory is located at `~/.talon/user`. -For GPT functionality, install the `talon-gpt` repo dependency in your Talon user directory by running +For GPT functionality, install the `talon-ai-tools` repo dependency in your Talon user directory by running ``` -git clone https://github.com/C-Loftus/talon-gpt +git clone https://github.com/C-Loftus/talon-ai-tools ``` ## OS Specific Setup diff --git a/nvda/nvda.talon b/nvda/nvda.talon index 4a5ccae..1c82267 100644 --- a/nvda/nvda.talon +++ b/nvda/nvda.talon @@ -2,6 +2,8 @@ tag: user.nvda_running os: windows - +reader press : user.with_nvda_mod_press(keys) + next heading: key(h) previous heading: diff --git a/nvda/overrides.talon b/nvda/overrides.talon index 196c048..c174c2a 100644 --- a/nvda/overrides.talon +++ b/nvda/overrides.talon @@ -7,8 +7,10 @@ and tag: browser # text select via the mouse ^control cap$: user.with_nvda_mod_press("f2") - key(ctrl-c) + sleep(0.5) + edit.copy() ^copy (that | this)$: - user.with_nvda_mod_press(f2) - key(ctrl-c) + user.with_nvda_mod_press("f2") + sleep(0.5) + edit.copy() diff --git a/pedal/nvda-pedal.talon b/pedal/nvda-pedal.talon index 00d0c28..3ae33c2 100644 --- a/pedal/nvda-pedal.talon +++ b/pedal/nvda-pedal.talon @@ -3,13 +3,7 @@ tag: user.nvda_running - # navigate through links on a page -deck(pedal_left:repeat): +deck(pedal_left:repeat): key(tab) sleep(.2) -deck(pedal_middle:down): - key(capslock:down) - -deck(pedal_middle:up): - key(capslock:up) - \ No newline at end of file diff --git a/sight-free-global.talon b/sight-free-global.talon index db8222a..ffd65ec 100644 --- a/sight-free-global.talon +++ b/sight-free-global.talon @@ -39,5 +39,5 @@ echo tab level: toggle [screen] reader: user.toggle_reader() -toggle key sound: +toggle (key | keypress) sound: user.toggle_keypress_sound() diff --git a/sight-free-settings.talon b/sight-free-settings.talon index 3d39bb4..3be7b61 100644 --- a/sight-free-settings.talon +++ b/sight-free-settings.talon @@ -31,8 +31,9 @@ settings(): # Disable keypresses from Talon in high risk contexts that cannot afford typos user.disable_keypresses = false - # Every 20 minutes, send a notification, prompting you to rest your eyes + # Every given number of minutes, send a notification, prompting you to rest your eyes # user.enable_break_timer = true + # user.user.min_until_break = 10 ### Relevant Community Settings Below ### # Change key_wait if you want the screen reader to speak words diff --git a/utils/timer.py b/utils/timer.py index 4e054d2..bc2c46a 100644 --- a/utils/timer.py +++ b/utils/timer.py @@ -1,13 +1,17 @@ from talon import cron, Module, actions, app, settings +import os +if os.name == "nt": + import ctypes + """ -Every 20 minutes, remind the user to take a break +Every certain amount of minutes, remind the user to take a break to rest their eyes by looking at something 20 feet away -for 20 seconds. +for at least 20 seconds. """ -# Used for 20 / 20 / 20 rule -twenty_min = cron.seconds_to_timespec(20 * 60) +#Convert minutes to seconds +ten_min = cron.seconds_to_timespec(settings.get("user.min_until_break") * 60) # Defaults to Andreas' notification system, but falls back to Talon's def notify(message: str): @@ -19,6 +23,7 @@ def notify(message: str): mod = Module() + def break_wrapper(): if settings.get("user.enable_break_timer"): actions.user.eye_break_callback() @@ -31,6 +36,12 @@ def eye_break_callback(): the timer is triggered """ # Intentionally vague in case you are in a meeting - notify("20 Elapsed") + if os.name == "nt": + # ctypes.windll.user32.MessageBoxW(0, "Elapsed", "Notification", 1) + actions.user.tts("Elapsed") + actions.user.with_nvda_mod_press('ctrl-escape') + else: + notify("Elapsed") + +cron.interval(ten_min, break_wrapper) -cron.interval(twenty_min, break_wrapper) \ No newline at end of file