[gnome-shell] MessageTray: pass keyboard events to tray icons



commit 59ecd610b1971e0f9891a3a9105f9e1cb6f88910
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Fri Nov 2 16:09:04 2012 +0100

    MessageTray: pass keyboard events to tray icons
    
    Synthetize XKeyEvents for clicks emulated by StButton using Return or
    Space.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=687425

 js/ui/keyboard.js           |    6 +---
 js/ui/messageTray.js        |    2 +-
 js/ui/notificationDaemon.js |    6 +---
 src/shell-tray-icon.c       |   59 ++++++++++++++++++++++++++++++------------
 4 files changed, 46 insertions(+), 27 deletions(-)
---
diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js
index 7ce21d2..c60649d 100644
--- a/js/ui/keyboard.js
+++ b/js/ui/keyboard.js
@@ -637,11 +637,7 @@ const KeyboardSource = new Lang.Class({
         this.keepTrayOnSummaryClick = true;
     },
 
-    handleSummaryClick: function() {
-        let event = Clutter.get_current_event();
-        if (event.type() != Clutter.EventType.BUTTON_RELEASE)
-            return false;
-
+    handleSummaryClick: function(button) {
         this.open();
         return true;
     },
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index 246bbf6..9e408ff 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -1831,7 +1831,7 @@ const MessageTray = new Lang.Class({
     },
 
     _onSummaryItemClicked: function(summaryItem, button) {
-        if (summaryItem.source.handleSummaryClick()) {
+        if (summaryItem.source.handleSummaryClick(button)) {
             if (summaryItem.source.keepTrayOnSummaryClick)
                 this._setClickedSummaryItem(null);
             else
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index ba0c06a..f23b268 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -565,19 +565,17 @@ const Source = new Lang.Class({
             this.notify(notification);
     },
 
-    handleSummaryClick: function() {
+    handleSummaryClick: function(button) {
         if (!this.trayIcon)
             return false;
 
         let event = Clutter.get_current_event();
-        if (event.type() != Clutter.EventType.BUTTON_RELEASE)
-            return false;
 
         // Left clicks are passed through only where there aren't unacknowledged
         // notifications, so it possible to open them in summary mode; right
         // clicks are always forwarded, as the right click menu is not useful for
         // tray icons
-        if (event.get_button() == 1 &&
+        if (button == 1 &&
             this.notifications.length > 0)
             return false;
 
diff --git a/src/shell-tray-icon.c b/src/shell-tray-icon.c
index 08bffa8..15b4e34 100644
--- a/src/shell-tray-icon.c
+++ b/src/shell-tray-icon.c
@@ -180,6 +180,7 @@ void
 shell_tray_icon_click (ShellTrayIcon *icon,
                        ClutterEvent  *event)
 {
+  XKeyEvent xkevent;
   XButtonEvent xbevent;
   XCrossingEvent xcevent;
   GdkWindow *remote_window;
@@ -187,8 +188,10 @@ shell_tray_icon_click (ShellTrayIcon *icon,
   int x_root, y_root;
   Display *xdisplay;
   Window xwindow, xrootwindow;
+  ClutterEventType event_type = clutter_event_type (event);
 
-  g_return_if_fail (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE);
+  g_return_if_fail (event_type == CLUTTER_BUTTON_RELEASE ||
+                    event_type == CLUTTER_KEY_RELEASE);
 
   gdk_error_trap_push ();
 
@@ -215,22 +218,44 @@ shell_tray_icon_click (ShellTrayIcon *icon,
   XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xcevent);
 
   /* Now do the click */
-  xbevent.type = ButtonPress;
-  xbevent.window = xwindow;
-  xbevent.root = xrootwindow;
-  xbevent.subwindow = None;
-  xbevent.time = xcevent.time;
-  xbevent.x = xcevent.x;
-  xbevent.y = xcevent.y;
-  xbevent.x_root = xcevent.x_root;
-  xbevent.y_root = xcevent.y_root;
-  xbevent.state = clutter_event_get_state (event);
-  xbevent.button = clutter_event_get_button (event);
-  xbevent.same_screen = True;
-  XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent);
-
-  xbevent.type = ButtonRelease;
-  XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent);
+  if (event_type == CLUTTER_BUTTON_RELEASE)
+    {
+      xbevent.window = xwindow;
+      xbevent.root = xrootwindow;
+      xbevent.subwindow = None;
+      xbevent.time = xcevent.time;
+      xbevent.x = xcevent.x;
+      xbevent.y = xcevent.y;
+      xbevent.x_root = xcevent.x_root;
+      xbevent.y_root = xcevent.y_root;
+      xbevent.state = clutter_event_get_state (event);
+      xbevent.same_screen = True;
+      xbevent.type = ButtonPress;
+      xbevent.button = clutter_event_get_button (event);
+      XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent);
+
+      xbevent.type = ButtonRelease;
+      XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xbevent);
+    }
+  else
+    {
+      xkevent.window = xwindow;
+      xkevent.root = xrootwindow;
+      xkevent.subwindow = None;
+      xkevent.time = xcevent.time;
+      xkevent.x = xcevent.x;
+      xkevent.y = xcevent.y;
+      xkevent.x_root = xcevent.x_root;
+      xkevent.y_root = xcevent.y_root;
+      xkevent.state = clutter_event_get_state (event);
+      xkevent.same_screen = True;
+      xkevent.type = KeyPress;
+      xkevent.keycode = clutter_event_get_key_code (event);
+      XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xkevent);
+
+      xkevent.type = KeyRelease;
+      XSendEvent (xdisplay, xwindow, False, 0, (XEvent *)&xkevent);
+    }
 
   /* And move the pointer back out */
   xcevent.type = LeaveNotify;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]