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

[Mac] Support more identifiers for filtering devices #516

Conversation

MuhammedZakir
Copy link
Contributor

  • Mac: Support more identifiers for filtering devices
  • Mac: list-keyboards: Print all available identifiers
  • Mac: Change functions to accept DeviceIdentifiers record
  • Something's wrong. Add tracing function.
  • Mac: Fix for compilation errors.

For some reason, this is not working when a product name is given in iokit-name. Need help!

cc: @slotThe @thoelze1

Create a new record to store a device's identifiers/properties.
All stuff that accept "product name" are modified to
accept `DeviceIdentifiers` record or it's equivalent
C struct.

From a user point of view, nothing has been
changed - still only accepts an optional product name.
Only internal API is changed to check whether this
is working as intended.
Print the `DeviceIdentifiers` record to check the
correctness of the struct.
@MuhammedZakir
Copy link
Contributor Author

MuhammedZakir commented Mar 29, 2022

  1. Printing from C/C++ code doen't output anything. How can I debug C side while app is running? This is working. My mistake. Probably not; this is related to #3.

  2. Can the Haskell-malloced memory that won't be used in Haskell side be freed from C side? Will that cause any problems?

  3. How can I force compile C/C++ code? Stack doesn't recompile when changing those files. I am sure because I didn't get any compilation errors unlike whats shown in CI.

Edit:

For #3, I was able to force-compile C/C++ code by deleting related build objects in .stack-work/dist/<arch>-<os>/Cabal-<ver>/build/. Is this okay?

@@ -107,7 +116,7 @@ instance HasKeyRepeatCfg SendEventCfg where keyRepeatCfg = seRepCfg

data KeyInputCfg
= LinuxEvdevCfg EvdevCfg
| MacIOKitCfg IOKitCfg
| MacIOKitCfg (Maybe IOKitCfg)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this okay?

Comment on lines +133 to +136
dp <- deviceProperties cfg
str <- print dp
let t f dp = (D.trace ("DeviceProperites: \n" <> str) f dp)
t grabKb dp
Copy link
Contributor Author

@MuhammedZakir MuhammedZakir Mar 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: remove this debugging expressions.


where
print dp = do
dp <- peek dp
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: remove this.

Can this where section be moved to below init function? I am getting errors when I do that. I guess I am still not clear on where I can use where.

, ("iokit-name" , KIOKitSource <$> optional textP)]
, ("iokit-name" , KIOKitSource <$> optional (textP >>= mkCfg))]
where
mkCfg n = pure $ def {_cfgProductName = n}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for testing only. Will write a proper parser after we get this working.

TODO: check Karabiner-Elements repo and other sites to find
the corresponding macOS keycodes. It plausibly corresponds
to some `International`-named keys.
@MuhammedZakir MuhammedZakir force-pushed the mac-support-more-device-identifiers branch from 426621f to b11ad6c Compare March 29, 2022 22:53
@MuhammedZakir
Copy link
Contributor Author

@slotThe: Can you create a repo for dext and give me write access?

Reason: To fix compilation errors, I had to modify dext's header files. I opened an issue in the official repo, but I don't think it will be fixed soon.Therefore, I fixed them in my fork. I want to move that repo into this orgnanization, so I can use that URL as the submodule's url rather than mine. This way, the code won't be tied to me and making changes (if needed) will be easier.

@slotThe
Copy link
Member

slotThe commented Mar 31, 2022

@MuhammedZakir: https://github.com/kmonad/kmonad-dext

You should have an invite for the right perms. I'll try to look at the PR this weekend but I have no experience with MacOS and I'm hopeless in non-functional languages :)

@MuhammedZakir
Copy link
Contributor Author

@MuhammedZakir: https://github.com/kmonad/kmonad-dext

You should have an invite for the right perms.

Got it. I should have asked earlier... isn't it better to do a Github-fork of official repo? [1] This way we can see when new commit are made there.

[1] https://github.com/pqrs-org/Karabiner-DriverKit-VirtualHIDDevice

I'll try to look at the PR this weekend but I have no experience with MacOS and I'm hopeless in non-functional languages :)

Okay. But if you got time, it would helpful if you could answer my doubts posted in the second post.

@slotThe
Copy link
Member

slotThe commented Mar 31, 2022

Got it. I should have asked earlier... isn't it better to do a Github-fork of official repo? [1] This way we can see when new commit are made there.

Good point! Should be switched now

Okay. But if you got time, it would helpful if you could answer my doubts posted in the second post.

Will try!

`kIOMasterPortDefault` is deprecated in macOS 12. Use
`kIOMainPortDefault` in macOS 12 & above.

Cast (const char *) to (char *) to inhibit "loses qualifier"
warning.
@MuhammedZakir
Copy link
Contributor Author

MuhammedZakir commented Apr 1, 2022

Should we support a list of keyboard identifiers? This is useful and doable in macOS as we already can(are) capture(ing) multiple keyboards.

;; tl;dr --
;;
;; All identifiers that are not given are considered as
;; MATCHED.
;;
;; Suppose 'all, a, b and c are keyboard identifiers, then
;;
;;   variations       =>  how they are matched.
;;   ----------           ---------------------
;;   ('all)           =>  <all keyboards are captured>
;;
;;   ((a)
;;    (b))            =>  a OR b
;;   ((a b)
;;    (c))            =>  (a AND b) OR c
;;   (exclude (a))    =>  NOT a
;;   (exclude ((a)
;;             (b)))  =>  NOT (A OR b)
;;   (exclude ((a b)
;;             (c)))  =>  NOT ((a AND b) OR c)
;;   ((a)
;;    (exclude (b)))  =>  a OR (NOT b)

(defcfg

;; Only ONE `iokit` block is supported. You can use any of
;; the variations listed below.

;; #1: A stub for "no identifier" => capture all keyboards.
 iokit ('all)

;; #2: A list of identifiers => capture matching keyboards.
;;
;;  Useful to capture a single keyboard or a set of keyboards
;;  matching a criteria. For example, same  manufacturer, or
;;  transport (usb vs bluetooth).
;;
;;  All identifiers are optional, and identifiers not given
;;  are considered as MATCHEd. As you can expect, more
;;  identifiers make it easier to fine-tune the capturing.
;;
;; e.g. Capture keyboards if
;;        product name is "some name" *AND* transport is USB
 iokit (:product-name "some name"
        :transport 'usb)

;; #3: A list of lists of identifiers => similiar to #2.
;;
;;  More flexible version of #2. Also useful to capture only
;;  specific keyboards in a single KMonad instance. An example
;;  usecase is mapping a key combo to some other action, but
;;  instead of pressing everything in a single keyboard, you
;;  press the keys in different keyboards. This is not possible
;;  with "1 keyboard per KMonad" style. This is maybe a cliche,
;;  but if we already have everything to support this, why not?
;;
;; e.g. Capture keyboards if
;;        product name is "nice keyboard" *AND* transport is USB
;;   *OR* manufacturer is "Wierd Keyboards Limited"
 iokit ((:product-name "nice keyboard" :transport 'usb)
        (:manufacturer "Wierd Keyboards Limited"))

;; #4: Same as #3, but with exclusions by prepending a list
;;     with `exclude`.
;;
;;  Useful to exclude certain keyboards.
;;
;; e.g. Capture
;;
;; 4.1. if product name is "Apple Internal Keyboard"
  iokit (exclude (:product-name "Apple Internal Keyboard"))
;; 4.2. all Apple keyboards except the internal one.
  iokit ((:manufacturer "Apple Inc.")
         (exclude (:product-name "Apple Internal Keyboard")))
;; 4.3. all keyboards except
;;           bluetooth keyboards
;;      *OR* whose product name is "some funky keyboard"
  iokit (exclude ((:product-name "some funky keyboard")
                  (:transport 'bluetooth)))
) ;; defcfg

@MuhammedZakir
Copy link
Contributor Author

I didn't forget this. It will take a few more weeks before I am free to work on this. Sorry!

Before getting into this, I would like to know what you guys think about the question I posted above. Should we support capturing multiple devices using identifiers? I think it maybe useful for some split-keyboards.

@david-janssen
Copy link
Collaborator

I didn't forget this. It will take a few more weeks before I am free to work on this. Sorry!

No worries, I can relate... ;-) On the same note let me apologize for being gone for a while too. Life fluctuates and we do what we can, and no more.

Should we support capturing multiple devices using identifiers? I think it maybe useful for some split-keyboards.

I think this is a good idea. Ideally we would have a stream of uniquely identified keys. In the case of multiple keyboards, that means keyboard-id and keycode-id. I am again starting to think about how to merge ideas from keycode refactor into master, and I will be keeping this in mind as I work on the KeyEvent representations.

@kieran-mace
Copy link
Contributor

This may or may not be useful for your PR, but this comment seems to be affecting M2 Macs from identifying keyboards: #633 (comment)

slotThe added a commit that referenced this pull request Oct 7, 2023
Notable changes:

- Added `around-next-single`, a variant of `around-next` that will
  release its context on any change, as opposed to only on the release
  of the 'arounded' button.
- Added default compose sequence for Ü
- Added a `sticky-key`
- Added `--version` (`-V`) flag
- Added `+,` for  "add a cedilla"
- Added `:timeout-button` keyword to `tap-hold-next` and
  `tap-hold-next-release`, so that they can switch to a button
  other than the hold button when the timeout expires.
- The `multi-tap` key now immediately taps the current key when another
  key is pressed during tapping.
- Fixed compilation error under Mac, having to do with typo in Keycodes.
- Fixed issue with empty-names for uinput-sinks.
- Ignore SIGCHLD to deal with non-termination bug.

---

This should probably be 0.5, but notable issues like [1..6] still
preventing me from being comfortable with that. None of these seem
completely insurmountable, though, so stay tuned :)

[1]: #475
[2]: #704
[3]: #681
[4]: #716
[5]: #516
[6]: #426
@david-janssen david-janssen deleted the branch kmonad:keycode-refactor February 2, 2024 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants