summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2023-02-27 14:30:38 +0100
committerMarge Bot <marge-bot@gnome.org>2023-02-27 15:38:25 +0000
commit022e20e87e9c5ce6b7da71e24960226f923a052f (patch)
tree31bf7823903504b8e429b2d87435dade98ac3fc1
parent6df9eab8800097ee44729bb775e7ae3660e011ea (diff)
downloadmutter-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.c64
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)