pqrs-org / Karabiner-Elements

Karabiner-Elements is a powerful utility for keyboard customization on macOS Sierra (10.12) or later.
https://pqrs.org/osx/karabiner/
The Unlicense
18.59k stars 835 forks source link

[Feature request] CLI option to enable/disable devices #2628

Open atanasj opened 3 years ago

atanasj commented 3 years ago

I use an external keyboard and trackpad on my MBP and would like the external trackpad to be in similar to when I use the MPB without the external peripherals. However, I always bump the external trackpad when typing.

Is there a way to only activate the external trackpad (or internal one for that matter) when I hold a particular key down e.g., "q"?

MuhammedZakir commented 3 years ago

No option to do that. You can make a feature request for it. It is easy to add a cli option to enable/disable device. Change the title to something like "[Feature request] CLI option to enable/disable devices".

P.S. If you can't wait, you can write a script to change ignore_device's (iirc) value in karabiner.json and call that script when you press a key.

P.S.2. Alternatively, you can create another profile, enable device in one profile and disable it in the other one and switch between them using Karabiner cli when a key is pressed. Note: You can duplicate the current profile and change the name, instead of creating a new profile.

atanasj commented 3 years ago

Thanks @MuhammedZakir. I think a feature request is a good avenue and a script in the interim. Would you be able to provide and example or some references for me to look at as an idea?

MuhammedZakir commented 3 years ago

Updates location_id of a keyboard in Karabiner.json file -- https://github.com/ajanian/KarabinerBluetoothKeyboardLocationUpdater/blob/main/src/index.ts#L29-L42.

atanasj commented 3 years ago

@MuhammedZakir, thanks so much for that… I'm afraid that is a bit beyond my skill set! lol. I'll have to stick with the feature request for now.

MuhammedZakir commented 3 years ago

If you want, I can write one for you. But, before that, can you make sure ignore_device is the correct field? You can verify it by enabling/disabling a device and checking whether ignore_device of that device's properties is changing.

atanasj commented 3 years ago

That'd be great, thanks! Where do I find this out? Is it via the preferences app:

image

Or via the EventViewer? I can't see anything in the latter, but cannot find that ignore_device variable in the former… Am I looking in the right spot?

MuhammedZakir commented 3 years ago

I found a native solution.

Note: Don't forget to change vendor_id and product_id.

{
  "title": "F & J => Disable internal keyboard",
  "rules": [
    {
      "description": "F & J => Disable internal keyboard",
      "manipulators": [
        {
          "type": "basic",
          "description": "Set variable's value to 0",
          "from": {
            "simultaneous": [
              { "key_code": "f" },
              { "key_code": "j" }
            ],
            "modifiers": {
              "optional": ["caps_lock"]
            }
          },
          "to": [
            {
              "set_variable": {
                "name": "disable_internal_keyboard",
                "value": 0
              }
            }
          ],
          "conditions": [
            {
              "type": "variable_if",
              "name": "disable_internal_keyboard",
              "value": 1
            }
          ]
        },
        {
          "type": "basic",
          "description": "Set variable's value to 1",
          "from": {
            "simultaneous": [
              { "key_code": "f" },
              { "key_code": "j" }
            ],
            "modifiers": {
              "optional": ["caps_lock"]
            }
          },
          "to": [
            {
              "set_variable": {
                "name": "disable_internal_keyboard",
                "value": 1
              }
            }
          ]
        },
        {
          "type": "basic",
          "description": "All key presses of matching device(s) are disabled when variable's value is 1.",
          "from": {
            "any": "key_code",
            "modifiers":{
              "optional":[
                "any"
              ]
            }
          },
          "to":[
            {
              "key_code":"vk_none"
            }
          ],
          "conditions": [
            {
              "type": "variable_if",
              "name": "disable_internal_keyboard",
              "value": 1
            },
            {
              "type": "device_if",
              "identifiers": [
                {
                  "description": "Internal Keyboard",
                  "vendor_id": 1111,
                  "product_id": 111,
                  "is_keyboard": true
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
MuhammedZakir commented 3 years ago

That'd be great, thanks! Where do I find this out? Is it via the preferences app:

< img alt="image" width="1056" src="https://user-images.githubusercontent.com/27214625/108486840-a58c0080-72f2-11eb-9639-e9af00137a58.png">

Or via the EventViewer? I can't see anything in the latter, but cannot find that ignore_device variable in the former… Am I looking in the right spot?

It's in karabiner.json file.

atanasj commented 3 years ago

Okay, great. So this is a complex modification, and changing the vendor_id and the product_id to that of the external trackpad should do it, even when is_keyboard variable is true? I'll test it and get back to you.

MuhammedZakir commented 3 years ago

Okay, great. So this is a complex modification, and changing the vendor_id and the product_id to that of the external trackpad should do it, even when is_keyboard variable is true? I'll test it and get back to you.

Oops! :grimacing: I used keyboard for testing, so this code is for disabling keyboard. You will have to change a few things:

  1. In third manipulator, change "any": "key_code" to "any": "pointing_button".
  2. Change is_keyboard to is_pointing_device.
    • This field is not mandatory, unless you have two devices with same identifiers. (E.g. internal keyboard/trackpad).
atanasj commented 3 years ago

I can't get this to work. I'm getting this error:

[2021-02-26 20:52:48.298] [error] [grabber] parse error in /Users/atanas/.config/karabiner/karabiner.json: `complex_modifications` error: `manipulators` is missing or empty in {"rules":[{"description":"F & J => Disable internal keyboard","manipulators":[{"conditions":[{"name":"disable_internal_keyboard","type":"variable_if","value":1}],"description":"Set variable's value to 0","from":{"modifiers":{"optional":["caps_lock"]},"s...
[2021-02-26 20:52:48.306] [error] [console_user_server] parse error in /Users/atanas/.config/karabiner/karabiner.json: `complex_modifications` error: `manipulators` is missing or empty in {"rules":[{"description":"F & J => Disable internal keyboard","manipulators":[{"conditions":[{"name":"disable_internal_keyboard","type":"variable_if","value":1}],"description":"Set variable's value to 0","from":{"modifiers":{"optional":["caps_lock"]},"s...

Also, I'm wondering how I would write this with goku...

MuhammedZakir commented 3 years ago

Did you perhaps add that to karabiner.json file? I forgot to mention that the code above is not a rule, and is a custom complex modification file [1]. You can either copy the rule inside the code into karabiner.json file, or save the code in a file in ~/config/karabiner/assets/complex_modifications and import it from the app.

[1] https://karabiner-elements.pqrs.org/docs/json/root-data-structure/#custom-json-file-in-configkarabinerassetscomplex_modifications


Also, I'm wondering how I would write this with goku...

I haven't verified it with goku. If you're using gokuw, do run goku -d with this code before putting it into your main config file.

{:devices {:ext-trackpad [{:vendor_id 1111
                           :product_id 111
                           :is_pointing_device true}]}
 :main [{:des "F & J => Enable/Disable External Trackpad"
                 ;; <from> <to> <conditions>
         :rules [[[:f :j] ["disable_ext_trackpad" 0] :disable_ext_trackpad]
                 [[:f :j] ["disable_ext_trackapd" 1]]
                 ;; use [<cond1> <cond2> ...] for multiple conditions
                 [{:any "pointing_button"} :vk_none
                  [:disable_ext_trackpad :ext-trackpad]]]}]}
atanasj commented 3 years ago

Thanks for that @MuhammedZakir. I'm getting an error and have raised it on the goku repo. I'll try other option of saving a complex modification.