Is it possible to trigger a macro by pressing the Caps Lock key twice in succession?
I tried an experiment, which is to execute an action based on Caps Lock being set, as follows.
I run “periodically while logged in” every 1 second, checking for the state of the caps lock key. If it is down, I execute an action.
One problem with this is the response time feels slow because I have to wait up to 1 second for it to notice.
Also, it renders my caps lock key unusable as caps lock (due to the actions I am executing, which I would not want to do if I just want to use caps lock).
If you are curious why I want to use caps lock twice, the basic idea is that I need a hotkey that’s very easy to reach, but I don’t want to interfere with the caps lock function, which you get by pressing it once.
If you are wondering what my action is, it’s related to mouse functionality. I use it to avoid using the mouse too much, which causes repetitive strain injury for me.
Use the USB Device Key trigger and "tapped twice" option.
Note that the "ignoring modifiers" may be necessary. It certainly is for me since I have my Caps Lock key mapped to a Hyper Key (Command-Control-Option-Shift) and so the modifiers are definitely involved when pressing the caps lock key for me.
That gets me part way there, but it loses its function as Caps Lock.
But I have a better idea. The same idea works if I use the left shift key instead of Caps Lock, and left shift doesn’t lose its function. So I will do that.
I need one other part to this script. I need to display a prominent notification when I enter or leave “mouse mode” (as I am calling it). Ideally a colorful window (say bright yellow) would appear along the top of the screen, or at one of the top corners, when entering mouse mode, and it would stay there until exiting mouse mode, at which point it would disappear.
I tried this with notifications, but first of all notifications are gray, which doesn’t make them stand out, and second I don’t know how to get a notification to appear, stay for as long as needed, and then disappear instantly when it’s time to disappear.
Sorry for the necromancy, but think this is a helpful add for this thread.
I figured out how to make a persistent notification popup dialog run via applescript -> shell, without halting further execution of the main thread (other steps in the macro).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>ActionColor</key>
<string>Green</string>
<key>ActionName</key>
<string>_G_SuspendedAlert</string>
<key>DisplayKind</key>
<string>None</string>
<key>HonourFailureSettings</key>
<true/>
<key>IncludeStdErr</key>
<false/>
<key>MacroActionType</key>
<string>ExecuteAppleScript</string>
<key>Path</key>
<string></string>
<key>Text</key>
<string>use framework "Foundation"
use scripting additions
property NSScreen : a reference to current application's NSScreen
# Get display size
set display to NSDeviceSize ¬
of deviceDescription() ¬
of item 1 ¬
of NSScreen's screens() as record
# set width (x) and height (y) of resolution
set scrx to display's width
set scry to display's height
-------------- invoke shell script to display a dialog window, route the script's return value to null
-- (runs asynchronously, allows further KBM/applescript steps while the dialog box remains displayed)
--------------
do shell script "osascript -e 'tell application \"System Events\"' -e 'display dialog \"KBM Macros: OFF!\" buttons \"OK\"' -e 'end tell' > /dev/null 2>&1 &"
-- do shell script "sleep 0.5"
---------- this part is just to move the dialog window, and isn't necessary ----------
tell application "System Events"
delay 1
try
set thewin to window 1 of application process "System Events"
set winsize to size of thewin
set sizx to item 1 of winsize as integer
set sizy to item 2 of winsize as integer
set winpos to {scrx - sizx, 0} -- change as needed to set position of the dialog
set position of thewin to winpos
end try
end tell
---------- end of snippet to move the dialog window ----------</string>
<key>TimeOutAbortsMacro</key>
<true/>
<key>TrimResults</key>
<true/>
<key>TrimResultsNew</key>
<true/>
<key>UseText</key>
<true/>
</dict>
</array>
</plist>
And this part I use from the other state of the toggle (macros suspended) to dismiss the shell-instanced dialog box.
I know you've other stuff in there as well, but you should be able to do what you want (and more cheaply in terms of resources) with a simple ignoring application responses block. This, for example, won't block macro execution: