Skip to content

[Bug]: pick events do not forward mouseevent-key on Linux #24199

Closed

Description

@raphaelquast

Bug summary

Somehow on CentOS Linux 7 keyboard-buttons are not forwarded with pick_events... on Windows 10 everything works as expected.

Code for reproduction

import matplotlib.pyplot as plt

f, ax = plt.subplots()
s = ax.scatter([1,2,3,4], [1,2,3,4], s=1000)
s.set_picker(True)

def doit(event):
    if event.name == "button_press_event":
        print(event.name, event.key)
    if event.name == "pick_event":
        print(event.name, event.mouseevent.key)

f.canvas.mpl_connect("button_press_event", doit)
f.canvas.mpl_connect("pick_event", doit)

Actual outcome

When clicking on one of the datapoints while pressing the buttons 1 2 and 3 the following happens:

on Windows I get:

pick_event 1
button_press_event 1
pick_event 2
button_press_event 2
pick_event 3
button_press_event 3

on CentOS Linux I get:

pick_event None
button_press_event 1
pick_event None
button_press_event 2
pick_event None
button_press_event 3

Expected outcome

The same output for both OS

Operating system

Windows / Linux CentOS7

Matplotlib Version

3.6.1

Matplotlib Backend

Qt5Agg

Python version

3.9.13

Installation

conda

Activity

  1. oscargus commented on Oct 18, 2022

    @oscargus
    Member

    (As I have some issues with my Qt install, I tried it with tk and wx and get None for both types of events... Also on CentOS 7.)

  2. raphaelquast commented on Oct 18, 2022

    @raphaelquast
    ContributorAuthor

    @oscargus
    Thanks for the response! That's even worse 😅 Do you have any idea what's going on here?
    (as far as I know this is the correct way of determining if a key is pressed while a mouse-button is clicked...)

  3. oscargus commented on Oct 18, 2022

    @oscargus
    Member

    Oh, I wouldn't trust my statement so much...

    Ler me fet back tomorrow (left the office now) with the proper outcome.

    No, I do not really know what is going on, but I seem to recall that there is something with Wayland not reporting keys correctly. Will try to dig up that issue.

  4. tacaswell commented on Oct 20, 2022

    @tacaswell
    Member

    @oscargus It took me a while to sort out, you have to hold down '1" (or really any key) as this is looking at the key board key not the mouse button). I was also thrown using 1, 2, 3 as those are the names of the mouse buttons. If I hold 'a' down I get

    pick_event None
    button_press_event a
    pick_event None
    button_press_event a
    

    which matches the OP.

    This a regression from 3.5, likely due to the refactoring of the event tracking done in #16931 but have not bisected to be sure.

    attn @anntzer

  5. added this to the v3.6.2 milestone on Oct 20, 2022
  6. anntzer commented on Oct 20, 2022

    @anntzer
    Contributor

    Indeed, this occurs because both (1) attaching the key attribute to the mouseevent and (2) emitting the pick_event are now done by callbacks, and we just need to ensure that callback (1) comes before callback (2), i.e.

    diff --git i/lib/matplotlib/figure.py w/lib/matplotlib/figure.py
    index 1636e20101..2bbd5254b9 100644
    --- i/lib/matplotlib/figure.py
    +++ w/lib/matplotlib/figure.py
    @@ -2444,10 +2444,6 @@ class Figure(FigureBase):
             # pickling.
             self._canvas_callbacks = cbook.CallbackRegistry(
                 signals=FigureCanvasBase.events)
    -        self._button_pick_id = self._canvas_callbacks._connect_picklable(
    -            'button_press_event', self.pick)
    -        self._scroll_pick_id = self._canvas_callbacks._connect_picklable(
    -            'scroll_event', self.pick)
             connect = self._canvas_callbacks._connect_picklable
             self._mouse_key_ids = [
                 connect('key_press_event', backend_bases._key_handler),
    @@ -2458,6 +2454,10 @@ class Figure(FigureBase):
                 connect('scroll_event', backend_bases._mouse_handler),
                 connect('motion_notify_event', backend_bases._mouse_handler),
             ]
    +        self._button_pick_id = self._canvas_callbacks._connect_picklable(
    +            'button_press_event', self.pick)
    +        self._scroll_pick_id = self._canvas_callbacks._connect_picklable(
    +            'scroll_event', self.pick)
     
             if figsize is None:
                 figsize = mpl.rcParams['figure.figsize']

    fixes the issue AFAICT.

    Feel free to pick up the patch, or I'll make a PR if no one else does.

  7. added a commit that references this issue on Oct 22, 2022
    9b34b25
  8. raphaelquast commented on Oct 23, 2022

    @raphaelquast
    ContributorAuthor

    awesome! thanks for fixing this!!

  9. added a commit that references this issue on Dec 19, 2022
    3862b87
  10. added a commit that references this issue on Apr 19, 2026
    c22a025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions