diff --git a/ChangeLog b/ChangeLog index 042b9739f..6d92c4b52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2002-11-03 Havoc Pennington + + * src/window-props.c (meta_display_init_window_prop_hooks): add + _NET_WM_NAME, WM_NAME, _NET_WM_ICON_NAME, WM_ICON_NAME support + + * src/window.c (meta_window_new): use window-props.h for + _NET_WM_NAME, WM_NAME, _NET_WM_ICON_NAME, WM_ICON_NAME + 2002-11-03 Havoc Pennington * src/window.c (meta_window_new): use window-props.h stuff for a diff --git a/src/window-props.c b/src/window-props.c index 13c5eb03c..503124d89 100644 --- a/src/window-props.c +++ b/src/window-props.c @@ -22,6 +22,7 @@ #include #include "window-props.h" #include "xprops.h" +#include "frame.h" #include typedef void (* InitValueFunc) (MetaDisplay *display, @@ -167,6 +168,170 @@ reload_net_wm_pid (MetaWindow *window, } } +static void +set_window_title (MetaWindow *window, + const char *title) +{ + char *str; + + g_free (window->title); + + if (title == NULL) + window->title = g_strdup (""); + else + window->title = g_strdup (title); + + /* strndup is a hack since GNU libc has broken %.10s */ + str = g_strndup (window->title, 10); + g_free (window->desc); + window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str); + g_free (str); + + if (window->frame) + meta_ui_set_frame_title (window->screen->ui, + window->frame->xwindow, + window->title); +} + +static void +init_net_wm_name (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_UTF8; + value->atom = display->atom_net_wm_name; +} + +static void +reload_net_wm_name (MetaWindow *window, + MetaPropValue *value) +{ + if (value->type != META_PROP_VALUE_INVALID) + { + set_window_title (window, value->v.str); + window->using_net_wm_name = TRUE; + + meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"\n", + window->desc, window->title); + } + else + { + set_window_title (window, NULL); + window->using_net_wm_name = FALSE; + } +} + + +static void +init_wm_name (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_STRING; + value->atom = XA_WM_NAME; +} + +static void +reload_wm_name (MetaWindow *window, + MetaPropValue *value) +{ + if (window->using_net_wm_name) + { + meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set\n", + value->v.str); + return; + } + + if (value->type != META_PROP_VALUE_INVALID) + { + set_window_title (window, value->v.str); + + meta_verbose ("Using WM_NAME for new title of %s: \"%s\"\n", + window->desc, window->title); + } + else + { + set_window_title (window, NULL); + } +} + +static void +set_icon_title (MetaWindow *window, + const char *title) +{ + char *str; + + g_free (window->icon_name); + + if (title == NULL) + window->icon_name = g_strdup (""); + else + window->icon_name = g_strdup (title); +} + +static void +init_net_wm_icon_name (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_UTF8; + value->atom = display->atom_net_wm_icon_name; +} + +static void +reload_net_wm_icon_name (MetaWindow *window, + MetaPropValue *value) +{ + if (value->type != META_PROP_VALUE_INVALID) + { + set_icon_title (window, value->v.str); + window->using_net_wm_icon_name = TRUE; + + meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n", + window->desc, window->title); + } + else + { + set_icon_title (window, NULL); + window->using_net_wm_icon_name = FALSE; + } +} + + +static void +init_wm_icon_name (MetaDisplay *display, + Atom property, + MetaPropValue *value) +{ + value->type = META_PROP_VALUE_STRING; + value->atom = XA_WM_ICON_NAME; +} + +static void +reload_wm_icon_name (MetaWindow *window, + MetaPropValue *value) +{ + if (window->using_net_wm_icon_name) + { + meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n", + value->v.str); + return; + } + + if (value->type != META_PROP_VALUE_INVALID) + { + set_icon_title (window, value->v.str); + + meta_verbose ("Using WM_ICON_NAME for new title of %s: \"%s\"\n", + window->desc, window->title); + } + else + { + set_icon_title (window, NULL); + } +} + + #define N_HOOKS 22 void @@ -203,15 +368,25 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) ++i; hooks[i].property = display->atom_net_wm_name; - hooks[i].init_func = NULL; - hooks[i].reload_func = NULL; + hooks[i].init_func = init_net_wm_name; + hooks[i].reload_func = reload_net_wm_name; ++i; hooks[i].property = XA_WM_NAME; - hooks[i].init_func = NULL; - hooks[i].reload_func = NULL; + hooks[i].init_func = init_wm_name; + hooks[i].reload_func = reload_wm_name; ++i; + hooks[i].property = display->atom_net_wm_icon_name; + hooks[i].init_func = init_net_wm_icon_name; + hooks[i].reload_func = reload_net_wm_icon_name; + ++i; + + hooks[i].property = XA_WM_ICON_NAME; + hooks[i].init_func = init_wm_icon_name; + hooks[i].reload_func = reload_wm_icon_name; + ++i; + hooks[i].property = XA_WM_HINTS; hooks[i].init_func = NULL; hooks[i].reload_func = NULL; @@ -272,16 +447,6 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) hooks[i].reload_func = NULL; ++i; - hooks[i].property = display->atom_net_wm_icon_name; - hooks[i].init_func = NULL; - hooks[i].reload_func = NULL; - ++i; - - hooks[i].property = XA_WM_ICON_NAME; - hooks[i].init_func = NULL; - hooks[i].reload_func = NULL; - ++i; - hooks[i].property = display->atom_net_wm_strut; hooks[i].init_func = NULL; hooks[i].reload_func = NULL; diff --git a/src/window.c b/src/window.c index d8fec1b03..ab4bf60b6 100644 --- a/src/window.c +++ b/src/window.c @@ -74,7 +74,6 @@ static void constrain_position (MetaWindow *window, int *new_y); static void update_size_hints (MetaWindow *window); -static void update_title (MetaWindow *window); static void update_protocols (MetaWindow *window); static void update_wm_hints (MetaWindow *window); static void update_net_wm_state (MetaWindow *window); @@ -85,7 +84,6 @@ static void update_sm_hints (MetaWindow *window); static void update_role (MetaWindow *window); static void update_net_wm_type (MetaWindow *window); static void update_initial_workspace (MetaWindow *window); -static void update_icon_name (MetaWindow *window); static void update_icon (MetaWindow *window); static void redraw_icon (MetaWindow *window); static void update_struts (MetaWindow *window); @@ -160,8 +158,9 @@ meta_window_new (MetaDisplay *display, GSList *tmp; MetaWorkspace *space; gulong existing_wm_state; -#define N_INITIAL_PROPS 2 +#define N_INITIAL_PROPS 6 Atom initial_props[N_INITIAL_PROPS]; + int i; g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props)); @@ -422,6 +421,9 @@ meta_window_new (MetaDisplay *display, window->bottom_strut = 0; window->cached_group = NULL; + + window->using_net_wm_name = FALSE; + window->using_net_wm_icon_name = FALSE; window->layer = META_LAYER_LAST; /* invalid value */ window->stack_position = -1; @@ -429,14 +431,18 @@ meta_window_new (MetaDisplay *display, meta_display_register_x_window (display, &window->xwindow, window); /* Fill these in the order we want them to be gotten */ - initial_props[0] = display->atom_wm_client_machine; - initial_props[1] = display->atom_net_wm_pid; - g_assert (N_INITIAL_PROPS == 2); + i = 0; + initial_props[i++] = display->atom_wm_client_machine; + initial_props[i++] = display->atom_net_wm_pid; + initial_props[i++] = display->atom_net_wm_name; + initial_props[i++] = XA_WM_NAME; + initial_props[i++] = display->atom_net_wm_icon_name; + initial_props[i++] = XA_WM_ICON_NAME; + g_assert (N_INITIAL_PROPS == i); meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS); - + update_size_hints (window); - update_title (window); update_protocols (window); update_wm_hints (window); update_struts (window); @@ -450,7 +456,6 @@ meta_window_new (MetaDisplay *display, update_role (window); update_net_wm_type (window); update_initial_workspace (window); - update_icon_name (window); update_icon (window); if (window->initially_iconic) @@ -3843,12 +3848,40 @@ static gboolean process_property_notify (MetaWindow *window, XPropertyEvent *event) { - if (event->atom == XA_WM_NAME || - event->atom == window->display->atom_net_wm_name) + if (event->atom == XA_WM_NAME) { - meta_verbose ("Property notify on %s for WM_NAME or NET_WM_NAME\n", window->desc); - update_title (window); + meta_verbose ("Property notify on %s for WM_NAME\n", window->desc); + + /* don't bother reloading WM_NAME if using _NET_WM_NAME already */ + if (!window->using_net_wm_name) + meta_window_reload_property (window, XA_WM_NAME); } + else if (event->atom == window->display->atom_net_wm_name) + { + meta_verbose ("Property notify on %s for NET_WM_NAME\n", window->desc); + meta_window_reload_property (window, window->display->atom_net_wm_name); + + /* if _NET_WM_NAME was unset, reload WM_NAME */ + if (!window->using_net_wm_name) + meta_window_reload_property (window, XA_WM_NAME); + } + else if (event->atom == XA_WM_ICON_NAME) + { + meta_verbose ("Property notify on %s for WM_ICON_NAME\n", window->desc); + + /* don't bother reloading WM_ICON_NAME if using _NET_WM_ICON_NAME already */ + if (!window->using_net_wm_icon_name) + meta_window_reload_property (window, XA_WM_ICON_NAME); + } + else if (event->atom == window->display->atom_net_wm_icon_name) + { + meta_verbose ("Property notify on %s for NET_WM_ICON_NAME\n", window->desc); + meta_window_reload_property (window, window->display->atom_net_wm_icon_name); + + /* if _NET_WM_ICON_NAME was unset, reload WM_ICON_NAME */ + if (!window->using_net_wm_icon_name) + meta_window_reload_property (window, XA_WM_ICON_NAME); + } else if (event->atom == XA_WM_NORMAL_HINTS) { meta_verbose ("Property notify on %s for WM_NORMAL_HINTS\n", window->desc); @@ -3931,14 +3964,6 @@ process_property_notify (MetaWindow *window, meta_verbose ("Property notify on %s for NET_WM_WINDOW_TYPE or WIN_LAYER\n", window->desc); update_net_wm_type (window); } - else if (event->atom == - window->display->atom_net_wm_icon_name || - event->atom == XA_WM_ICON_NAME) - { - meta_verbose ("Property notify on %s for NET_WM_ICON_NAME or WM_ICON_NAME\n", window->desc); - - update_icon_name (window); - } else if (event->atom == window->display->atom_net_wm_icon) { meta_verbose ("Property notify on %s for NET_WM_ICON\n", window->desc); @@ -4261,60 +4286,6 @@ update_size_hints (MetaWindow *window) spew_size_hints_differences (&old_hints, &window->size_hints); } -static void -update_title (MetaWindow *window) -{ - char *str; - - if (window->title) - { - g_free (window->title); - window->title = NULL; - } - - str = NULL; - meta_prop_get_utf8_string (window->display, - window->xwindow, - window->display->atom_net_wm_name, - &str); - window->title = g_strdup (str); - meta_XFree (str); - - if (window->title) - { - meta_verbose ("Using _NET_WM_NAME for new title of %s: '%s'\n", - window->desc, window->title); - } - - if (window->title == NULL) - { - meta_prop_get_text_property (window->display, - window->xwindow, - XA_WM_NAME, - &window->title); - - if (window->title) - { - meta_verbose ("Using WM_NAME for new title of %s: '%s'\n", - window->desc, window->title); - } - } - - if (window->title == NULL) - window->title = g_strdup (""); - - /* strndup is a hack since GNU libc has broken %.10s */ - str = g_strndup (window->title, 10); - g_free (window->desc); - window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str); - g_free (str); - - if (window->frame) - meta_ui_set_frame_title (window->screen->ui, - window->frame->xwindow, - window->title); -} - static void update_protocols (MetaWindow *window) { @@ -4938,49 +4909,6 @@ update_initial_workspace (MetaWindow *window) } } -static void -update_icon_name (MetaWindow *window) -{ - char *str; - - if (window->icon_name) - { - g_free (window->icon_name); - window->icon_name = NULL; - } - - str = NULL; - meta_prop_get_utf8_string (window->display, window->xwindow, - window->display->atom_net_wm_icon_name, - &str); - - window->icon_name = g_strdup (str); - if (str) - meta_XFree (str); - - if (window->icon_name) - { - meta_verbose ("Using _NET_WM_ICON_NAME for new icon name of %s: '%s'\n", - window->desc, window->icon_name); - } - - if (window->icon_name == NULL) - { - meta_prop_get_text_property (window->display, window->xwindow, - XA_WM_ICON_NAME, - &window->icon_name); - - if (window->icon_name) - { - meta_verbose ("Using WM_ICON_NAME for new title of %s: '%s'\n", - window->desc, window->icon_name); - } - } - - if (window->icon_name == NULL) - window->icon_name = g_strdup (""); -} - static void update_icon (MetaWindow *window) { diff --git a/src/window.h b/src/window.h index 03e25dce0..09d580334 100644 --- a/src/window.h +++ b/src/window.h @@ -211,6 +211,10 @@ struct _MetaWindow /* Transient parent is a root window */ guint transient_parent_is_root_window : 1; + + /* Info on which props we got our attributes from */ + guint using_net_wm_name : 1; /* vs. plain wm_name */ + guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */ /* Number of UnmapNotify that are caused by us, if * we get UnmapNotify with none pending then the client