Giter Club home page Giter Club logo

kanata's People

Contributors

11kilobytes avatar andrewsmithdev avatar br-lemes avatar brockelmore avatar dependabot[bot] avatar eugenesvk avatar gerhard-h avatar itaygarin avatar jian-lin avatar johni0702 avatar jtroo avatar kircheneer avatar lgug2z avatar moritzketzer avatar nightscape avatar oberblastmeister avatar octavec avatar pheon-dev avatar philipp-m avatar pinoinha avatar postsolar avatar psych3r avatar quazirate avatar rappie avatar rayanamal avatar reidprichard avatar rszyma avatar teras avatar wis avatar wolfwood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kanata's Issues

Doesn't work on Wayland

It seems kanata doesn't support Wayland. I've tested Plasma and Gnome on Wayland. Debug output shows kanata gets key presses, but doesn't return keycodes to the system.

08:19:23 [DEBUG] (2) kanata::kanata: press     A
08:19:23 [DEBUG] (2) kanata::oskbd::linux: input ev: InputEvent { time: TimeVal { tv_sec: 0, tv_usec: 0 }, event_type: EV_KEY, event_code: EV_KEY(KEY_A), value: 1 }
08:19:23 [DEBUG] (2) kanata::kanata: release   A
08:19:23 [DEBUG] (2) kanata::oskbd::linux: input ev: InputEvent { time: TimeVal { tv_sec: 0, tv_usec: 0 }, event_type: EV_KEY, event_code: EV_KEY(KEY_A), value: 0 }

Kanata under X11 works correctly. Probably it's not important, as I suspect there is no support at all, but I'm using

kwayland 5.94.0-2
kwayland-server 5.24.5-1
wayland 1.20.0-2

ItayGarin/ktrl#32 might be related to this issue.

102d is not working

I have Pinebook Pro with ISO keyboard, and it seems that kanata cannot handle 102d key. With this simple config

(defcfg
  linux-dev /dev/input/by-id/usb-HAILUCK_CO._LTD_USB_KEYBOARD-event-kbd
)

(defsrc
  esc  f1    f2   f3   f4   f5   f6   f7   f8   f9   f10  f11  f12
  grv  1     2    3    4    5    6    7    8    9    0    -    =    bspc
  tab  q     w    e    r    t    y    u    i    o    p    [    ]    ret
  caps a     s    d    f    g    h    j    k    l    ;    '    \
  lsft 102d  z    x    c    v    b    n    m    ,    .    /    rsft            up
  lctl lmet  lalt           spc                 ralt rctl                left down rght
)

(deflayer qwerty
  esc  f1    f2   f3   f4   f5   f6   f7   f8   f9   f10  f11  f12
  grv  1     2    3    4    5    6    7    8    9    0    -    =    bspc
  tab  q     w    e    r    t    y    u    i    o    p    [    ]    ret
  caps a     s    d    f    g    h    j    k    l    ;    '    \
  lsft 102d  z    x    c    v    b    n    m    ,    .    /    rsft            up
  lctl lmet  lalt           spc                 ralt rctl                left down rght
)

all keys work, except for nubs.

kanata prints

19:51:53 [DEBUG] (2) kanata::oskbd::linux: input ev: InputEvent { time: TimeVal { tv_sec: 0, tv_usec: 0 }, event_type: EV_KEY, event_code: EV_KEY(KEY_UNKNOWN), value: 0 }

xev (with kanata disabled):

KeyPress event, serial 39, synthetic NO, window 0x1200001,
    root 0x226, subw 0x0, time 6757247, (-249,402), root:(622,847),
    state 0x0, keycode 94 (keysym 0x3c, less), same_screen YES,
    XLookupString gives 1 bytes: (3c) "<"
    XmbLookupString gives 1 bytes: (3c) "<"
    XFilterEvent returns: False

I've added some prints, and in linux.rs

impl From<KeyCode> for OsCode {
    fn from(item: KeyCode) -> Self {

receives KeyCode::No, and from(item: OsCode) -> KeyCode receives OsCode::KEY_UNKNOWN.

Problem is present under both X11 and Wayland.

Add some way for an external application to receive structured output events from kanata

The code that logs layer changes is:

fn check_handle_layer_change(&mut self) {

A new member could be added to the Kanata struct to hold any server configurations:

let kbd_in_path = cfg

pub struct Kanata {

It probably makes sense to start the server in main_impl, though I haven't thought too hard about:

fn main_impl(cfg: CfgPath) -> Result<()> {

Reducing CPU usage

I have an AMD Ryzen 9 3900X 12-core processor, and when left running unchecked, kanata's CPU usage sits at 30%+.

If I use Task Manager to restrict which processors kanata.exe can utilise, the CPU drops down to a negligible 0.x% without any noticeable performance impact (including with the TCP server emitting outgoing and processing incoming messages).

image

I think it would be a good idea to allow the number of processors that kanata utilises to be configurable either via a command line flag or through the configuration file.

Allow to emit on release only

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 copy tap-macro-release, you'd probably just have to combine on-release with multi and macro)

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).

Add mouse click

This should be more easily cross platform than replicating the whole mouse.

Here's my use case: I have a trackball that is great for scrolling and movement but I don't like it much for clicking. So instead, when paired with my QMK board, I click with my left hand using the keyboard and navigate+scroll with my right hand using the trackball.

Feature request: System tray support

I personally like using kanata without system tray but system tray comes in handy to know if kanata is running or not and on which keyboard(or configuration).
It can be used at a later stage to control multiple keyboards on and of, or improvement in gui configurations.

Add action for releasing state

Use case:

Let's say I want lalt as a multi-use key that acts as lalt as well as layer-toggle at the same time. Some desired actions in the new layer want lalt to be held down the whole time (1) since repeated press-release of alt results in the wrong behaviour. Other actions (2) actually don't want alt to be pressed at all.

To achieve (1), one could use (multi lalt (layer-toggle other-layer)). To achieve (2), a theoretical action (multi (release lalt) <un-alted key>) could work.

behaviour of multi cmd is incorrect

It seems that multi cannot process more than 2 cmd.
For example:
pp (multi q (cmd notify-send "hello") t (cmd notify-send "hi"))
will print qt and display hello without notifying the hi
the same if I put it like this
pp (multi (cmd notify-send "hello") (cmd notify-send "hi")) will process only the first cmd.

evdev device resources are not correctly released when kanata is killed by signals

evdev device should call these functions to release resources before closing the device fd. They are wrapped by evdev-rs in the Drop trait.

Currently, the only way to terminate kanata is to kill it by a signal, e.g. SIGINT and SIGTERM.

Rust doesn't unwind and call drop() by default when receive SIGINT and SIGTERM, which causes those devices fail to release resources properly.

Relates to #46 , but I think this should be a separate issue and I cannot re-open that issue.

order of log `Kanata: config parsed` can be improved

Kanata: config parsed should be before Created device "/dev/input/event7"

12:57:40 [INFO] Created device "/dev/input/event7"
12:57:40 [INFO] Created symlink "/run/kanata-mykbd/mykbd" -> "/dev/input/event7"
12:57:40 [INFO] Kanata: config parsed
12:57:40 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones.
12:57:42 [INFO] Kanata: entering the processing loop
12:57:42 [INFO] Kanata: entering the event loop
12:57:42 [INFO] Init: catching only releases and sending immediately
12:57:42 [INFO] Starting kanata proper

Live reload of configuration

Have a key action for hot reloading the configuration. A ~1-second convenience compared to closing and restarting the application.

When active on Linux

Hi

Just to clarify ... when is this active on Linux?

  1. at boot (to command line) ?
  2. in desktop environment ?

I have my own custom layout, but it's currently only configured in KDE, so to log in I need to know where the Qwerty keys are. Avoiding that would be good.

Thanks, Ian

Figure out a better workaround for newline repeat on startup

When starting the program, newlines get repeatedly and rapidly sent into the active application until a new key is pressed. This is currently worked around by sending spaces for 1s on program start, but this is pretty ugly. Need to see if there's a better solution.

Gracefully exit

I am trying to add a functionality of creating a symlink in /dev/input/by-id/ for the newly created device /dev/input/eventxx.

Creating a symlink works if #45 is applied. However, kanata doesn't gracefully exit, which makes cleaning up the symlink rather hard if not impossible.

I would like to discuss about graceful exit.

Unicode support

Unicode support should be possible in Linux applications with the existing functionality. Holding Ctrl+Shift+u then typing the unicode number will input the unicode character.

E.g. this sad smiley โ˜น is U+2639, so the alias below works correctly to input the sad smiley.

(defalias sad (multi lctl lsft u 2 6 3 9))

However, Windows does not have any such convenient and well-designed feature. It looks like kbremap has unicode support for Windows though, so it's definitely possible.

https://github.com/timokroeger/kbremap

Doesn't build on Manjaro ARM

I was able to build kanata on regular x86_64 PC without any issues, but it fails to build on Pinebook Pro under Manjaro ARM. Error is

   Compiling kanata v1.0.1 (/home/fenuks/Projects/keyboard/kanata)
error[E0308]: mismatched types
  --> src/oskbd/linux.rs:91:29
   |
91 |             uidev.name[0] = 'k' as i8;
   |             -------------   ^^^^^^^^^ expected `u8`, found `i8`
   |             |
   |             expected due to the type of this binding

error[E0308]: mismatched types
  --> src/oskbd/linux.rs:92:29
   |
92 |             uidev.name[1] = 't' as i8;
   |             -------------   ^^^^^^^^^ expected `u8`, found `i8`
   |             |
   |             expected due to the type of this binding

error[E0308]: mismatched types
  --> src/oskbd/linux.rs:93:29
   |
93 |             uidev.name[2] = 'r' as i8;
   |             -------------   ^^^^^^^^^ expected `u8`, found `i8`
   |             |
   |             expected due to the type of this binding

error[E0308]: mismatched types
  --> src/oskbd/linux.rs:94:29
   |
94 |             uidev.name[3] = 'l' as i8;
   |             -------------   ^^^^^^^^^ expected `u8`, found `i8`
   |             |
   |             expected due to the type of this binding

For more information about this error, try `rustc --explain E0308`.
error: could not compile `kanata` due to 4 previous errors

Changing these casts to u8 fixes compilation error, so it seems it's portability problem, and c_char on my CPU is u8, as seen in libc sources:

//! AArch64-specific definitions for 64-bit linux-like values

pub type c_char = u8;

I'm not that familiar with rust, but perhaps code should be changed to something to this in order to fix problem for various strange machines:

diff --git i/src/oskbd/linux.rs w/src/oskbd/linux.rs
index a7de646..b3424ae 100644
--- i/src/oskbd/linux.rs
+++ w/src/oskbd/linux.rs
@@ -14,6 +14,7 @@
 use crate::custom_action::*;
 use crate::keys::*;
 use libc::input_event as raw_event;
+use libc::c_char;
 
 // file i/o
 use io::Write;
@@ -88,10 +89,10 @@ pub fn new() -> Result<Self, io::Error> {
             }
 
             let mut uidev: uinput_user_dev = mem::zeroed();
-            uidev.name[0] = 'k' as i8;
-            uidev.name[1] = 't' as i8;
-            uidev.name[2] = 'r' as i8;
-            uidev.name[3] = 'l' as i8;
+            uidev.name[0] = 'k' as c_char;
+            uidev.name[1] = 't' as c_char;
+            uidev.name[2] = 'r' as c_char;
+            uidev.name[3] = 'l' as c_char;
             uidev.id.bustype = 0x3; // BUS_USB
             uidev.id.vendor = 0x1;
             uidev.id.product = 0x1;

Multiple defcfg linux-dev

I use two of these 6x4 keypad as a split keyboard. As they are two independent keyboards, normally I can't setup layers which works across the "halves" (a key in one keypad which activates a layer in the other one). To solve this I currently use evsieve to fake one device out of these two. This way:

# evsieve --input /dev/input/by-id/usb-BlackC_Sayobot.cn_L-event-kbd grab --input /dev/input/by-id/usb-BlackC_Sayobot.cn_R-event-kbd grab --output create-link=/dev/input/by-id/sayo

It would be nice if kanata could use multiple devices this way out of the box.

H80454abdae6b4f8c9749ffbb733055a5D

Programmatically changing layers

I have a vague idea in my head of being able to programmatically change layers when the focused application changes.

As I mentioned on Reddit, komorebi has an event stream that can be subscribed to and acted upon; the idea I have looks like writing a daemon to respond to FocusChange events from komorebi by triggering LayerChange events in kanata.

The concrete use case I have for this right now is automatically changing to my ff layer for Vim-like navigation in Firefox whenever it takes focus and switching back to my base layer whenever any other application takes focus. I'm sure as I add more and more application-specific layers this sort of functionality would become exponentially more useful and ergonomic for long sessions at the computer.

This feature seems like it could naturally fit into the work that is being done in #44, which the server responding to client messages to trigger layer changes (and maybe other actions in the future?).

Let me know what you think!

Add support for macros

A macro is different from the current multi action in the configuration because multi keeps all of the keys pressed for the entire duration. This makes some string sequences impossible to type with multi, e.g. http://localhost because : requires shift to type and then shift will be held for the entire duration.

Mouse support for scroll and extra buttons

Is it doable for including more mouse support as in default x11.

1 = left button
2 = middle button (pressing the scroll wheel)
3 = right button
4 = turn scroll wheel up
5 = turn scroll wheel down
6 = push scroll wheel left
7 = push scroll wheel right
8 = 4th button (aka browser backward button)
9 = 5th button (aka browser forward button)

Rename layer-toggle to layer-hold

I've had this discussion before in this thread: kmonad/kmonad#560 (comment)

Basically, the main points are:

  • toggle doesn't imply a momentary switch
  • toggle's usage in here contradicts its usage in a lot of applications and games
  • After not looking at your config for a long time, if you look at it again and try to differentiate between layer-switch and layer-toggle, the average user might be initially confused and have to look for the config reference again.

With kmonad, we eventually settled with adding momentary-layer as an alias, but I still think renaming it layer-hold is the more succinct solution because

  • It keeps the layer prefix pattern
  • hold is much simpler and more precise for the average user

The author seems to want to reserve hold for patterns like tap-hold, but I believe the average user would easily differentiate between tap-hold and layer-hold because of the different namespaces/contexts.

ralt is sending lctl press

Hello and thank you for working on this.

I have an issue using kanata with windows. If my config (defsrc and deflayer) includes lctl it will send a lctl keypress when I press ralt. Here is the debug log:

10:08:27 [INFO] NOTE: kanata was compiled to never allow cmd
10:08:27 [INFO] Kanata: config parsed
10:08:27 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones.
10:08:27 [INFO] Kanata: entering the processing loop
10:08:27 [INFO] Init: catching only releases and sending immediately
10:08:37 [INFO] Starting kanata proper
10:08:40 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
10:08:40 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_RIGHTALT, value: Press }
10:08:40 [DEBUG] (2) kanata::kanata: press     LCtrl
10:08:40 [DEBUG] (2) kanata::kanata: press     RAlt
10:08:40 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_RIGHTALT, value: Release }
10:08:40 [DEBUG] (2) kanata::kanata: release   RAlt
10:08:54 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Press }
10:08:54 [DEBUG] (2) kanata::kanata: repeat    LCtrl
10:08:54 [DEBUG] (1) kanata::kanata: event loop: KeyEvent { code: KEY_LEFTCTRL, value: Release }
10:08:54 [DEBUG] (2) kanata::kanata: release   LCtrl

What I am doing here is:

  1. Start kanata
  2. Press and hold RAlt
  3. Notice that the left ctrl is "pressed" but not released
  4. Release RAlt
  5. Now the computer behaves as if lctl is pressed
  6. Pressing lctl again releases lctl

Here is my config:

(defcfg
  ;; Windows does not need any input / output config
 )

(defalias
  met_a (tap-hold 200 200 a lmet)
  alt_s (tap-hold 200 200 s lalt)
  ctl_d (tap-hold 200 200 d lctl)
  sft_f (tap-hold 200 200 f lsft)
  sft_j (tap-hold 200 200 j rsft)
  ctl_k (tap-hold 200 200 k rctl)
  alt_l (tap-hold 200 200 l ralt)
  met_; (tap-hold 200 200 ; lmet)
)

(defsrc
  grv  1    2    3    4    5    6    7    8    9    0    -    =    bspc
  tab  q    w    e    r    t    y    u    i    o    p    [    ]    \
  caps a    s    d    f    g    h    j    k    l    ;    '    ret
  lsft z    x    c    v    b    n    m    ,    .    /    rsft
  lctl lmet lalt           spc            ralt rmet rctl
)

(deflayer homerowmods
  grv   1       2       3       4       5       6       7       8       9       0       -     =     bspc
  tab   q       w       e       r       t       y       u       i       o       p       [     ]     \
  caps  @met_a  @alt_s  @ctl_d  @sft_f  g       h       @sft_j  @ctl_k  @alt_l  @met_;  '     ret
  lsft  z       x       c       v       b       n       m       ,       .       /       rsft
  lctl  lmet    lalt                    spc                     ralt    rmet    rctl
)

To get around this issue I can simply remove lctl from my config and everything will work as intended.

Not sure if it matters, but I am using norwegian keyboard layout with Alt Gr as right alt key.

Bug: Transparent keys on base layer act as dead keys

Expected

Transparent keys (i.e. using underscore _) on the first layer should not be remapped at all, sending whatever key is defined in the defsrc declaration. This is how kmonad behaves.

Actual

Although input is registered and visible from debug logs, no key is output at all leaving these keys dead.

To Reproduce

Use the following config:

(defcfg)
(defsrc a f)
(deflayer one (layer-toggle two) _)
(deflayer two a z)

Tapping f sends no key. Holding a and then tapping f sends z as expected. Logs for this sequence:

$ ./target/debug/kanata.exe --cfg repro.kbd --debug
06:27:50 [INFO] Kanata: config parsed
06:27:50 [INFO] Kanata: entering the processing loop
06:27:50 [INFO] Init: catching only releases and sending immediately
06:27:51 [INFO] Starting kanata proper
06:27:59 [DEBUG] (2) kanata::kanata: event loop: KeyEvent { code: KEY_F, value: Press }
06:27:59 [DEBUG] (2) kanata::kanata: event loop: KeyEvent { code: KEY_F, value: Release }
06:28:01 [DEBUG] (2) kanata::kanata: event loop: KeyEvent { code: KEY_A, value: Press }
06:28:01 [INFO] Entered layer:
(deflayer two a z)
06:28:01 [DEBUG] (2) kanata::kanata: event loop: KeyEvent { code: KEY_F, value: Press }
06:28:01 [DEBUG] (3) kanata::kanata: press     Z
06:28:01 [DEBUG] (2) kanata::kanata: event loop: KeyEvent { code: KEY_F, value: Release }
06:28:01 [DEBUG] (3) kanata::kanata: release   Z
06:28:02 [DEBUG] (2) kanata::kanata: event loop: KeyEvent { code: KEY_A, value: Release }
06:28:02 [INFO] Entered layer:
(deflayer one (layer-toggle two) _)

System Info

I'm on Windows 10, compiling myself using the most recent main branch.

tap-hold inside tap hold behaves incorrectly

I was trying to fully utilize tap-hold by inserting another tap-hold inside it with no luck
pp (tap-hold 200 200 a (tap-hold 200 2000 b c))
no matter how I hold key, could not get b. it either prints a or c

Feature request: shell command or workaround

I am really impressed with kanata. It replaced my xcape and kind of my use of kmonad. Tap-hold works well.
I was struggling to get a notification when changing layers , I got this workaround
nnlck ( multi (layer-switch numpad) (macro C-A-S-a))
the chord is binded to a shell notification that numpad is active. So far so good

The only thing that i miss from kmonad is switching out of virtualbox. In kmonad I could do it with a shell command to show the desktop.
kkk (multi-tap 300 (cmd-button "wmctrl -k on") (cmd-button "wmctrl -k off") )
For kanata, using a macro with chording I could not do it since virtualbox took over my keyboard and mouse

Add f13 ~ f23 mapping for kbd configuration

I have the truly ergonomic keyboard which can mapping the keys to F16, ... , F23 to remap.
https://trulyergonomic.com/ergonomic-keyboards/knowledge-base/

When I added 'f22' in the kbd file, kanata makes error like

thread 'kanata' panicked at 'Could not parse cfg: Unknown key in defsrc: "f22"', src\main.rs:85:51
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Any { .. }', src\main.rs:94:20

please add more function keys to find proper OS keys at mod.rs

Thank you for your great program.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.