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

Standalone keys + One-to-many mappings #247

Closed
wants to merge 2 commits into from

Conversation

wwwjfy
Copy link
Contributor

@wwwjfy wwwjfy commented Oct 6, 2016

This is to implement Karabiner's Control_L to Control_L (+when you type Control_L only, send Escape) functionality. It's a temp solution, which can be used until the official one comes out.

Updated (2017.01.06): Added one-to-many mappings, to get one key behaves like multiple keys.

Download the customized build at https://github.com/wwwjfy/Karabiner-Elements/releases

Usage:

{
    "profiles": [
        {
            "name": "Default profile",
            "selected": true,
            "simple_modifications": {
                "caps_lock": "left_control"
            },
            "standalone_keys": {
                "caps_lock": "escape"
            },
            "one_to_many_mappings": {
                "left_control": ["left_control", "left_shift", "left_option", "left_command"]
            }
        }
    ]
}

@wwwjfy wwwjfy force-pushed the standalone-modifiers branch 4 times, most recently from fb1ca4a to 6a742a3 Compare October 6, 2016 07:15
@omnikron
Copy link

omnikron commented Oct 6, 2016

This works absolutely perfectly! I absolutely need this functionality as I remap Caps Lock to Escape (on single press) and Left Control (when held down) so I never have to leave the home row when using vim. I hadn't realised quite how ingrained this was until it broke and I couldn't work any more! Thought I would leave a comment, not only to say thanks but also to make this potentially a bit easier to google.

@garymh
Copy link

garymh commented Oct 7, 2016

7f15552 seems to have broken the functionality for me :( Using the configuration above with this build will change caps lock to control, but not include the escape key at the end:

screen shot 2016-10-07 at 11 28 33 am

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 8, 2016

@garymh It works for me. Please try to recompile and reinstall (a easier way is to run make install in src/core/grabber). If possible, try to recompile the one before this to ensure this commit is the reason.

7f15552 should not break this, as this commit changes the key with modifier or not, and should not affect when used alone.

@garymh
Copy link

garymh commented Oct 8, 2016

@wwwjfy Yep, totally right! Thanks and sorry for the confusion!

@erwald erwald mentioned this pull request Oct 8, 2016
@zhexuany
Copy link

@wwwjfy Your fix is nice; but when I type control_l only instead of typing control_l togehter with other key, it means I want to use esc. For now, control_l seems like waiting for possible future input. Maybe we can short such time that control_l waiting for incoming input.

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

@zhexuany That'd be ideal (Karabiner should be doing that, I can't remember clearly). Current hack is using the simpler way, that esc is sent to system when control_l (left control, right?) is released.
This way I don't have to add a timer, so the code is less "messed". :)

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

JFYI, I rebased the code on latest master (0.90.47)

@kibin
Copy link

kibin commented Oct 10, 2016

@wwwjfy I have the same issue as @garymh did, where can I find src/core/grabber?

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

@kibin clone the repo, and it's in root path of the repo.
A easier way is to uninstall and reinstall, which can remove outdated files and kexts (hopefully :).

@kibin
Copy link

kibin commented Oct 10, 2016

@wwwjfy I’ve uninstalled, reinstalled (esc started working), then updated and it stopped working again. Guess I’ll try to clone repo

@zhexuany
Copy link

@wwwjfy It worked on your last release but not work in your latest code. Maybe there are something you overlooked.

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

@kibin I see. You have to build it yourself (or someone build it for every new release), because this is a PR, not in mainstream, and when you updated, the hack is gone.

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

@zhexuany I'm not sure about your case now. I've changed something to suit other cases.
Could you post your action (press which key, release which key), your expected behavior and actual behavior?

@zhexuany
Copy link

zhexuany commented Oct 10, 2016

@wwwjfy I just download your release from your repo. It works just fine. But the copy I compiled myself from your code under standalone_modifers branch does not work(It works, what I mean is that when I use in in spacemacs, it does not work. When I type control_l, it actually waits for incoming input.). By checking the event viewer, the difference is flagsChanged(I can't remember the exact name). Your old release only has KeyDown and KeyUp.

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

@zhexuany By When I type control_l, do you mean press and release it alone?

I did various fixes and rebase in last week, could you try the latest commit? (committed a few hours ago)

@zhexuany
Copy link

@wwwjfy That may be the issue. I just pulled from you repo. A lots conflicts.

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 10, 2016

It's expected because I did rebase. Just git reset --hard wwwjfy/standalone-modifiers or origin/standalone-modifiers depends on how you cloned~

@zhexuany
Copy link

@wwwjfy Now everything works just fine. Thanks for you patience.

@ChrisPenner
Copy link

Looking forward to this! It's one of the main features I used in Karabiner.

@zhexuany
Copy link

zhexuany commented Oct 11, 2016

@tekezo When will this pull request can be merged into master? To me, @wwwjfy 's approach is pretty nice. Any comments about this?

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 11, 2016

@zhexuany Thanks, but I don't think the hack should be in merged. It's just to be convenient for Sierra users before the official feature implemented. And I created the pull request to be simpler to apply for any one who needs it, not to be merged. :)

@hndrewaall
Copy link

@wwwjfy This works really well for me, thanks! However, this seems to break the ctrl-shift-power shortcut for screen locking :( the events look no different in the event viewer, but so long as Elements is running, I can't use this sequence. Any idea why?

@wwwjfy
Copy link
Contributor Author

wwwjfy commented Oct 12, 2016

@hndrewaall It's related to #89, not this patch. Event Viewer uses system event to show the pressed keys, so it doesn't mean Karabiner-Elements can handle it currently.

@kennonb
Copy link

kennonb commented Jun 6, 2017

@bosr I'm running this PR in High Sierra beta 1 and all appears ok so far. I'm just doing a basic "Caps to HYPER while holding and tapping Caps pressing ESC" modification, but that's still working fine for me.

@bosr
Copy link

bosr commented Jun 6, 2017

@kennonb thanks!

@tomislav
Copy link

Happy to report the newest version (0.91.3) now supports complex modifications (no GUI yet). This is my configuration to get the hyper key.

{
    "profiles": [
        {
            "complex_modifications": {
                "rules": [
                    {
                        "manipulators": [
                            {
                                "description": "Change caps_lock to command+control+option.",
                                "from": {
                                    "key_code": "caps_lock",
                                    "modifiers": {
                                        "optional": [
                                            "any"
                                        ]
                                    }
                                },
                                "to": [
                                    {
                                        "key_code": "left_command",
                                        "modifiers": [
                                            "left_control",
                                            "left_option"
                                        ]
                                    }
                                ],
                                "to_if_alone": [
                                    {
                                        "key_code": "escape"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    }
                ]
            },
            "name": "Profile",
            "selected": true
        }
    ]
}

@blackxored
Copy link

Is there a way to preserve the fn while it being mapped to hyper?
I'm trying to get it to work as a hyper key, while working on the volume controls as normal. Can this be achieved via karabiner elements or karabiner+hammerspoon?

@blackxored
Copy link

blackxored commented Jun 15, 2017

Answering myself, certainly not the most elegant way by any means, but managed to do it with hammerspoon:

local hyper_fn_keys =  {
  {'f1', 'BRIGHTNESS_DOWN'},
  {'f2', 'BRIGHTNESS_UP'},
  {'f5', 'ILLUMINATION_DOWN'},
  {'f6', 'ILLUMINATION_UP'},
  {'f7', 'PREVIOUS'},
  {'f8', 'PLAY'},
  {'f9', 'NEXT'},
  {'f10', 'MUTE'},
  {'f11', 'SOUND_DOWN'},
  {'f12', 'SOUND_UP'}
}

for i, keymap in ipairs(hyper_fn_keys) do
  hs.hotkey.bind(hyper, keymap[1], function() 
    hs.eventtap.event.newSystemKeyEvent(keymap[2], true):post()
    hs.eventtap.event.newSystemKeyEvent(keymap[2], false):post()
  end)
end

I can't get mission control or launch panel to work but given they've gestures I'm not too concerned.

@jahamed
Copy link

jahamed commented Jun 15, 2017

@tomislav
Awesome that worked for me! Might I ask how you found out about these new options? I'm not seeing any documentation but might have just missed it.

For anyone else who wants to make Caps Lock into Hyper (ctrl, opt, cmd, shift) make this your ~/karabiner/karabiner.json (also update to the beta version under the misc menu in Karabiner)

{
    "global": {
        "check_for_updates_on_startup": true,
        "show_in_menu_bar": true,
        "show_profile_name_in_menu_bar": false
    },
    "profiles": [
        {
            "complex_modifications": {
                "rules": [
                    {
                        "manipulators": [
                            {
                                "description": "Change caps_lock to command+control+option+shift.",
                                "from": {
                                    "key_code": "caps_lock",
                                    "modifiers": {
                                        "optional": [
                                            "any"
                                        ]
                                    }
                                },
                                "to": [
                                    {
                                        "key_code": "left_shift",
                                        "modifiers": [
                                            "left_command",
                                            "left_control",
                                            "left_option"
                                        ]
                                    }
                                ],
                                "to_if_alone": [
                                    {
                                        "key_code": "escape"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    }
                ]
            },
            "devices": [],
            "fn_function_keys": {
                "f1": "display_brightness_decrement",
                "f10": "mute",
                "f11": "volume_decrement",
                "f12": "volume_increment",
                "f2": "display_brightness_increment",
                "f3": "mission_control",
                "f4": "launchpad",
                "f5": "illumination_decrement",
                "f6": "illumination_increment",
                "f7": "rewind",
                "f8": "play_or_pause",
                "f9": "fastforward"
            },
            "name": "Default profile",
            "selected": true,
            "simple_modifications": {},
            "standalone_keys": {
            },
            "virtual_hid_keyboard": {
                "caps_lock_delay_milliseconds": 0,
                "keyboard_type": "ansi"
            }
        }
    ]
}

@tomislav
Copy link

@jahamed mostly by reading the commits. Also check out the examples folder. There is also a timeout option for to_if_alone.

@knu
Copy link

knu commented Jun 16, 2017

Finally, 0.91.x has complex_modifications and I've successfully migrated from this fork. The from/to/to_if_alone keys allow you to set up any-to-any mappings and standalone key bindings.

@wwwjfy You really saved my life, thank you for everything you've done!

@jhegedus42
Copy link

what is this complex modification thing ? what can i do with it ?

@probablykasper
Copy link

@jhegedus42 A lot. Here's an example:
You remap from "caps_lock" to "left_shift+left_control+left_option+left_command", as well as to "escape" if caps_lock is pressed alone.

You can even choose both mandatory and optional modifier keys for the key combination you're remapping - So you could have shift+caps_lock remap to something.
It's in the beta, which you can get under the "Misc" menu in Karabiner-Elements.

Check out these examples:
https://github.com/tekezo/Karabiner-Elements/blob/master/examples/caps_lock_to_command_control_option_shift.json
https://github.com/tekezo/Karabiner-Elements/blob/master/examples/emacs_key_bindings.json
https://github.com/tekezo/Karabiner-Elements/blob/master/examples/exchange_number_and_symbols.json
https://github.com/tekezo/Karabiner-Elements/blob/master/examples/spacebar_to_shift.json

@henrebotha
Copy link

For those wondering, here is how you get Ctrl to emit Esc when pressed alone in Karabiner Elements 0.91.4:

            "complex_modifications": {
                "rules": [
                    {
                        "manipulators": [
                            {
                                "description": "Change ctrl to esc if pressed alone.",
                                "from": {
                                    "key_code": "left_control",
                                    "modifiers": {
                                        "optional": [
                                            "any"
                                        ]
                                    }
                                },
                                "to": [
                                    {
                                        "key_code": "left_control"
                                    }
                                ],
                                "to_if_alone": [
                                    {
                                        "key_code": "escape"
                                    }
                                ],
                                "type": "basic"
                            }
                        ]
                    }
                ]
            }

@davidchambers
Copy link

If you're a modern space cadet, try this configuration:

{
  "profiles": [
    {
      "name": "Default profile",
      "selected": true,
      "complex_modifications": {
        "rules": [
          {
            "description": "A Modern Space Cadet (Steve Losh)",
            "manipulators": [
              {
                "type": "basic",
                "from": {"key_code": "caps_lock"},
                "to": [{"key_code": "left_control"}],
                "to_if_alone": [{"key_code": "escape"}]
              },
              {
                "type": "basic",
                "from": {"key_code": "left_shift"},
                "to": [{"key_code": "left_shift"}],
                "to_if_alone": [{"key_code": "9", "modifiers": ["left_shift"]}]
              },
              {
                "type": "basic",
                "from": {"key_code": "right_shift"},
                "to": [{"key_code": "right_shift"}],
                "to_if_alone": [{"key_code": "0", "modifiers": ["right_shift"]}]
              }
            ]
          }
        ]
      }
    }
  ]
}

It feels so good to have shift-parens back! 🎉

@ipetepete
Copy link
Contributor

Here's an example of Space/FN + IJKL arrow keys...

            {
              "manipulators":[
                  {
                      "description":"Space + L = RIGHT",
                      "type":"basic",
                      "from":{
                          "key_code":"l",
                          "modifiers":{ "mandatory":["fn"]}
                      },
                      "to":[{"key_code":"right_arrow"}]
                  }
              ]
          },{
              "manipulators":[
                  {
                      "description":"Space + K = DOWN",
                      "type":"basic",
                      "from":{
                          "key_code":"k",
                          "modifiers":{ "mandatory":["fn"]}
                      },
                      "to":[{"key_code":"down_arrow"}]
                  }
              ]
          },{
              "manipulators":[
                  {
                      "description":"Space + J = Left",
                      "type":"basic",
                      "from":{
                          "key_code":"j",
                          "modifiers":{ "mandatory":["fn"]}
                      },
                      "to":[{"key_code":"left_arrow"}]
                  }
              ]
          },{
              "manipulators":[
                  {
                      "description":"Space + I = UP",
                      "type":"basic",
                      "from":{
                          "key_code":"i",
                          "modifiers":{ "mandatory":["fn"]}
                      },
                      "to":[{"key_code":"up_arrow"}]
                  }
              ]
          },{
              "manipulators":[
                  {
                    "description":"Space as fn",
                    "type":"basic",
                    "from":{
                        "key_code":"spacebar",
                        "modifiers":{"optional":["any"]}
                    },
                      "to":[{"key_code":"fn"}],
                    "to_if_alone":[{"key_code":"spacebar"}]
                  }
              ]
          }

Pull request here: #794

@aaronjensen
Copy link

Is fn the only "custom modifier" we get?

@ipetepete
Copy link
Contributor

@aaronjensen No, you can change fn to whatever modifier you want, or combination of modifiers. The original has been updated and has an example similar to this one but they used Sas the modifier. See the examples here: https://github.com/tekezo/Karabiner-Elements/tree/master/examples

@aaronjensen
Copy link

Sorry, I should have been more clear. In karabiner you could create custom modifiers. Fn is not actually custom, it is built in. Furthermore, I believe it is flagged along with every key press if you have the use f keys as f keys checked, making it not useful in those instances. If I were to use fn as an additional modifier, to say, make my home row produce brackets, I could not then also use f keys as f keys afaict.

That said, these additions are huge as they are and I'm looking forward to what comes next. If there is a way to have custom modifiers that I don't know of then great, otherwise I'll probably open a new issue if there isn't one already.

@aaronjensen
Copy link

Furthermore, I believe it is flagged along with every key press if you have the use f keys as f keys checked

Seems I was mistaken on this, I don't remember when I saw that...

@lambdalisue
Copy link

This is a memo for anyone who had problems with complex_modifications

I could not make the following with complex_modifications but standalone_keys

  • lang1 is left_shift or return_or_enter when pressed alone (complex_modifications or standalone_keys)
  • right_shift is lang1 (simple_modifications)

With complex_modifications, it seems the mapping applied recursively. So the right_shift actually became left_shift or return_or_enter. So I don't have any way to hit lang1 with complex_modifications but standalone_keys. I hope that the original complex_modifications behave like standalone_keys ...

@tekezo
Copy link
Member

tekezo commented Sep 11, 2017

Thank you for the fork!
Karabiner-Elements supports complex remapping rules since v0.91.2.
Thus, I close this PR.

@tekezo tekezo closed this Sep 11, 2017
samhstn added a commit to samhstn/my-config that referenced this pull request Sep 21, 2017
nathanaelkane added a commit to nathanaelkane/dotfiles that referenced this pull request Nov 14, 2017
@krasnovpro
Copy link

I need to map "button3 -> space+button1". How can I do this?

@dtothefp
Copy link

dtothefp commented May 3, 2019

@wwwjfy did this functionality get merged into the @tekezo Karabiner Elements repo / releases? I've been using your fork for awhile and wondering if I can switch?

@wwwjfy
Copy link
Contributor Author

wwwjfy commented May 4, 2019

@dtothefp it's not merged and wasn't meant to be 😅
The feature is implemented in another way in main repo.

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