[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