Commit 6a1abc74 authored by Havoc Pennington's avatar Havoc Pennington Committed by Havoc Pennington
Browse files

new function, and remove workspace->name field, instead just get the name

2002-11-03  Havoc Pennington  <hp@pobox.com>

	* 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.
parent 7f36a8c7
2002-11-03 Havoc Pennington <hp@pobox.com>
* 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 <chris@gnome-de.org>
* configure.in: We want at least autoconf 2.5.
......
......@@ -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
......
......@@ -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,
......
......@@ -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 _
......
......@@ -177,6 +177,35 @@
</locale>
</schema>
<schema>
<key>/schemas/apps/metacity/workspace_names/name</key>
<applyto>/apps/metacity/workspace_names/name_1</applyto>
<applyto>/apps/metacity/workspace_names/name_2</applyto>
<applyto>/apps/metacity/workspace_names/name_3</applyto>
<applyto>/apps/metacity/workspace_names/name_4</applyto>
<applyto>/apps/metacity/workspace_names/name_5</applyto>
<applyto>/apps/metacity/workspace_names/name_6</applyto>
<applyto>/apps/metacity/workspace_names/name_7</applyto>
<applyto>/apps/metacity/workspace_names/name_8</applyto>
<applyto>/apps/metacity/workspace_names/name_9</applyto>
<applyto>/apps/metacity/workspace_names/name_10</applyto>
<applyto>/apps/metacity/workspace_names/name_11</applyto>
<applyto>/apps/metacity/workspace_names/name_12</applyto>
<applyto>/apps/metacity/workspace_names/name_13</applyto>
<applyto>/apps/metacity/workspace_names/name_14</applyto>
<applyto>/apps/metacity/workspace_names/name_15</applyto>
<applyto>/apps/metacity/workspace_names/name_16</applyto>
<owner>metacity</owner>
<type>string</type>
<default></default>
<locale name="C">
<short>Name of workspace</short>
<long>
The name of a workspace.
</long>
</locale>
</schema>
<!-- Window Keybindings -->
<schema>
......
......@@ -27,6 +27,9 @@
#include <string.h>
#include <stdlib.h>
#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)
{
......
......@@ -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"
......
......@@ -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);
......