Skip to content
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

Bug: Kanata doesn't automatically register bluetooth keyboard when it connects the second time #1390

Open
2 tasks done
Udragg opened this issue Nov 27, 2024 · 2 comments
Open
2 tasks done
Assignees
Labels
bug Something isn't working linux Issue pertains to Linux only PRs welcome jtroo has no plans to work on this at present, but PRs are welcome

Comments

@Udragg
Copy link

Udragg commented Nov 27, 2024

Requirements

Describe the bug

When using a bluetooth keyboard (Logitech MX Mechanical) kanata fails to notice the keyboard after connecting the second time. The device will be detected if kanata is restarted or another device is registered, prompting kanata to also notice and register the bluetooth device.

This behaviour does not occur for a wired keyboard.

Relevant kanata config

(defsrc caps)
(deflayer base esc)

To Reproduce

  1. Start kanata with any configuration (verified to work with provided config, as well as my actual one)
  2. Connect the bluetooth keyboard, it should get registered by kanata
  3. Disconnect the bluetooth keyboard
  4. Connect the bluetooth keyboard once again, kanata doesn't register it

Expected behavior

Kanata notices the new input device and registers it.

Kanata version

kanata 1.7.0

Debug logs

19:45:47.7815 [INFO] kanata v1.7.0 starting
19:45:47.7817 [WARN] No defcfg is defined. Consider whether the process-unmapped-keys defcfg option should be yes vs. no. Adding defcfg with process-unmapped-keys defined will remove this warning.
19:45:47.7818 [INFO] process unmapped keys: false
19:45:47.7818 [INFO] NOTE: kanata was compiled to never allow cmd
19:45:47.7818 [DEBUG] (1) kanata_parser::cfg::alloc: freeing allocations of length 0
19:45:47.7820 [INFO] config file is valid
19:45:47.7830 [INFO] Created device "/dev/input/event17"
19:45:47.7831 [INFO] Sleeping for 2s. Please release all keys and don't press additional ones. Run kanata with --help to see how understand more and how to disable this sleep.
19:45:49.7833 [INFO] entering the processing loop
19:45:49.7835 [INFO] entering the event loop
19:45:49.7835 [INFO] looking for devices in /dev/input
19:45:49.7836 [INFO] Init: catching only releases and sending immediately
19:45:49.7837 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Lid Switch
19:45:49.7980 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Power Button
19:45:49.8413 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Sleep Button
19:45:49.8679 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Video Bus
19:45:49.8849 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: AT Translated Set 2 keyboard
19:45:49.8849 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: PC Speaker
19:45:49.9616 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ITE5570:00 048D:8051
19:45:50.0013 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Asus WMI hotkeys
19:45:50.0182 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: ASUF1204:00 2808:0202 Mouse
19:45:50.0182 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ASUF1204:00 2808:0202 Touchpad
19:45:50.0646 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=3
19:45:50.1083 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=7
19:45:50.1712 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic HDMI/DP,pcm=3
19:45:50.2280 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=8
19:45:50.3016 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=9
19:45:50.3648 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic Headphone
19:45:50.3875 [INFO] Starting kanata proper
19:45:50.3875 [INFO] You may forcefully exit kanata by pressing lctl+spc+esc at any time. These keys refer to defsrc input, meaning BEFORE kanata remaps keys.
19:45:50.4179 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: WH-1000XM4 (AVRCP)
19:45:50.4180 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: Logitech MX Master 3S
19:45:50.4180 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: solaar-keyboard
19:45:50.4180 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: Hewlett-Packard Company HP USB Smart Card Keyboard
19:45:50.4447 [INFO] registering /dev/input/event4: "AT Translated Set 2 keyboard"
19:45:50.5012 [INFO] registering /dev/input/event8: "ASUF1204:00 2808:0202 Mouse"
19:45:50.5412 [INFO] registering /dev/input/event20: "WH-1000XM4 (AVRCP)"
19:45:50.5945 [INFO] registering /dev/input/event16: "Logitech MX Master 3S"
19:45:50.6712 [INFO] registering /dev/input/event19: "solaar-keyboard"
19:45:50.7412 [INFO] registering /dev/input/event21: "Hewlett-Packard Company HP USB Smart Card Keyboard"
19:46:05.2653 [INFO] watch found file changes, looking for new devices
19:46:05.2653 [INFO] sleeping for a moment to let devices become ready
19:46:05.4654 [INFO] looking for devices in /dev/input
19:46:05.4656 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Lid Switch
19:46:05.4948 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Power Button
19:46:05.5151 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Sleep Button
19:46:05.5378 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Video Bus
19:46:05.5713 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: AT Translated Set 2 keyboard
19:46:05.5713 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: PC Speaker
19:46:05.6615 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ITE5570:00 048D:8051
19:46:05.6819 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Asus WMI hotkeys
19:46:05.7118 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: ASUF1204:00 2808:0202 Mouse
19:46:05.7119 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ASUF1204:00 2808:0202 Touchpad
19:46:05.7448 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=3
19:46:05.8250 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=7
19:46:05.8848 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic HDMI/DP,pcm=3
19:46:05.9413 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=8
19:46:05.9815 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=9
19:46:06.0347 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic Headphone
19:46:06.1179 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: WH-1000XM4 (AVRCP)
19:46:06.1180 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: Logitech MX Master 3S
19:46:06.1180 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: solaar-keyboard
19:46:06.1181 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: Hewlett-Packard Company HP USB Smart Card Keyboard
19:46:06.1514 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: MX MCHNCL Keyboard
19:46:06.3512 [INFO] registering /dev/input/event18: "MX MCHNCL Keyboard"
19:46:11.0478 [DEBUG] (3) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_CAPSLOCK (58), value: Press }
19:46:11.0479 [DEBUG] (3) kanata_state_machine::kanata: key press     Escape
19:46:11.0479 [DEBUG] (3) kanata_state_machine::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(KEY_ESC), value: 1 }
^[19:46:11.1379 [DEBUG] (3) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_CAPSLOCK (58), value: Release }
19:46:11.1380 [DEBUG] (3) kanata_state_machine::kanata: key release   Escape
19:46:11.1380 [DEBUG] (3) kanata_state_machine::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(KEY_ESC), value: 0 }
19:46:12.9885 [DEBUG] (3) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_CAPSLOCK (58), value: Press }
19:46:12.9885 [DEBUG] (3) kanata_state_machine::kanata: key press     Escape
19:46:12.9885 [DEBUG] (3) kanata_state_machine::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(KEY_ESC), value: 1 }
^[19:46:13.0728 [DEBUG] (3) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_CAPSLOCK (58), value: Release }
19:46:13.0729 [DEBUG] (3) kanata_state_machine::kanata: key release   Escape
19:46:13.0729 [DEBUG] (3) kanata_state_machine::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(KEY_ESC), value: 0 }
19:46:17.7353 [WARN] removing kbd device: /dev/input/event18
19:46:50.9749 [WARN] removing kbd device: /dev/input/event21
19:46:53.8882 [INFO] watch found file changes, looking for new devices
19:46:53.8883 [INFO] sleeping for a moment to let devices become ready
19:46:54.0884 [INFO] looking for devices in /dev/input
19:46:54.0885 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Lid Switch
19:46:54.1415 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Power Button
19:46:54.1583 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Sleep Button
19:46:54.1812 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Video Bus
19:46:54.2112 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: AT Translated Set 2 keyboard
19:46:54.2113 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: PC Speaker
19:46:54.2615 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ITE5570:00 048D:8051
19:46:54.2846 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Asus WMI hotkeys
19:46:54.3082 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: ASUF1204:00 2808:0202 Mouse
19:46:54.3083 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ASUF1204:00 2808:0202 Touchpad
19:46:54.3312 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=3
19:46:54.3813 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=7
19:46:54.4479 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic HDMI/DP,pcm=3
19:46:54.5146 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=8
19:46:54.6046 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=9
19:46:54.6815 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic Headphone
19:46:54.7582 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: WH-1000XM4 (AVRCP)
19:46:54.7583 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: Logitech MX Master 3S
19:46:54.7583 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: solaar-keyboard
19:46:54.7815 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: MX MCHNCL Keyboard
19:46:54.7815 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: Hewlett-Packard Company HP USB Smart Card Keyboard
19:46:54.9378 [INFO] registering /dev/input/event18: "MX MCHNCL Keyboard"
19:46:54.9945 [INFO] registering /dev/input/event21: "Hewlett-Packard Company HP USB Smart Card Keyboard"
19:46:55.0446 [INFO] watch found file changes, looking for new devices
19:46:55.0446 [INFO] sleeping for a moment to let devices become ready
19:46:55.2447 [INFO] looking for devices in /dev/input
19:46:55.2449 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Lid Switch
19:46:55.2645 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Power Button
19:46:55.2846 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Sleep Button
19:46:55.3182 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Video Bus
19:46:55.3513 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: AT Translated Set 2 keyboard
19:46:55.3513 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: PC Speaker
19:46:55.4212 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ITE5570:00 048D:8051
19:46:55.4479 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: Asus WMI hotkeys
19:46:55.4845 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: ASUF1204:00 2808:0202 Mouse
19:46:55.4846 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: ASUF1204:00 2808:0202 Touchpad
19:46:55.5180 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=3
19:46:55.5845 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=7
19:46:55.6379 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic HDMI/DP,pcm=3
19:46:55.6946 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=8
19:46:55.7379 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HDA ATI HDMI HDMI/DP,pcm=9
19:46:55.7879 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. Non-input device: HD-Audio Generic Headphone
19:46:55.8479 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: WH-1000XM4 (AVRCP)
19:46:55.8479 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: false. detect type KeyboardMice; device type Mouse, device name: Logitech MX Master 3S
19:46:55.8480 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: solaar-keyboard
19:46:55.8679 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: MX MCHNCL Keyboard
19:46:55.8679 [DEBUG] (1) kanata_state_machine::oskbd::linux: Use for input: true. detect type KeyboardMice; device type Keyboard, device name: Hewlett-Packard Company HP USB Smart Card Keyboard
19:47:07.4815 [DEBUG] (3) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_CAPSLOCK (58), value: Press }
19:47:07.4815 [DEBUG] (3) kanata_state_machine::kanata: key press     Escape
19:47:07.4815 [DEBUG] (3) kanata_state_machine::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(KEY_ESC), value: 1 }
^[19:47:07.5514 [DEBUG] (3) kanata_state_machine::kanata: process recv ev KeyEvent { code: KEY_CAPSLOCK (58), value: Release }
19:47:07.5514 [DEBUG] (3) kanata_state_machine::kanata: key release   Escape
19:47:07.5514 [DEBUG] (3) kanata_state_machine::oskbd::linux: send to uinput: InputEvent { time: SystemTime { tv_sec: 0, tv_nsec: 0 }, kind: Key(KEY_ESC), value: 0 }
^C19:47:10.0032 [ERROR] failed poll: Os { code: 4, kind: Interrupted, message: "Interrupted system call" }

Operating system

Linux (Arch, kanata-bin from AUR)

Additional context

The bluetooth keyboard in question is the MX MCHNCL Keyboard in the logs.

Near the middle of the debug log I unplug the Hewlett-Packard (wired) keyboard (/dev/input/event21) and plug it back in. After which both the wired and bluetooth keyboards get picked up and registered.

I encountered the bug because my keyboard can switch between multiple devices, which has the same effect as disconnecting and reconnecting when switching from and to the device. (The test for the bug report was done by turning the keyboard off instead of switching devices to make the test more generally reproducible.)

@Udragg Udragg added the bug Something isn't working label Nov 27, 2024
@jtroo
Copy link
Owner

jtroo commented Nov 28, 2024

Kanata is deregistering the device because it gets a "no device" error.

kanata/src/oskbd/linux.rs

Lines 158 to 166 in 70f5a85

self.poll
.registry()
.deregister(&mut SourceFd(&device.as_raw_fd()))?;
if let Some((_, path)) = self.devices.remove(&event.token()) {
log::warn!("removing kbd device: {path}");
if let Some(ref mut missing) = self.missing_device_paths {
missing.push(path);
}
}

The discovery of devices is based on new files created in the filesystem path of /dev/input. From inference, it seems bluetooth functionality doesn't always remove devices from the filesystem even though the device is no longer connected. If the bluetooth device isn't being removed and then recreated in the filesystem, kanata currently cannot detect it.

kanata/src/oskbd/linux.rs

Lines 708 to 712 in 70f5a85

fn watch_devinput() -> Result<Inotify, io::Error> {
let inotify = Inotify::init().expect("Failed to initialize inotify");
inotify.watches().add("/dev/input", WatchMask::CREATE)?;
Ok(inotify)
}

Perhaps you can play around with adding new watch types. But would need to be wary of the watched event being too noisy and causing a lot of extra processing.

https://docs.rs/inotify/latest/inotify/struct.WatchMask.html#associatedconstant.MODIFY

@jtroo jtroo added linux Issue pertains to Linux only PRs welcome jtroo has no plans to work on this at present, but PRs are welcome labels Nov 28, 2024
@Udragg
Copy link
Author

Udragg commented Dec 15, 2024

Since I found some time I did some more testing with the directions you gave me. I started by somewhat brute forcing WatchMask flag combinations and finally arrived at WatchMask::CREATE | WatchMask::DELETE which reliably causes the device to be re-registered upon connecting.

Why (I think) the addition of WatchMask::DELETE "fixes" the problem

It appears that kanata somehow gets "stuck" or "forgets to check" the updates of the file after the watch event triggers it to register (concluded in initial report). However triggering the watch event of another device seems to "reset" this. (This doesn't need to be a keyboard, it also seems to work when connecting a bluetooth mouse.) My guess would be that when handling the DELETE event the "stuck" state gets reset resulting in the next register working.

Therefore I don't believe that DELETE actually solves the core problem. Unfortunately I haven't had the time to add logging to kanata itself to see what watch events trigger.

Further testing

I've written a simple test program which just logs all inotify events (except the ACCESS event) and ran this both with and without kanata active. This gave me the following results.

Inotify events without kanata running

// disconnect keyboard 1st time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(DELETE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }

// reconnect keyboard 1st time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CREATE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_NOWRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(MODIFY), cookie: 0, name: Some("event19") }

// disconnect keyboard 2nd time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(DELETE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }

// reconnect keyboard 2nd time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CREATE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_NOWRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(MODIFY), cookie: 0, name: Some("event19") }

Inotify events with kanata running

// disconnect keyboard 1st time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(DELETE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }

// reconnect keyboard 1st time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CREATE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_NOWRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(MODIFY), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN | ISDIR), cookie: 0, name: None }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event0") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event0") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event1") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event1") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event2") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event2") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event3") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event3") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event4") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event5") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event5") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event6") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event6") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event7") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event7") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event8") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event8") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event9") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event9") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event10") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event10") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event11") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event11") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event12") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event12") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event13") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event14") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event14") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event15") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event15") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event16") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event17") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event18") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event20") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event20") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_NOWRITE | ISDIR), cookie: 0, name: None }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event4") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event13") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event16") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event17") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event18") }

// disconnect keyboard 2nd time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(DELETE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }

// reconnect keyboard 2nd time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CREATE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_NOWRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(MODIFY), cookie: 0, name: Some("event19") }

// disconnect keyboard 3rd time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(DELETE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_WRITE), cookie: 0, name: Some("event19") }

// reconnect keyboard 3rd time
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CREATE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(CLOSE_NOWRITE), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(ATTRIB), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(OPEN), cookie: 0, name: Some("event19") }
Event { wd: WatchDescriptor { id: 1, fd: (Weak) }, mask: EventMask(MODIFY), cookie: 0, name: Some("event19") }

In both cases when connecting the keyboard there is actually a CREATE event, though I haven't been able to test if kanata itself also registers this event or not. It does however lead me to believe the problem lies somewhere within kanata and not inotify or the way bluetooth devices are created/removed by the OS.

The next thing I'm planning to do is add logging wherever kanata handles the watch events and see whats happening there when I find the time to do so. Any further suggestions of what I should look into would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working linux Issue pertains to Linux only PRs welcome jtroo has no plans to work on this at present, but PRs are welcome
Projects
None yet
Development

No branches or pull requests

2 participants