Support for multiple keyboards

Hi.
I love BTT and I can't imagine working without it, but ... keyboard recognition is for me the biggest downside of BTT.
When I assign an action to a key on the Magic Keyboard (e.g. do nothing, because Keyboard Maestro will do the macro) it works fine for several days, but then the same key on the Apple Keyboard also stops working.
I would also like to know when a solution that recognizes a particular keyboard will be available.
BTW. Maybe there is a solution to disable all Magic Keyboard keys for a specific application or better - for the entire computer?

that looks cool!
I have a version that includes keyboard specific recognition, but I didn’t have time to finish it yet. I think I’ll be able to release a working preview later this week (please remind if I forget to do so)

that looks cool!
Thanks :slight_smile:

OK, so I'm waiting, Thank you!

Hi Andreas,
did you find some time to finish update?

Hi Andreas,
I care about this feature. What is the chance that you will take care of this in the near future?

Hi all!
Im using a Macbook Pro 2018 and a Magic Keyboard (the one without the numpad). Don't know if this is a bug but here goes.

When I choose a trigger (and have set everything to recognise the different keyboards as per the screenshots from above) it selects it fine. However it selects it on the opposite keyboard. So if I select G on the macbook pro keyboard as a trigger, the G on the magic keyboard actually triggers the sequence and the one on the laptop works normally.

I'm not complaining I just thought its weird. It works fine (as long as I keep in mind which keyboard to use) and I'm starting to re-label my magic keyboard already.

Ok, now it doesn't work. Yesterday it worked as I described, today however no matter which keyboard I use to select the trigger it always attaches it to the laptop keyboard instead of the one I used. So technically it works in 50% of my cases :smiley: Yeah I've no idea what happened to change the behaviour.

Also could be useful info - I didn't shutdown the laptop during the night if that matters.

I'm running version 3.209 (1386).

With 3.303 keyboard specific shortcuts should actually work correctly! However unfortunately they might need to be re-recorded as the old keyboard information is useless ;-(

From what little testing I could do due to time constraints, it appears that when creating new ones it works perfectly fine. If I have setup the A key as a shortcut from Keyboard1 then test it - it works - if i go to change the key used as a shortcut to say T from Keyboard2 it changes the key to T but it stays on Keyboard1.

Now that I think back I'm not sure if it was a bug or it was me just messing up the order of performed actions.

For my use case this feature currently works awesomely and properly! Thank you!

Is this currently working? I have a MacBook Pro with a USB Matias Tactile Pro and a bluetooth satechi touchpad. When I record a key sequence and select "Recognize only on keyboard used for recording the shortcut (may require new recording)" it doesn't seem to work. I record the 0 on the numbed from both of them and they both trigger the same action (HUD showing keypad or keyboard). I have noticed that the option for "recognize only" seems to get reset in the UI.

For the bluetooth keypad:

    [
      {
        "BTTTriggerType" : 624,
        "BTTTriggerTypeDescription" : "Please Select a Trigger ",
        "BTTTriggerClass" : "BTTTriggerTypeKeySequence",
        "BTTPredefinedActionType" : 254,
        "BTTPredefinedActionName" : "Show HUD Overlay",
        "BTTHUDActionConfiguration" : "{\"BTTActionHUDDetail\":\"\",\"BTTActionHUDTitle\":\"keypad\",\"BTTActionHUDDuration\":0.90000000000000002,\"BTTActionHUDBackground\":\"38.719535, 38.720697, 38.720067, 213.662109\",\"BTTActionHUDSlideDirection\":0}",
        "BTTEnabled2" : 1,
        "BTTAlternateModifierKeys" : 0,
        "BTTRepeatDelay" : 0,
        "BTTUUID" : "71246EA7-1251-4B0D-8DC6-FE99797A3779",
        "BTTNotesInsteadOfDescription" : 0,
        "BTTEnabled" : 1,
        "BTTModifierMode" : 0,
        "BTTOrder" : 0,
        "BTTDisplayOrder" : 0,
        "BTTKeySequence" : {
          "BTTPauseBetween" : 0.29999999999999999,
          "BTTKeyCount" : 2,
          "BTTKeySequenceDownKeys" : [
            {
              "BTTKEYCharacter" : " 0",
              "BTTKEYCode" : 82,
              "BTTKEYDown" : 1,
              "BTTKEYOrderRelevant" : 1,
              "BTTKEYRequired" : 1
            }
          ],
          "BTTKeySequenceMixedKeys" : [
            {
              "BTTKEYCharacter" : " 0",
              "BTTKEYCode" : 82,
              "BTTKEYDown" : 1,
              "BTTKEYOrderRelevant" : 1,
              "BTTKEYRequired" : 1
            },
            {
              "BTTKEYCharacter" : " 0",
              "BTTKEYCode" : 82,
              "BTTKEYRequired" : 1
            }
          ],
          "BTTKeySequenceUpKeys" : [
            {
              "BTTKEYCharacter" : " 0",
              "BTTKEYCode" : 82,
              "BTTKEYRequired" : 1
            }
          ]
        }
      }
    ]

For the USB keyboard:

[
  {
    "BTTTriggerType" : 624,
    "BTTTriggerTypeDescription" : "Please Select a Trigger ",
    "BTTTriggerClass" : "BTTTriggerTypeKeySequence",
    "BTTPredefinedActionType" : 254,
    "BTTPredefinedActionName" : "Show HUD Overlay",
    "BTTHUDActionConfiguration" : "{\"BTTActionHUDDetail\":\"\",\"BTTActionHUDTitle\":\"keyboard\",\"BTTActionHUDDuration\":0.90000000000000002,\"BTTActionHUDBackground\":\"38.719535, 38.720697, 38.720067, 213.662109\",\"BTTActionHUDSlideDirection\":0}",
    "BTTEnabled2" : 1,
    "BTTAlternateModifierKeys" : 0,
    "BTTRepeatDelay" : 0,
    "BTTUUID" : "9403ECF8-081D-4A73-A0CF-6BDA4793A2F4",
    "BTTNotesInsteadOfDescription" : 0,
    "BTTEnabled" : 1,
    "BTTModifierMode" : 0,
    "BTTOrder" : 1,
    "BTTDisplayOrder" : 0,
    "BTTKeySequence" : {
      "BTTPauseBetween" : 0.29999999999999999,
      "BTTCharactersToDeleteAfterwards" : 1,
      "BTTKeyCount" : 2,
      "BTTKeySequenceDownKeys" : [
        {
          "BTTKEYCharacter" : " 0",
          "BTTKEYCode" : 82,
          "BTTKEYDown" : 1,
          "BTTKEYOrderRelevant" : 1,
          "BTTKEYRequired" : 1
        }
      ],
      "BTTKeySequenceMixedKeys" : [
        {
          "BTTKEYCharacter" : " 0",
          "BTTKEYCode" : 82,
          "BTTKEYDown" : 1,
          "BTTKEYOrderRelevant" : 1,
          "BTTKEYRequired" : 1
        },
        {
          "BTTKEYCharacter" : " 0",
          "BTTKEYCode" : 82,
          "BTTKEYRequired" : 1
        }
      ],
      "BTTKeySequenceUpKeys" : [
        {
          "BTTKEYCharacter" : " 0",
          "BTTKEYCode" : 82,
          "BTTKEYRequired" : 1
        }
      ]
    }
  }
]

If I make Keyboard shortcut instead of a sequence both of these keyboards have the same type. I thought you were incorporating vendor, etc. to differentiate thought:

[
  {
    "BTTGestureNotes" : "Keypad",
    "BTTTriggerType" : 0,
    "BTTTriggerClass" : "BTTTriggerTypeKeyboardShortcut",
    "BTTPredefinedActionType" : -1,
    "BTTPredefinedActionName" : "No Action",
    "BTTAdditionalConfiguration" : "0",
    "BTTEnabled2" : 1,
    "BTTKeyboardShortcutScope" : 1,
    "BTTKeyboardShortcutKeyboardType" : 3407,
    "BTTRepeatDelay" : 0,
    "BTTUUID" : "874862A6-4193-4A0B-9910-8CCCA261D940",
    "BTTTriggerOnDown" : 1,
    "BTTNotesInsteadOfDescription" : 1,
    "BTTLayoutIndependentChar" : "0",
    "BTTEnabled" : 1,
    "BTTModifierMode" : 0,
    "BTTShortcutKeyCode" : 82,
    "BTTShortcutModifierKeys" : 0,
    "BTTOrder" : 7,
    "BTTDisplayOrder" : 0,
    "BTTAutoAdaptToKeyboardLayout" : 0,
    "BTTTriggerConfig" : {
      "BTTKeyboardShortcutScope" : 1
    }
  },
  {
    "BTTGestureNotes" : "Keyboard",
    "BTTTriggerType" : 0,
    "BTTTriggerClass" : "BTTTriggerTypeKeyboardShortcut",
    "BTTPredefinedActionType" : -1,
    "BTTPredefinedActionName" : "No Action",
    "BTTAdditionalConfiguration" : "0",
    "BTTEnabled2" : 1,
    "BTTKeyboardShortcutScope" : 1,
    "BTTKeyboardShortcutKeyboardType" : 3407,
    "BTTRepeatDelay" : 0,
    "BTTUUID" : "93BB017B-2C48-427A-B41B-48A24B548726",
    "BTTTriggerOnDown" : 1,
    "BTTNotesInsteadOfDescription" : 0,
    "BTTLayoutIndependentChar" : "0",
    "BTTEnabled" : 1,
    "BTTModifierMode" : 0,
    "BTTShortcutKeyCode" : 82,
    "BTTShortcutModifierKeys" : 0,
    "BTTOrder" : 8,
    "BTTDisplayOrder" : 0,
    "BTTAutoAdaptToKeyboardLayout" : 0,
    "BTTTriggerConfig" : {
      "BTTKeyboardShortcutScope" : 1
    }
  }
]

It should work fine with keyboard shortcuts but I’m not sure about key sequences. I’ll have a look!

For keyboard shortcuts it seems to work fine here (only requirement - secure input mode must be disabled, BTT would show a warning about this in the menubar menu)

Secure input is disabled. What are you using to disambiguate the keyboards in your code? If I look at the devices for karabiner-elements I noticed that the bluetooth and USB keyboards are eerily similar though there are some differences:

    {
        "device_id": 4294971848,
        "is_karabiner_virtual_hid_device": false,
        "is_keyboard": true,
        "is_pointing_device": false,
        "location_id": 337776640,
        "manufacturer": "Matias",
        "product": "Matias Keyboard",
        "product_id": 544,
        "serial_number": "00fk302",
        "transport": "USB",
        "vendor_id": 1452
    },
    {
        "device_id": 4294998808,
        "is_karabiner_virtual_hid_device": false,
        "is_keyboard": true,
        "is_pointing_device": false,
        "location_id": 1638157034,
        "manufacturer": "Unknown",
        "product": "Satechi Bluetooth Keypad",
        "product_id": 544,
        "serial_number": "1e-c7-61-a4-4a-ea",
        "transport": "Bluetooth",
        "vendor_id": 1452
    },

I’m not at my Mac at the moment but I think B TT can only use vendor and device id at the moment (I’m not sure if there is a way to access the other info without some lower level system integration)

What kind of keyboards are these? It‘s kind of weird that they have the same vendor/product id :-/

It is very weird. I think there is some Mac issue going on which I will try to debug:

One is a Satechi bluetooth keypad and one is a Matias Tactile Pro. There's no way they should both show up as Matias. Let me get to the bottom of that before you debug any further. Thanks for your help. I'll post back here when I figure it out so others can benefit.

~/projects/tabninetest on  master is 📦 v1.0.0 via ⬢ v15.2.0 on ☁️ andrew@janian.net took 18s
❯ system_profiler SPUSBDataType \
    | awk '
      /Product ID:/{p=$3}
      /Vendor ID:/{v=$3}
      /Manufacturer:/{sub(/.*: /,""); m=$0}
      /Location ID:/{sub(/.*: /,""); printf("%s:%s %s (%s)\n", v, p, $0, m);}
    '
2020-11-14 15:03:24.953 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2020-11-14 15:03:24.953 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2020-11-14 15:03:24.954 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2020-11-14 15:03:24.954 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2020-11-14 15:03:24.955 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2020-11-14 15:03:24.955 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
2020-11-14 15:03:24.956 system_profiler[2190:2751576] SPUSBDevice: IOCreatePlugInInterfaceForService failed 0xe00002be
0x1058:0x260f 0x00100000 / 1 (Western Digital)
0x0451:0x8442 0x14200000 / 2 (Western Digital)
0x046d:0xc52b 0x14240000 / 3 (Logitech)
0x05e3:0x0610 0x14220000 / 4 (Logitech)
0x05ac:0x0220 0x14221000 / 7 (Matias)
0x046d:0x085c 0x14210000 / 6 (Matias)
0x0451:0x82ff 0x14250000 / 5 (Matias)
0x05ac:0x8104 0x80800000 / 5 (Apple)
0x05ac:0x8102 0x80700000 (Apple Inc.)
0x05ac:0x8302 0x80600000 (Apple Inc.)
0x05ac:0x0340 0x80500000 (Apple Inc.)
0x05ac:0x8103 0x80400000 (Apple)
0x05ac:0x8262 0x80300000 (Apple Inc.)
0x05ac:0x8514 0x80200000 (Apple Inc.)
0x05ac:0x8233 0x80100000 (Apple Inc.)

Edit: This last command isn't useful as it is only USB and not bluetooth. The problem is real but this isn't accurately showing it.

Ok. they are both showing as apple vendor 05AC and ANSI aluminum keyboard per System Information and https://devicehunt.com/view/type/usb/vendor/05AC. I am guessing they are both using a generic apple driver which is the cause. I wonder if there is a way for you to add Manufacturer to whatever you are doing to disambiguate the keyboards? What do your multiple keyboards show for Vendor and Product? I'm surprised that these are behaving so oddly

I was able to get this working using karabiner and BTT together. In karabiner there is a setting for complex modifications that can use the location_id in addition to the vendor and product IDs to differentiate devices. I now have a json that looks something like:

                "rules": [
                    {
                        "description": "external keypad",
                        "manipulators": [
                            {
                                "conditions": [
                                    {
                                        "identifiers": [
                                            {
                                                "location_id": 1638157034,
                                                "product_id": 544,
                                                "vendor_id": 1452
                                            }
                                        ],
                                        "type": "device_if"
                                    }
                                ],
                                "from": {
                                    "key_code": "keypad_0"
                                },
                                "to": [
                                    {
                                        "key_code": "keypad_0",
                                        "modifiers": [
                                            "left_control",
                                            "left_command",
                                            "left_option",
                                            "shift"
                                        ]
                                    }
                                ],
                                "type": "basic"
                            },

That handles mapping the keys on the keypad to their normal value with modifiers for ctrl+option+command+shift. Then I can use those in BTT to do the real work that I want.

The downside to this approach is that location_id isn't permanent and changes depending on where the device is connected. I don't know if this even persists across restarts. I have another daemon that runs and replaces the location_id in the karabiner.json file to the new location of the keypad if it changes.

Hi there.
Better Touch Tool is very useful for me, but to be able to use an entire second keyboard as a bank of macro keys separate to the original keyboard would be ideal. I have small X7 gaming keyboard to one side which handles all of my macro work very well.

Karabiner seems to always manage both keyboards separately with sound, solid performance but it doesn't allow me to use certain hotkeys on an app by app basis that BTT is able to.

I REALLY want this ability, but the 'Works on Keyboards with same type as used for recording' feature just never ever seems to work unfortunately, which is really frustrating, and I have to say, unless I can use a GUI to program my stuff, I can't do it!

I hope that this can be implemented in future updates!

I'm in the same boat. I have a microsoft Natural Keyboard (7000) and a Razer Tartarus I need to use for macros, but BTT can't differentiate between the two. Setting up a hotkey on one also changes the keys on the other. Any tips at all would be much appreciated! If this feature worked, BTT would be exactly what I need for my work.

Did you try the "Works on Keyboards with same type as used for recording" option?
Would be weird if the microsoft keyboard and the razer tartarus were using the same product & vendor id. (Using this option possibly requires re-recording the shortcut)