-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
How to detect shift shift key in VSCode? #5280
Comments
That is a cool idea. Currently, the keybinding dispatching ignores only modifier keys (does not try to dispatch them unless they are accompanied by a non-modifier key). |
@alexandrudima With the Vim extension, users can remap their vim keybindings. We're discovering that some key combinations don't get dispatched to the extension: VSCodeVim/Vim#757. Particularly, Verified this by building a new extension with @k--kato's sample code above with VSCode 1.5.1 Related question: Can you have more than one extension register the |
@jpoon the keybindings.json use key codes. This issue is regarding registering a keybinding in the form of Registering |
(this likely belongs in a separate issue, let me know if you want me to move it) With registering As for the more than one extension question, what I'm seeing is:
This seems to imply that only one extension at a time can register the |
@jpoon This has a very simple reason. It is driven by our platform (web browser). Pressing a key combination can end up generating the following DOM events:
It all depends on the keyboard layout you have installed and the key combinations you press. For example:
The relevant code is at:
I am certain there must be things I've missed in how this works, so I would love PRs improving things, while keeping in mind that everything must work in Windows, Linux, OSX, on Chrome, on IE9-11, on Edge and on Firefox. I bubble this up in two conceptual different ways:
|
Indeed, would be nice if we could define this key binding in { "key": "shift shift", "command": "workbench.action.quickOpen" } |
Any progress on this? |
@hastebrot it does not work on vscode 1.17.1 |
Would like to see this. |
Looks like Google Chrome now sends a keydown event when just the Shift key is pressed, with code 13. Should this be possible to implement now? |
I'll just add my ditto to this. |
Any news on this ? (I'll wait relentlessly for this feature) |
I would love this as well! |
I'm currently using a workaround, taking advantage of BetterTouchTools. You can mimic this behaviour by adding a new shortcut, in BTT and selecting the 'Key Sequence' (inside the keyboard tab). Then press 'Record New Key Sequence' and press shift > shift. This is what it will look like. I didn't touch any of the settings. Save it, bind it to a key combination inside of VScode (I believe it's CMD + P by default). Et voilá! You have your desired functionality. Of course, it would still be nicer if this was natively supported in VSCode without having to use third party software. Figured I'd share my solution anyway. |
Workaround for Windows:
lastShift := 0 |
I proposed something similar in #29407 which was closed. Did not see this issue. My +1. |
I spent only 1 hour at 2am on this. please only look at it as a starting point ;) This is my first time cloning vscode and having a crack at the codebase. After applying the hack here and rebuilding vscode: And using this shortcut chord:
Will make it work. Bugs (Known):
Cons:
|
Complexities of implementing this: I originally thought that using the Chord system, which is the double key combination detection system "Ctrl+K, Ctrl+D", might be doable... but it turns out, no, here's why Shift+AlphaNumeric will not work if shift was in Chord mode:
Unwanted trigger when holding shift:
VSCode's underlying keybinding system does not check the time between key presses. Need to do a architecture modification while making sure that there's no regressions with existing keybindings, and with cross-platform mac, linux, windows, and with different country keyboards. :) |
I think shift + shift can only be implemented as a special case, like how alt + mouse click works. And only shift + nothing should count as the first shift hit, means it must be processed in keyup event. The second is maybe able to be dispatched in keydown event. |
Maybe we should have a
|
I still don't think this will fit into Code's keybinding system.
But I still think a special case for |
Agreed, I'm thinking of implementing it as @hastebrot mentioned:
To keep keybinds somewhat intuitive, I think adding extra compatibility for other modifier keys, such as the below, will be a must. Should make a timeout function that is started when a modifier key is pressed (perhaps modifiers only for now?); then if the same key is pressed within the time limit, it fires off a single resolve as usual... Of importance is not to resolve the keybind database twice (the search for keybind functionality, mentioned in code as a resolver function), potential big performance / battery drain? So probably put some sort of hardcode here?
Otherwise we could go up the tree and hardcode here?
Is this the mouse hardcode?
|
maybe have real specific cases that get fired rather than trying to parse it. Something like
I differentiated between L and R side so there can be an alternate mapping for the other side of the keyboard. Something like LShift LShift for QuickOpen and RShift RShift to search for commands |
Good news, Initial working implementation in this commit. Feel free to give it a go! after building give these a go:
I'll clean it up a bit later, in hindsight after getting a little more familiar with the codebase, I realised I've added a bunch of unecessary code regarding keybind -> dispatch string... maybe. Will need to see if there are indeed keycode differences between Mac/Win/Linux regarding Ctrl/Alt/Shift haven't got around to running the keybind unit tests either - not too sure how to at this stage |
@PathToLife Good job! Looked a little bit into your changes, I think there are actual two parts: "allow dispatching single modifier key" and "time sensitive key chords". For the second part I have some new ideas: allowing declare max allowed interval in keybindings.json, and even declaring multiple keybindings with same key chords, but different max allowed intervals, mapping to different commands. I think this will enable many more interesting usages. The default value is Dispatching single modifier key is only the part that dispatches modifier keys at keyup. Mixing single modifier key with a normal key combo in a single key chord should also be possible, considering current usage of keybindings.json. I saw some performance concern. Maybe we can pre-parse keybindings.json to a |
Thanks for the suggestions @yume-chan
To detect other duration, need to use Hopefully can have minimal impact on the codebase if we do implement this
I think the current architecture's decision to use only one keyboard event? is cleaner, don't want to play with more events than usual
It is already O(1), |
I thought by default Code will wait for second chord forever, but that's not the case. Now there is a hardcoded 5s timeout vscode/src/vs/platform/keybinding/common/abstractKeybindingService.ts Lines 149 to 152 in d03925a
So adding time sensitive keybindings should be pretty easy. I will try that when I have time, and I believe this is the proper way toward dispatching single modifiers. |
I have done my time sensitive key chords implementation at yume-chan@300dd01 The core part is only 5 lines long: yume-chan@300dd01#diff-7bda82440de1deb3c14304313cd37fed2299a8778cef3a9dc2004543c8a3c76bR130-R134 this._currentChord = {
keypress: firstPart,
label: keypressLabel
label: keypressLabel,
+ enterTime: chordEnterTime,
}; Record when did the first key chord was pressed. yume-chan@300dd01#diff-1bea564a53de9969cb7e8758c4a6d68e3f57fbcd6302f4761338f63cd4fc1f42R286-R288 if (candidate.keypressParts[1] === keypress && // Key matches
KeybindingResolver.contextMatchesRules(context, candidate.when) && // When clause matches
+ timeElapsed <= candidate.timeout) { // Timeout matches Compare time between two chords with declaration. These three lines used to be scattered, I rewrote them this way. This check requires a first chord, so smashing Backspace won't get here unless you really have a keybinding for yume-chan@300dd01#diff-1bea564a53de9969cb7e8758c4a6d68e3f57fbcd6302f4761338f63cd4fc1f42R323 else if (candidate.keypressParts.length > 1 && candidate.keypressParts[1] !== null) {
candidateChords.push(candidate);
maxChordTimeout = Math.max(maxChordTimeout, candidate.timeout);
} Gather all candidate second key chord when first chord was pressed. video.mp4 |
Thank you so much! |
I tested it. It works like a charm. Thanks for everyone who supported this feature. Now I won't get crazy anymore trying to use PHPStorm shortcuts on VS Code and Code shortcuts on PHPStorm, since I use both very often. |
Verified, though it seems that the shortcuts must be set in the json file rather than using the keyboard shortcut editor. |
There are now two types of dispatchers in the keybinds resolver.
The decision to add the [NEW] modifier dispatcher is because the [EXISTING] normal dispatcher does not allow for rapid, single modifier shortcut events - this is because the chord system implementation interferes and gives unwanted behavior: For example, after enabling single modifier key support on [EXISTING] normal dispatcher:
This introduces the problem in that: I did have a initial implementation that made it so that the shortcut editor did work, however a by product of this was that the aforementioned unwanted behavior. Any changes that give support to shortcut editor may be - overly complex? and I feel would be better to have in a separate PR :) Or even better - an overhaul of the keybinds system, including removal of hacks for the alt-select (mouse keys + keyboard keys). |
Has been released as of vscode version 1.54.1 :) put this in your keybindings.json:
Not sure what to do with ctrl ctrl, yet :) |
This is nothing but awesome. Really appreciate the effort to add this! |
Steps to Reproduce:
I'm trying to bind
quick open
(ctrl+p) command toshift shift
(shift x2) keys like IntelliJ IDEA in VS Code Extension (TypeScript).But
vscode.commands.registerCommand('type', (args) => args.text)
can't detect shfit key.How can I detect shift shift key?
The text was updated successfully, but these errors were encountered: