[Xfce4-commits] <xfce4-taskbar-plugin:master> Added global hotkeys

Valentin Dudouyt noreply at xfce.org
Fri Oct 5 15:40:01 CEST 2012


Updating branch refs/heads/master
         to 1ab8f1f5c2f6bfeeb38ca06ba5ee335ffaf180e9 (commit)
       from 5ae70547f78f225063f6845be07c87cac246c3e9 (commit)

commit 1ab8f1f5c2f6bfeeb38ca06ba5ee335ffaf180e9
Author: Valentin Dudouyt <valentin.dudouyt at gmail.com>
Date:   Fri Oct 5 20:39:26 2012 +0700

    Added global hotkeys

 Makefile         |    6 ++--
 hotkeys.c        |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hotkeys.h        |    3 ++
 taskbar-widget.c |   21 +++++++++++
 4 files changed, 130 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 4affeb1..0c7aee3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-CFLAGS=-fPIC -I. `pkg-config --cflags-only-I gtk+-2.0 exo-1 libwnck-1.0 libxfce4panel-1.0 libxfce4ui-1 libxfconf-0`
-LINKFLAGS=`pkg-config --libs gtk+-2.0 exo-1 libwnck-1.0 libxfce4panel-1.0 libxfce4ui-1 libxfconf-0 gobject-2.0 gtk+-x11-2.0 glib-2.0`
+CFLAGS=-fPIC -I. `pkg-config --cflags-only-I gtk+-2.0 exo-1 libwnck-1.0 libxfce4panel-1.0 libxfce4ui-1 libxfconf-0 gtkhotkey-1.0`
+LINKFLAGS=`pkg-config --libs gtk+-2.0 exo-1 libwnck-1.0 libxfce4panel-1.0 libxfce4ui-1 libxfconf-0 gobject-2.0 gtk+-x11-2.0 glib-2.0 gtkhotkey-1.0`
 
-OBJ=taskbar.o taskbar-widget.o
+OBJ=taskbar.o taskbar-widget.o hotkeys.o
 
 all:libtaskbar
 
diff --git a/hotkeys.c b/hotkeys.c
new file mode 100644
index 0000000..6b73d04
--- /dev/null
+++ b/hotkeys.c
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <xfconf/xfconf.h>
+#include <libxfce4util/libxfce4util.h>
+#include <gtkhotkey.h>
+#include "taskbar-widget.h"
+
+#define TASKBAR_XFCONF_CHANNEL "xfce4-keyboard-shortcuts"
+#define TASKBAR_XFCONF_PREFIX "/xftaskbar"
+
+typedef struct _hotkey_cb_data {
+	char *cmd;
+	XfceTaskBar *taskbar;
+} hotkey_cb_data;
+
+typedef struct _HotkeysHandler {
+	XfconfChannel *xfconf_channel;
+	char *xfconf_prefix;
+	XfceTaskBar *taskbar;
+	GHashTable *keymap;
+	GtkHotkeyListener *listener;
+	/* To be freed */
+	GArray *hotkey_cbs;
+} HotkeysHandler;
+
+gchar *strip_path(gchar *str) {
+	gchar **chunks = g_strsplit_set(str, "/", 0);
+	gchar *ret = NULL;
+	while(chunks[0]) {
+		ret = chunks[0];
+		chunks++;
+	}
+	return(ret);
+}
+
+void create_default_keymap(XfconfChannel *channel) {
+	int i;
+	char key[32];
+	char value[16];
+	for(i = 1; i <= 10; i++) {
+		g_sprintf(key, "%s/<Super>%d", TASKBAR_XFCONF_PREFIX, i % 10);
+		g_sprintf(value, "selgrp %d", i);
+		xfconf_channel_set_string(channel, key, value);
+	}
+	return;
+}
+
+void hotkey_activated_callback (GtkHotkeyInfo *hotkey, guint event_time, hotkey_cb_data *data) {
+	int arg;
+	if(sscanf(data->cmd, "selgrp %d", &arg)) {
+			xfce_taskbar_selgrp_cmd(data->taskbar, arg);
+	} else {
+		g_message("xfce4-taskbar-plugin: unknown command %s", data->cmd);
+	}
+}
+
+void hotkey_parsed_callback (gpointer key, gpointer unused_value, HotkeysHandler *handler) {
+	char *value = xfconf_channel_get_string(handler->xfconf_channel, key, NULL);
+	g_assert(value != NULL);
+	key = strip_path(key);
+	g_assert(key != NULL);
+	GtkHotkeyInfo *hotkey = gtk_hotkey_info_new("xftaskbar",value,key,NULL);
+	GError *error = NULL;
+	gtk_hotkey_info_bind (hotkey, &error);
+	if (error) {
+		g_critical ("Error binding hotkey: for '%s': %s",
+				    (char*) key, error->message);
+	}
+	hotkey_cb_data *data = g_malloc(sizeof(hotkey_cb_data));
+	g_array_append_val(handler->hotkey_cbs, data);
+	data->cmd = value;
+	data->taskbar = handler->taskbar;
+	g_signal_connect (hotkey, "activated",
+                      G_CALLBACK(hotkey_activated_callback), data);
+}
+
+HotkeysHandler *init_global_hotkeys(XfceTaskBar *taskbar) {
+	HotkeysHandler *handler = g_malloc(sizeof(HotkeysHandler));
+	handler->xfconf_channel = xfconf_channel_get(TASKBAR_XFCONF_CHANNEL);
+	if(!handler->xfconf_channel)
+	    	g_critical("Couldn't acquire channel: %s", TASKBAR_XFCONF_CHANNEL);
+	handler->xfconf_prefix = TASKBAR_XFCONF_PREFIX;
+	handler->taskbar = taskbar;
+	handler->keymap = xfconf_channel_get_properties(handler->xfconf_channel, handler->xfconf_prefix);
+	handler->hotkey_cbs = g_array_new(FALSE, FALSE, sizeof(hotkey_cb_data));
+	if(!g_hash_table_size(handler->keymap)) {
+		/* The config doesn't exists yet (e.g. first run).
+		   Initializing with defaults. */
+		g_message("xfce4-taskbar-plugin: creating default keymap");
+		create_default_keymap(handler->xfconf_channel);
+		handler->keymap = xfconf_channel_get_properties(handler->xfconf_channel, handler->xfconf_prefix);
+	}
+	handler->listener = gtk_hotkey_listener_get_default();
+	g_hash_table_foreach(handler->keymap, (GHFunc)hotkey_parsed_callback, handler);
+	return(handler);
+}
+
+void finish_global_hotkeys(HotkeysHandler *handler) {
+	// TODO: hotkey_cbs
+	g_array_free(handler->hotkey_cbs, TRUE);
+	g_free(handler);
+}
diff --git a/hotkeys.h b/hotkeys.h
new file mode 100644
index 0000000..4c63bca
--- /dev/null
+++ b/hotkeys.h
@@ -0,0 +1,3 @@
+typedef struct _HotkeysHandler HotkeysHandler;
+HotkeysHandler *init_global_hotkeys(XfceTaskBar *taskbar);
+void finish_global_hotkeys(HotkeysHandler *handler);
diff --git a/taskbar-widget.c b/taskbar-widget.c
index 8319b37..1c85389 100644
--- a/taskbar-widget.c
+++ b/taskbar-widget.c
@@ -25,6 +25,7 @@
 #endif
 
 #include "taskbar-widget.h"
+#include "hotkeys.h"
 
 #define DEFAULT_BUTTON_SIZE             (25)
 #define DEFAULT_MAX_BUTTON_LENGTH       (400)
@@ -134,6 +135,7 @@ struct _XfceTaskBar
     guint unique_id_counter ;
     
     gchar *rc_path ;
+    HotkeysHandler *hotkeys_handler;
 
 #ifdef GDK_WINDOWING_X11
     /* wireframe window */
@@ -310,6 +312,7 @@ static void xfce_taskbar_init (XfceTaskBar *taskbar)
     taskbar->screen = NULL;
     taskbar->wgroups = NULL;
     taskbar->skipped_windows = NULL;
+    taskbar->hotkeys_handler = NULL;
     taskbar->horizontal = TRUE;
     taskbar->all_workspaces = TRUE;
     taskbar->switch_workspace = TRUE;
@@ -527,6 +530,7 @@ void xfce_taskbar_save_pinned_config (XfceTaskBar *taskbar)
 
 static void xfce_taskbar_finalize (GObject *object)
 {
+    g_message("taskbar finalize");
     XfceTaskBar *taskbar = XFCE_taskbar (object);
 
     /* data that should already be freed when disconnecting the screen */
@@ -551,6 +555,8 @@ static void xfce_taskbar_finalize (GObject *object)
     /* destroy the wireframe window */
     xfce_taskbar_wireframe_destroy (taskbar);
 #endif
+    if(taskbar->hotkeys_handler)
+    	finish_global_hotkeys(taskbar->hotkeys_handler);
 
     (*G_OBJECT_CLASS (xfce_taskbar_parent_class)->finalize) (object);
 }
@@ -840,6 +846,9 @@ static void xfce_taskbar_connect_screen (XfceTaskBar *taskbar)
     /* set the new screen */
     taskbar->gdk_screen = gtk_widget_get_screen (GTK_WIDGET (taskbar));
     taskbar->screen = wnck_screen_get (gdk_screen_get_number (taskbar->gdk_screen));
+
+    /* initialize global hotkeys */
+    taskbar->hotkeys_handler = init_global_hotkeys(taskbar);
     
     
     /* add all existing windows on this screen */
@@ -1667,6 +1676,18 @@ static GtkWidget *xfce_taskbar_button_proxy_menu_item (XfceTaskBarWNode *child,
     return mi;
 }
 
+void xfce_taskbar_selgrp_cmd(XfceTaskBar *taskbar, char id) {
+	XfceTaskBarGroup *group = g_list_nth_data(taskbar->wgroups, id-1);
+	if(!group)
+		return;
+	XfceTaskBarWNode *first = g_slist_nth_data(group->wnodes, 0);
+	if(!first) {
+		xfce_taskbar_group_button_launch_pinned(group);
+	} else if (!wnck_window_is_active(first->window)) {
+		xfce_taskbar_button_activate(first, 0);
+	}
+}
+
 static void xfce_taskbar_button_activate (XfceTaskBarWNode *wnode, guint32 timestamp)
 {
     WnckWorkspace *workspace;


More information about the Xfce4-commits mailing list