Thanks to visit codestin.com
Credit goes to github.com

Skip to content

MNT: Add modifier key press handling to macosx backend #21512

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

Merged
merged 5 commits into from
Nov 30, 2021

Conversation

greglucas
Copy link
Contributor

@greglucas greglucas commented Oct 31, 2021

PR Summary

The flagsChanged event handles single presses of modifier keys, so we need to send the corresponding string to our key press handlers from within that routine. Modifier + second key is handled within the KeyUp/KeyDown routines already, so leave those alone.

Taking the example from issue #20486

import matplotlib.pyplot as plt
fig = plt.figure()

def on_key(event):
    print('you pressed', event.key, event.xdata, event.ydata)
def on_key_release(event):
    print('you released', event.key, event.xdata, event.ydata)

fig.canvas.mpl_connect('key_press_event', on_key)
fig.canvas.mpl_connect('key_release_event', on_key_release)
plt.show()

this adds the single modifier key presses back in. Before this, the (modifier + key) "cmd+a" would show up, but there wasn't a single "cmd" (modifier) preceding it.

you pressed cmd None None
you pressed cmd+a None None

I'm not sure how to send key press events through the terminal natively, so there are no automated tests.

closes #20486
closes #9837

PR Checklist

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (run flake8 on changed files to check).
  • New features are documented, with examples if plot related.
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • Conforms to Matplotlib style conventions (install flake8-docstrings and run flake8 --docstring-convention=all).
  • New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there).
  • API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).

@greglucas greglucas added OS: Apple GUI: MacOSX PR: bugfix Pull requests that fix identified bugs labels Oct 31, 2021
@greglucas greglucas added this to the v3.6.0 milestone Oct 31, 2021
Copy link
Member

@jklymak jklymak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works as advertised. Not an expert on macOS backend, so not sure this is the "right" fix, but....

@greglucas greglucas requested a review from dstansby November 18, 2021 14:59
src/_macosx.m Outdated
match up with what the front-end and does the front-end even handle modifier keys by themselves?

// flagsChanged gets called on single modifier keypresses
// The modifier + second key gets handled in convertKeyEvent in KeyUp/KeyDown
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it also work for e.g. "ctrl+shift"? (dunno, just asking)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a ctrl, shift, f for example produces this:

you pressed cmd None None
you pressed shift None None
you pressed cmd+F None None
you pressed cmd None None

I think the extra command at the end is there due to the shift also being let up and changing state while command is still pressed...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On other backends, the second press is "cmd+shift", not just shift. (Well, ctrl+shift on non-osx.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so this was more complicated than I had hoped... The flagsChanged gets called on any press OR release, which is why I was printing out "pressed" when it was really a "release".

I think this means we have to keep track of the state of the keys ourselves and what is going up/down. I think this now matches what other backends do, including press/release properly.

@greglucas greglucas force-pushed the macosx-keypress branch 2 times, most recently from fc77052 to 2120ca0 Compare November 20, 2021 14:40
src/_macosx.m Outdated
lastCommand = false;
keyChangeCommand = true;
keyrelease = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge deal, but I guess each of these pairs can be grouped to

bool isPress = true;  // false for release
if ([event modifierFlags] & NSEventModifierFlagCommand) {
    lastCommand = !lastCommand
    keyChangeCommand = true
    isPress = lastCommand;
} else if (...)
    ...
} else {  // Unknown flag
    return;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NSEventModifierFlagCommand will only be true when it is held down, so we would miss the release with that implementation I think... We could probably squash the two cases into a single if block with your suggestion, but maybe I'm missing a more elegant way to keep track of the push/release here:

    if ((([event modifierFlags] & NSEventModifierFlagCommand) && !lastCommand) ||
        (!([event modifierFlags] & NSEventModifierFlagCommand) && lastCommand)) {
        // Command pressed or released
        lastCommand = !lastCommand;
        keyChangeCommand = true;
        keypress = lastCommand;
    } ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, I missed the inversion. Perhaps a good place for a ^ (xor)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Yep, a good place for it, thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, although probably another mac user should test :-)

@anntzer
Copy link
Contributor

anntzer commented Nov 26, 2021

@greglucas
Copy link
Contributor Author

Good suggestion about updating the table.

  • The shift + 2 on US keyboards is @, so I'm not sure whether the " for the other backends are expected or not.
  • I don't have an altGr key, so I can't check that.
  • I don't have a capital A key, I'm not entirely clear what that entry is referring to? Possibly pressing a with caps_lock on...

@anntzer
Copy link
Contributor

anntzer commented Nov 26, 2021

The shift + 2 on US keyboards is @, so I'm not sure whether the " for the other backends are expected or not.

Looks like the original author was from Mexico where shift+2 is " (http://kbdlayout.info/KBDLA/), probably the entry should be fixed for qwerty.

I don't have an altGr key, so I can't check that.

Per https://en.wikipedia.org/wiki/AltGr_key I guess that's "left alt/option"

I don't have a capital A key, I'm not entirely clear what that entry is referring to? Possibly pressing a with caps_lock on...

I guess no one has, probably that was capslocked indeed?

@anntzer
Copy link
Contributor

anntzer commented Nov 27, 2021

Thanks for the table update. I'll merge in a day or two if the macos crew doesn't manifest themselves for a second review :)

@jklymak
Copy link
Member

jklymak commented Nov 27, 2021

I've not been following. Has it diverged significantly from when I reviewed? I can try it again.

@anntzer
Copy link
Contributor

anntzer commented Nov 27, 2021

Mostly just check that things work just as advertised in the table under event_handling.rst.

Copy link
Contributor

@anntzer anntzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modulo @jklymak checking, per the above.

@greglucas
Copy link
Contributor Author

There was quite a bit of logic rework since your initial review, and this now handles modifier key_release events too. Mostly just mash some keys and make sure you get back what you're expecting when testing with the script included in the example. If you have an AltGr key, it would be good to update the table entry for that too, as I can't check that.

@jklymak
Copy link
Member

jklymak commented Nov 27, 2021

I've never heard of an AltGr key so I guess if don't have one. I'll try and check tomorrow

Copy link
Member

@dstansby dstansby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well for me, and fixes issues as advertised. I haven't reviewed the code in _macosx.m, but the doc update looks good.

@dstansby
Copy link
Member

Oh, and I don't think macs have AltGr keys, so leaving that empty is fine.

greglucas and others added 4 commits November 30, 2021 07:49
The flagsChanged event handles single presses of modifier keys,
so we need to send the corresponding string to our key press handlers
from within that routine. Modifier + second key is handled within
the KeyUp/KeyDown routines already, so leave those alone.
Handle the key-press and release events on macosx.
This removes half of the else-if blocks and combines the
keypress/keyrelease for each key into a single statement with negation
for whether it was a press or release being handled.
- This updates the if conditional to use XOR logic instead of the
  two negated and/or conditions.
- It also handles the shift modifier when combined with other modifier
  keys, as before (ctrl + shift + cmd) would have not printed out the
  middle shift.
@greglucas
Copy link
Contributor Author

I am going to self-merge this based on the 3 approvals and to avoid future rebases. It is a bugfix, but it has been broken for a while, so I don't think we should worry about backporting this.

@greglucas greglucas merged commit 4569a70 into matplotlib:main Nov 30, 2021
@greglucas greglucas deleted the macosx-keypress branch November 30, 2021 23:43
@QuLogic QuLogic mentioned this pull request Sep 9, 2022
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GUI: MacOSX OS: Apple PR: bugfix Pull requests that fix identified bugs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Modifier key press events not recognized on MacOSX backend MacOS: Key modifiers deprecated
4 participants