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 335707 - notebook DND with event boxes in tab labels
notebook DND with event boxes in tab labels
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: Other
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2006-03-23 17:05 UTC by Christian Persch
Modified: 2011-02-04 16:10 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
testcase as patch for testnotebookdnd.c (1.48 KB, text/plain)
2006-03-23 17:05 UTC, Christian Persch
  Details
patch (4.51 KB, patch)
2006-03-24 13:07 UTC, Carlos Garnacho
committed Details | Review
a patch (58.62 KB, patch)
2006-04-07 20:19 UTC, Carlos Garnacho
none Details | Review
another patch (58.86 KB, patch)
2006-04-07 21:36 UTC, Carlos Garnacho
none Details | Review
new patch, with some optimization (64.87 KB, patch)
2006-04-10 12:14 UTC, Carlos Garnacho
none Details | Review
updated patch (66.33 KB, patch)
2006-04-19 14:45 UTC, Carlos Garnacho
none Details | Review
new patch (75.99 KB, patch)
2006-05-06 14:08 UTC, Carlos Garnacho
none Details | Review
updated patch (79.92 KB, patch)
2006-05-09 01:10 UTC, Carlos Garnacho
none Details | Review

Description Christian Persch 2006-03-23 17:05:17 UTC
The notebook DND has weird bugs when the tab label contains a GtkEventBox:
- extreme flickering while dragging the tab, and
- the tab doesn't follow the mouse directly, but lags it instead

Attaching testcase.
Comment 1 Christian Persch 2006-03-23 17:05:45 UTC
Created attachment 61857 [details]
testcase as patch for testnotebookdnd.c
Comment 2 Matthias Clasen 2006-03-23 17:49:09 UTC
Carlos, can you look at that ?
Comment 3 Carlos Garnacho 2006-03-23 18:11:10 UTC
sure! I'm on it
Comment 4 Carlos Garnacho 2006-03-24 13:07:55 UTC
Created attachment 61912 [details] [review]
patch

with this patch the tabs follow the pointer properly, and all flickering is avoided.

A side effect of using event boxes as tab labels is that they get expose events independently of the notebook, so they overlap while reordering (both with other tab labels and with the tab extensions drawn by the notebook), due to the impossibility of imposing a drawing order, the only workaround I've seen is setting "visible-window" to FALSE. This is done already by gnome-terminal, ephy and gedit, so they wouldn't be affected.

Now my question is: should I try to avoid this somehow (I really don't know how) or should it just be considered another case where the event box could cause artifacts?
Comment 5 Matthias Clasen 2006-03-24 22:08:08 UTC
hmm, yes thats ugly.
I guess you could perhaps create an extra window and move that, that might
help. Check out how the treeview does header reordering...
Comment 6 Carlos Garnacho 2006-03-28 17:07:09 UTC
Thanks for the tip, Matthias :), I'm working on it already, but it will require a completely different approach, right now I'm focusing on refactoring a bit the code (specially the gtk_notebook_pages_allocate beast), I think it will help to make the whole task easier...

In the meantime, I think it could be good to apply this patch, at least it will work for ephy, g-t, and gedit
Comment 7 Matthias Clasen 2006-03-28 18:11:16 UTC
Makes sense. Feel free to commit the bandaid fix
Comment 8 Matthias Clasen 2006-03-29 03:46:48 UTC
Turns out I already committed the fix in comment #4.
Comment 9 Carlos Garnacho 2006-04-07 20:19:26 UTC
Created attachment 62951 [details] [review]
a patch

Summary of changes:
- gtk_notebook_pages_allocate() code has been splitted into gtk_notebook_tab_space(), gtk_notebook_calculate_shown_tabs() and gtk_notebook_calculate_tabs_allocation(), some of the code here has been improved/modified, but most of it is still the same. I think this has made the code much more hacker-friendly
- now the reordered tab is shown in an independent GdkWindow. The drawing code has been slightly modified to draw there when it's necessary
- the default DnD icon has been improved, it's now a copy of the new GdkWindow

I've been testing it with apps and testnotebookdnd and I can't appreciate regressions, and works fine with the testcase too
Comment 10 Carlos Garnacho 2006-04-07 21:36:07 UTC
Created attachment 62956 [details] [review]
another patch

Oops, it seems I managed to delete more code than necessary in my last cleanup, this patch fixes DnD icon creation with tab_labels with their own GdkWindow (it seems to be broken too in the current code, sorry...). but AFAICT it won't manage to copy child GdkWindow contents (if tab_label has any), am I wrong? recursing through GdkWindow's seems too much for just creating a DnD icon...
Comment 11 Matthias Clasen 2006-04-08 04:29:59 UTC
I only had occasion to test this remotely so far, and it felt pretty unusable.
Sometimes the dragged tab stayed black, and the non-dragged tabs would only redraw 
with a big delay. Also, button release only stopped the drag with a big delay.
(admittedly, the current version does not feel much better when used remotely)

Regarding the copying of the window contents for a drag icon, have you considered
simply using the drag window as the drag icon, using gtk_drag_set_icon_widget ?
You'd have to turn it into a GtkWindow for that, of course.
Comment 12 Carlos Garnacho 2006-04-10 12:13:49 UTC
Ugh, right...

I've been investigating using the tc trick that Federico posted [1] and found out that the main culprit seems to be the call to gdk_window_get_pointer() (and thus to XQueryPointer) in the ::motion-notify handler [2].

To improve this I've used the GdkEvent coordinates, but (I don't know if there's something wrong in my setup) with some latency enabled the event coordinates were extremely unreliable (i.e.: having strange values) not only in this case, treeview column reordering from testtreeview also behaved wrongly.

I've also improved gtk_notebook_pages_allocate() for not making superfluous calls to gtk_notebook_redraw_tabs(), which invalidates the tabs area.

I've still got to investigate gtk_drag_set_icon_widget(), but it seems that detaching completely the tab_label widget from the notebook to create an independent window will require more changes to the code, and it was quite pretty to draw the tab border :)

[1] http://primates.ximian.com/~federico/news-2006-03.html#24
[2] selection in GtkTextView and GtkIconView seem to be affected too
Comment 13 Carlos Garnacho 2006-04-10 12:14:55 UTC
Created attachment 63100 [details] [review]
new patch, with some optimization
Comment 14 Carlos Garnacho 2006-04-19 14:45:35 UTC
Created attachment 63870 [details] [review]
updated patch

Fixes a defect with expanded tabs that was introduced in the refactor, plus other slight code improvements.

I still seem to be able to reproduce the GdkEvent coordinates problem, haven't found any cause, though... It'd be great if the patch were tested in a real network environment
Comment 15 Matthias Clasen 2006-04-19 17:07:40 UTC
Hmm, trying the tc trick to simulate latency hangs my system.
So, I'll give it a remote test run from home tonight.
In principle, the patch looks ok, there is one problem that
is going to be hard to fix: if you position the notebook so that 
part of a  tab label is offscreen, and then start a drag, you get
garbage in the drag icon for the offscreen parts.
Comment 16 Matthias Clasen 2006-04-19 17:12:14 UTC
Note that that problem already exists with the current code, though, so
its not a regression. 
Comment 17 Matthias Clasen 2006-04-20 04:15:12 UTC
Hmm, I see what you mean now, both for the notebook tab reordering and
treeview column reordering, latency kills it.
Comment 18 Carlos Garnacho 2006-04-20 09:55:11 UTC
Maybe It's a silly theory, but might the cause be a glitch in the drag_window position between the creation of the ::motion-notify event and the event dispatch?

I'm not sure if it's even possible, but can't think of a better cause...
Comment 19 Carlos Garnacho 2006-05-06 14:08:21 UTC
Created attachment 64925 [details] [review]
new patch

Sorry for the delay handling this bug, here's a new patch with the following new features:

- uses gtk_drag_set_icon_widget, reparenting the tab label to a window, this fixes the "garbage in offscreen parts" case. Also fixes the issue raised in comment #10. Of course, the tab_label is reparented again to the notebook before the drag window is destroyed
- fixes here and there to make the notebook aware that it could not be the parent of tab_label.
- To avoid an annoying borderless drag icon, the expose handler is modified to draw the tab extension in the DnD window
- Other small code improvements
Comment 20 Matthias Clasen 2006-05-08 20:11:34 UTC
Big patch. It would be easier to review if the refactoring bits were broken out, but lets try anyway...

The behaviour seems good, ie no garbage anymore.

Some comments on style (I notice that you just copied existing
things...)

As a matter of principle, I always add a /* fall thru */
comment if a break is intentionally missing.

+    case GTK_POS_TOP:
+      y += page->allocation.height;
+    case GTK_POS_BOTTOM:
+      height -= page->allocation.height;
+      break;
+    case GTK_POS_LEFT:
+      x += page->allocation.width;
+    case GTK_POS_RIGHT:
+      width -= page->allocation.width;
+      break;


extraneous parens here:

+	    gap_x = (notebook->cur_page->allocation.x - widget->allocation.x - border_width);


missing space before (

+      gtk_paint_extension(widget->style, window,


missing spaces around comment text
+      /*unmap all non-visible tabs*/


With those changes, I think it should be fine to commit.
Comment 21 Carlos Garnacho 2006-05-09 01:10:58 UTC
Created attachment 65059 [details] [review]
updated patch

Yeah, sorry about the big patch, it should have been definitely a 2 step process, but has helped a lot to make these changes (and will help too for future improvements)

gtk_notebook_pages_allocate() was splitted into subtasks, but almost all of its codebase is unchanged to avoid new bugs, I already found other similar style issues that were fixed, but it seems I didn't spot all the offenders...

The attached patch fixes the style issues you raised and other small ones found through grep and code reading
Comment 22 Matthias Clasen 2006-05-09 01:55:53 UTC
thanks, please commit
Comment 23 Carlos Garnacho 2006-05-09 02:36:42 UTC
Thanks!

2006-05-09  Carlos Garnacho  <carlosg@gnome.org>

        * gtk/gtknotebook.c: create an independent GdkWindow to behave nicely
        during reordering with tab_labels with their own window, also use
        gtk_drag_set_icon_widget() for the DnD icon to avoid drawing garbage
        from offscreen regions. Closes bug #335707.
        (gtk_notebook_tab_space), (gtk_notebook_calculate_shown_tabs),
        (gtk_notebook_calculate_tabs_allocation): new functions,
        gtk_notebook_pages_allocate() functionality has been splitted into
        these.