GNOME Bugzilla – Bug 565559
Incorrect leave-notify signals for treeview
Last modified: 2010-05-12 10:17:53 UTC
OpenSuSE 11.0 and 11.1 I am using a treeview to display a small table. See the ascii drawing below. 1. I get leave-notify signals when I move the pointer from the main area ("A") to the header area ("B"). That's wrong. 2. I do not get them when I move from the header area to the outside. That's very wrong. Note, that motion events are correctly triggered for the entire treeview area ("A" + "B"s.) +-------+-------+-------+-------+-------+-------+-------+ | B | B | B | B | B | B | B | +-------+-------+-------+-------+-------+-------+-------+ | | | | | | | | | A | | | | | | | | | +-------------------------------------------------------+
I have added a patch that performs exactly this behavior. I have implemented this patch on top of another patch I submitted before (71926). Leave and Enter events are suppressed when the mouse moves between the header window and the bin window. Those events are emitted when the bin window is left on the bottom side or the left/right side as well as when the header window is left on the top side or the left/right side. The Leave and Enter event is also emitted when a row is dragged, a header column is dragged or when a child of the treeview widget is entered. This seems logical to me as the focus is not on the treeview anymore but on the dragwindow or on the child widget. The patched code is clearly identified by comments "bug 565559" and "bug 565559 - end".
(In reply to comment #0) > OpenSuSE 11.0 and 11.1 > > I am using a treeview to display a small table. See the ascii drawing > below. > > 1. I get leave-notify signals when I move the pointer from the main > area ("A") to the header area ("B"). That's wrong. This is actually correct. The pointer moves into a new GdkWindow and thus the current GdkWindow is left, because of this a leave-notify signal is sent. I agree that the API is confusing here. A leave-notify-event happens on a GdkWindow, and it is emitted on the widget this window belongs to. There is a case to be made for an additional leave-notify signal that corresponds to just the widget and not windows. > 2. I do not get them when I move from the header area to the > outside. That's very wrong. This is fixed by the following patch: diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 93bb688..139687a 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -1811,6 +1811,8 @@ gtk_tree_view_realize (GtkWidget *widget) attributes.height = tree_view->priv->header_height; attributes.event_mask = (GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | Note that this will cause two leave-notify events to be sent when moving the mouse upwards: one for leaving bin_window and going to the header, and one for moving from the header to "outside". These events can be distinguished by comparing the window field in the events.
(In reply to comment #1) > I have added a patch that performs exactly this behavior. I have implemented > this patch on top of another patch I submitted before (71926). Leave and Enter > events are suppressed when the mouse moves between the header window and the > bin window. Those events are emitted when the bin window is left on the bottom > side or the left/right side as well as when the header window is left on the > top side or the left/right side. As I have explained in section 2, these events should not be suppressed. I will look into committing the proposed patch in commit 2 on master soon.
> This is actually correct. The pointer moves into a new GdkWindow and > thus the current GdkWindow is left, because of this a leave-notify > signal is sent. This really looks like details of the implementation are showing. If an implementation decided to use multiple windows for A and/or Bs, would it be correct to observe leave-notify going from one part of A to another?
(In reply to comment #4) > This really looks like details of the implementation are showing. That is correct, unfortunately the details of the implementation are showing here. > If an implementation decided to use multiple windows for A and/or > Bs, would it be correct to observe leave-notify going from one > part of A to another? Yes, because leave-notify event are emitted for windows (but through a widget). If a widget has multiple windows, there will be multiple leave-notify events. Refer to GtkCalendar for an obscure example, its implementation employs multiple windows ... Multiple widgets are showing this behavior. A way to correct this would be to make GDK more abstract in this sense and to have a new leave-notify signal that relates to widgets and not windows. The current behavior is really an artifact of the X11-ness of GDK ...
Committed patch in comment 2 on 2.22 and 2.90 branches.