aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Gateau <aurelien.gateau@canonical.com>2010-07-20 14:51:23 +0200
committerAurelien Gateau <aurelien.gateau@canonical.com>2010-07-20 14:51:23 +0200
commit646c74694e86d6e5d479028a7dbd8cf9a1aca37a (patch)
tree6e190570c47270eae95bfc7b2a7b7e8ce15710ba
parent6da7a3341f028d913fd3ad01d47a59f436b5e780 (diff)
downloadlibdbusmenu-646c74694e86d6e5d479028a7dbd8cf9a1aca37a.tar.gz
libdbusmenu-646c74694e86d6e5d479028a7dbd8cf9a1aca37a.tar.bz2
libdbusmenu-646c74694e86d6e5d479028a7dbd8cf9a1aca37a.zip
Ripped some code from wnckprop to do proper click-to-dump
-rw-r--r--configure.ac11
-rw-r--r--tools/Makefile.am4
-rw-r--r--tools/dbusmenu-dumper.c100
3 files changed, 109 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac
index 99911fa..2e95d55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,13 +51,16 @@ AC_SUBST(DBUSMENUGTK_CFLAGS)
AC_SUBST(DBUSMENUGTK_LIBS)
###########################
-# Dependencies - tools
+# Dependencies - dumper
###########################
-PKG_CHECK_MODULES(DBUSMENUTOOLS, x11)
+X11_REQUIRED_VERSION=1.3
-AC_SUBST(DBUSMENUTOOLS_CFLAGS)
-AC_SUBST(DBUSMENUTOOLS_LIBS)
+PKG_CHECK_MODULES(DBUSMENUDUMPER, gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ x11 >= $X11_REQUIRED_VERSION)
+
+AC_SUBST(DBUSMENUDUMPER_CFLAGS)
+AC_SUBST(DBUSMENUDUMPER_LIBS)
###########################
# Dependencies - Testing
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 3cd5538..ab7a598 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -10,11 +10,11 @@ dbusmenu_dumper_SOURCES = \
dbusmenu_dumper_CFLAGS = \
-I $(srcdir)/.. \
- $(DBUSMENUGLIB_CFLAGS) $(DBUSMENUTOOLS_CFLAGS) -Wall -Werror
+ $(DBUSMENUGLIB_CFLAGS) $(DBUSMENUDUMPER_CFLAGS) -Wall -Werror
dbusmenu_dumper_LDADD = \
../libdbusmenu-glib/libdbusmenu-glib.la \
- $(DBUSMENUGLIB_LIBS) $(DBUSMENUTOOLS_LIBS)
+ $(DBUSMENUGLIB_LIBS) $(DBUSMENUDUMPER_LIBS)
doc_DATA = README.dbusmenu-bench
diff --git a/tools/dbusmenu-dumper.c b/tools/dbusmenu-dumper.c
index 4a0dd03..3a47f21 100644
--- a/tools/dbusmenu-dumper.c
+++ b/tools/dbusmenu-dumper.c
@@ -23,6 +23,10 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <glib.h>
#include <dbus/dbus-glib.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
#include <libdbusmenu-glib/client.h>
#include <libdbusmenu-glib/menuitem.h>
@@ -93,6 +97,12 @@ new_root_cb (DbusmenuClient * client, DbusmenuMenuitem * newroot)
return;
}
+/* Window clicking ***************************************************/
+static GdkFilterReturn
+click_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ gpointer data);
+
static Window
find_real_window(Display * display, Window w, int depth)
{
@@ -148,6 +158,91 @@ get_window_under_cursor()
return find_real_window(display, child, 0);
}
+static void
+uninstall_click_filter (void)
+{
+ GdkWindow *root;
+
+ root = gdk_get_default_root_window ();
+ gdk_window_remove_filter (root, (GdkFilterFunc) click_filter, NULL);
+
+ gdk_pointer_ungrab (GDK_CURRENT_TIME);
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+ gtk_main_quit ();
+}
+
+static GdkFilterReturn
+click_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ gpointer data)
+
+{
+ XEvent *xevent = (XEvent *) gdk_xevent;
+ gboolean *success = (gboolean *)data;
+
+ switch (xevent->type) {
+ case ButtonPress:
+ uninstall_click_filter();
+ *success = TRUE;
+ return GDK_FILTER_REMOVE;
+ case KeyPress:
+ if (xevent->xkey.keycode == XKeysymToKeycode(gdk_display, XK_Escape)) {
+ uninstall_click_filter();
+ *success = FALSE;
+ return GDK_FILTER_REMOVE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static gboolean
+install_click_filter (gpointer data)
+{
+ GdkGrabStatus status;
+ GdkCursor *cross;
+ GdkWindow *root;
+
+ root = gdk_get_default_root_window();
+
+ gdk_window_add_filter(root, (GdkFilterFunc) click_filter, data);
+
+ cross = gdk_cursor_new(GDK_CROSS);
+ status = gdk_pointer_grab(root, FALSE, GDK_BUTTON_PRESS_MASK,
+ NULL, cross, GDK_CURRENT_TIME);
+ gdk_cursor_unref(cross);
+
+ if (status != GDK_GRAB_SUCCESS) {
+ g_warning("Pointer grab failed.\n");
+ uninstall_click_filter();
+ return FALSE;
+ }
+
+ status = gdk_keyboard_grab(root, FALSE, GDK_CURRENT_TIME);
+ if (status != GDK_GRAB_SUCCESS) {
+ g_warning("Keyboard grab failed.\n");
+ uninstall_click_filter();
+ return FALSE;
+ }
+
+ gdk_flush();
+ return FALSE;
+}
+
+static gboolean
+wait_for_click (int argc, char **argv)
+{
+ gtk_init(&argc, &argv);
+ gboolean success;
+ g_idle_add (install_click_filter, (gpointer)(&success));
+ gtk_main ();
+ return success;
+}
+
static gchar * dbusname = NULL;
static gchar * dbusobject = NULL;
@@ -191,6 +286,7 @@ init_dbus_vars_from_window(Window window)
return TRUE;
}
+/* Option parser *****************************************************/
static gboolean
option_dbusname (const gchar * arg, const gchar * value, gpointer data, GError ** error)
{
@@ -245,6 +341,9 @@ main (int argc, char ** argv)
}
if (dbusname == NULL && dbusobject == NULL) {
+ if (!wait_for_click(argc, argv)) {
+ return 1;
+ }
Window window = get_window_under_cursor();
if (window == None) {
g_printerr("ERROR: could not get the id for the pointed window\n");
@@ -256,6 +355,7 @@ main (int argc, char ** argv)
return 1;
}
g_debug("dbusname: %s, dbusobject: %s", dbusname, dbusobject);
+ return 1;
} else {
if (dbusname == NULL) {
g_printerr("ERROR: dbus-name not specified\n");