[gnome-control-center] Allow a window manager to inherit keybindings from another window manager



commit a01e8daa6dbefca3948d2a7be6358b41b58cb3f3
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Sep 3 14:36:12 2009 -0400

    Allow a window manager to inherit keybindings from another window manager
    
    Mutter shares most (currently all) its keybindings with Metacity, and uses
    the same /apps/metacity GConf keys. For 2.28, the schemas stay in Metacity;
    the eventual plan is to have a gnome-wm-data package.
    
    This patch allows a window manager to put a _GNOME_WM_KEYBINDINGS property
    on its _NET_SUPPORTING_WM_CHECK window to provide a comma separated list of
    window manager names to use for keybinding lookup instead of _NET_WM_NAME.
    
    http://bugzilla.gnome.org/show_bug.cgi?id=594066

 capplets/common/wm-common.c                        |   50 ++++++++++++++++++--
 capplets/common/wm-common.h                        |    4 ++
 capplets/keybindings/gnome-keybinding-properties.c |   40 +++++++++++----
 3 files changed, 79 insertions(+), 15 deletions(-)
---
diff --git a/capplets/common/wm-common.c b/capplets/common/wm-common.c
index 61b1a4d..ef38489 100644
--- a/capplets/common/wm-common.c
+++ b/capplets/common/wm-common.c
@@ -15,10 +15,10 @@ typedef struct _WMCallbackData
 /* Our WM Window */
 static Window wm_window = None;
 
-char*
-wm_common_get_current_window_manager (void)
+static char *
+wm_common_get_window_manager_property (Atom atom)
 {
-  Atom utf8_string, atom, type;
+  Atom utf8_string, type;
   int result;
   char *retval;
   int format;
@@ -30,7 +30,6 @@ wm_common_get_current_window_manager (void)
     return g_strdup (WM_COMMON_UNKNOWN);
 
   utf8_string = XInternAtom (GDK_DISPLAY (), "UTF8_STRING", False);
-  atom = XInternAtom (GDK_DISPLAY (), "_NET_WM_NAME", False);
 
   gdk_error_trap_push ();
 
@@ -60,6 +59,49 @@ wm_common_get_current_window_manager (void)
   return retval;
 }
 
+char*
+wm_common_get_current_window_manager (void)
+{
+  Atom atom = XInternAtom (GDK_DISPLAY (), "_NET_WM_NAME", False);
+  char *result;
+
+  result = wm_common_get_window_manager_property (atom);
+  if (result)
+    return result;
+  else
+    return g_strdup (WM_COMMON_UNKNOWN);
+}
+
+char**
+wm_common_get_current_keybindings (void)
+{
+  Atom keybindings_atom = XInternAtom (GDK_DISPLAY (), "_GNOME_WM_KEYBINDINGS", False);
+  char *keybindings = wm_common_get_window_manager_property (keybindings_atom);
+  char **results;
+
+  if (keybindings)
+    {
+      char **p;
+      results = g_strsplit(keybindings, ",", -1);
+      for (p = results; *p; p++)
+	g_strstrip (*p);
+      g_free (keybindings);
+    }
+  else
+    {
+      Atom wm_atom = XInternAtom (GDK_DISPLAY (), "_NET_WM_NAME", False);
+      char *wm_name = wm_common_get_window_manager_property (wm_atom);
+      char *to_copy[] = { NULL, NULL };
+
+      to_copy[0] = wm_name;
+
+      results = g_strdupv (to_copy);
+      g_free (wm_name);
+    }
+
+  return results;
+}
+
 static void
 update_wm_window (void)
 {
diff --git a/capplets/common/wm-common.h b/capplets/common/wm-common.h
index 08c7145..4da0d28 100644
--- a/capplets/common/wm-common.h
+++ b/capplets/common/wm-common.h
@@ -6,6 +6,10 @@
 #define WM_COMMON_UNKNOWN  "Unknown"
 
 gchar *wm_common_get_current_window_manager (void);
+/* Returns a strv of keybinding names for the window manager;
+ * using _GNOME_WM_KEYBINDINGS if available, _NET_WM_NAME otherwise. */
+char **wm_common_get_current_keybindings (void);
+
 void   wm_common_register_window_manager_change (GFunc    func,
 						 gpointer data);
 
diff --git a/capplets/keybindings/gnome-keybinding-properties.c b/capplets/keybindings/gnome-keybinding-properties.c
index 5383298..814bee2 100644
--- a/capplets/keybindings/gnome-keybinding-properties.c
+++ b/capplets/keybindings/gnome-keybinding-properties.c
@@ -816,10 +816,22 @@ parse_start_tag (GMarkupParseContext *ctx,
   g_array_append_val (keylist->entries, key);
 }
 
+static gboolean
+strv_contains (char **strv,
+	       char  *str)
+{
+  char **p = strv;
+  for (p = strv; *p; p++)
+    if (strcmp (*p, str) == 0)
+      return TRUE;
+
+  return FALSE;
+}
+
 static void
 append_keys_to_tree_from_file (GtkBuilder *builder,
 			       const char *filename,
-			       const char *wm_name)
+			       char      **wm_keybindings)
 {
   GMarkupParseContext *ctx;
   GMarkupParser parser = { parse_start_tag, NULL, NULL, NULL, NULL };
@@ -860,7 +872,7 @@ append_keys_to_tree_from_file (GtkBuilder *builder,
   /* If there's no keys to add, or the settings apply to a window manager
    * that's not the one we're running */
   if (keylist->entries->len == 0
-      || (keylist->wm_name != NULL && !g_str_equal (wm_name, keylist->wm_name))
+      || (keylist->wm_name != NULL && strv_contains (wm_keybindings, keylist->wm_name))
       || keylist->name == NULL)
     {
       g_free (keylist->name);
@@ -951,12 +963,15 @@ append_keys_to_tree_from_gconf (GtkBuilder *builder, const gchar *gconf_path)
 }
 
 static void
-reload_key_entries (gpointer wm_name, GtkBuilder *builder)
+reload_key_entries (GtkBuilder *builder)
 {
+  gchar **wm_keybindings;
   GDir *dir;
   const char *name;
   GList *list, *l;
 
+  wm_keybindings = wm_common_get_current_keybindings();
+
   clear_old_model (builder);
 
   dir = g_dir_open (GNOMECC_KEYBINDINGS_DIR, 0, NULL);
@@ -979,7 +994,7 @@ reload_key_entries (gpointer wm_name, GtkBuilder *builder)
         gchar *path;
 
 	path = g_build_filename (GNOMECC_KEYBINDINGS_DIR, l->data, NULL);
-        append_keys_to_tree_from_file (builder, path, wm_name);
+        append_keys_to_tree_from_file (builder, path, wm_keybindings);
 	g_free (l->data);
 	g_free (path);
     }
@@ -991,6 +1006,8 @@ reload_key_entries (gpointer wm_name, GtkBuilder *builder)
    * such keys not show up in the custom section.
    */
   append_keys_to_tree_from_gconf (builder, GCONF_BINDING_DIR);
+
+  g_strfreev (wm_keybindings);
 }
 
 static void
@@ -999,9 +1016,7 @@ key_entry_controlling_key_changed (GConfClient *client,
 				   GConfEntry  *entry,
 				   gpointer     user_data)
 {
-  gchar *wm_name = wm_common_get_current_window_manager();
-  reload_key_entries (wm_name, user_data);
-  g_free (wm_name);
+  reload_key_entries (user_data);
 }
 
 static gboolean
@@ -1795,7 +1810,6 @@ setup_dialog (GtkBuilder *builder)
   GtkTreeViewColumn *column;
   GtkWidget *widget;
   GtkTreeView *treeview;
-  gchar *wm_name;
   GtkTreeSelection *selection;
   GSList *allowed_keys;
 
@@ -1852,9 +1866,7 @@ setup_dialog (GtkBuilder *builder)
 			   builder, NULL, NULL);
 
   /* set up the dialog */
-  wm_name = wm_common_get_current_window_manager();
   reload_key_entries (wm_name, builder);
-  g_free (wm_name);
 
   widget = _gtk_builder_get_widget (builder, "gnome-keybinding-dialog");
   capplet_set_icon (widget, "preferences-desktop-keyboard-shortcuts");
@@ -1895,6 +1907,12 @@ setup_dialog (GtkBuilder *builder)
                                 GTK_WINDOW (widget));
 }
 
+static void
+on_window_manager_change (const char *wm_name, GtkBuilder *builder)
+{
+  reload_key_entries (builder);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -1916,7 +1934,7 @@ main (int argc, char *argv[])
   if (!builder) /* Warning was already printed to console */
     exit (EXIT_FAILURE);
 
-  wm_common_register_window_manager_change ((GFunc) reload_key_entries, builder);
+  wm_common_register_window_manager_change ((GFunc) on_window_manager_change, dialog);
   setup_dialog (builder);
 
   gtk_main ();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]