Replies: 16 comments 11 replies
|
Is tcp server needed? In linux xdotool can get the activewindow |
|
The TCP server is not necessary for this particular feature as you've shown. There can be workarounds that don't involve inter-process communication. However, the TCP server is nice to have for software integrations. |
|
For ease of discovery:
|
|
Just a thought. I have been using Espanso as a text expander and noticed they have application aware triggers. |
|
Yep, that's a good reference to use if one were to implement this in kanata. https://github.com/espanso/espanso/tree/9f82b4e146e6090897c876a02f5eee697b85e979/espanso-info |
|
espanso offers similar features than autohotkey hotstrings, and similar to ahk hotstrings espanso won't work while kanata is running (at least on windows). But if we could tell espanso to listen to the kanata ouput instead of the real keyboard it should work? |
|
I quickly put together a rough draft.
Sends a request to change the layer to the current window name. Needs significant improvements, for example switch to the default layer, if current window is not in the list of application-specific layers. Here is the code: https://github.com/veyxov/qanata (sorry for the name 😅) Updates: |
|
Wow, would you believe that timing! I just finished my own daemon to interact with Kanata's TCP server. I guess it's pretty similar to kanawin with a few pros and cons. Cons
Pros
While it's still a work in progress, it's 100% working on my end. I'd love feedback if anyone gives it a try! |
|
Hey are there any plans for linux application aware layer switching or is xremaps the only solution? |
|
Hi. I created a tool for application (and input source) aware key mapping on macOS based on kanata's virtual keys. |
|
Should this feature be implemented in Kanata? If not, why? I'd also like to point out that Keyd seems to take the most minimalistic approach to application-aware remapping. |
|
Linux |
|
App-aware keymaps via virtual keys + switch (no layer duplication needed) I wanted to share a pattern I've been using in KeyPath (a macOS Kanata frontend) that solves this without requiring any Kanata changes and avoids the need to duplicate entire layers per app. Most tools in this thread switch layers on app change. The downside is you need a full copy of your layer for every app — if you have 3 apps with custom bindings and a 60-key layout, that's 3×60 key definitions even if you only want to override 2-3 keys per app. The alternative: virtual keys + Instead of switching layers, you define a virtual key per app and use (defvirtualkeys
vk_safari nop
vk_vs_code nop
)
(defalias
;; j → down in Safari, unchanged elsewhere
kp-j (switch
((input virtual vk_safari)) down break
() j break)
;; k → up in Safari, unchanged elsewhere
kp-k (switch
((input virtual vk_safari)) up break
() k break)
)
(deflayer base
@kp-j @kp-k ;; ... rest of layer unchanged
)Your companion tool just watches for app focus changes and sends TCP commands: Why this is nice:
On macOS, detecting the frontmost app is just an The full implementation in KeyPath is in |
|
One thought on this — rather than building platform-specific app detection into Kanata core, would a lightweight {"SetContext": {"key": "app", "value": "safari"}}That config could reference as: (defalias
kp-j (switch
((context app "safari")) down break
() j break))It would give companion tools a cleaner API than the virtual key workaround, while keeping all the platform-specific detection external where it belongs. Kanata stays focused on key remapping, companion tools handle environment awareness. Curious what others think — @jtroo would something like this fit Kanata's scope? |
|
For refernce, here is a simple script I'm using for app specific keymaps on Linux with Hyprland. #!/bin/bash
toggle_context_in_kanata() {
printf '%s\n' "{\"ActOnFakeKey\": {\"name\": \"$1\", \"action\": \"$2\"}}" | socat -u - TCP:localhost:10000,connect-timeout=1 &
}
handle_focus_change() {
if echo "$1" | grep -qi 'alacritty'; then
toggle_context_in_kanata "terminal" "Press"
else
toggle_context_in_kanata "terminal" "Release"
fi
}
# Listen to Hyprland's event socket
socat -U - UNIX-CONNECT:$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -r line; do
# Check if the event is a window focus change
if [[ "$line" =~ ^activewindowv2\>\> ]]; then
# Extract the window data (comes after the '>>')
window_address="${line#*>>}"
window_data=$(
hyprctl clients -j \
| jq -r \
--arg windowAddress $window_address \
'.[]
| select(
(.address | test($windowAddress;"i")))'
)
handle_focus_change "$window_data"
fi
doneI added it to the auto-start config in hyprland as follows: |
Uh oh!
There was an error while loading. Please reload this page.
For Linux, can use https://github.com/k0kubun/xremap for inspiration.
For Windows: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getforegroundwindow
All reactions