Multiple Button Linking

To bind to key 1 , I use:

hs.hotkey.bind(hyper, '1' 

How to bind a few keystrokes 1 ? Sort of:

 hs.hotkey.bind(hyper, '1+1' 

Reading documentation , this functionality is not mentioned.

With many taps, I mean pressing 1 twice to run some code, and pressing 1 three times to run a single piece of code.

+5
source share
2 answers

You will have to implement this yourself. Here is a basic summary of how to do this:

  • Start the timer from scratch and set the flag for the first press first to false, which means that the first press has not yet occurred.
  • Watch and watch keys with hs.eventtap , specifically hs.eventtap.event.types.keyPress
  • When an event ( keyPress ) occurs, check if the key has been pressed with the correct key.
  • If it was the right key, check if it pressed the second press, and if it was on time, if it was not on time or there was no second press, set the timer to the current time and the first flag to true
  • If this was the second press and on time, execute our handler and reset the timer and the first flag
  • If it was not the correct key, then reset the timer and the first flag

Translated to code, this is what it might look like (I'm not a Lua expert). Note that flags can be implemented as Boolean here or as internal tables holding down keys so far that you could check:

 local timer = require("hs.timer") local eventtap = require("hs.eventtap") local keycodes = require("hs.keycodes") local events = eventtap.event.types --all the event types timeFrame = 1 --this is the timeframe in which the second press should occur, in seconds key = 50 --the specific keycode we're detecting, in this case, 50 --print(keycodes.map["`"]) you can look up the certain keycode by accessing the map function twoHandler() hs.alert("Pressed ` twice!") --the handler for the double press end function correctKeyChecker(event) --keypress validator, checks if the keycode matches the key we're trying to detect local keyCode = event:getKeyCode() return keyCode == key --return if keyCode is key end function inTime(time) --checks if the second press was in time return timer.secondsSinceEpoch() - time < timeFrame --if the time passed from the first press to the second was less than the timeframe, then it was in time end local pressTime, firstDown = 0, false --pressTime was the time the first press occurred which is set to 0, and firstDown indicates if the first press has occurred or not eventtap.new({ events.keyDown }, function(event) --watch the keyDown event, trigger the function every time there is a keydown if correctKeyChecker(event) then --if correct key if firstDown and inTime(pressTime) then --if first press already happened and the second was in time twoHandler() --execute the handler elseif not firstDown or inTime(pressTime) then --if the first press has not happened or the second wasn't in time pressTime, firstDown = timer.secondsSinceEpoch(), true --set first press time to now and first press to true return false --stop prematurely end end pressTime, firstDown = 0, false --if it reaches here that means the double tap was successful or the key was incorrect, thus reset timer and flag return false --keeps the event propogating end):start() --start our watcher 

I commented the code line by line for a better understanding. If you want to detect 3 or 4 or any other arbitrary number of N presses, just set the flags for the N - 1 presets and add a few checks, but it is unusual to have a key combination that takes more than two consecutive keystrokes. It sounds a bit verbose, but AFAIK is how you do it. To avoid duplication of code and template, try placing it in a structure class or module so that you can reuse the code.

As for executing another handler for two consecutive keystrokes or 3 consecutive keystrokes, this will be a little more hacked, since you have to wait for the whole timeframe before knowing whether the user will click again to find out which handler to execute. This can cause a little delay and a bad user experience, I would suggest against this, although you could probably implement this by refactoring the code and doing some other checks, such as starting the timeframe and the first flag, then execute the handler for one click.

0
source

You cannot bind all keys or multiple keys to a binding. Instead, you can use this function: http://www.hammerspoon.org/docs/hs.eventtap.html#keyStroke

Thus, the most aggressive approach with a direct programming language is as follows:

  • Call your function for any keystroke.
  • Static instance variables that will contain previous keystrokes are stored inside the function.
  • As the first task of your function, add a new suitable character to this variable.
  • Check the last 3 characters if they are the desired string "11".

Additionally for extreme conditions:

  1. If the variable length passes a certain point, reduce it to a length of 1 so that it does not remain unnecessary in memory.
0
source

Source: https://habr.com/ru/post/1268433/


All Articles