From 6a1abc7482600a30cab239a1f7aa6b7b25bdcebd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sun, 3 Nov 2002 19:06:39 +0000 Subject: [PATCH] new function, and remove workspace->name field, instead just get the name 2002-11-03 Havoc Pennington * src/workspace.c (meta_workspace_get_name): new function, and remove workspace->name field, instead just get the name from prefs each time * src/screen.c (meta_screen_update_workspace_names): update the gconf key to persist workspace names here, instead of changing the names we use * src/util.c (topic_name): add META_DEBUG_PREFS * src/prefs.c: change NUM_COMMANDS to 32 to allow more custom commands, implement workspace names * src/metacity.schemas.in: add workspace_names/name_NN gconf keys. --- ChangeLog | 17 +++ src/core.c | 4 +- src/core.h | 6 +- src/menu.c | 20 ++-- src/metacity.schemas.in | 29 +++++ src/prefs.c | 228 ++++++++++++++++++++++++++++++++++++---- src/prefs.h | 7 +- src/screen.c | 67 ++++++++++-- src/util.c | 2 + src/util.h | 3 +- src/workspace.c | 20 +--- src/workspace.h | 5 +- 12 files changed, 339 insertions(+), 69 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc31a06cd..ef33d481b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-11-03 Havoc Pennington + + * src/workspace.c (meta_workspace_get_name): new function, + and remove workspace->name field, instead just get the + name from prefs each time + + * src/screen.c (meta_screen_update_workspace_names): update the + gconf key to persist workspace names here, instead of changing + the names we use + + * src/util.c (topic_name): add META_DEBUG_PREFS + + * src/prefs.c: change NUM_COMMANDS to 32 to allow more custom + commands, implement workspace names + + * src/metacity.schemas.in: add workspace_names/name_NN gconf keys. + 2002-11-01 Christian Neumair * configure.in: We want at least autoconf 2.5. diff --git a/src/core.c b/src/core.c index b70420194..49dda84bc 100644 --- a/src/core.c +++ b/src/core.c @@ -641,7 +641,7 @@ meta_core_get_menu_accelerator (MetaMenuOp menu_op, } } -char * +const char* meta_core_get_workspace_name_with_index (Display *xdisplay, Window xroot, int index) @@ -654,7 +654,7 @@ meta_core_get_workspace_name_with_index (Display *xdisplay, screen = meta_display_screen_for_root (display, xroot); g_assert (screen != NULL); workspace = meta_screen_get_workspace_by_index (screen, index); - return (workspace != NULL) ? workspace->name : NULL; + return workspace ? meta_workspace_get_name (workspace) : NULL; } gboolean diff --git a/src/core.h b/src/core.h index 3af281841..cc02d5a09 100644 --- a/src/core.h +++ b/src/core.h @@ -102,9 +102,9 @@ int meta_core_get_num_workspaces (Screen *xscreen); int meta_core_get_active_workspace (Screen *xscreen); int meta_core_get_frame_workspace (Display *xdisplay, Window frame_xwindow); -char* meta_core_get_workspace_name_with_index (Display *xdisplay, - Window xroot, - int index); +const char* meta_core_get_workspace_name_with_index (Display *xdisplay, + Window xroot, + int index); void meta_core_get_frame_extents (Display *xdisplay, Window frame_xwindow, diff --git a/src/menu.c b/src/menu.c index 1d78496be..9cec2f5fb 100644 --- a/src/menu.c +++ b/src/menu.c @@ -136,8 +136,8 @@ get_workspace_name_with_accel (Display *display, Window xroot, int index) { - char *name; - unsigned int number; + const char *name; + int number; name = meta_core_get_workspace_name_with_index (display, xroot, index); @@ -146,16 +146,18 @@ get_workspace_name_with_accel (Display *display, * integer, insert a '_' before the number if it is less than 10 and * return it */ - if (sscanf (name, _("Workspace %u"), &number) == 1) + if (sscanf (name, _("Workspace %d"), &number) == 1) { + char *new_name; + /* * Above name is a pointer into the Workspace struct. Here we make * a copy copy so we can have our wicked way with it. */ - name = g_strdup_printf (_("Workspace %s%d"), - number < 10 ? "_" : "", - number); - return name; + new_name = g_strdup_printf (_("Workspace %s%d"), + number < 10 ? "_" : "", + number); + return new_name; } else { @@ -164,7 +166,9 @@ get_workspace_name_with_accel (Display *display, * add accelerators. Escape any _ characters so that the user's * workspace names do not get mangled. */ - char *new_name, *source, *dest; + char *new_name; + const char *source; + char *dest; source = name; /* * Assume the worst case, that every character is a _ diff --git a/src/metacity.schemas.in b/src/metacity.schemas.in index b64b7e86e..682b02c6e 100644 --- a/src/metacity.schemas.in +++ b/src/metacity.schemas.in @@ -177,6 +177,35 @@ + + /schemas/apps/metacity/workspace_names/name + /apps/metacity/workspace_names/name_1 + /apps/metacity/workspace_names/name_2 + /apps/metacity/workspace_names/name_3 + /apps/metacity/workspace_names/name_4 + /apps/metacity/workspace_names/name_5 + /apps/metacity/workspace_names/name_6 + /apps/metacity/workspace_names/name_7 + /apps/metacity/workspace_names/name_8 + /apps/metacity/workspace_names/name_9 + /apps/metacity/workspace_names/name_10 + /apps/metacity/workspace_names/name_11 + /apps/metacity/workspace_names/name_12 + /apps/metacity/workspace_names/name_13 + /apps/metacity/workspace_names/name_14 + /apps/metacity/workspace_names/name_15 + /apps/metacity/workspace_names/name_16 + metacity + string + + + Name of workspace + + The name of a workspace. + + + + diff --git a/src/prefs.c b/src/prefs.c index 99a1c5df5..e607d25c4 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -27,6 +27,9 @@ #include #include +#define MAX_REASONABLE_WORKSPACES 32 +#define MAX_COMMANDS 32 + /* If you add a key, it needs updating in init() and in the gconf * notify listener and of course in the .schemas file */ @@ -47,6 +50,8 @@ #define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings" #define KEY_WINDOW_BINDINGS_PREFIX "/apps/metacity/window_keybindings" +#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_" + static GConfClient *default_client = NULL; static GList *listeners = NULL; static GList *changes = NULL; @@ -77,10 +82,11 @@ static MetaButtonLayout button_layout = { META_BUTTON_FUNCTION_LAST } }; - -#define NUM_COMMANDS 12 -static char *commands[NUM_COMMANDS] = { NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL }; + +static char *commands[MAX_COMMANDS] = { NULL, }; + +static char *workspace_names[MAX_REASONABLE_WORKSPACES] = { NULL, }; + static gboolean update_use_system_font (gboolean value); static gboolean update_titlebar_font (const char *value); @@ -104,6 +110,9 @@ static gboolean update_binding (MetaKeyPref *binding, static gboolean update_command (const char *name, const char *value); static void init_commands (void); +static gboolean update_workspace_name (const char *name, + const char *value); +static void init_workspace_names (void); static void queue_changed (MetaPreference pref); static void change_notify (GConfClient *client, @@ -111,8 +120,7 @@ static void change_notify (GConfClient *client, GConfEntry *entry, gpointer user_data); - - +static char* gconf_key_for_workspace_name (int i); typedef struct { @@ -165,8 +173,8 @@ emit_changed (MetaPreference pref) GList *tmp; GList *copy; - meta_verbose ("Notifying listeners that pref %s changed\n", - meta_preference_to_string (pref)); + meta_topic (META_DEBUG_PREFS, "Notifying listeners that pref %s changed\n", + meta_preference_to_string (pref)); copy = g_list_copy (listeners); @@ -214,14 +222,14 @@ changed_idle_handler (gpointer data) static void queue_changed (MetaPreference pref) { - meta_verbose ("Queueing change of pref %s\n", - meta_preference_to_string (pref)); + meta_topic (META_DEBUG_PREFS, "Queueing change of pref %s\n", + meta_preference_to_string (pref)); if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL) changes = g_list_prepend (changes, GINT_TO_POINTER (pref)); else - meta_verbose ("Change of pref %s was already pending\n", - meta_preference_to_string (pref)); + meta_topic (META_DEBUG_PREFS, "Change of pref %s was already pending\n", + meta_preference_to_string (pref)); /* add idle at priority below the gconf notify idle */ if (changed_idle == 0) @@ -338,6 +346,9 @@ meta_prefs_init (void) /* commands */ init_commands (); + + /* workspace names */ + init_workspace_names (); gconf_client_notify_add (default_client, "/apps/metacity", change_notify, @@ -609,6 +620,22 @@ change_notify (GConfClient *client, if (update_command (key, str)) queue_changed (META_PREF_COMMANDS); } + else if (str_has_prefix (key, KEY_WORKSPACE_NAME_PREFIX)) + { + const char *str; + + if (value && value->type != GCONF_VALUE_STRING) + { + meta_warning (_("GConf key \"%s\" is set to an invalid type\n"), + key); + goto out; + } + + str = value ? gconf_value_get_string (value) : NULL; + + if (update_workspace_name (key, str)) + queue_changed (META_PREF_WORKSPACE_NAMES); + } else if (strcmp (key, KEY_BUTTON_LAYOUT) == 0) { const char *str; @@ -627,8 +654,8 @@ change_notify (GConfClient *client, } else { - meta_verbose ("Key %s doesn't mean anything to Metacity\n", - key); + meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n", + key); } out: @@ -867,8 +894,8 @@ update_button_layout (const char *value) } else { - meta_verbose ("Ignoring unknown or already-used button name \"%s\"\n", - buttons[b]); + meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n", + buttons[b]); } ++b; @@ -905,8 +932,8 @@ update_button_layout (const char *value) } else { - meta_verbose ("Ignoring unknown or already-used button name \"%s\"\n", - buttons[b]); + meta_topic (META_DEBUG_PREFS, "Ignoring unknown or already-used button name \"%s\"\n", + buttons[b]); } ++b; @@ -933,8 +960,6 @@ meta_prefs_get_titlebar_font (void) return titlebar_font; } -#define MAX_REASONABLE_WORKSPACES 32 - static gboolean update_num_workspaces (int value) { @@ -1277,7 +1302,7 @@ init_commands (void) GError *err; i = 0; - while (i < NUM_COMMANDS) + while (i < MAX_COMMANDS) { char *str_val; char *key; @@ -1297,6 +1322,33 @@ init_commands (void) } } +static void +init_workspace_names (void) +{ + int i; + GError *err; + + i = 0; + while (i < MAX_REASONABLE_WORKSPACES) + { + char *str_val; + char *key; + + key = gconf_key_for_workspace_name (i); + + err = NULL; + str_val = gconf_client_get_string (default_client, key, &err); + cleanup_error (&err); + + update_workspace_name (key, str_val); + + g_free (str_val); + g_free (key); + + ++i; + } +} + static gboolean update_binding (MetaKeyPref *binding, const char *value) @@ -1424,13 +1476,21 @@ update_command (const char *name, i = atoi (p); i -= 1; /* count from 0 not 1 */ - if (i >= NUM_COMMANDS) + if (i >= MAX_COMMANDS) { meta_topic (META_DEBUG_KEYBINDINGS, "Command %d is too highly numbered, ignoring\n", i); return FALSE; } + if ((commands[i] == NULL && value == NULL) || + (commands[i] && value && strcmp (commands[i], value) == 0)) + { + meta_topic (META_DEBUG_KEYBINDINGS, + "Command %d is unchanged\n", i); + return FALSE; + } + g_free (commands[i]); commands[i] = g_strdup (value); @@ -1444,7 +1504,7 @@ update_command (const char *name, const char* meta_prefs_get_command (int i) { - g_return_val_if_fail (i >= 0 && i < NUM_COMMANDS, NULL); + g_return_val_if_fail (i >= 0 && i < MAX_COMMANDS, NULL); return commands[i]; } @@ -1459,6 +1519,128 @@ meta_prefs_get_gconf_key_for_command (int i) return key; } +static gboolean +update_workspace_name (const char *name, + const char *value) +{ + char *p; + int i; + + p = strrchr (name, '_'); + if (p == NULL) + { + meta_topic (META_DEBUG_PREFS, + "Workspace name %s has no underscore?\n", name); + return FALSE; + } + + ++p; + + if (!g_ascii_isdigit (*p)) + { + meta_topic (META_DEBUG_PREFS, + "Workspace name %s doesn't end in number?\n", name); + return FALSE; + } + + i = atoi (p); + i -= 1; /* count from 0 not 1 */ + + if (i >= MAX_REASONABLE_WORKSPACES) + { + meta_topic (META_DEBUG_PREFS, + "Workspace name %d is too highly numbered, ignoring\n", i); + return FALSE; + } + + if ((workspace_names[i] == NULL && value == NULL) || + (workspace_names[i] && value && strcmp (workspace_names[i], value) == 0)) + { + meta_topic (META_DEBUG_PREFS, + "Workspace name %d is unchanged\n", i); + return FALSE; + } + + g_free (workspace_names[i]); + if (value != NULL) + workspace_names[i] = g_strdup (value); + else + { + /* use a default name */ + char *d; + d = g_strdup_printf (_("Workspace %d"), i + 1); + if (workspace_names[i] && strcmp (workspace_names[i], d) == 0) + { + g_free (d); + return FALSE; + } + else + { + workspace_names[i] = d; + } + } + + meta_topic (META_DEBUG_PREFS, + "Updated workspace name %d to \"%s\"\n", + i, workspace_names[i] ? workspace_names[i] : "none"); + + return TRUE; +} + +const char* +meta_prefs_get_workspace_name (int i) +{ + g_return_val_if_fail (i >= 0 && i < MAX_REASONABLE_WORKSPACES, NULL); + + return workspace_names[i]; +} + +void +meta_prefs_change_workspace_name (int i, + const char *name) +{ + char *key; + GError *err; + + g_return_if_fail (i >= 0 && i < MAX_REASONABLE_WORKSPACES); + + if ((name == NULL && workspace_names[i] == NULL) || + (name && workspace_names[i] && strcmp (name, workspace_names[i]) == 0)) + { + meta_topic (META_DEBUG_PREFS, + "Workspace %d already has name %s\n", + i, name ? name : "none"); + return; + } + + key = gconf_key_for_workspace_name (i); + + err = NULL; + gconf_client_set_string (default_client, + key, name, + &err); + + if (err) + { + meta_warning (_("Error setting name for workspace %d to \"%s\": %s\n"), + i, name ? name : "none", + err->message); + g_error_free (err); + } + + g_free (key); +} + +static char* +gconf_key_for_workspace_name (int i) +{ + char *key; + + key = g_strdup_printf (KEY_WORKSPACE_NAME_PREFIX"%d", i + 1); + + return key; +} + void meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p) { diff --git a/src/prefs.h b/src/prefs.h index d074ddbf7..fe79edaf0 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -41,7 +41,8 @@ typedef enum META_PREF_SCREEN_KEYBINDINGS, META_PREF_DISABLE_WORKAROUNDS, META_PREF_COMMANDS, - META_PREF_BUTTON_LAYOUT + META_PREF_BUTTON_LAYOUT, + META_PREF_WORKSPACE_NAMES } MetaPreference; typedef void (* MetaPrefsChangedFunc) (MetaPreference pref, @@ -75,6 +76,10 @@ MetaActionDoubleClickTitlebar meta_prefs_get_action_double_click_titlebar (void) void meta_prefs_set_num_workspaces (int n_workspaces); +const char* meta_prefs_get_workspace_name (int i); +void meta_prefs_change_workspace_name (int i, + const char *name); + /* Screen bindings */ #define META_KEYBINDING_WORKSPACE_1 "switch_to_workspace_1" #define META_KEYBINDING_WORKSPACE_2 "switch_to_workspace_2" diff --git a/src/screen.c b/src/screen.c index 4bcae0e77..ca24ef7dc 100644 --- a/src/screen.c +++ b/src/screen.c @@ -51,6 +51,7 @@ static char* get_screen_name (MetaDisplay *display, static void update_num_workspaces (MetaScreen *screen); static void update_focus_mode (MetaScreen *screen); +static void update_workspace_names (MetaScreen *screen); static void prefs_changed_callback (MetaPreference pref, gpointer data); @@ -727,6 +728,10 @@ prefs_changed_callback (MetaPreference pref, { update_focus_mode (screen); } + else if (pref == META_PREF_WORKSPACE_NAMES) + { + update_workspace_names (screen); + } } @@ -1130,7 +1135,7 @@ meta_screen_ensure_workspace_popup (MetaScreen *screen) g_assert (workspace); entries[iter].key = (MetaTabEntryKey) workspace; - entries[iter].title = workspace->name; + entries[iter].title = meta_workspace_get_name (workspace); entries[iter].icon = NULL; iter++; } @@ -1149,7 +1154,7 @@ meta_screen_ensure_workspace_popup (MetaScreen *screen) g_assert (workspace); entries[i].key = (MetaTabEntryKey) workspace; - entries[i].title = workspace->name; + entries[i].title = meta_workspace_get_name (workspace); entries[i].icon = NULL; } } @@ -1389,13 +1394,58 @@ meta_screen_update_workspace_layout (MetaScreen *screen) screen->starting_corner); } +static void +update_workspace_names (MetaScreen *screen) +{ + /* This updates names on root window when the pref changes, + * note we only get prefs change notify if things have + * really changed. + */ + GString *flattened; + int i; + int n_spaces; + + /* flatten to nul-separated list */ + n_spaces = meta_screen_get_n_workspaces (screen); + flattened = g_string_new (""); + i = 0; + while (i < n_spaces) + { + const char *name; + + name = meta_prefs_get_workspace_name (i); + + if (name) + g_string_append_len (flattened, name, + strlen (name) + 1); + else + g_string_append_len (flattened, "", 1); + + ++i; + } + + meta_error_trap_push (screen->display); + XChangeProperty (screen->display->xdisplay, + screen->xroot, + screen->display->atom_net_desktop_names, + screen->display->atom_utf8_string, + 8, PropModeReplace, + flattened->str, flattened->len); + meta_error_trap_pop (screen->display, FALSE); + + g_string_free (flattened, TRUE); +} + void meta_screen_update_workspace_names (MetaScreen *screen) { char **names; int n_names; int i; - GList *tmp; + + /* this updates names in prefs when the root window property changes, + * iff the new property contents don't match what's already in prefs + */ names = NULL; n_names = 0; @@ -1410,16 +1460,11 @@ meta_screen_update_workspace_names (MetaScreen *screen) } i = 0; - tmp = screen->workspaces; - while (tmp != NULL && i < n_names) + while (i < n_names) { - MetaWorkspace *w = tmp->data; - - meta_workspace_set_name (w, names[i]); - - ++i; + meta_prefs_change_workspace_name (i, names[i]); - tmp = tmp->next; + ++i; } g_strfreev (names); diff --git a/src/util.c b/src/util.c index 4126b1dbf..5d9c68a8e 100644 --- a/src/util.c +++ b/src/util.c @@ -260,6 +260,8 @@ topic_name (MetaDebugTopic topic) return "ERRORS"; case META_DEBUG_STARTUP: return "STARTUP"; + case META_DEBUG_PREFS: + return "PREFS"; } return "Window manager"; diff --git a/src/util.h b/src/util.h index 6ac6f55d5..7ade91b7a 100644 --- a/src/util.h +++ b/src/util.h @@ -61,7 +61,8 @@ typedef enum META_DEBUG_KEYBINDINGS = 1 << 12, META_DEBUG_SYNC = 1 << 13, META_DEBUG_ERRORS = 1 << 14, - META_DEBUG_STARTUP = 1 << 15 + META_DEBUG_STARTUP = 1 << 15, + META_DEBUG_PREFS = 1 << 16 } MetaDebugTopic; diff --git a/src/workspace.c b/src/workspace.c index a627dd0f3..551c813f2 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -22,6 +22,7 @@ #include #include "workspace.h" #include "errors.h" +#include "prefs.h" #include #include @@ -46,9 +47,6 @@ meta_workspace_new (MetaScreen *screen) workspace->work_area.width = screen->width; workspace->work_area.height = screen->height; workspace->work_area_invalid = TRUE; - - workspace->name = g_strdup_printf (_("Workspace %d"), - meta_workspace_index (workspace) + 1); return workspace; } @@ -85,8 +83,6 @@ meta_workspace_free (MetaWorkspace *workspace) workspace->screen->workspaces = g_list_remove (workspace->screen->workspaces, workspace); - - g_free (workspace->name); g_free (workspace); @@ -520,16 +516,8 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace, i); } -void -meta_workspace_set_name (MetaWorkspace *workspace, - const char *name) +const char* +meta_workspace_get_name (MetaWorkspace *workspace) { - if (strcmp (name, workspace->name) == 0) - return; - - g_free (workspace->name); - workspace->name = g_strdup (name); - - meta_verbose ("Workspace has new name \"%s\"\n", - workspace->name); + return meta_prefs_get_workspace_name (meta_workspace_index (workspace)); } diff --git a/src/workspace.h b/src/workspace.h index 67bf50923..22d004b80 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -40,8 +40,6 @@ struct _MetaWorkspace MetaScreen *screen; GList *windows; - - char *name; MetaRectangle work_area; guint work_area_invalid : 1; @@ -70,8 +68,7 @@ void meta_workspace_get_work_area (MetaWorkspace *workspace, MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace, MetaMotionDirection direction); -void meta_workspace_set_name (MetaWorkspace *workspace, - const char *name); +const char* meta_workspace_get_name (MetaWorkspace *workspace); #endif