1. 15
  1. 6

    If someone’s using another approach to achieve the same result I’d love to hear about it!

    I use a keyboard that runs the QMK firmware, and my dual-function keys are all defined at the firmware level. QMK lets you fine-tune the parameters of tap-hold behavior, but the defaults are good.

    I chose to remap “;” to Control. It’s been great.

    1. 2

      I had a few of these dual function keys set up with my QMK board and I found that getting the timing is tricky because you can’t hit the key in succession very well. Another thing is that if you hit the key and release it, then hit it again without waiting properly, it might register as a tap instead of a hold.

      I’m sure these things are fixable in firmware. It’s just another thing you might have to adjust.

    2. 5

      On NixOS I do this to remap Caps Lock to both Escape and Control on only my laptop keyboard:

        services.interception-tools = {
          enable = true;
          # sudo uinput -p -d /dev/input/event0
          # only works on laptop keyboard, since i need esc on hhkb
          udevmonConfig = ''
            - JOB: "intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE"
                NAME: AT Translated Set 2 keyboard
                  EV_KEY: [KEY_CAPSLOCK, KEY_ESC]

      It doesn’t look like dual-function-keys is packaged for NixOS, but the same idea should work should you choose to package it.

      1. 4

        Why remap to enter key? It’s so far placed. I remapped my ‘a’ key to control as I pretty much always hover over ‘a’ key already.

        1. 1

          I agree with you, but the author shared their motivations in an older post, http://emacsredux.com/blog/2013/11/12/a-crazy-productivity-boost-remap-return-to-control/

          1. 1

            I guess I can see it, but the advantages seem pretty minor, certainly not what I would call “crazy”. Also, having used the “dual function” key that is described, is can be pretty finicky sometimes. Hitting Enter instead of Control can be rather disruptive.

            If it works, great. It just feels unnecessary.

            1. 2

              Well, back then this type of keyboard remapping seemed pretty novel to me, probably today I wouldn’t use the adjective crazy to describe it. :-) Still, Enter is definitely easier to press than the actual left CTRL with a pinky on most ANSI keyboards, and not having to move my hand off the home row is quite nice. I did play at some point with using SPC as control, but I typing several spaces in a row becomes quite problematic with this arrangement. :-)

              1. 1

                One more thing - I came across this idea when I was working on a Mac keyboard without a left control to begin with and it was the only way I wouldn’t lose any other key (e.g. one of the Options) in exchange for the left control I desperately needed. With Linux and a normal Win keyboard that’s not as big of an issue, but I still prefer that arrangement over a control on the bottom row of the keyboard.

        2. 3

          Isn’t caps lock ->control the canonical remap? On the home row, not good for anything else…?

          1. 2

            Yeah, I really don’t understand why people are advocating for remapping extremely useful keys like enter or A to control. That seems like it would cause way more problems than it solves.

            1. 5

              The article says that it’s a dual-function remap - holding enter causes it to act like control, but merely tapping it causes it to continue to act like enter.

              1. 2

                That’ll teach me to skim, I guess.

                I still dislike this though. I don’t like keys that simultaneously act as regular keys and modifier keys. The Windows key on PCs is a prime example: there are a bunch of shortcuts bound to Windows+, but tapping Windows alone causes the start menu to come up. When using Windows, I frequently find myself going for a keyboard shortcut, typing Windows, changing my mind, releasing Windows, and then having to deal with the annoyance of the Start menu appearing.

                Given that enter is used as a “submit” key on a huge number of programs, I expect it would be even worse.

                1. 4

                  That’s an implementation problem, not a conceptual problem. The way that xcape (and theoretically any other implementation of this) works (or could work) is that if you hold down the key long enough, even if you release it without pressing anything else, it acts like the modifier key and doesn’t send the “tap” event. My xcape is configured to have a 250 ms delay - if I press left shift as part of a chord, and then change my mind, if I just make sure that I hold the shift key for the required quarter of a second, the left parenthesis (tap functionality) is not emitted.

                  1. 1

                    The way I see it, the existence (and arbitrariness) of that 250 ms parameter is strong evidence that it is a fundamental conceptual problem. I’m with @Kronopath in that having both modifier and non-modifier functionality on the same physical key drives me thoroughly up the wall.

                    And for anyone else who feels similarly, a Firefox setting I was relieved to stumble across a few years ago: in about:config, set ui.key.menuAccessKeyFocuses to false. And if (as I do) you keep the menu bar hidden, note that it will unfortunately auto-revert this setting to true if you show and then hide the menu bar manually (e.g. via a right-click on the tab bar), though you can use F10 to show it temporarily and avoid that particular quirk (or bug?).

                    1. 1

                      I don’t quite see how the existence of a timeout parameter implies a fundamental conceptual parameter - could you clarify? The universe, and programming, are filled with timing-related parameters, such as the TCP connection timeout parameter, the length of time you have to hold down a key before it is repeated, or the oscillation frequency of a Josephson Junction when exposed to a particular voltage. This particular parameter isn’t actually arbitrary, either - I chose it myself based on my preferences and after some experimentation to find a comfortable value. This is no more arbitrary than you picking your mouse’s DPI.

                      It’s unfortunate that the functionality “drives you up a wall”, but that doesn’t actually mean that it’s a bad idea. For instance, vim-style modal editing is very unpleasant for some people (mostly people who eventually switch to emacs) - but that doesn’t have anything to do with the soundness of the idea, nor its efficiency.

                      1. 1

                        Sure, it’s not arbitrary for any given individual, but overall it’s a magic number with no clear “right” value, whereas otherwise it’s a simple matter of which keys were pressed and released in which order, no guessing or heuristics involved. Adding time durations as semantically-significant signals where they otherwise didn’t factor in at all is a fundamental change to the signaling mechanism.

                        And I’m not arguing against time-based behavior in general (certainly there are contexts in which it’s appropriate) but I find predictable, synchronous behavior highly preferable unless there’s a very compelling reason to introduce asynchrony. The sort of time-based behavior you’ve got is, ultimately, a race condition – and for people who are okay with it that’s fine, but I don’t like it when software (e.g. Firefox, or Windows as mentioned upthread) bakes it in.

                        1. 1

                          a magic number with no clear “right” value

                          I don’t think that this is right. I see a clear “right” value - that which works for you. Actually, it’s a range of values, bounded on the lower end by how quickly you tap individual keys, and on the upper end by how long you want to have to hold the modifier key in case you decide to “back out” of a chord.

                          no guessing or heuristics involved

                          There’s no guessing or heuristics involved here, either. You know exactly how long you have to press a modifier key for in order to send the “hold” command, as opposed to the “tap” command. The fact that humans don’t have very high precision on their internal timers in order to measure that duration is irrelevant - you can just hold the key until you’re sure it won’t act like a tap. Most people can’t tell the difference between 250 milliseconds and 260, but they sure can tell the difference between 250 and 1000 - and since you can train yourself to rarely decide to back out of key chords, the extra 0.75s is insignificant.

                          Adding time durations as semantically-significant signals where they otherwise didn’t factor in at all is a fundamental change to the signaling mechanism.

                          A fundamental change that is useful, makes perfect logical sense, and is easy to adapt to. I cannot recall the last time that I accidentally emitted a parenthesis by accident using space-cadet shift keys (tap to emit parenthesis, hold to act like shift) over the past few weeks, and it’s pretty obviously useful to take a key that does nothing when you tap it by yourself (e.g. shift) and make it do something when tapped by itself, in a way that doesn’t reduce the functionality of your computer in any way whatsoever.

                          I find predictable, synchronous behavior highly preferable

                          You can prefer it, but that doesn’t mean that dual-function keys have a “fundamental conceptual problem”. That’s what I’m arguing against - not what you prefer to use, but the idea that there’s somehow something wrong with the idea itself.

                          a race condition

                          This isn’t a race condition. The Wikipedia page on race conditions[1] defines it as “the condition of an electronics, software, or other system where the system’s substantive behavior is dependent on the sequence or timing of other uncontrollable events”. The order in which you press keys are not “uncontrollable events”. You have complete control over the order in which you press keys using your fingers - or, rather, that’s the model of human hands that most people operate under.

                          Edit: I think I see where you might be getting the idea that this is similar to a race condition - you might be thinking that if you don’t hold a key for the threshold e.g. 250 ms, it registers as a tap, even if you press another key. The way that actually it works is that there are three cases: (1) if you press the key and then release it sooner than THRESHOLD later without pressing another, it registers as a tap (2) if you press the key and don’t release it less than THRESHOLD later, it acts as a modifier (nothing happens) (3) if you press the key and then another key (a chord) before letting go of the first, it acts like a normal chord, regardless of whether you held the dual-function key for longer or shorter than the threshold. That is, you do NOT have to hold the chord for the threshold duration in order for the key to be counted as a “hold”/modifier instead of a “tap” - if you hold the key and press another, it acts like a modifier, no matter whether you hold it for longer or shorter than the threshold.

                          Windows as mentioned upthread

                          As also mentioned upthread, that’s an implementation problem, not a conceptual problem. You’re taking a bug in an implementation and conflating that with the idea that is represented by the implementation.

                          [1] https://en.wikipedia.org/wiki/Race_condition

            2. 2

              A great many Emacs users remap the infrequently used CapsLock key to Control to alleviate partially the problem with the accessibility of the control keys. That, while useful, is not sufficient for the optimal typing experience, since that way you’re breaking the key symmetry on both sides of your keyboard. Also - your right pinky has to go much further than your left one, while you’re typing. Many people seem to be using only the left Control and I guess they’re not particularly bothered by this, but touch typists like me are generally quite bothered by such things.

              1. 1

                Who are you quoting?

                1. 2

                  @bbatsov in their previous article that they link to in the opening note:

                  Note: Check out my original article from 2013 about the rationale behind this remapping.

                2. 1

                  Thanks, I missed that link/follow in the original. I still don’t understand though.

                  I don’t see how using Enter instead of capslock is more symmetrical. If anything it is less? the enter key is further from the letter home row than capslock is.

                  Also - your right pinky has to go much further than your left one, while you’re typing

                  So having the left little finger go a little more to the left (for capslock) is more symmetrical, right? And it already does this for shift anyway (just below capslock).

                  Sorry if it seems like I’m trying to pick nits, I’m really not getting the argument.

              2. 2

                Thanks for this! I’ve tried xcape before, but it has never really worked that well.

                1. 1

                  I’ve always used xcape for space-cadet shift keys (same principle) and never had problems - what did you run into?

                  1. 3

                    Not him, but for starters, xcape is X11 specific while I rock the wayland boat.

                    1. 1

                      I had problems with lag. Hitting Return would take some extra time to enter a newline.

                      1. 1

                        Oh, that would be a huge problem. Would you share your xcape config so I can test it out on my box?

                        1. 1

                          Hm, unfortunately I haven’t used it for about a year. But I think I used a fairly standard config for remapping a single key, with xcape + xmodmap or possibly a custom key map.