Merge lp:~vanvugt/unity/fix-742664-trunk into lp:unity

Proposed by Daniel van Vugt
Status: Merged
Approved by: Neil J. Patel
Approved revision: no longer in the source branch.
Merged at revision: 1325
Proposed branch: lp:~vanvugt/unity/fix-742664-trunk
Merge into: lp:unity
Diff against target: 289 lines (+46/-89)
8 files modified
UnityCore/DBusIndicators.cpp (+0/-7)
UnityCore/Indicators.h (+0/-8)
plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp (+9/-5)
plugins/unityshell/src/PanelView.cpp (+36/-2)
plugins/unityshell/src/PanelView.h (+1/-0)
services/panel-main.c (+0/-32)
services/panel-service.c (+0/-31)
services/panel-service.h (+0/-4)
To merge this branch: bzr merge lp:~vanvugt/unity/fix-742664-trunk
Reviewer Review Type Date Requested Status
Neil J. Patel (community) Approve
Andrea Azzarone (community) Needs Fixing
Review via email: mp+69751@code.launchpad.net

Description of the change

Make panel menus more responsive, less laggy, when scrubbing. Removed logic that used to send pointer motion events over dbus. (LP: #742664)

Currently unity-panel-service receives all pointer motion (scrubbing) events and sends them ALL to unity(compiz) via dbus. unity(compiz) then decides which indicator/menu this is and sends a message back to unity-panel-service telling it which menu to display. Once the menu is visible unity-panel-service sends another message back to unity(compiz) so it can then display the panel menu background. So that's 3 interprocess communication stages for every motion event. Not to mention the fact that it's responding to every single motion event which is known to be bad practice in GUI design.

This proposal reduces the number of interprocess communication stages between pointer movement and the panel repainting from 3 to 0 (but still 1 for the menu to draw). So the end result is that indicators and panel menus feel much more responsive and always draw where the mouse pointer actually is.

Disclaimer: I developed and tested this fix on nattywith unity 3. I have only hand-ported it to unity-4 and made sure it builds in oneiric. So there has been no functional testing on oneiric yet, only natty.

To post a comment you must log in.
Revision history for this message
Andrea Azzarone (azzar1) wrote :

Review: Need Fixing

87 +static
88 +gboolean
89 +track_menu_pointer (gpointer data)

Should be

static gboolean track_menu_pointer(gpointer data).

91 + PanelView *self = (PanelView*)data;

Please avoid C cast.

93 + gdk_display_get_pointer (gdk_display_get_default (), NULL, &x, &y, NULL);

Please no space between the function name and the open parenthesis.

_menu_view->AllMenusClosed ();

The same applies here.

Please note that I have reviewed only the style roughly.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

A C cast is correct for gpointer data because it is the parameter to a C callback (g_timeout_add). Not C++.

And I agree with no space after function names. Was only copying the style that the unity code already used :)

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

Excellent work.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UnityCore/DBusIndicators.cpp'
--- UnityCore/DBusIndicators.cpp 2011-07-21 20:24:04 +0000
+++ UnityCore/DBusIndicators.cpp 2011-07-29 08:57:18 +0000
@@ -438,13 +438,6 @@
438 RequestSyncAll();438 RequestSyncAll();
439 }439 }
440 }440 }
441 else if (signal_name == "ActiveMenuPointerMotion")
442 {
443 int x = 0;
444 int y = 0;
445 g_variant_get(parameters, "(ii)", &x, &y);
446 owner_->on_menu_pointer_moved.emit(x, y);
447 }
448 else if (signal_name == "EntryShowNowChanged")441 else if (signal_name == "EntryShowNowChanged")
449 {442 {
450 gchar* id = NULL;443 gchar* id = NULL;
451444
=== modified file 'UnityCore/Indicators.h'
--- UnityCore/Indicators.h 2011-07-21 20:24:04 +0000
+++ UnityCore/Indicators.h 2011-07-29 08:57:18 +0000
@@ -64,14 +64,6 @@
64 sigc::signal<void, Indicator::Ptr const&> on_object_removed;64 sigc::signal<void, Indicator::Ptr const&> on_object_removed;
6565
66 /**66 /**
67 * This signal is emitted when an entry is activated and the user moves the
68 * mouse.
69 * @param x x coordinate
70 * @param y y coordinate
71 */
72 sigc::signal<void, int, int> on_menu_pointer_moved;
73
74 /**
75 * Service wants the view to activate an entry.67 * Service wants the view to activate an entry.
76 * Example use-case: user has activated an entry with the mouse and pressed68 * Example use-case: user has activated an entry with the mouse and pressed
77 * Left or Right key to activate previous or next entry.69 * Left or Right key to activate previous or next entry.
7870
=== modified file 'plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp'
--- plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp 2011-07-22 14:04:58 +0000
+++ plugins/unityshell/src/PanelIndicatorObjectEntryView.cpp 2011-07-29 08:57:18 +0000
@@ -101,11 +101,15 @@
101 GetAbsoluteY() + PANEL_HEIGHT,101 GetAbsoluteY() + PANEL_HEIGHT,
102 time(NULL),102 time(NULL),
103 nux::GetEventButton(button_flags));103 nux::GetEventButton(button_flags));
104 }104 proxy_->set_active(true);
105 else105 //
106 {106 // ^ Set active even before the menu appears. This allows the below
107 Refresh();107 // Refresh call to know it should draw_menu_bg() immediately
108 }108 // rather than waiting for slow inter-process communication with
109 // unity-panel-service, which causes visible lag in many cases.
110 //
111 }
112 Refresh();
109}113}
110114
111void PanelIndicatorObjectEntryView::OnMouseUp(int x, int y, long button_flags, long key_flags)115void PanelIndicatorObjectEntryView::OnMouseUp(int x, int y, long button_flags, long key_flags)
112116
=== modified file 'plugins/unityshell/src/PanelView.cpp'
--- plugins/unityshell/src/PanelView.cpp 2011-07-28 11:02:56 +0000
+++ plugins/unityshell/src/PanelView.cpp 2011-07-29 08:57:18 +0000
@@ -79,7 +79,6 @@
7979
80 _remote = indicator::DBusIndicators::Ptr(new indicator::DBusIndicators());80 _remote = indicator::DBusIndicators::Ptr(new indicator::DBusIndicators());
81 _remote->on_object_added.connect(sigc::mem_fun(this, &PanelView::OnObjectAdded));81 _remote->on_object_added.connect(sigc::mem_fun(this, &PanelView::OnObjectAdded));
82 _remote->on_menu_pointer_moved.connect(sigc::mem_fun(this, &PanelView::OnMenuPointerMoved));
83 _remote->on_entry_activate_request.connect(sigc::mem_fun(this, &PanelView::OnEntryActivateRequest));82 _remote->on_entry_activate_request.connect(sigc::mem_fun(this, &PanelView::OnEntryActivateRequest));
84 _remote->on_entry_activated.connect(sigc::mem_fun(this, &PanelView::OnEntryActivated));83 _remote->on_entry_activated.connect(sigc::mem_fun(this, &PanelView::OnEntryActivated));
85 _remote->on_synced.connect(sigc::mem_fun(this, &PanelView::OnSynced));84 _remote->on_synced.connect(sigc::mem_fun(this, &PanelView::OnSynced));
@@ -100,10 +99,14 @@
100 this);99 this);
101 // request the latest colour from bghash100 // request the latest colour from bghash
102 ubus_server_send_message (ubus, UBUS_BACKGROUND_REQUEST_COLOUR_EMIT, NULL);101 ubus_server_send_message (ubus, UBUS_BACKGROUND_REQUEST_COLOUR_EMIT, NULL);
102
103 _track_menu_pointer_id = 0;
103}104}
104105
105PanelView::~PanelView()106PanelView::~PanelView()
106{107{
108 if (_track_menu_pointer_id)
109 g_source_remove(_track_menu_pointer_id);
107 _style->UnReference();110 _style->UnReference();
108 UBusServer *ubus = ubus_server_get_default();111 UBusServer *ubus = ubus_server_get_default();
109 ubus_server_unregister_interest(ubus, _handle_bg_color_update);112 ubus_server_unregister_interest(ubus, _handle_bg_color_update);
@@ -343,10 +346,41 @@
343 }346 }
344}347}
345348
349static gboolean track_menu_pointer(gpointer data)
350{
351 PanelView *self = (PanelView*)data;
352 gint x, y;
353 gdk_display_get_pointer(gdk_display_get_default(), NULL, &x, &y, NULL);
354 self->OnMenuPointerMoved(x, y);
355 return TRUE;
356}
357
346void PanelView::OnEntryActivated(std::string const& entry_id)358void PanelView::OnEntryActivated(std::string const& entry_id)
347{359{
348 if (entry_id == "")360 bool active = (entry_id.size() > 0);
361 if (active && !_track_menu_pointer_id)
362 {
363 //
364 // Track menus being scrubbed at 60Hz (about every 16 millisec)
365 // It might sound ugly, but it's far nicer (and more responsive) than the
366 // code it replaces which used to capture motion events in another process
367 // (unity-panel-service) and send them to us over dbus.
368 // NOTE: The reason why we have to use a timer instead of tracking motion
369 // events is because the motion events will never be delivered to this
370 // process. All the motion events will go to unity-panel-service while
371 // scrubbing because the active panel menu has (needs) the pointer grab.
372 //
373 _track_menu_pointer_id = g_timeout_add(16, track_menu_pointer, this);
374 }
375 else if (!active)
376 {
377 if (_track_menu_pointer_id)
378 {
379 g_source_remove(_track_menu_pointer_id);
380 _track_menu_pointer_id = 0;
381 }
349 _menu_view->AllMenusClosed();382 _menu_view->AllMenusClosed();
383 }
350}384}
351385
352void PanelView::OnSynced()386void PanelView::OnSynced()
353387
=== modified file 'plugins/unityshell/src/PanelView.h'
--- plugins/unityshell/src/PanelView.h 2011-07-28 11:02:56 +0000
+++ plugins/unityshell/src/PanelView.h 2011-07-29 08:57:18 +0000
@@ -116,6 +116,7 @@
116 guint _handle_dash_hidden;116 guint _handle_dash_hidden;
117 guint _handle_dash_shown;117 guint _handle_dash_shown;
118 guint _handle_bg_color_update;118 guint _handle_bg_color_update;
119 guint _track_menu_pointer_id;
119};120};
120121
121}122}
122123
=== modified file 'services/panel-main.c'
--- services/panel-main.c 2011-07-21 20:24:04 +0000
+++ services/panel-main.c 2011-07-29 08:57:18 +0000
@@ -85,11 +85,6 @@
85 " <arg type='s' name='indicator_id' />"85 " <arg type='s' name='indicator_id' />"
86 " </signal>"86 " </signal>"
87 ""87 ""
88 " <signal name='ActiveMenuPointerMotion'>"
89 " <arg type='i' name='x' />"
90 " <arg type='i' name='y' />"
91 " </signal>"
92 ""
93 " <signal name='EntryActivateRequest'>"88 " <signal name='EntryActivateRequest'>"
94 " <arg type='s' name='entry_id' />"89 " <arg type='s' name='entry_id' />"
95 " </signal>"90 " </signal>"
@@ -254,30 +249,6 @@
254}249}
255250
256static void251static void
257on_service_active_menu_pointer_motion (PanelService *service,
258 GDBusConnection *connection)
259{
260 GError *error = NULL;
261 gint x=0, y=0;
262
263 panel_service_get_last_xy (service, &x, &y);
264
265 g_dbus_connection_emit_signal (connection,
266 S_NAME,
267 S_PATH,
268 S_IFACE,
269 "ActiveMenuPointerMotion",
270 g_variant_new ("(ii)", x, y),
271 &error);
272
273 if (error)
274 {
275 g_warning ("Unable to emit ActiveMenuPointerMotionsignal: %s", error->message);
276 g_error_free (error);
277 }
278}
279
280static void
281on_service_entry_activate_request (PanelService *service,252on_service_entry_activate_request (PanelService *service,
282 const gchar *entry_id,253 const gchar *entry_id,
283 GDBusConnection *connection)254 GDBusConnection *connection)
@@ -339,8 +310,6 @@
339 G_CALLBACK (on_service_resync), connection);310 G_CALLBACK (on_service_resync), connection);
340 g_signal_connect (service, "entry-activated",311 g_signal_connect (service, "entry-activated",
341 G_CALLBACK (on_service_entry_activated), connection);312 G_CALLBACK (on_service_entry_activated), connection);
342 g_signal_connect (service, "active-menu-pointer-motion",
343 G_CALLBACK (on_service_active_menu_pointer_motion), connection);
344 g_signal_connect (service, "entry-activate-request",313 g_signal_connect (service, "entry-activate-request",
345 G_CALLBACK (on_service_entry_activate_request), connection);314 G_CALLBACK (on_service_entry_activate_request), connection);
346 g_signal_connect (service, "entry-show-now-changed",315 g_signal_connect (service, "entry-show-now-changed",
@@ -370,7 +339,6 @@
370 {339 {
371 g_signal_handlers_disconnect_by_func (service, on_service_resync, connection);340 g_signal_handlers_disconnect_by_func (service, on_service_resync, connection);
372 g_signal_handlers_disconnect_by_func (service, on_service_entry_activated, connection);341 g_signal_handlers_disconnect_by_func (service, on_service_entry_activated, connection);
373 g_signal_handlers_disconnect_by_func (service, on_service_active_menu_pointer_motion, connection);
374 g_signal_handlers_disconnect_by_func (service, on_service_entry_activate_request, connection);342 g_signal_handlers_disconnect_by_func (service, on_service_entry_activate_request, connection);
375 g_signal_handlers_disconnect_by_func (service, on_service_entry_show_now_changed, connection);343 g_signal_handlers_disconnect_by_func (service, on_service_entry_show_now_changed, connection);
376 }344 }
377345
=== modified file 'services/panel-service.c'
--- services/panel-service.c 2011-07-22 14:05:38 +0000
+++ services/panel-service.c 2011-07-29 08:57:18 +0000
@@ -62,9 +62,6 @@
62 gint last_right;62 gint last_right;
63 gint last_bottom;63 gint last_bottom;
64 guint32 last_menu_button;64 guint32 last_menu_button;
65
66 gint last_menu_x;
67 gint last_menu_y;
68};65};
6966
70/* Globals */67/* Globals */
@@ -74,7 +71,6 @@
74{71{
75 ENTRY_ACTIVATED = 0,72 ENTRY_ACTIVATED = 0,
76 RE_SYNC,73 RE_SYNC,
77 ACTIVE_MENU_POINTER_MOTION,
78 ENTRY_ACTIVATE_REQUEST,74 ENTRY_ACTIVATE_REQUEST,
79 ENTRY_SHOW_NOW_CHANGED,75 ENTRY_SHOW_NOW_CHANGED,
80 GEOMETRIES_CHANGED,76 GEOMETRIES_CHANGED,
@@ -173,15 +169,6 @@
173 g_cclosure_marshal_VOID__STRING,169 g_cclosure_marshal_VOID__STRING,
174 G_TYPE_NONE, 1, G_TYPE_STRING);170 G_TYPE_NONE, 1, G_TYPE_STRING);
175171
176 _service_signals[ACTIVE_MENU_POINTER_MOTION] =
177 g_signal_new ("active-menu-pointer-motion",
178 G_OBJECT_CLASS_TYPE (obj_class),
179 G_SIGNAL_RUN_LAST,
180 0,
181 NULL, NULL,
182 g_cclosure_marshal_VOID__VOID,
183 G_TYPE_NONE, 0);
184
185 _service_signals[ENTRY_ACTIVATE_REQUEST] =172 _service_signals[ENTRY_ACTIVATE_REQUEST] =
186 g_signal_new ("entry-activate-request",173 g_signal_new ("entry-activate-request",
187 G_OBJECT_CLASS_TYPE (obj_class),174 G_OBJECT_CLASS_TYPE (obj_class),
@@ -249,16 +236,6 @@
249236
250 priv->last_menu_button = 0;237 priv->last_menu_button = 0;
251 }238 }
252 else if (event && event->evtype == XI_Motion)
253 {
254 priv->last_menu_x = event->root_x;
255 priv->last_menu_y = event->root_y;
256
257 if (priv->last_menu_y <= priv->last_y)
258 {
259 g_signal_emit (self, _service_signals[ACTIVE_MENU_POINTER_MOTION], 0);
260 }
261 }
262 }239 }
263240
264 return ret;241 return ret;
@@ -1185,11 +1162,3 @@
1185 abs(delta/120), direction);1162 abs(delta/120), direction);
1186}1163}
11871164
1188void
1189panel_service_get_last_xy (PanelService *self,
1190 gint *x,
1191 gint *y)
1192{
1193 *x = self->priv->last_menu_x;
1194 *y = self->priv->last_menu_y;
1195}
11961165
=== modified file 'services/panel-service.h'
--- services/panel-service.h 2011-07-21 20:24:04 +0000
+++ services/panel-service.h 2011-07-29 08:57:18 +0000
@@ -103,10 +103,6 @@
103 const gchar *entry_id,103 const gchar *entry_id,
104 gint32 delta);104 gint32 delta);
105105
106void panel_service_get_last_xy (PanelService *self,
107 gint *x,
108 gint *y);
109
110G_END_DECLS106G_END_DECLS
111107
112#endif /* _PANEL_SERVICE_H_ */108#endif /* _PANEL_SERVICE_H_ */