Skip to content

Modifier key press events not recognized on MacOSX backend #20486

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

Closed
Pixadus opened this issue Jun 22, 2021 · 3 comments · Fixed by #21512
Closed

Modifier key press events not recognized on MacOSX backend #20486

Pixadus opened this issue Jun 22, 2021 · 3 comments · Fixed by #21512
Milestone

Comments

@Pixadus
Copy link

Pixadus commented Jun 22, 2021

Bug report

Bug summary

Key press events identify every key, except modifiers (control, option, command and shift). This behaviour is different from that of Linux and Windows where modifiers are recognized. This behaviour is identical to what was presented in #9835, and supposedly fixed in #9836.

Code for reproduction

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

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

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

Actual outcome

All characters recognized, except modifier keys.

Expected outcome

We should be seeing identifiers, such as shift and control as output from the above script.

Matplotlib version

  • Operating system: MacOS Big Sur 11.4
  • Matplotlib version (import matplotlib; print(matplotlib.__version__)): 3.4.2
  • Matplotlib backend (print(matplotlib.get_backend())): MacOSX
  • Python version: 3.9.5
  • Jupyter version (if applicable): n/a
  • Other libraries: n/a
@tacaswell tacaswell added this to the v3.4.3 milestone Jun 22, 2021
@tacaswell
Copy link
Member

@Pixadus Could you check if this works for you on the 3.3.x series? We did some work in 3.4 to unify the key handling and I'm worried we put a regression in.

Can you also check if this works with other backends (eg qtagg on tkagg) on OSX?

@Pixadus
Copy link
Author

Pixadus commented Jun 22, 2021

I took a look at it using matplotlib==3.3.0, however it exhibited the same behavior. Following your idea, I changed versions to matplotlib=2.2.0, the version this original issue was fixed in, and it still did not reveal any modifiers.

Using matplotlib.use('TkAgg') with the code above did show modifier keys, indicating it might just be an issue with the MacOSX backend.

One additional thing of note - this computer is using one of the new M1 ARM-based processors. I'm not sure if that would impact this at all, but thought I should note.

@tacaswell
Copy link
Member

This does seem like there is as issue newer versions of OSX.

This comment + commented code is worrying:

matplotlib/src/_macosx.m

Lines 2158 to 2180 in 6f92db0

/* This is all wrong. Address of pointer is being passed instead of pointer, keynames don't
match up with what the front-end and does the front-end even handle modifier keys by themselves?
- (void)flagsChanged:(NSEvent*)event
{
const char *s = NULL;
if (([event modifierFlags] & NSControlKeyMask) == NSControlKeyMask)
s = "control";
else if (([event modifierFlags] & NSShiftKeyMask) == NSShiftKeyMask)
s = "shift";
else if (([event modifierFlags] & NSAlternateKeyMask) == NSAlternateKeyMask)
s = "alt";
else return;
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* result = PyObject_CallMethod(canvas, "key_press_event", "s", &s);
if(result)
Py_DECREF(result);
else
PyErr_Print();
PyGILState_Release(gstate);
}
*/

but I think the code that is actually run is:

matplotlib/src/_macosx.m

Lines 2024 to 2086 in 6f92db0

- (const char*)convertKeyEvent:(NSEvent*)event
{
NSDictionary* specialkeymappings = [NSDictionary dictionaryWithObjectsAndKeys:
@"left", [NSNumber numberWithUnsignedLong:NSLeftArrowFunctionKey],
@"right", [NSNumber numberWithUnsignedLong:NSRightArrowFunctionKey],
@"up", [NSNumber numberWithUnsignedLong:NSUpArrowFunctionKey],
@"down", [NSNumber numberWithUnsignedLong:NSDownArrowFunctionKey],
@"f1", [NSNumber numberWithUnsignedLong:NSF1FunctionKey],
@"f2", [NSNumber numberWithUnsignedLong:NSF2FunctionKey],
@"f3", [NSNumber numberWithUnsignedLong:NSF3FunctionKey],
@"f4", [NSNumber numberWithUnsignedLong:NSF4FunctionKey],
@"f5", [NSNumber numberWithUnsignedLong:NSF5FunctionKey],
@"f6", [NSNumber numberWithUnsignedLong:NSF6FunctionKey],
@"f7", [NSNumber numberWithUnsignedLong:NSF7FunctionKey],
@"f8", [NSNumber numberWithUnsignedLong:NSF8FunctionKey],
@"f9", [NSNumber numberWithUnsignedLong:NSF9FunctionKey],
@"f10", [NSNumber numberWithUnsignedLong:NSF10FunctionKey],
@"f11", [NSNumber numberWithUnsignedLong:NSF11FunctionKey],
@"f12", [NSNumber numberWithUnsignedLong:NSF12FunctionKey],
@"f13", [NSNumber numberWithUnsignedLong:NSF13FunctionKey],
@"f14", [NSNumber numberWithUnsignedLong:NSF14FunctionKey],
@"f15", [NSNumber numberWithUnsignedLong:NSF15FunctionKey],
@"f16", [NSNumber numberWithUnsignedLong:NSF16FunctionKey],
@"f17", [NSNumber numberWithUnsignedLong:NSF17FunctionKey],
@"f18", [NSNumber numberWithUnsignedLong:NSF18FunctionKey],
@"f19", [NSNumber numberWithUnsignedLong:NSF19FunctionKey],
@"scroll_lock", [NSNumber numberWithUnsignedLong:NSScrollLockFunctionKey],
@"break", [NSNumber numberWithUnsignedLong:NSBreakFunctionKey],
@"insert", [NSNumber numberWithUnsignedLong:NSInsertFunctionKey],
@"delete", [NSNumber numberWithUnsignedLong:NSDeleteFunctionKey],
@"home", [NSNumber numberWithUnsignedLong:NSHomeFunctionKey],
@"end", [NSNumber numberWithUnsignedLong:NSEndFunctionKey],
@"pagedown", [NSNumber numberWithUnsignedLong:NSPageDownFunctionKey],
@"pageup", [NSNumber numberWithUnsignedLong:NSPageUpFunctionKey],
@"backspace", [NSNumber numberWithUnsignedLong:NSDeleteCharacter],
@"enter", [NSNumber numberWithUnsignedLong:NSEnterCharacter],
@"tab", [NSNumber numberWithUnsignedLong:NSTabCharacter],
@"enter", [NSNumber numberWithUnsignedLong:NSCarriageReturnCharacter],
@"backtab", [NSNumber numberWithUnsignedLong:NSBackTabCharacter],
@"escape", [NSNumber numberWithUnsignedLong:27],
nil
];
NSMutableString* returnkey = [NSMutableString string];
if ([event modifierFlags] & NSEventModifierFlagControl)
[returnkey appendString:@"ctrl+" ];
if ([event modifierFlags] & NSEventModifierFlagOption)
[returnkey appendString:@"alt+" ];
if ([event modifierFlags] & NSEventModifierFlagCommand)
[returnkey appendString:@"cmd+" ];
unichar uc = [[event charactersIgnoringModifiers] characterAtIndex:0];
NSString* specialchar = [specialkeymappings objectForKey:[NSNumber numberWithUnsignedLong:uc]];
if (specialchar){
if ([event modifierFlags] & NSEventModifierFlagShift)
[returnkey appendString:@"shift+" ];
[returnkey appendString:specialchar];
}
else
[returnkey appendString:[event charactersIgnoringModifiers]];
return [returnkey UTF8String];
}

but I have not traced through everything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants