2 * This file is part of GtkHotkey.
3 * Copyright Mikkel Kamstrup Erlandsen, March, 2008
5 * GtkHotkey is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GtkHotkey is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with GtkHotkey. If not, see <http://www.gnu.org/licenses/>.
19 #include "gtk-hotkey-error.h"
20 #include "gtk-hotkey-x11-listener.h"
21 #include "gtk-hotkey-listener.h"
22 #include "gtk-hotkey-info.h"
23 #include "x11/tomboykeybinder.h"
25 struct _GtkHotkeyX11ListenerPrivate {
30 GTK_HOTKEY_X11_LISTENER_DUMMY_PROPERTY
32 static gboolean gtk_hotkey_x11_listener_real_bind_hotkey (GtkHotkeyListener *base,
33 GtkHotkeyInfo *hotkey,
36 static gboolean gtk_hotkey_x11_listener_real_unbind_hotkey (GtkHotkeyListener *base,
37 GtkHotkeyInfo *hotkey,
40 static void hotkey_activated_cb (char *signature,
44 find_hotkey_from_key_id (GtkHotkeyX11Listener *self,
47 static gpointer gtk_hotkey_x11_listener_parent_class = NULL;
51 * SECTION:gtk-hotkey-x11-listener
52 * @short_description: Implementation of #GtkHotkeyListener for a standard X11
54 * @see_also: #GtkHotkeyRegistry, #GtkHotkeyInfo
56 * This implementation of a #GtkHotkeyListener should work in any X11
61 gtk_hotkey_x11_listener_real_bind_hotkey (GtkHotkeyListener *base,
62 GtkHotkeyInfo *hotkey,
65 GtkHotkeyX11Listener *self;
67 g_return_val_if_fail (GTK_HOTKEY_IS_X11_LISTENER(base), FALSE);
68 g_return_val_if_fail (GTK_HOTKEY_IS_INFO (hotkey), FALSE);
69 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
71 self = GTK_HOTKEY_X11_LISTENER (base);
73 if (find_hotkey_from_key_id(self,
74 gtk_hotkey_info_get_key_id (hotkey))) {
75 g_warning ("Hotkey '%s' already registered. Ignoring register request.",
76 gtk_hotkey_info_get_key_id (hotkey));
80 if (tomboy_keybinder_bind (gtk_hotkey_info_get_signature(hotkey),
83 self->priv->hotkeys = g_list_prepend (self->priv->hotkeys, hotkey);
84 g_object_ref (hotkey);
88 /* Bugger, we failed to bind */
89 g_set_error (error, GTK_HOTKEY_LISTENER_ERROR,
90 GTK_HOTKEY_LISTENER_ERROR_BIND,
91 "Failed to register hotkey '%s' with signature '%s'",
92 gtk_hotkey_info_get_key_id (hotkey),
93 gtk_hotkey_info_get_signature (hotkey));
100 gtk_hotkey_x11_listener_real_unbind_hotkey (GtkHotkeyListener *base,
101 GtkHotkeyInfo *hotkey,
104 GtkHotkeyX11Listener *self;
105 GtkHotkeyInfo *saved_hk;
106 const gchar *signature;
108 g_return_val_if_fail (GTK_HOTKEY_IS_X11_LISTENER (base), FALSE);
109 g_return_val_if_fail (GTK_HOTKEY_IS_INFO (hotkey), FALSE);
111 self = GTK_HOTKEY_X11_LISTENER (base);
112 signature = gtk_hotkey_info_get_signature (hotkey);
113 saved_hk = find_hotkey_from_key_id (self, gtk_hotkey_info_get_key_id(hotkey));
116 g_set_error (error, GTK_HOTKEY_LISTENER_ERROR,
117 GTK_HOTKEY_LISTENER_ERROR_UNBIND,
118 "Failed to unregister hotkey '%s' with signature '%s'. "
119 "No hotkey with that signature is known",
120 gtk_hotkey_info_get_key_id (hotkey),
125 /* Remove actual keybinding */
126 tomboy_keybinder_unbind (signature, hotkey_activated_cb);
129 self->priv->hotkeys = g_list_remove (self->priv->hotkeys, saved_hk);
130 g_object_unref (saved_hk);
132 /* Clean up signal handler */
133 gulong handler = g_signal_handler_find (self,
134 G_SIGNAL_MATCH_DATA | G_SIGNAL_MATCH_FUNC,
135 0, 0, NULL, gtk_hotkey_info_activated,
138 g_warning ("Failed to disconnect signal handler for hotkey '%s'",
139 gtk_hotkey_info_get_key_id (hotkey));
141 g_signal_handler_disconnect (self, handler);
149 hotkey_activated_cb (char *signature,
152 GtkHotkeyX11Listener *self;
153 GtkHotkeyInfo *hotkey;
157 g_return_if_fail (GTK_HOTKEY_IS_X11_LISTENER(user_data));
158 g_return_if_fail (signature != NULL);
160 self = GTK_HOTKEY_X11_LISTENER(user_data);
161 event_time = tomboy_keybinder_get_current_event_time ();
163 /* Trigger signals for hotkeys with matching signature */
164 for (iter = self->priv->hotkeys; iter; iter = iter->next) {
165 hotkey = GTK_HOTKEY_INFO (iter->data);
166 if (g_str_equal (signature, gtk_hotkey_info_get_signature (hotkey))) {
167 gtk_hotkey_listener_activated (GTK_HOTKEY_LISTENER(self),
169 gtk_hotkey_info_activated (hotkey, event_time);
175 static GtkHotkeyInfo*
176 find_hotkey_from_key_id (GtkHotkeyX11Listener *self,
180 GtkHotkeyInfo *hotkey;
182 g_return_val_if_fail (GTK_HOTKEY_IS_X11_LISTENER(self), NULL);
183 g_return_val_if_fail (key_id != NULL, NULL);
185 for (iter = self->priv->hotkeys; iter; iter = iter->next) {
186 hotkey = GTK_HOTKEY_INFO (iter->data);
188 if (g_str_equal (gtk_hotkey_info_get_key_id(hotkey), key_id))
196 gtk_hotkey_x11_listener_class_init (GtkHotkeyX11ListenerClass * klass)
198 gtk_hotkey_x11_listener_parent_class = g_type_class_peek_parent (klass);
200 GTK_HOTKEY_LISTENER_CLASS (klass)->bind_hotkey =
201 gtk_hotkey_x11_listener_real_bind_hotkey;
202 GTK_HOTKEY_LISTENER_CLASS (klass)->unbind_hotkey =
203 gtk_hotkey_x11_listener_real_unbind_hotkey;
205 /* Initialize the tomboy keybinder */
206 tomboy_keybinder_init ();
211 gtk_hotkey_x11_listener_init (GtkHotkeyX11Listener * self)
213 self->priv = g_new0 (GtkHotkeyX11ListenerPrivate, 1);
217 gtk_hotkey_x11_listener_finalize (GtkHotkeyX11Listener * self)
223 gtk_hotkey_x11_listener_get_type (void)
225 static GType gtk_hotkey_x11_listener_type_id = 0;
227 if (G_UNLIKELY (gtk_hotkey_x11_listener_type_id == 0)) {
228 static const GTypeInfo g_define_type_info = {
229 sizeof (GtkHotkeyX11ListenerClass),
230 (GBaseInitFunc) NULL,
231 (GBaseFinalizeFunc) gtk_hotkey_x11_listener_finalize,
232 (GClassInitFunc) gtk_hotkey_x11_listener_class_init,
233 (GClassFinalizeFunc) NULL,
235 sizeof (GtkHotkeyX11Listener),
237 (GInstanceInitFunc) gtk_hotkey_x11_listener_init
240 gtk_hotkey_x11_listener_type_id = g_type_register_static (GTK_HOTKEY_TYPE_LISTENER, "GtkHotkeyX11Listener", &g_define_type_info, 0);
242 return gtk_hotkey_x11_listener_type_id;