-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to emit on release only #80
Comments
Currently Activating arbitrary actions on release is not well supported by the underlying key state machine at present. It does however support emitting a release event for Given that this functionality seems quite specific, it may be sufficient to provide |
Would I be able to listen to layer switches in order to run a cmd? Because in kmonad, I run a cmd along with the layer switch to change my key layer widget (in AwesomeWM) to display the current layer. |
Yea you could write your own code that connects to the kanata TCP server and runs the commands itself. Or another event could be added for |
Okay then it seems Do you think a general Because I've this concept I named Proxy Mod where, in the base layer, I hold a key (the proxy mod) -> it changes to a layer that lets you pick modifiers like ctrl (via |
It's certainly possible if I or someone else can think of a design that fits well with keyberon's state machine. An idea that popped into my head is that rather than have general-case press-only or on-release, have the ability to create fake keys that have arbitrary actions. And then there can be other actions to tap/press/release these fake keys that are disconnected from the keyboard inputs. A specific on-release case could act on these fake keys. The concept of fake keys works better in keyberon's state machine than general on-release does. |
Not sure I follow the whole fake keys concept. Also, I just want to differentiate between I believe |
The fake keys idea would probably make more sense if you look at the design docs as well as the code. The kanata code leaves the key state management to the keyberon library. The library doesn't have a good way to handle on-release. It also doesn't have a good way to handle press-only; all key states (not layer though) are tied to a physical key being pressed and the state goes away when the physical key is released. Fake keys would be a way to use the keyberon library to decouple physical key presses and releases from key state. |
Okay I think I understand. Basically, use fake keys as a middle-man (or filtering mechanism) to trick the keyberon's state management. |
I think #92 should be able to replicate all the functionality you want. It'll require a different setup compared to kmonad, but I think it'll work. See the kanata.kbd file changes for examples. Please test at your leisure and let me know what you think. |
Fake keys seem to work as intended. Thanks! I appreciate how quickly you added it in. I also noticed you can map Now my issues are pretty much API-related. (Note: I haven't really studied the source code as I'm not familiar with Rust as much so I'm looking at this from a more UX perspective. Forgive me for my lack of knowledge of the source code's limitations.) Fake Keys APIFor the average user, I think fake keys are probably better of as an implementation detail for some abstraction rather than a direct API, but here are my suggestions to improve the API anyway:
From a UX perspective, it just seems redundant having to manually map a normal key to a fake key alias. Perhaps
The added prefix makes it more clear. For instance, A More Composable API
This would add a lot of composability. You can still keep the fake keys API if you want, but such composable abstractions would be nice. For instance, I could create a bunch of (defalias
;; GENERAL
;;; lock modifiers
po-lalt (press-only lalt)
po-lmeta (press-only lmet)
po-lshift (press-only lsft)
po-lctrl (press-only lctl)
;;; clear modifiers
ro-lalt (release-only lalt)
ro-lmeta (release-only lmet)
ro-lshift (release-only lsft)
ro-lctrl (release-only lctl)
lclear (multi @ro-lalt @ro-lmeta @ro-lshift @ro-lctrl)
ro-ralt (release-only ralt)
ro-rmeta (release-only rmet)
ro-rshift (release-only rsft)
ro-rctrl (release-only rctl)
rclear (multi @ro-ralt @ro-rmeta @ro-rshift @ro-rctrl)
clear (multi @lclear @rclear)
;;; layers
base (layer-switch base)
extend (layer-switch extend)
media (layer-switch media)
navigation (layer-switch navigation)
;;; control/(escape+clear) key
esc-from-ctrl (multi (release-only lctl) esc @clear)
esc-from-ctrl-to-base (multi @esc-from-ctrl @base)
ctrl_maybe-esc (multi lctl (tap-hold-press 200 200 @esc-from-ctrl XX))
ctrl_maybe-esc-base (multi lctl (tap-hold-press 200 200 @esc-from-ctrl-to-base XX))
cte @ctrl_maybe-esc ;; Map to Caps key for base layer
ctb @ctrl_maybe-esc-base ;; Map to Caps key for other layers
;; BASE LAYER
extend-base (multi (on-press @extend) (on-release (multi @base @clear))) ;; The example I was talking about
alt-extend-base (multi lalt @extend-base)
alt @alt-extend-base ;; Map to Alt key
;; EXTEND LAYER
;;; sub-layer keys
;;;; if you release this before releasing @alt, temporarily keep the layer until @alt is released
;;;; if you release this after releasing @alt, permanently keep the layer
media-media (multi (on-press @media) (on-release @media))
navigation-navigation (multi (on-press @navigation) (on-release @navigation))
med @media-media ;; Map to Q key
nav @navigation-navigation ;; Map to W key
;;; proxy mods
;;;; Lock a modifier until @alt is released. Go to base layer
pxc (multi @po-lctrl @base) ;; Map to A key
pxs (multi @po-lshift @base) ;; Map to S key
pxa (multi @po-lalt @base) ;; Map to D key
pxm (multi @po-lmeta @base) ;; Map to F key
) Other Notes
|
The fake keys API should be composable enough to achieve the effects of what you're describing. I think what you're going for is ergonomics instead, and I can see how the kmonad way of doing it could be more ergonomic than fake keys. The fake keys API is the simplest possible API implementation that works for generic on-release, press-only, and release-only, since it maps very closely to the underlying state machine. It may be possible to hide the fake keys functionality behind press/release-only + on-release APIs, but the backing code will need to become more complex to do the bookkeeping for which actions map to which fake keys. It may happen one day, but I'm not particularly motivated to do the work to make an already complex use case more ergonomic, particularly since I don't actually use the feature myself. |
One thing to note is that fake key actions currently should also be able to refer to other previously defined fake key, and accept multi as well. This might help get closer to the ergonomics you're describing. |
Ah, I did not test that, but that's good to know. I'll try to convert my kmonad config to kanata using the fake keys API and see how it goes. In the mean time, what do you think about my suggestions on improving the fake keys API? |
To summarize my earlier comment, it's certainly possible but at this time I believe the current API and the suggested improvements have the same expressive power - just with different ergonomics - I'm not currently motivated to design and implement any changes. |
I meant just the first 2 suggestions. I assume getting rid of |
Ah I see. It's unclear how removing Renaming to |
I've force-pushed the PR branch to make the change to |
Found a bug. It seems a (deffakekeys
flctl lctl
flsft lsft
flmet lmet
flalt lalt
flclear (multi
(on-release-fake-key-op flctl release)
(on-release-fake-key-op flsft release)
(on-release-fake-key-op flmet release)
(on-release-fake-key-op flalt release)
)
)
(defalias
pct (on-press-fake-key-op flctl press)
;; DOESN'T WORK
clr (on-release-fake-key-op flclear press)
;; DOESN'T WORK
clr (on-release-fake-key-op flclear release)
;; DOESN'T WORK
clr (on-press-fake-key-op flclear press)
;; DOESN'T WORK
clr (on-press-fake-key-op flclear release)
;; WORKS
clr (multi
(on-release-fake-key-op flctl release)
(on-release-fake-key-op flsft release)
(on-release-fake-key-op flmet release)
(on-release-fake-key-op flalt release)
)
) |
My suggestion is to use normal key (instead of fake key) as arguments in So anytime you refer to a normal key inside a |
Let me check my understanding. The suggestion is that if argument to |
Maybe I'm missing something, but I'm not sure what flexibility you would lose (at least from a user's perspective).
|
Regarding the bug, I can't reproduce it. Do note that
|
I forgot to try |
I think we're missing some details in each other's understanding of how the feature should work. The simple case which loses flexibility (in my view) is:
This loses flexibility since fake keys can no longer be arbitrary actions. But it might be that it's unnecessary, not sure. The complicated case, which if implemented correctly may as well go all the way to suggestion 3 is:
This is complicated because designing the code such that press/tap/release on various physical keys will map to the correct intended common fake keys is complex. |
Oh I understand now. I was so fixated on key actions, I forgot some other arbitrary action like a Maybe you can allow to auto-generate fake keys for normal key actions, but don't remove |
It's possible and not so difficult, but to me doesn't seem worth it since the feature then becomes inconsistent, which may harm the user experience more than the inconvenience of always using |
Fair enough. Thanks for responding quickly. I suppose my only suggestion left is probably to shorten |
I'm good with shortening the action names. I'll push to the PR shortly. |
I'd like a functionality where you can emit a tap on-release only. The expression could be named
on-release
.You can get a similar functionality in kmonad with
tap-macro-release
by ignoring the all the arguments except the last. (Note: To fully copytap-macro-release
, you'd probably just have to combineon-release
withmulti
andmacro
)I've found the
on-release
functionality useful for complex layer switching where I would keep/change a layer depending on which key I release last.I've also found it useful for clearing modifiers (especially since kmonad has a
press-only
button that allows to keep mods activated).The text was updated successfully, but these errors were encountered: