From 0243071f158363895db559652848463b25423fa0 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 22 Jun 2002 04:52:35 +0000 Subject: [PATCH] new utility function 2002-06-22 Havoc Pennington * src/xprops.c (meta_prop_get_utf8_list): new utility function * src/display.c (meta_display_open): _NET_DESKTOP_NAMES atom (event_callback): update workspace names when the property changes * src/screen.c (set_supported_hint): "support" _NET_DESKTOP_NAMES (nothing to do really) --- ChangeLog | 10 ++++++ src/display.c | 4 +++ src/display.h | 1 + src/screen.c | 43 +++++++++++++++++++++- src/screen.h | 1 + src/workspace.c | 22 ++++++++++++ src/workspace.h | 5 +++ src/xprops.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ src/xprops.h | 5 +++ 9 files changed, 186 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0741b7e95..2a860436f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2002-06-22 Havoc Pennington + + * src/xprops.c (meta_prop_get_utf8_list): new utility function + + * src/display.c (meta_display_open): _NET_DESKTOP_NAMES atom + (event_callback): update workspace names when the property changes + + * src/screen.c (set_supported_hint): "support" _NET_DESKTOP_NAMES + (nothing to do really) + 2002-06-21 Havoc Pennington Theme breakage! Themes have to implement "border" frames diff --git a/src/display.c b/src/display.c index ee0d43e89..32c09f4ad 100644 --- a/src/display.c +++ b/src/display.c @@ -355,6 +355,7 @@ meta_display_open (const char *name) display->atom_timestamp = atoms[62]; display->atom_version = atoms[63]; display->atom_atom_pair = atoms[64]; + display->atom_net_desktop_names = atoms[65]; /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, * created in screen_new @@ -1383,6 +1384,9 @@ event_callback (XEvent *event, if (event->xproperty.atom == display->atom_net_desktop_layout) meta_screen_update_workspace_layout (screen); + else if (event->xproperty.atom == + display->atom_net_desktop_names) + meta_screen_update_workspace_names (screen); } } break; diff --git a/src/display.h b/src/display.h index 52b8292fc..1b26ad9e5 100644 --- a/src/display.h +++ b/src/display.h @@ -137,6 +137,7 @@ struct _MetaDisplay Atom atom_timestamp; Atom atom_version; Atom atom_atom_pair; + Atom atom_net_desktop_names; /* This is the actual window from focus events, * not the one we last set diff --git a/src/screen.c b/src/screen.c index 0cfd051df..aef9e82b8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -81,7 +81,7 @@ set_wm_check_hint (MetaScreen *screen) static int set_supported_hint (MetaScreen *screen) { -#define N_SUPPORTED 32 +#define N_SUPPORTED 33 #define N_WIN_SUPPORTED 1 Atom atoms[N_SUPPORTED]; @@ -117,6 +117,7 @@ set_supported_hint (MetaScreen *screen) atoms[29] = screen->display->atom_net_wm_workarea; atoms[30] = screen->display->atom_net_show_desktop; atoms[31] = screen->display->atom_net_desktop_layout; + atoms[32] = screen->display->atom_net_desktop_names; XChangeProperty (screen->display->xdisplay, screen->xroot, screen->display->atom_net_supported, @@ -460,6 +461,7 @@ meta_screen_new (MetaDisplay *display, set_wm_check_hint (screen); meta_screen_update_workspace_layout (screen); + meta_screen_update_workspace_names (screen); /* Screens must have at least one workspace at all times, * so create that required workspace. @@ -1112,6 +1114,45 @@ meta_screen_update_workspace_layout (MetaScreen *screen) screen->vertical_workspaces); } +void +meta_screen_update_workspace_names (MetaScreen *screen) +{ + char **names; + int n_names; + int i; + GList *tmp; + + names = NULL; + n_names = 0; + if (!meta_prop_get_utf8_list (screen->display, + screen->xroot, + screen->display->atom_net_desktop_names, + &names, &n_names)) + { + meta_verbose ("Failed to get workspace names from root window %d\n", + screen->number); + return; + } + + i = 0; + tmp = screen->display->workspaces; + while (tmp != NULL && i < n_names) + { + MetaWorkspace *w = tmp->data; + + if (w->screen == screen) + { + meta_workspace_set_name (w, names[i]); + + ++i; + } + + tmp = tmp->next; + } + + g_strfreev (names); +} + Window meta_create_offscreen_window (Display *xdisplay, Window parent) diff --git a/src/screen.h b/src/screen.h index d8b938e30..018348e5e 100644 --- a/src/screen.h +++ b/src/screen.h @@ -106,6 +106,7 @@ const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *s MetaWindow *window); void meta_screen_update_workspace_layout (MetaScreen *screen); +void meta_screen_update_workspace_names (MetaScreen *screen); Window meta_create_offscreen_window (Display *xdisplay, Window parent); diff --git a/src/workspace.c b/src/workspace.c index 2a2c6ed60..984326759 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -23,6 +23,7 @@ #include "workspace.h" #include "errors.h" #include +#include void meta_workspace_queue_calc_showing (MetaWorkspace *workspace); @@ -47,6 +48,9 @@ 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\n"), + meta_workspace_index (workspace) + 1); /* Update hint for current number of workspaces */ set_number_of_spaces_hint (screen); @@ -87,10 +91,15 @@ meta_workspace_free (MetaWorkspace *workspace) workspace->screen->display->workspaces = g_list_remove (workspace->screen->display->workspaces, workspace); + g_free (workspace->name); + g_free (workspace); /* Update hint for current number of workspaces */ set_number_of_spaces_hint (screen); + /* don't bother to reset names, pagers can just ignore + * extra ones + */ } void @@ -747,3 +756,16 @@ meta_workspace_ensure_tab_popup (MetaDisplay *display, /* don't show tab popup, since proper window isn't selected yet */ } +void +meta_workspace_set_name (MetaWorkspace *workspace, + const char *name) +{ + 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); +} diff --git a/src/workspace.h b/src/workspace.h index 90c62a5b7..8fbdc74c0 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -41,6 +41,8 @@ struct _MetaWorkspace GList *windows; + char *name; + MetaRectangle work_area; guint work_area_invalid : 1; }; @@ -72,6 +74,9 @@ MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace, void meta_workspace_ensure_tab_popup (MetaDisplay *display, MetaScreen *screen); +void meta_workspace_set_name (MetaWorkspace *workspace, + const char *name); + #endif diff --git a/src/xprops.c b/src/xprops.c index bb539c30b..3c54ebd13 100644 --- a/src/xprops.c +++ b/src/xprops.c @@ -24,6 +24,7 @@ #include "errors.h" #include "util.h" #include +#include static gboolean check_type_and_format (MetaDisplay *display, @@ -291,6 +292,101 @@ meta_prop_get_utf8_string (MetaDisplay *display, return TRUE; } +gboolean +meta_prop_get_utf8_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p) +{ + Atom type; + int format; + gulong bytes_after; + guchar *val; + gulong n_items; + int i; + int n_strings; + char **retval; + const char *p; + + *str_p = NULL; + *n_str_p = 0; + + meta_error_trap_push (display); + if (XGetWindowProperty (display->xdisplay, xwindow, xatom, + 0, G_MAXLONG, + False, display->atom_utf8_string, + &type, &format, &n_items, + &bytes_after, (guchar **)&val) != Success || + type == None) + { + meta_error_trap_pop (display); + return FALSE; + } + + if (meta_error_trap_pop (display) != Success) + return FALSE; + + if (!check_type_and_format (display, xwindow, xatom, 8, + display->atom_utf8_string, + -1, format, type)) + { + XFree (val); + return FALSE; + } + + /* I'm not sure this is right, but I'm guessing the + * property is nul-separated + */ + i = 0; + n_strings = 1; + while (i < (int) n_items) + { + if (val[i] == '\0') + ++n_strings; + ++i; + } + + /* we're guaranteed that val has a nul on the end + * by XGetWindowProperty + */ + + retval = g_new0 (char*, n_strings + 1); + + p = val; + i = 0; + while (i < n_strings) + { + if (!g_utf8_validate (p, -1, NULL)) + { + char *name; + + meta_error_trap_push (display); + name = XGetAtomName (display->xdisplay, xatom); + meta_error_trap_pop (display); + meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"), + name, xwindow, i); + meta_XFree (name); + meta_XFree (val); + + g_strfreev (retval); + return FALSE; + } + + retval[i] = g_strdup (p); + + p = p + strlen (p) + 1; + ++i; + } + + *str_p = retval; + *n_str_p = i; + + meta_XFree (val); + + return TRUE; +} + gboolean meta_prop_get_window (MetaDisplay *display, Window xwindow, diff --git a/src/xprops.h b/src/xprops.h index 0992979b0..aef8b4fb4 100644 --- a/src/xprops.h +++ b/src/xprops.h @@ -89,6 +89,11 @@ gboolean meta_prop_get_utf8_string (MetaDisplay *display, Window xwindow, Atom xatom, char **str_p); +gboolean meta_prop_get_utf8_list (MetaDisplay *display, + Window xwindow, + Atom xatom, + char ***str_p, + int *n_str_p); gboolean meta_prop_get_window (MetaDisplay *display, Window xwindow, Atom xatom,