Comments (16)
To summarize for posterity, just use skhd -k "escape"
(qes
mentioned above was merged into skhd). For example:
example_mode < f : skhd -k "escape";\
chunkc tiling::desktop --layout float
from skhd.
I wonder if we could just use the same as we do today, but have EOL be either end of bind, or followed by a new command.
This might look something like:
cmd - 5 : do_stuff
: do_more_stuff
; focus
grammar would look something like the following:
command_seq = <command> 'EOL' | <command> 'EOL' <command>
command = <internal_command> | <external_command>
internal_command = ';' <mode>
external_command = ':' <shell>
shell = 'some shell string'
from skhd.
One thing I didn't quite get was Is this syntax still going to be possible in the future? Having the ability to dump back into a mode after executing commands would be pretty handy. Or was your writeup explaining the difficulties?
It would work, but it's not really bulletproof.
Take case2 which was exiting a mode, synthesizing a keypress for space transition, and then entering the mode again.
focus < ctrl - space ; default
default < ctrl - space ; focus
focus < 1 : qes -k "ctrl - space"; qes -k "cmd + alt - 1"; qes -k "ctrl - space";
This works because when we synthesize a keypress, they enter the key-callback of skhd just as if you would have manually pressed these keys in the given sequence.
If you write what would be considered the equivalent functionality in the proposed integration, it would look like:
focus < 1 ; default
: qes -k "cmd + alt - 1"
; focus
This is not equivalent to the first one though. What would happen here is that skhd would first enter the default mode, then fork_and_exec the key-synthesize command, and then switch back to focus mode. But the key part here is that there is no guarantee that the key-synthesize command finished executing and got processed by skhd, before the last focus change command was placed into effect. Most likely it will not be processed, as the last focus change command is actually running in the thread that the next key-event to process is supposed to be processed by..
So I'm not sure if this change is really all that useful after all.
from skhd.
qes is working just fine for me on Mojave, well the --text option is not working, but the --key does work (which is the one using the deprecated API)
Build log:
rm -rf ./bin
mkdir -p ./bin
clang src/qes.c -std=c99 -Wall -g -O0 -framework Carbon -o bin/qes
src/qes.c:27:5: warning: 'CGPostKeyboardEvent' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)key, pressed);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:342:19: note:
'CGPostKeyboardEvent' has been explicitly marked deprecated here
CG_EXTERN CGError CGPostKeyboardEvent(CGCharCode keyChar, CGKeyCode virtualKey,
^
src/qes.c:57:9: warning: 'CGSetLocalEventsSuppressionInterval' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
CGSetLocalEventsSuppressionInterval(0.0f);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:379:19: note:
'CGSetLocalEventsSuppressionInterval' has been explicitly marked deprecated here
CG_EXTERN CGError CGSetLocalEventsSuppressionInterval(CFTimeInterval seconds)
^
src/qes.c:58:9: warning: 'CGEnableEventStateCombining' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
CGEnableEventStateCombining(false);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:280:19: note:
'CGEnableEventStateCombining' has been explicitly marked deprecated here
CG_EXTERN CGError CGEnableEventStateCombining(boolean_t combineState)
^
3 warnings generated.
Edit: It works if you give qes accessibility permissions.
from skhd.
I like your idea better!
from skhd.
I'm in the process of converting my khdrc to a skhdrc right now and I think this could be used to replicate the prefix timeout.
Below is what I want to do based on this GHI. Otherwise my prefix
mode will not time out in my real skhdrc
# Define the modes
# prefix is to temporarily consume all key presses for easier commands
# manage is to manage chunkwm, it consumes all key presses
# insert is to be free of all key bindings
:: default : chunkc border::color 0xFF6699CC
:: prefix @ : chunkc border::color 0xFFFAC863 : sleep 5 ; default
:: manage @ : chunkc border::color 0xFFC594C5
:: insert : chunkc border::color 0xFFF99157
prefix, manage, insert < escape ; default
ctrl - k ; prefix
prefix < i ; insert
prefix < m ; manage
The thing to note is :: prefix @ : chunkc border::color 0xFFFAC863 : sleep 5 ; default
The basic idea is to wait for the shell script to exit (after sleep 5
then dump back into the default mode).
Maybe there is better syntax for the idea, maybe the idea is bad all around. I just figured that behavior might be nice in order to not have to introduce a timer into skhd and still offer a timeout (prefix) capability.
from skhd.
This is gonna sound silly at first, but stay with me.
While adding the ability to have commands and mode-switching intermixed sounds great at first, it has a couple of limitations that might not a first be obvious, and it was not really obvious to me either before I spent some time thinking about how to implement the proposed feature.
The modal system is currently separated entirely from runtime, due to how we separate between a mode activation command, and a shell command during parsing.
When we detect that a bind mapped to a hotkey has been pressed, we check to see whether this hotkey is an internal mode activation, or a shell command.
If it is a mode activator, we switch the current mode at this point in time.
That means, if you try to spin off something like
:: prefix @ : chunkc border::color 0xFFFAC863 : sleep 5 ; default
The sleep 5
would actually sleep skhd's main-thread, and that is the only way it could ever perform the command to activate default mode after the sleep ends.
We could do a double fork() to get an async run, and it would no longer sleep the main-thread, but then it would not be able to modify the active mode of skhd.
the updated system described in the first post would roughly work something like this:
// ..
for (int i = 0; i < hotkey->command_chain_length; ++i) {
struct command *cmd = hotkey->command_chain[i];
if (cmd->is_internal) {
// swap active mode
} else {
fork_and_exec_command(cmd->command);
}
}
// ..
HOWEVER
you can (in the current version of skhd) do the following to get prefix timeout:
default < shift + cmd - o ; prefix
prefix < escape ; default
:: prefix @ : chunkc border::color 0xFFFAC863; sleep 5; qes -k "escape"
So to summarize, yes it is possible to do this to make the syntax simpler, but it is less powerful than synthesizing keypresses.
from skhd.
The sleep 5 would actually sleep skhd's main-thread, and that is the only way it could ever perform the command to activate default mode after the sleep ends.
That sounds less than ideal, thanks for pointing out that potential downfall
you can (in the current version of skhd) do the following to get prefix timeout:
This is a pretty nifty workaround. If I find that I'm missing the prefix system I'll use that.
So far though, I have found that I don't need it.
Thanks for the through writeup!
cmd - 5 : do_stuff
: do_more_stuff
; focus
One thing I didn't quite get was Is this syntax still going to be possible in the future? Having the ability to dump back into a mode after executing commands would be pretty handy. Or was your writeup explaining the difficulties?
from skhd.
@koekeishiya makes sense to me. In both my use cases, there is a viable and working solution, so Iβm happy. One last question though, when I compiled βqesβ, I saw the deprecation note. What happens when Apple completely eliminates that API? Is there any other way to build a new βqesβ? (Iβm not a Mac developer)
from skhd.
khd uses the version that is not deprecated, but that API seems rather unstable, as it does not always work for some reason (timing related). That's why I opted to use the deprecated version in skhd, as it actually works.
I'm not too worried about Apple removing them yet, as there are tons of API's that was deprecated in 10.5-10.6 that still work just fine on modern systems, and I would expect these to go first.
@dominiklohmann could you test https://github.com/koekeishiya/qes on Mojave when you have some spare time, so we can at least make sure that it will stay around for the next year or so.
from skhd.
could you test https://github.com/koekeishiya/qes on Mojave when you have some spare time, so we can at least make sure that it will stay around for the next year or so.
Not looking good. Note how the warnings say "No longer supported". You can run qes
, but it does nothing except for printing its version with -v
.
clang src/qes.c -std=c99 -Wall -g -O0 -framework Carbon -o bin/qes
src/qes.c:27:5: warning: 'CGPostKeyboardEvent' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)key, pressed);
^
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:342:19: note:
'CGPostKeyboardEvent' has been explicitly marked deprecated here
CG_EXTERN CGError CGPostKeyboardEvent(CGCharCode keyChar, CGKeyCode virtualKey,
^
src/qes.c:57:9: warning: 'CGSetLocalEventsSuppressionInterval' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
CGSetLocalEventsSuppressionInterval(0.0f);
^
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:379:19: note:
'CGSetLocalEventsSuppressionInterval' has been explicitly marked deprecated here
CG_EXTERN CGError CGSetLocalEventsSuppressionInterval(CFTimeInterval seconds)
^
src/qes.c:58:9: warning: 'CGEnableEventStateCombining' is deprecated: first deprecated in macOS 10.6 - No longer supported [-Wdeprecated-declarations]
CGEnableEventStateCombining(false);
^
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:280:19: note:
'CGEnableEventStateCombining' has been explicitly marked deprecated here
CG_EXTERN CGError CGEnableEventStateCombining(boolean_t combineState)
^
3 warnings generated.
(Rant: Honestly what the fuck even is the new GitHub dashboard that doesn't show this mention or this issue, had I not looked into my mails I wouldn't have seen this.)
from skhd.
Thanks for testing this. So yeaaaah.. let's hope they actually fixed event-taps then..
from skhd.
I haven't yet migrated to skhd
, never found the time and motivation to do so. I have not run into any issues with khd
so far, but I also have not linked it against the 10.14 APIs since I just continued using the build I signed like a year ago. I probably should test a few more things here.
from skhd.
See https://github.com/koekeishiya/khd/issues/81 and https://github.com/koekeishiya/khd/issues/15 for history regarding synthesizing keypresses.
from skhd.
I do wish there was a way to dump back to the "default" mode after a key command is pressed. This is what I have now
# Change the split mode of the current node (\)
prefix < 0x2A : chunkc tiling::window --toggle split; qes -k "escape"
# Toggle window state of focused node
prefix < shift - f : chunkc tiling::window --toggle fullscreen; qes -k "escape"
prefix < p : chunkc tiling::window --toggle parent; qes -k "escape"
prefix < w : chunkc tiling::window --toggle float; qes -k "escape"
# Set space tiling mode
prefix < b : chunkc tiling::desktop --layout bsp; qes -k "escape"
prefix < f : chunkc tiling::desktop --layout monocle; qes -k "escape"
prefix < w : chunkc tiling::desktop --layout float; qes -k "escape"
I wonder if something like this would work:
:: default : chunkc border::color 0xFF6699CC
:: prefix ; default @ : chunkc border::color 0xFFFAC863
prefix < escape ; default
ctrl - k ; prefix
prefix < p : chunkc tiling::window --toggle parent
prefix < w : chunkc tiling::window --toggle float
So there wouldn't be chaining or timers or anything fancy. Just a way to dump back to any mode after receiving a bound keypress. It wouldn't wait for the command to execute, or care if it executed. It would just be a way to toggle modes when a different mode runs a command.
Perhaps there are some downfalls with that I am not thinking of. Having qes -k "escape"
works well enough
from skhd.
Probably a beta 2 change then, haven't tested since. That's very nice to see. π
from skhd.
Related Issues (20)
- Running as a service under Sonoma 14.2.1 doesn't work
- Running as a service under Sonoma 14.2.1 doesn't work HOT 4
- Works fine, until I try to implement modes HOT 2
- Passing through modifier keys HOT 2
- Hotload of config file not working when symlinked HOT 2
- cmd and pageup issues
- Bindings matched with `*` inside `proc_map_lst` doesn't work as expected HOT 1
- skhd getting keypres after other apps HOT 2
- Output keypresses but using a different input source (language)
- command using jq works when running from command line but not as a service HOT 1
- 0x37 aka print screen HOT 1
- zsh:1: command not found: yabai HOT 5
- cmd - 0x38 (printscreen) is moving window to another workspace HOT 1
- Cannot build
- `zsh:1: command not found: yabai` - only when running the service HOT 2
- How to map simple key chords like emacs? HOT 1
- Move window to space not working on macOS Sonoma 14.5 HOT 3
- Multiple action hotkeys not working HOT 2
- Hotkeys often stop working after the first time they work. HOT 5
- Can't use alt key for other things while skhd is running (e. g. backslash)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from skhd.