Skip to content

[Bug]: macOS backend doesn't always pair key_press_event and key_release_event #31886

@iccir

Description

@iccir

Bug summary

I'm trying to better understand the macOS key_press_event/key_release_event logic. Should each key_press_event be paired with a key_release_event?

While basic usage works, there are several scenarios where this is not the case.

Key Repeats

While the figure is the active window, press and hold A:

you pressed a None None
you pressed a None None
you pressed a None None

This occurs due to keyDown: being called on a repeating timer to handle macOS keyboard repeats. Is this the correct behavior, or should only the first press be reported?

Window loses active focus

While the figure is the active window, press Control, Shift, A:

you pressed control None None
you pressed ctrl+shift None None
you pressed ctrl+A None None

While still holding the keys, use the mouse to select another window. When the keys are released, no event will fire. If a window in a different app was selected, there will be no way to tell when the keys were released. Should the macOS backend send release events if it will no longer receive keyUp: messages?

Window gains active focus

The inverse of the above. Press control and shift in a different window, then select a Figure and release only shift:

you pressed control None None

The is never a "you released shift" message posted. Still bugged, but not the exact inverse of the "loses active" state.

Save Figure Fun

Select a Figure. Press A. While still holding down A, press S:

you pressed a None None
…
you pressed a None None
you pressed a None None

The save dialog appears. If you release A, no message will be printed (same case as above).

Now press Escape to cancel the dialog:

you pressed s None None
you released escape None None

You now get a single pressed s message (even though you stopped pressing it a long time ago) and an unbalanced "you released escape" message.

Code for reproduction

I'm using the following from PR #21512:

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()

Actual outcome

See cases above.

Expected outcome

(I'm not sure what the desired outcome is.)

Additional information

No response

Operating system

No response

Matplotlib Version

dev

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions