After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 341571 - tabs too easily reordered
tabs too easily reordered
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkNotebook
2.9.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2006-05-12 18:43 UTC by Diego González
Modified: 2011-02-04 16:10 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
proposed patch (11.88 KB, patch)
2006-05-31 17:17 UTC, Carlos Garnacho
none Details | Review
updated patch (17.15 KB, patch)
2006-06-02 11:46 UTC, Carlos Garnacho
none Details | Review
updated patch, now compiles agains HEAD, plus other small fixes (17.27 KB, patch)
2006-06-15 16:35 UTC, Carlos Garnacho
committed Details | Review

Description Diego González 2006-05-12 18:43:18 UTC
when clicking over a tab somehow it thinks i'm dragging it when i only want to bring that tab  to the front. After clicking on the tab i move the mouse of out it, and it starts moving getting crazy.

Also if i actually want to drag the tab the movement is very unpleasant it move too fast and sometimes shakes...
Comment 1 Christian Persch 2006-05-12 21:17:38 UTC
I see this too.

If I'm moving the mouse left-right over the tab labels and do a quick left-click, I can get into a mode where the tab is sliding with the mouse even though the button isn't pressed anymore!

-> gtk+
Comment 2 Carlos Garnacho 2006-05-14 15:19:09 UTC
I've been investigating these issues:

- the "shaking" movement looks exactly the same than the stated in comment #12 from bug #335707. It appeared when I began using the GdkEvent coordinates to avoid gdk_window_get_pointer() calls from ::motion-notify (synchronous and network unfriendly), with some latency, the event coordinates relative to a moving GdkWindow were unreliable, and hence the "shaking" effect when moving the window to the new position.

some investigation has shown me that during normal tabs movement, the ::motion-notify handler is called ~100 times per second in my computer, and that number may even grow.

So my proposed solution would be to limit it to a saner ammount (say ~30 times per second) and use the totally reliable gdk_window_get_pointer, that will get rid of the "shaking" effect, and hopefully would be more network friendly.

- regarding comment #2, curiously the BUTTON_RELEASE_EVENT gets swallowed at some point, because it doesn't even enter in the GtkNotebook handler, and the drag isn't terminated. I'm a bit puzzled by this.

comments/ideas?
Comment 3 Matthias Clasen 2006-05-15 17:09:32 UTC
we should avoid get_pointer roundtrips, if at all possible 
Comment 4 Federico Mena Quintero 2006-05-30 16:24:35 UTC
It would be good to know when the BUTTON_RELEASE gets dropped.  Set a breakpoint in gdk/x11/gdkevents-x11.c:gdk_event_translate() on the case where it processes ButtonRelease, and trace the program from there to see if GTK+ drops the event.

Also, consider watching the event->state of your motion events.  (event->state & GDK_BUTTON1_MASK) will be turned on while the button is down, and off when the button is released.  You can use that to know if the button was released.
Comment 5 Carlos Garnacho 2006-05-30 23:40:43 UTC
Oh, thanks Federico for the clues :), I already found gdk_event_translate() the hard way through grepping for gdk_event_new() and some code learning, I wasn't aware of event->state until now, thanks heaps for this :).

It turns out that the event gets filtered in this code segment: 

if (window_private && GDK_WINDOW_DESTROYED (window))
  {
    if (xevent->type != DestroyNotify)
      {
        return_val = FALSE;
        goto done;
      }
  }

so the window that's receiving the ButtonRelease event is destroyed (evidently it's not the GdkWindow I expected to get the event), after all my debugging I couldn't know which GdkWindow is getting the event, my guess is that it's one inside tab_label (it's unrealized and reparented to get drawn inside drag_window)

I think I'll take the more reliable event->state path, unless you tell me that what I've described is a blatant bug :)
Comment 6 Carlos Garnacho 2006-05-31 17:17:23 UTC
Created attachment 66550 [details] [review]
proposed patch

- uses gdk_window_get_pointer()
- limits the ammount of drag_window repositioning (and thus, of gdk_window_get_pointer() calls) to a maximum of 45 times per second. Actually it gets drawn between 28 and 36 times per second in this computer. This reduces CPU use and hopefully will be more network friendly.
- also stops the drag operation if event->state & GDK_BUTTON1_MASK is false in ::motion-notify-event
- Takes into account the pointer offset inside the tab when beginning a drag operation, this gets rid of the "tab jumps to mouse position" sensation
- Gets rid of gtk_notebook_redraw_tabs_union(), I could see artifacts with it (rarely), and the performance gain seemed quite small...
- Also contains the fix I suggested for bug #168105

I'll try to find out what could make event coordinates unreliable, so not only GtkNotebook could benefit from this, but also the other gdk_window_get_pointer()-during-motion-events users (GtkIconView and GtkTextView, from what I could see...)
Comment 7 Matthias Clasen 2006-06-01 16:42:52 UTC
I haven't reviewed the patch in detail, but while testing it, a number
of beauty warts showed up.

- if the drag fails, the cancel animation just shows a gray tab, while the
tab label gets immediately reparented back. It would be much nicer if we could
reparent it back when the animation is done.

- when dragging "lemonade" up to the northwest notebook, I noticed that it
occasionally shoots over a bit (ie it gets drawn a few pixels outside of the
east border of the notebook. And when tearing it off again, a small artifact
is left behind there.
Comment 8 Carlos Garnacho 2006-06-02 11:46:38 UTC
Created attachment 66656 [details] [review]
updated patch

Fixes the first issue commented by Matthias, plus some fixes related to detachable and not reorderable tabs.

Matthias, I haven't been able to reproduce your second issue, moving the "lemonade" tab here doesn't make tabs arrive to the east border, and moving more tabs make the arrows appear. Could that be related somehow to bug #168105?
Comment 9 Carlos Garnacho 2006-06-15 16:35:08 UTC
Created attachment 67437 [details] [review]
updated patch, now compiles agains HEAD, plus other small fixes
Comment 10 Matthias Clasen 2006-06-15 17:28:30 UTC
Works much better. Can you commit it, please ?
Comment 11 Carlos Garnacho 2006-06-15 18:48:05 UTC
Committed, thanks :)

2006-06-15  Carlos Garnacho  <carlosg@gnome.org>

        * gtk/gtknotebook.c (gtk_notebook_motion_notify): use
        gdk_window_get_pointer() to get pointer coordinates, but limit its
        calls to a maximum of 45 times per second for not being too
        CPU/network abusive. stop drag operation if (event->state &
        GDK_BUTTON1_MASK) is FALSE to prevent tabs from "adhering" to the
        pointer. Fixes bug #341571
        (gtk_notebook_calculate_tabs_allocation), (gtk_notebook_button_press):
        get rid of the "tab jumps to pointer" sensation when beginning a drag
        by using the pointer offset in the tab when the drag begins as an
        anchor.
        (gtk_notebook_redraw_tabs_union): remove, it wasn't worth the little
        performance gain and could draw artifacts under some circumstances.
        (gtk_notebook_drag_end): do not reparent the detached tab label until
        the animation has ended.