[gnome-shell] shell-global: try to resync the pointer state after grabs
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] shell-global: try to resync the pointer state after grabs
- Date: Mon, 21 Mar 2011 18:58:28 +0000 (UTC)
commit 2782011ce8f79e4f4acbd8a4f4b64817bbca177b
Author: Dan Winship <danw gnome org>
Date: Wed Jan 19 10:29:50 2011 -0500
shell-global: try to resync the pointer state after grabs
If the pointer moves on or off the stage while another process has a
grab, we will lose track of it. One example of this is that if you use
a popup menu from a message tray trayicon, the tray will stay up after
the menu goes away, because the shell never saw the pointer leave it.
Add a new method shell_global_sync_pointer() that causes clutter to
recheck what actor is under the pointer and generate leave/enter
events if appropriate.
Of course, we can't actually tell for sure when another process has a
grab, so we need a heuristic of when to call this. Currently we call
it from Chrome._windowsRestacked(), which is not really the right
thing at all, but does fix the menu-from-trayicon case...
https://bugzilla.gnome.org/show_bug.cgi?id=630842
js/ui/chrome.js | 5 +++++
src/shell-global.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/shell-global.h | 9 +++++----
3 files changed, 52 insertions(+), 4 deletions(-)
---
diff --git a/js/ui/chrome.js b/js/ui/chrome.js
index 32b8f04..27779fc 100644
--- a/js/ui/chrome.js
+++ b/js/ui/chrome.js
@@ -335,6 +335,11 @@ Chrome.prototype = {
this._updateVisibility();
this._queueUpdateRegions();
}
+
+ // Figure out where the pointer is in case we lost track of
+ // it during a grab. (In particular, if a trayicon popup menu
+ // is dismissed, see if we need to close the message tray.)
+ global.sync_pointer();
},
_updateRegions: function() {
diff --git a/src/shell-global.c b/src/shell-global.c
index 32836cb..44f4aff 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -1491,6 +1491,48 @@ shell_global_get_pointer (ShellGlobal *global,
}
/**
+ * shell_global_sync_pointer:
+ * @global: the #ShellGlobal
+ *
+ * Ensures that clutter is aware of the current pointer position,
+ * causing enter and leave events to be emitted if the pointer moved
+ * behind our back (ie, during a pointer grab).
+ */
+void
+shell_global_sync_pointer (ShellGlobal *global)
+{
+ int x, y;
+ GdkModifierType mods;
+ ClutterMotionEvent event;
+
+ gdk_display_get_pointer (gdk_display_get_default (), NULL, &x, &y, &mods);
+
+ event.type = CLUTTER_MOTION;
+ event.time = shell_global_get_current_time (global);
+ event.flags = 0;
+ /* This is wrong: we should be setting event.stage to NULL if the
+ * pointer is not inside the bounds of the stage given the current
+ * stage_input_mode. For our current purposes however, this works.
+ */
+ event.stage = CLUTTER_STAGE (meta_plugin_get_stage (global->plugin));
+ event.x = x;
+ event.y = y;
+ event.modifier_state = mods;
+ event.axes = NULL;
+ event.device = clutter_device_manager_get_core_device (clutter_device_manager_get_default (),
+ CLUTTER_POINTER_DEVICE);
+
+ /* Leaving event.source NULL will force clutter to look it up, which
+ * will generate enter/leave events as a side effect, if they are
+ * needed. We need a better way to do this though... see
+ * http://bugzilla.clutter-project.org/show_bug.cgi?id=2615.
+ */
+ event.source = NULL;
+
+ clutter_event_put ((ClutterEvent *)&event);
+}
+
+/**
* shell_get_event_state:
* @event: a #ClutterEvent
*
diff --git a/src/shell-global.h b/src/shell-global.h
index 40f9a8f..cda10e4 100644
--- a/src/shell-global.h
+++ b/src/shell-global.h
@@ -103,10 +103,11 @@ MetaRectangle *shell_global_get_primary_monitor (ShellGlobal *global);
int shell_global_get_primary_monitor_index (ShellGlobal *global);
MetaRectangle *shell_global_get_focus_monitor (ShellGlobal *global);
-void shell_global_get_pointer (ShellGlobal *global,
- int *x,
- int *y,
- ClutterModifierType *mods);
+void shell_global_get_pointer (ShellGlobal *global,
+ int *x,
+ int *y,
+ ClutterModifierType *mods);
+void shell_global_sync_pointer (ShellGlobal *global);
GSettings *shell_global_get_settings (ShellGlobal *global);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]