Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Stop relying on dead-reckoning mouse buttons for motion_notify_event.#28453

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
QuLogic merged 1 commit intomatplotlib:mainfromanntzer:buttons-nodeadreckoning
Oct 30, 2024

Conversation

anntzer
Copy link
Contributor

Previously, for motion_notify_event,event.attribute was set by checking the last button_press_event/button_release event. This is brittle for the same reason as to why we introducedevent.modifiers to improve overevent.key (#23473), so introduce the more robustevent.buttons (see detailed discussion in the attribute docstring).

For a concrete example, consider e.g.

from matplotlib import pyplot as pltfrom matplotlib.backends.qt_compat import QtWidgetsdef on_button_press(event):    if event.button != 3:  # Right-click.        return    menu = QtWidgets.QMenu()    menu.addAction("Some menu action", lambda: None)    menu.exec(event.guiEvent.globalPosition().toPoint())fig = plt.figure()fig.canvas.mpl_connect("button_press_event", on_button_press)fig.add_subplot()plt.show()

(connecting a contextual menu on right button click) where a right click while having selected zoom mode on the toolbar starts a zoom mode that stays on even after the mouse release (because the mouse release event is received by the menu widget, not by the main canvas). This PR does not fix the issue, but will allow a followup fix (where the motion_notify_event associated with zoom mode will be able to first check whether the button is indeed still pressed when the motion occurs).

Limitations, on macOS only (everything works on Linux and Windows AFAICT):

  • tk only reports a single pressed button even if multiple buttons are pressed.
  • gtk4 spams the terminal with Gtk-WARNINGs: "Broken accounting of active state for widget ..." on right-clicks only; similar issues appear to have been reported a while ago to Gtk (https://gitlab.gnome.org/GNOME/gtk/-/issues/3356 and linked issues) but it's unclear whether any action was taken on their side.

(Alternatively, some GUI toolkits have a "permissive" notion of drag events defined as mouse moves with a button pressed, which we could use as well to define event.button{,s} for motion_notify_event, but e.g. Qt attaches quite heavy semantics to drags which we probably don't want to bother with.)

PR summary

PR checklist

is_over, x, y, event_state = surface.get_device_position(
self.get_display().get_default_seat().get_pointer())
# NOTE: alternatively we could use
# event_state = controller.get_current_event_state()
Copy link
Member

Choose a reason for hiding this comment

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

Given that MouseEvent rejects passingbuttons for anything but move events, should we use the non-spammy version?

Copy link
ContributorAuthor

@anntzeranntzerJun 25, 2024
edited
Loading

Choose a reason for hiding this comment

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

Both versions are spammy :/ Perhaps@QuLogic may be knowledgeable here?
I think this definitely needs to be fixed before merging; I would hope that gtk4 offers some non-broken way of checking mouse button state on macos... Fixing multiclicks+tk+macos, while desirable, seems to be less of a blocker for me; that issue won't prevent fixing the example in the initial message.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

(Also, this appears empirically to have possibly been fixed at some point between gtk4.14.2 and 4.14.5...)

@tacaswelltacaswell added this to thev3.10.0 milestoneJun 25, 2024
@QuLogic
Copy link
Member

Do you have some script to test this out?

@anntzer
Copy link
ContributorAuthor

anntzer commentedOct 22, 2024
edited
Loading

To check that.buttons works:

# pick a backend and then...frompylabimport*;gcf().canvas.mpl_connect("motion_notify_event",lambdae:print(e.buttons));show()

then move the mouse over the canvas while pressing various buttons.

To check that this does not rely on dead-reckoning (i.e. the right-click context menu example above): the context menu is implemented for gtk3/qt/tk/wx (but not gtk4 or macos) athttps://github.com/anntzer/mplinorm; run

# pick a backend and then...frompylabimport*;importmplinorm;imshow([[1,2]]);mplinorm.install()gcf().canvas.mpl_connect("motion_notify_event",lambdae:print(e.buttons));show()

then right click to trigger the menu and check that after quitting the menu, motion_notify_event sees that no buttons is pressed.

(Also rebased the PR.)

@anntzeranntzerforce-pushed thebuttons-nodeadreckoning branch from96afd2c to4091945CompareOctober 22, 2024 11:10
@QuLogic
Copy link
Member

On TkAgg, middle and right buttons are swapped for me.

Previously, for motion_notify_event, `event.attribute` was set bychecking the last button_press_event/button_release event.  This isbrittle for the same reason as to why we introduced `event.modifiers`to improve over `event.key`, so introduce the more robust`event.buttons` (see detailed discussion in the attribute docstring).For a concrete example, consider e.g.    from matplotlib import pyplot as plt    from matplotlib.backends.qt_compat import QtWidgets    def on_button_press(event):        if event.button != 3:  # Right-click.            return        menu = QtWidgets.QMenu()        menu.addAction("Some menu action", lambda: None)        menu.exec(event.guiEvent.globalPosition().toPoint())    fig = plt.figure()    fig.canvas.mpl_connect("button_press_event", on_button_press)    fig.add_subplot()    plt.show()(connecting a contextual menu on right button click) where a right clickwhile having selected zoom mode on the toolbar starts a zoom mode thatstays on even after the mouse release (because the mouse release eventis received by the menu widget, not by the main canvas).  This PR doesnot fix the issue, but will allow a followup fix (where themotion_notify_event associated with zoom mode will be able to firstcheck whether the button is indeed still pressed when the motionoccurs).Limitations, on macOS only (everything works on Linux and WindowsAFAICT):- tk only reports a single pressed button even if multiple buttons are  pressed.- gtk4 spams the terminal with Gtk-WARNINGs: "Broken accounting of  active state for widget ..." on right-clicks only; similar  issues appear to have been reported a while ago to Gtk  (https://gitlab.gnome.org/GNOME/gtk/-/issues/3356 and linked issues)  but it's unclear whether any action was taken on their side.(Alternatively, some GUI toolkits have a "permissive" notion ofdrag events defined as mouse moves with a button pressed, which we coulduse as well to define event.button{,s} for motion_notify_event, bute.g. Qt attaches quite heavy semantics to drags which we probably don'twant to bother with.)
@anntzeranntzerforce-pushed thebuttons-nodeadreckoning branch from4091945 tocd37b73CompareOctober 23, 2024 09:43
@anntzer
Copy link
ContributorAuthor

After some testing the values appear to be swapped on macosx compared to linux & windows, I adjusted the table accordingly. (The relevant chunk of code ishttps://github.com/tcltk/tk/blob/c9f915990df0d05cd6cc0ede5575a7ed32bb9978/macosx/tkMacOSXMouseEvent.c#L131-L133)

Perhaps if we want to be extra safe we should toggle based onTk().eval("tk windowingsystem") although I have no idea whether tkinter on macos can actually use X11 (tk itself can).

@tacaswell
Copy link
Member

Works with 1, 2, 3 on tk + qt5 in Mac and 1, 2, 3 on tk in linux (x11) and 1, 2, 3, 8, 9 with qt6 on linux for me.

@QuLogic
Copy link
Member

I was able to test with GTK3Agg, GTK4Agg, QtAgg, TkAgg, and wxAgg on Linux. GTK3Agg, TkAgg, and wxAgg couldn't see the back/forward buttons, but they're possibly just too old to do that right on Wayland.

@anntzer
Copy link
ContributorAuthor

Looking at it again I note that I don't try to report back/forward for macos just because I don't have such a mouse to test, but perhaps mpl_buttons() in _macosx.m just needs some additional entries for1<<3 and1<<4? (seehttps://developer.apple.com/documentation/appkit/nsevent/1527943-pressedmousebuttons for the docs)

@tacaswell
Copy link
Member

I am happy to merge this as-is and follow up with the back/forward buttons in another PR.

@ksunden
Copy link
Member

Mypy passes locally, CI was fixed in#29014

@QuLogicQuLogic merged commit6a8a80d intomatplotlib:mainOct 30, 2024
41 of 44 checks passed
@anntzeranntzer deleted the buttons-nodeadreckoning branchOctober 30, 2024 21:07
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell approved these changes

@QuLogicQuLogicQuLogic approved these changes

Assignees
No one assigned
Projects
None yet
Milestone
v3.10.0
Development

Successfully merging this pull request may close these issues.

4 participants
@anntzer@QuLogic@tacaswell@ksunden

[8]ページ先頭

©2009-2025 Movatter.jp