diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2023-02-27 14:30:38 +0100 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2023-02-27 15:38:25 +0000 |
commit | 022e20e87e9c5ce6b7da71e24960226f923a052f (patch) | |
tree | 31bf7823903504b8e429b2d87435dade98ac3fc1 | |
parent | 6df9eab8800097ee44729bb775e7ae3660e011ea (diff) | |
download | mutter-022e20e87e9c5ce6b7da71e24960226f923a052f.tar.gz |
frames: Handle WM_NAME
This is the most ancient form of "window titles", not guaranteed
to be UTF-8, take the usual precautions before using this string
and keep it as a last resort.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2872>
-rw-r--r-- | src/frames/meta-frame.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/frames/meta-frame.c b/src/frames/meta-frame.c index 61c16e404..853008e00 100644 --- a/src/frames/meta-frame.c +++ b/src/frames/meta-frame.c @@ -37,6 +37,7 @@ struct _MetaFrame char *net_wm_visible_name; char *net_wm_name; + char *wm_name; }; typedef struct @@ -83,6 +84,7 @@ meta_frame_finalize (GObject *object) g_free (frame->net_wm_visible_name); g_free (frame->net_wm_name); + g_free (frame->wm_name); G_OBJECT_CLASS (meta_frame_parent_class)->finalize (object); } @@ -291,6 +293,8 @@ update_frame_title (MetaFrame *frame) title = frame->net_wm_visible_name; else if (frame->net_wm_name) title = frame->net_wm_visible_name; + else if (frame->wm_name) + title = frame->wm_name; else title = ""; @@ -321,6 +325,63 @@ frame_sync_net_wm_name (GtkWindow *window, update_frame_title (frame); } +static char * +text_property_to_utf8 (GdkDisplay *display, + const XTextProperty *prop) +{ + Display *xdisplay; + char *ret = NULL; + char **local_list = NULL; + int count = 0; + int res; + + xdisplay = gdk_x11_display_get_xdisplay (display); + + res = XmbTextPropertyToTextList (xdisplay, prop, + &local_list, &count); + if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound) + goto out; + + if (count == 0) + goto out; + + if (!g_utf8_validate (local_list[0], -1, NULL)) + ret = NULL; + else + ret = g_strdup (local_list[0]); + + out: + XFreeStringList (local_list); + return ret; +} + +static void +frame_sync_wm_name (GtkWindow *window, + Window client_window) +{ + MetaFrame *frame = META_FRAME (window); + GdkDisplay *display; + XTextProperty text_prop; + int retval; + + display = gtk_widget_get_display (GTK_WIDGET (frame)); + + gdk_x11_display_error_trap_push (display); + + retval = XGetWMName (gdk_x11_display_get_xdisplay (display), + client_window, + &text_prop); + + if (gdk_x11_display_error_trap_pop (display)) + return; + if (retval == 0) + return; + + frame->wm_name = text_property_to_utf8 (display, &text_prop); + update_frame_title (frame); + XFree (text_prop.value); +} + static void frame_sync_motif_wm_hints (GtkWindow *window, Window client_window) @@ -441,6 +502,7 @@ meta_frame_new (Window window) frame_sync_net_wm_visible_name (GTK_WINDOW (frame), window); frame_sync_net_wm_name (GTK_WINDOW (frame), window); + frame_sync_wm_name (GTK_WINDOW (frame), window); frame_sync_motif_wm_hints (GTK_WINDOW (frame), window); frame_sync_wm_normal_hints (GTK_WINDOW (frame), window); @@ -477,6 +539,8 @@ meta_frame_handle_xevent (MetaFrame *frame, frame_sync_net_wm_visible_name (GTK_WINDOW (frame), xevent->xproperty.window); else if (xevent->xproperty.atom == frame->atom__NET_WM_NAME) frame_sync_net_wm_name (GTK_WINDOW (frame), xevent->xproperty.window); + else if (xevent->xproperty.atom == XA_WM_NAME) + frame_sync_wm_name (GTK_WINDOW (frame), xevent->xproperty.window); else if (xevent->xproperty.atom == frame->atom__MOTIF_WM_HINTS) frame_sync_motif_wm_hints (GTK_WINDOW (frame), xevent->xproperty.window); else if (xevent->xproperty.atom == XA_WM_NORMAL_HINTS) |