Merge lp:~vanvugt/unity/fix-687567-unity3.0 into lp:unity/3.0

Proposed by Daniel van Vugt
Status: Merged
Merged at revision: 1207
Proposed branch: lp:~vanvugt/unity/fix-687567-unity3.0
Merge into: lp:unity/3.0
Diff against target: 146 lines (+37/-66)
1 file modified
services/panel-service.c (+37/-66)
To merge this branch: bzr merge lp:~vanvugt/unity/fix-687567-unity3.0
Reviewer Review Type Date Requested Status
Neil J. Patel (community) Approve
Review via email: mp+67816@code.launchpad.net

Description of the change

Fix white "flashes" seen in the panel menus during scrubbing, or when they're unmapped (LP: #687567)

The problem, it seems, was that we were calling gdk/gtk/X11 functions in the middle of a GDK event filter. Removing these function calls and replacing them with a simpler, more optimized solution solves the problem.

I'm proposing this fix to unity 3.0 first because it was developed and tested on natty. I will forward port it to unity trunk (requires some conflict resolution) after this version has been approved.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

And before someone suggests the bug was a timing issue, it wasn't. I tried inserting delays in the affected code and it made no difference. Only removing the gdk/gtk/X calls fixed the problem.

Revision history for this message
Neil J. Patel (njpatel) wrote :

*hattips*

Very, very nice merge :) I couldn't compile old Unity on my system so couldn't test your branch but I did a quick port of your work to the latest unity (diff: http://paste.ubuntu.com/643341/) and it works perfectly!

If you want to merge-propose something for trunk, I'll compile and test this on my natty desktop this evening.

Revision history for this message
Neil J. Patel (njpatel) wrote :

Works perfectly, approved.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'services/panel-service.c'
2--- services/panel-service.c 2011-04-10 23:51:05 +0000
3+++ services/panel-service.c 2011-07-13 14:24:24 +0000
4@@ -55,6 +55,10 @@
5 guint32 last_menu_move_id;
6 gint32 last_x;
7 gint32 last_y;
8+ gint last_left;
9+ gint last_top;
10+ gint last_right;
11+ gint last_bottom;
12 guint32 last_menu_button;
13
14 gint last_menu_x;
15@@ -220,84 +224,29 @@
16 if (!GTK_IS_WIDGET (self->priv->last_menu))
17 return ret;
18
19- if (e->type == 5 && self->priv->last_menu_button != 0) //FocusChange
20+ // Don't call any gdk/gtk/X functions in here or you risk creating graphical
21+ // glitches (LP: #687567) and of course slowing down event processing.
22+ if (e->type == ButtonRelease && self->priv->last_menu_button != 0)
23 {
24- gint x=0, y=0, width=0, height=0, depth=0, x_root=0, y_root=0;
25- GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (self->priv->last_menu));
26- if (window == NULL)
27- return GDK_FILTER_CONTINUE;
28-
29- Window xwindow = gdk_x11_drawable_get_xid (GDK_DRAWABLE (window));
30-
31- if (xwindow == 0)
32- return GDK_FILTER_CONTINUE;
33-
34- Window root = 0, child = 0;
35- int win_x=0, win_y = 0;
36- guint32 mask_return = 0;
37-
38- XQueryPointer (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
39- xwindow,
40- &root,
41- &child,
42- &x_root,
43- &y_root,
44- &win_x,
45- &win_y,
46- &mask_return);
47-
48- gdk_window_get_geometry (window, &x, &y, &width, &height, &depth);
49- gdk_window_get_origin (window, &x, &y);
50-
51- if (x_root > x
52- && x_root < x + width
53- && y_root > y
54- && y_root < y + height)
55- {
56- ret = GDK_FILTER_CONTINUE;
57- }
58- else
59+ if (e->xbutton.x_root < self->priv->last_left ||
60+ e->xbutton.x_root > self->priv->last_right ||
61+ e->xbutton.y_root < self->priv->last_top ||
62+ e->xbutton.y_root > self->priv->last_bottom)
63 {
64 ret = GDK_FILTER_REMOVE;
65 }
66
67 self->priv->last_menu_button = 0;
68 }
69-
70- // FIXME: THIS IS HORRIBLE AND WILL BE CHANGED BEFORE RELEASE
71- // ITS A WORKAROUND SO I CAN TEST THE PANEL SCRUBBING
72- // DONT HATE ME
73- // --------------------------------------------------------------------------
74- else if (e->type == 6)
75+ else if (e->type == MotionNotify)
76 {
77- int x_root=0, y_root=0;
78- GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (self->priv->last_menu));
79- Window xwindow = gdk_x11_drawable_get_xid (GDK_DRAWABLE (window));
80- Window root = 0, child = 0;
81- int win_x=0, win_y = 0;
82- guint32 mask_return = 0;
83-
84- XQueryPointer (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
85- xwindow,
86- &root,
87- &child,
88- &x_root,
89- &y_root,
90- &win_x,
91- &win_y,
92- &mask_return);
93-
94- self->priv->last_menu_x = x_root;
95- self->priv->last_menu_y = y_root;
96-
97- if (y_root <= self->priv->last_y)
98+ self->priv->last_menu_x = e->xmotion.x_root;
99+ self->priv->last_menu_y = e->xmotion.y_root;
100+ if (self->priv->last_menu_y <= self->priv->last_y)
101 {
102 g_signal_emit (self, _service_signals[ACTIVE_MENU_POINTER_MOTION], 0);
103 }
104 }
105- // /DONT HATE ME
106- // /FIXME
107- // --------------------------------------------------------------------------
108 return ret;
109 }
110
111@@ -852,6 +801,10 @@
112 priv->last_menu_id = 0;
113 priv->last_menu_move_id = 0;
114 priv->last_entry = NULL;
115+ priv->last_left = 0;
116+ priv->last_right = 0;
117+ priv->last_top = 0;
118+ priv->last_bottom = 0;
119
120 g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, "");
121 }
122@@ -1149,6 +1102,24 @@
123
124 indicator_object_entry_activate (object, entry, CurrentTime);
125 gtk_menu_popup (priv->last_menu, NULL, NULL, positon_menu, self, 0, CurrentTime);
126+ GdkWindow *gdkwin = gtk_widget_get_window (GTK_WIDGET (priv->last_menu));
127+ if (gdkwin != NULL)
128+ {
129+ gint left, top, width, height;
130+ gdk_window_get_geometry (gdkwin, NULL, NULL, &width, &height, NULL);
131+ gdk_window_get_origin (gdkwin, &left, &top);
132+ priv->last_left = left;
133+ priv->last_right = left + width - 1;
134+ priv->last_top = top;
135+ priv->last_bottom = top + height - 1;
136+ }
137+ else
138+ {
139+ priv->last_left = 0;
140+ priv->last_right = 0;
141+ priv->last_top = 0;
142+ priv->last_bottom = 0;
143+ }
144
145 g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, entry_id);
146 }

Subscribers

People subscribed via source and target branches

to all changes: