[Xfce4-commits] <xfce4-panel:master> Hide calendar window on <Esc> or mouse press outside the popup.

Andrzej noreply at xfce.org
Sat Jan 12 01:24:01 CET 2013


Updating branch refs/heads/master
         to 8e4e5be299c09595a6ba19ab0216c29db69edb47 (commit)
       from a786acf194436b79c4c01417e996c9f231b26760 (commit)

commit 8e4e5be299c09595a6ba19ab0216c29db69edb47
Author: Andrzej <ndrwrdck at gmail.com>
Date:   Sat Jan 12 00:23:34 2013 +0000

    Hide calendar window on <Esc> or mouse press outside the popup.

 plugins/clock/clock.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 139 insertions(+), 1 deletions(-)

diff --git a/plugins/clock/clock.c b/plugins/clock/clock.c
index 85a9d76..04c4f88 100644
--- a/plugins/clock/clock.c
+++ b/plugins/clock/clock.c
@@ -28,6 +28,7 @@
 #include <math.h>
 #endif
 
+#include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #include <exo/exo.h>
 #include <libxfce4ui/libxfce4ui.h>
@@ -73,7 +74,21 @@ static void     clock_plugin_screen_position_changed   (XfcePanelPlugin       *p
                                                         XfceScreenPosition     position);
 static void     clock_plugin_configure_plugin          (XfcePanelPlugin       *panel_plugin);
 static void     clock_plugin_set_mode                  (ClockPlugin           *plugin);
-static void     clock_plugin_reposition_calendar       (ClockPlugin          *plugin);
+static void     clock_plugin_reposition_calendar       (ClockPlugin           *plugin);
+static gboolean clock_plugin_pointer_grab              (ClockPlugin           *plugin,
+                                                        GtkWidget             *widget,
+                                                        gboolean               keep);
+static void     clock_plugin_pointer_ungrab            (ClockPlugin           *plugin,
+                                                        GtkWidget             *widget);
+static gboolean clock_plugin_calendar_pointed          (GtkWidget             *calendar_window,
+                                                        gdouble                x_root,
+                                                        gdouble                y_root);
+static gboolean clock_plugin_calendar_button_press_event (GtkWidget           *calendar_window,
+                                                          GdkEventButton      *event,
+                                                          ClockPlugin         *plugin);
+static gboolean clock_plugin_calendar_key_press_event  (GtkWidget             *calendar_window,
+                                                        GdkEventKey           *event,
+                                                        ClockPlugin           *plugin);
 static void     clock_plugin_popup_calendar            (ClockPlugin           *plugin);
 static void     clock_plugin_hide_calendar             (ClockPlugin           *plugin);
 static gboolean clock_plugin_tooltip                   (gpointer               user_data);
@@ -130,6 +145,9 @@ struct _ClockPlugin
 
   gchar              *tooltip_format;
   ClockPluginTimeout *tooltip_timeout;
+
+  GdkGrabStatus       grab_pointer;
+  GdkGrabStatus       grab_keyboard;
 };
 
 struct _ClockPluginTimeout
@@ -963,6 +981,120 @@ clock_plugin_calendar_show_event (GtkWidget   *calendar_window,
 
 
 static void
+clock_plugin_pointer_ungrab (ClockPlugin *plugin,
+                             GtkWidget   *widget)
+{
+  if (plugin->grab_pointer == GDK_GRAB_SUCCESS)
+    gdk_pointer_ungrab (GDK_CURRENT_TIME);
+  if (plugin->grab_keyboard == GDK_GRAB_SUCCESS)
+    gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+}
+
+
+
+static gboolean
+clock_plugin_pointer_grab (ClockPlugin *plugin,
+                           GtkWidget   *widget,
+                           gboolean     keep)
+{
+  GdkWindow     *window;
+  gboolean       grab_succeed = FALSE;
+  guint          i;
+  GdkEventMask   pointer_mask = GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+                                | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
+                                | GDK_POINTER_MOTION_MASK;
+
+  window = widget->window;
+
+  /* don't try to get the grab for longer then 1/4 second */
+  for (i = 0; i < (G_USEC_PER_SEC / 100 / 4); i++)
+    {
+      plugin->grab_keyboard = gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME);
+      if (plugin->grab_keyboard == GDK_GRAB_SUCCESS)
+        {
+          plugin->grab_pointer = gdk_pointer_grab (window, TRUE, pointer_mask,
+                                                   NULL, NULL, GDK_CURRENT_TIME);
+          if (plugin->grab_pointer == GDK_GRAB_SUCCESS)
+            {
+              grab_succeed = TRUE;
+              break;
+            }
+        }
+
+      g_usleep (100);
+    }
+
+  /* release the grab */
+  if (!keep)
+    clock_plugin_pointer_ungrab (plugin, widget);
+
+  if (!grab_succeed)
+    {
+      clock_plugin_pointer_ungrab (plugin, widget);
+      g_printerr (PACKAGE_NAME ": Unable to get keyboard and mouse "
+                  "grab. Popup failed.\n");
+    }
+
+  return grab_succeed;
+}
+
+
+
+static gboolean
+clock_plugin_calendar_pointed (GtkWidget *calendar_window,
+                               gdouble    x_root,
+                               gdouble    y_root)
+{
+  gint          window_x, window_y;
+
+  if (gtk_widget_get_mapped (calendar_window))
+    {
+      gdk_window_get_position (calendar_window->window, &window_x, &window_y);
+
+      if (x_root >= window_x && x_root < window_x + calendar_window->allocation.width &&
+          y_root >= window_y && y_root < window_y + calendar_window->allocation.height)
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
+static gboolean
+clock_plugin_calendar_button_press_event (GtkWidget      *calendar_window,
+                                          GdkEventButton *event,
+                                          ClockPlugin    *plugin)
+{
+  if (event->type == GDK_BUTTON_PRESS &&
+      !clock_plugin_calendar_pointed (calendar_window, event->x_root, event->y_root))
+    {
+      clock_plugin_hide_calendar (plugin);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
+static gboolean
+clock_plugin_calendar_key_press_event (GtkWidget      *calendar_window,
+                                       GdkEventKey    *event,
+                                       ClockPlugin    *plugin)
+{
+  if (event->type == GDK_KEY_PRESS && event->keyval == GDK_KEY_Escape)
+    {
+      clock_plugin_hide_calendar (plugin);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
+
+static void
 clock_plugin_popup_calendar (ClockPlugin *plugin)
 {
   GtkWidget *calendar_frame;
@@ -991,12 +1123,17 @@ clock_plugin_popup_calendar (ClockPlugin *plugin)
                                         | GTK_CALENDAR_SHOW_WEEK_NUMBERS);
       g_signal_connect (G_OBJECT (plugin->calendar_window), "show",
                         G_CALLBACK (clock_plugin_calendar_show_event), plugin);
+      g_signal_connect (G_OBJECT (plugin->calendar_window), "button-press-event",
+                        G_CALLBACK (clock_plugin_calendar_button_press_event), plugin);
+      g_signal_connect (G_OBJECT (plugin->calendar_window), "key-press-event",
+                        G_CALLBACK (clock_plugin_calendar_key_press_event), plugin);
       gtk_container_add (GTK_CONTAINER (calendar_frame), plugin->calendar);
       gtk_widget_show (plugin->calendar);
     }
 
   gtk_widget_show (GTK_WIDGET (plugin->calendar_window));
   xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), TRUE);
+  clock_plugin_pointer_grab (plugin, GTK_WIDGET (plugin->calendar_window), TRUE);
 }
 
 
@@ -1006,6 +1143,7 @@ clock_plugin_hide_calendar (ClockPlugin *plugin)
 {
   panel_return_if_fail (plugin->calendar_window != NULL);
 
+  clock_plugin_pointer_ungrab (plugin, GTK_WIDGET (plugin->calendar_window));
   gtk_widget_hide (GTK_WIDGET (plugin->calendar_window));
   xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), FALSE);
 }


More information about the Xfce4-commits mailing list