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

Two-letter key combinations not working as expected #61

Closed
ryexley opened this issue Sep 21, 2012 · 4 comments
Closed

Two-letter key combinations not working as expected #61

ryexley opened this issue Sep 21, 2012 · 4 comments

Comments

@ryexley
Copy link

ryexley commented Sep 21, 2012

I'm working on a Backbone.js app, and I have a several different objects that register bindings with Mousetrap that don't seem to be working as expected.

I have a model on which I have registered: Mousetrap.bind('d+s', this.skipDocument);, and then I have a view on which I've registered: Mousetrap.bind('k+s', this.showKeyboardShortcuts); (yes, its a keyboard shortcut to show a list of the keyboard shortcuts for the page).

The problem I'm having, is that the key combinations don't seem to be matter at all. All I have to do on the page is hit the letter s and both functions fire. Not exactly what I was expecting. Am I doing something wrong here? Am I missing something?

@ccampbell
Copy link
Owner

Mousetrap doesn't currently support key combinations that use other keys as modifiers. You would have to use a modifier key as a modifier. If you want to make it a sequence you can change it to Mousetrap.bind('k s', this.showKeyboardShortcuts);. Then you could press k then s to fire that event.

@ryexley
Copy link
Author

ryexley commented Sep 21, 2012

Aahhh....I see...I didn't realize that. Thanks for clearing that up for me, much appreciated.

@ryexley ryexley closed this as completed Sep 21, 2012
@bhaux
Copy link

bhaux commented Nov 28, 2018

@ccampbell Hi Craig - this would be super useful for our application as well.
As this ticket is closed, I understand that there is no intention to add this functionality?
If so, I'm curious about the reasons, as to whether there is basic technical roadblock for this.
thanks : )

@ccampbell
Copy link
Owner

Sorry for the delayed reply. There are reasons why Mousetrap does not support this. I am not sure if I have touched on it in the past on other tickets here, but I will do my best to provide a short explanation.

The main reason is not technical, but rather is a user experience stance that I took from the beginning. Keyboard shortcuts are naturally designed to happen with single keys being pressed (with optional modifier keys). This is the case, for example, on MacOS. There is not a single shortcut in any application (that I know of) for “pressing a and j at the same time”, for example.

The keyboard APIs in the browser are built that way too. The key event is sent with properties to represent which modifiers, if any, were pressed along with the key.

I am not saying that it’s bad to build an app the other way or that your use case is bad. It is just that I personally think it’s a better practice to focus on the accessibility benefits of using a keyboard shortcut system people are already familiar with.


That being said, there are some technical issues as well. In order to provide callbacks when specific keys are pressed at the same time that means you have to track each key that is down at any given time. In my experience, that is less reliable than using the key events directly. For example, if you have a key held down before you focus on the page it will not trigger as being down in your application. That’s obviously not a common situation, but I didn’t want to add a bunch of hacks and workarounds to deal with a situation that I don’t think is very common.

This is a very crude example, but you could probably achieve something close like this:

let aKeyDown = false;
let jKeyDown = false;

function _ajDown() {
    console.log('pressed a+j');
}

Mousetrap.bind('a', () => {aKeyDown = false;}, 'keyup');
Mousetrap.bind('j', () => {jKeyDown = false;}, 'keyup');

Mousetrap.bind('a', () => {
    aKeyDown = true;
    if (aKeyDown && jKeyDown) {
        _ajDown();
    }
}, 'keydown');


Mousetrap.bind('j', () => {
    jKeyDown = true;
    if (aKeyDown && jKeyDown) {
        _ajDown();
    }
}, 'keydown');

That could definitely be polished up and improved, but you get the idea.

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

No branches or pull requests

3 participants