Switching Command and Control Keys

I would like to switch the command and control keys when using the OSX app Teamviewer. I can go in and map each command (like map Command A to Control A to “select all”). Is there a way to get the Control and Command keys to switch for all key combinations?

Also, can I get them to be switched when they’re each hit on their own (before combining them with a letter, like in command “A” or control “A”? I’m using Teamviewer to control Windows 10 and so if you just press the command key alone, it opens the windows 10 menu, which is a pain.

Anyone have any ideas? I appreciate it.

Basically no, not with Keyboard Maestro. You need something that operates at a lower level than Keyboard Maestro. Try Karabiner Elements.

I appreciate the reply. Ah, ok. Yes, Karibiner Elements is almost working
for me (but I don’t think you can set it to activate for just one
application (Teamviewer). Do you know if you can? I know Karbiner can…
waiting excitedly for that to come out for Sierra.

I don’t know I’m afraid, you would have to check the Karabiner docs or ask them. Someone else might know, I know a fair number of people on here use Karabiner Elements, but I only use it to change my Caps Lock key into a Hyper Key.

While KM can't do this with native Actions, here's an idea (untested):

  1. Create a KM macro triggered by launch or activation of Teamviewer app
  • In that macro, use AppleScript to set the System Preferences for the command and control keys
  • In another KM macro, triggered by when Teamview app is not active, use AppleScript to set the command and control keys back to normal.

That’s an excellent suggestion. Thank you, JMichaelTX.

I made a script, and I can’t get it to work at the "Modifier keys…"
section. The keyboard page opens within the keyboard system preference
panel, but I can’t get the next step. If you have the time and willingness,
could you look at the script?

tell application “System Preferences”

activate

reveal pane “Keyboard”

delay 1

tell application “System Events”

tell process “System Preferences”

click radio button “Keyboard” of tab group 1 of window
"Keyboard"

delay 1

click button “Modifier Keys…” of tab group 1 of window
"Keyboard"

delay 1

click pop up button 2 of sheet 1 of window “Keyboard”

click menu item 4 of menu 1 of pop up button 2 of sheet 1
of window “Keyboard”

delay 1

click pop up button 4 of sheet 1 of window “Keyboard”

click menu item 2 of menu 1 of pop up button 4 of sheet 1
of window “Keyboard”

click button “OK” of sheet 1 of window “Keyboard & Mouse”

end tell

end tell

end tell

Here's an example to help get you started.
I'm running macOS 10.11.6, so it might be different on Sierra. . .

2017-08-24 01:56 CT

  • Some improvements I hope you'll like
  • Toggles the Control Key
  • Display notice of remap
  • Use smart pauseUntil handler rather than fixed delay time
(*
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Example to Show How to ReMap Control Key to Command Key
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set frontApp to path to frontmost application as text

tell application "System Preferences" to activate
set elapTime to my pauseUntilWin("System Preferences", "System Preferences", 1)

tell application "System Events"
  tell process "System Preferences"
    
    click button "Keyboard" of scroll area 1 of window "System Preferences"
    set elapTime to my pauseUntilWin("Keyboard", "System Preferences", 1)
    
    log elapTime
    
    tell window "Keyboard"
      
      repeat until (button "Modifier Keys…" of tab group 1) exists
        delay 0.1
      end repeat
      
      click button "Modifier Keys…" of tab group 1
      
      repeat until (sheet 1) exists
        delay 0.1
      end repeat
      
      tell sheet 1 --  (modifier key list)
        
        --- TOGGLE CONTROL KEY Between CONTROL & COMMAND KEY CODE ---
        tell pop up button "Control (⌃) Key:"
          
          set ctrlVal to value
          set numDown to 3 -- for Command
          if (ctrlVal contains "Command") then set numDown to 1 -- for Control
          set newKeyMap to item numDown of {"Control", "", "Command"}
          
          perform action "AXShowMenu"
          delay 0.5 -- the "delay until exists" method doesn't work for this
          
          
          ### It should work with these menu items, but I get errors ###
          (*
                    --tell menu 1
                    --  --set menuList to title of every menu item
                    --              
                    --              
                    --  tell menu item 4 -- "⌘ Command"
                    --    --perform action "AXPress"
                    --    set menuTitle to title
                    --  end tell
                    --end tell
          *)
          
          ### So I was forced to use Key Codes to Move with Arrows ###
          --- Move Selection to TOP Menu Item ---
          key code 126 using {option down} -- UP Arrow
          
          --- TOGGLE Control Key ---
          repeat with iK from 1 to numDown
            key code 125 -- DOWN Arrow
            delay 0.1
          end repeat
          
          key code 36 -- return            
          
        end tell -- pop up button "Control (⌃) Key:"
        
        click button "OK" -- on sheet 1 (modifier key list)
        
      end tell -- sheet 1    --  (modifier key list)
    end tell -- window "Keyboard"
  end tell -- "System Preferences"
end tell -- "System Events"


tell application "System Preferences" to quit


tell application frontApp
  set msgStr to "CONTROL Key has been mapped to: " & newKeyMap
  set msgTitleStr to "Remap of Modifier Keys"
  display dialog msgStr with title msgTitleStr
end tell

on pauseUntilWin(pWinTitle, pProcessName, pMaxTimeSec)
  local startTime, elapTime, errMsg
  
  set startTime to current application's NSDate's |date|()
  
  tell application "System Events"
    
    repeat until window pWinTitle of process pProcessName exists
      if ((startTime's timeIntervalSinceNow()) > pMaxTimeSec) then
        set errMsg to "Max Time of " & pMaxTimeSec & " exceeded waiting for:" & LF & ¬
          "Window: " & pWinTitle & LF & "Process: " & pProcessName
        log errMsg
        error errMsg
      end if
      delay 0.1
    end repeat
    
    --- Make Sure Window is Fully Defined ---
    set uiElem to UI elements of window pWinTitle of process pProcessName
    
  end tell
  
  set elapTime to (-(round ((startTime's timeIntervalSinceNow()) * 100)) / 100.0)
  
  return uiElem
end pauseUntilWin

Good luck. If you come up with a final, or better solution, please post.

Thank you so much Michael TX. Very generous of you. I like the improvements you made. I tried plugging it in and so far, for some reason nothing gets triggered - maybe it relates to me being on Sierra. I’m going to play around with it and will post what I come up with.

I'm not sure what that means.
If you run the script from Script Editor, does it toggle the Control Key setting?

If not, you may want to put a dialog at key places so you can what what is happening.

In case you don’t get it working with KM, another option to consider is another low-level utility called ControllerMate by OrderedBytes. It is completely compatible with Sierra and has a great graphical interface for configuration/remapping almost any input controller (much nicer [1] than Karabiner’s complicated XML syntax). I’ve been using CM for many years and highly recommend it. Look over the main product page to get an idea but also check out the Examples page for just a small sample of what is possible with CM.

CM is free to try out and might even stay free for you (at least for a while). It is limited to 10 building blocks that send output. For what you need, you would only need 2 (to output control and command depending on the input and the active app)

I use CM to do similar remaps to what you are wanting. For example, when I’m using VMware Fusion to run a Windows VM …

  • CM remaps the left Command key to the Windows Key but keeps the right Command key as an OSX Command key.
  • Control+\ is already used for a KM shortcut so I have CM allow the left Control+\ run the KM shortcut but intercepts the right Control+\ to do a different macro appropriate for the Windows VM.
  • CM disables the main keyboard driver map and enables a custom keyboard map where certain F-Keys are sent through as normal F-Keys for Windows functions (edit, refresh, etc) but the other F-Keys are kept as OSX “media” keys (Play/Pause, Volume, etc).
  • For the Windows F-Keys that would normally do OSX functions, I have an advanced set of CM blocks to do the OSX function when the key is held down for more than 1 second.
  • CM immediately switches the keyboard mapping as soon as I switch out of the Fusion app.

When using a multi-button mouse instead of a Magic Trackpad, I have CM configured to remap the additional buttons to do many different functions based on which application is front-most.

Just recently I was given an old DJ mixer controller which connects via USB and is seen as a MIDI instrument. Using CM, it can react to every button, knob, and slider on the mixer, including sending back MIDI commands to turn the button lights on and off. It is very fun.

This is just a very small sample of how I use CM, and I know it can do a lot more. (Just like Keyboard Maestro. I think I have maybe a dozen KM macros and I’m sure others like Peter and JMichael probably use hundreds every day)

I hope this helps. Let me know if you try CM and run into problems (although we might have to take it over to the CM forums)

[1] Please don’t get me wrong in that I don’t like Karabiner. In fact, before Sierra, I loved it and used it to do many functions. It, along with the companion app Seil, were the only apps (I thought) capable of doing what I needed. Since then, I’ve ported all those functions over to KM and CM (and BetterTouchTool). As Karabiner Elements develops, I check on it but it has yet to even come close to what can be done with KM/CM/BTT.

1 Like

Thanks for posting this. It sounds like a great tool.

I'm a bit confused about which option to use to remap the keyboard keys.
The Examples state:

The goal of this example is to demonstrate how to modify the behavior of keyboard buttons using a Driver Configuration. Driver configurations are available only for devices that use ControllerMate's keyboard/mouse driver. ControllerMate cannot modify the behavior of another vendor's keyboard/mouse driver or one that is included with OS X.

So which option should be used to do the remap?


EDIT: 2017-08-30  5:18 PM CT

I have a Logitech K750 keyboard, and it doesn't see like it is compatible.
I just sent this email to support:

>Is ControllerMate Compatible with Logitech K750 Keyboard?
>
>This KB does NOT appear on your ControllerMate Compatibility list.
>
If it is compatible, how would I remap the Control Key to "Command" and Command Key to "Control"?
Also, can I remap the CapsLock Key to be a "hyper" key, a combination of all modifiers:  command, control, option, shift
>
>BTW, you really need a search tool for your web site, and for your forum.

I have confirmed (with others) that the Preferences Keyboard has changed with Sierra, so it is likely that my script will not work with Sierra.

Did you install a driver for the Logitech keyboard? If so, that is why. CM can only override (disable) keys when using it’s own driver. What this means is CM can react to the keys but it can’t stop the original value. For example, in CM you have “a” set to output “bcd”. The text “abcd” will be sent. “a” from the Logitech driver and “bcd” from CM.

Using the Driver Configurations, you would disable “a” so that only “bcd” would be sent. In a simple case like Command <-> Control, you would just remap those in the Driver Configuration screen.

As a test, try uninstalling/disabling the Logitech driver and see how CM is able to interact with it. It is possible that CM will be able to replace the Logitech driver, but not always. For example, I use a Microsoft Sculpt keyboard and they don’t make OSX drivers for it. CM is able to detect almost all of the keys except for a few of the “Media” keys (they have Windows 8 Charm icons and are see by CM as multiple keys at the same time)

Thank you so much Onan for the great suggestion (and thank you JMichaelTX for your suggestions and time).

I downloaded CM (I was aware of KM and BTT, but not CM) and it's awesome. Unfortunately, when trying to use CM's Driver Configurations, the Driver Configuration is greyed out. And if I go to "Create Driver Configuration", nothing happens. Any ideas of what I'm missing? When I click on Driver Configuration in the Palette, I get the attached error:

I have KM and BTT applications both quit (in the finder and in the upper right menu bar), so I'm not sure what's already using it.

So just like JMichael, your keyboard is using its own (Apple) driver so CM is not able to take over completely. Unlike my suggestion to JMichael, you probably don’t want to try to disable the Apple keyboard driver unless you know what you are doing. You could if you have an external USB keyboard or can SSH in from another system, just in case things don’t go right and you need to re-enable the driver (probably by booting into single user service mode or SSH in)

I’ve always used external 3rd party keyboards (but using CM’s driver) so it has always worked great for me.

Thank you for your reply. Without taking over the apple keyboard completely, do you think it’s not possible to switch the command and control keys for teamviewer? (When I use Karibiner elements and manually switch back and forth between two profiles, all works great - I guess another solution would be to automate the switch between the two - would the best way to do that be an AppleScript triggered by Keyboard Maestro, or is there a software that does that more easliy?).

Can I somehow use the karabiner virtuyalHID keyboard within ControllerMate? I have trouble understanding which levels which software is controlling which software from. I’ll play around with the karabiner virtuyalHID keyboard and see what I can come up with.

If CM doesn’t have driver level control, it would only be able to add to keypresses. So if you configured CM to send Control when you pressed the Command key, the Mac would see it as both Control and Command being pressed at the same time.

Last year before the old Karabiner app broke with the OS X Sierra upgrade, I was using Karabiner and had it configured to change functions based on the active app. I don’t know the current progress of KE so I can’t say if that functionality has been added yet. Try asking/searching in the KE issue/discussion pages.

I read in the CM forum that CM will not work with any of the Apple keyboards.

Ah, ok, thank you JMichaelTX and Onan.

I’m trying to record an action with automator (that I can trigger with Keyboard Maestro) to change the Karibiner elements Profile in the menu bar from one profile to another (or if there were a key command shortcut to do that, it would be awesome and easier). I can record an action in OSX’s automator and it works when I try it, but then when I save it as an application, I get an error when running that application (or when triggering that application from Keyboard Maestro). OR, if I try to trigger an automator action from Keyboard Maestro, it shows the Automation tasks as greyed out. Any ideas of a good way to do this, or what I might be doing wrong? If this works, I’ll be all set (when I do it manually, it works great - I just always forget to change it back so it’s a pain)

@cinematree Take a look at this discussion. It is a request to have Karabiner Elements switch profiles automatically based on the active application. About half way, a user did it himself and made it available but then at the very end, another user (Luca) says that it is now a default feature (as of 2 days ago). So try updating KE and see if you can configure separate profiles for each app.