mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	xwayland: handle unset _NET_WM_NAME
The spec says [1]: > If set, the Window Manager should use this in preference to WM_NAME. However we overwrite WM_NAME with NULL when _NET_WM_NAME is unset. Fix this by storing both WM_NAME and _NET_WM_NAME, so that we handle properly all combinations of events (e.g. a client setting both and later clearing one). [1]: https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html#id-1.6.2
This commit is contained in:
		
							parent
							
								
									2420bfef0b
								
							
						
					
					
						commit
						af34aaad53
					
				
					 2 changed files with 28 additions and 12 deletions
				
			
		| 
						 | 
					@ -232,6 +232,8 @@ struct wlr_xwayland_surface {
 | 
				
			||||||
	void *data;
 | 
						void *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
 | 
							char *wm_name, *net_wm_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct wl_listener surface_commit;
 | 
							struct wl_listener surface_commit;
 | 
				
			||||||
		struct wl_listener surface_map;
 | 
							struct wl_listener surface_map;
 | 
				
			||||||
		struct wl_listener surface_unmap;
 | 
							struct wl_listener surface_unmap;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -629,7 +629,8 @@ static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_event_source_remove(xsurface->ping_timer);
 | 
						wl_event_source_remove(xsurface->ping_timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(xsurface->title);
 | 
						free(xsurface->wm_name);
 | 
				
			||||||
 | 
						free(xsurface->net_wm_name);
 | 
				
			||||||
	free(xsurface->class);
 | 
						free(xsurface->class);
 | 
				
			||||||
	free(xsurface->instance);
 | 
						free(xsurface->instance);
 | 
				
			||||||
	free(xsurface->role);
 | 
						free(xsurface->role);
 | 
				
			||||||
| 
						 | 
					@ -739,7 +740,7 @@ static void read_surface_role(struct wlr_xwm *xwm,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void read_surface_title(struct wlr_xwm *xwm,
 | 
					static void read_surface_title(struct wlr_xwm *xwm,
 | 
				
			||||||
		struct wlr_xwayland_surface *xsurface,
 | 
							struct wlr_xwayland_surface *xsurface, xcb_atom_t property,
 | 
				
			||||||
		xcb_get_property_reply_t *reply) {
 | 
							xcb_get_property_reply_t *reply) {
 | 
				
			||||||
	if (reply->type != XCB_ATOM_STRING && reply->type != xwm->atoms[UTF8_STRING] &&
 | 
						if (reply->type != XCB_ATOM_STRING && reply->type != xwm->atoms[UTF8_STRING] &&
 | 
				
			||||||
			reply->type != XCB_ATOM_NONE) {
 | 
								reply->type != XCB_ATOM_NONE) {
 | 
				
			||||||
| 
						 | 
					@ -747,21 +748,34 @@ static void read_surface_title(struct wlr_xwm *xwm,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool is_utf8 = reply->type == xwm->atoms[UTF8_STRING];
 | 
						size_t len = xcb_get_property_value_length(reply);
 | 
				
			||||||
	if (!is_utf8 && xsurface->has_utf8_title && reply->type != XCB_ATOM_NONE) {
 | 
						const char *title_buffer = xcb_get_property_value(reply);
 | 
				
			||||||
		return;
 | 
						char *title = NULL;
 | 
				
			||||||
 | 
						if (len > 0) {
 | 
				
			||||||
 | 
							title = strndup(title_buffer, len);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size_t len = xcb_get_property_value_length(reply);
 | 
						if (property == XCB_ATOM_WM_NAME) {
 | 
				
			||||||
	char *title = xcb_get_property_value(reply);
 | 
							free(xsurface->wm_name);
 | 
				
			||||||
 | 
							xsurface->wm_name = title;
 | 
				
			||||||
 | 
						} else if (property == xwm->atoms[NET_WM_NAME]) {
 | 
				
			||||||
 | 
							free(xsurface->net_wm_name);
 | 
				
			||||||
 | 
							xsurface->net_wm_name = title;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							abort(); // unreachable
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(xsurface->title);
 | 
						// Prefer _NET_WM_NAME over WM_NAME if available
 | 
				
			||||||
	if (len > 0) {
 | 
						if (xsurface->net_wm_name != NULL) {
 | 
				
			||||||
		xsurface->title = strndup(title, len);
 | 
							xsurface->title = xsurface->net_wm_name;
 | 
				
			||||||
 | 
						} else if (xsurface->wm_name != NULL) {
 | 
				
			||||||
 | 
							xsurface->title = xsurface->wm_name;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		xsurface->title = NULL;
 | 
							xsurface->title = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	xsurface->has_utf8_title = is_utf8;
 | 
					
 | 
				
			||||||
 | 
						// TODO: drop this field
 | 
				
			||||||
 | 
						xsurface->has_utf8_title = reply->type == xwm->atoms[UTF8_STRING];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_signal_emit_mutable(&xsurface->events.set_title, NULL);
 | 
						wl_signal_emit_mutable(&xsurface->events.set_title, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1061,7 +1075,7 @@ static void read_surface_property(struct wlr_xwm *xwm,
 | 
				
			||||||
		read_surface_class(xwm, xsurface, reply);
 | 
							read_surface_class(xwm, xsurface, reply);
 | 
				
			||||||
	} else if (property == XCB_ATOM_WM_NAME ||
 | 
						} else if (property == XCB_ATOM_WM_NAME ||
 | 
				
			||||||
			property == xwm->atoms[NET_WM_NAME]) {
 | 
								property == xwm->atoms[NET_WM_NAME]) {
 | 
				
			||||||
		read_surface_title(xwm, xsurface, reply);
 | 
							read_surface_title(xwm, xsurface, property, reply);
 | 
				
			||||||
	} else if (property == XCB_ATOM_WM_TRANSIENT_FOR) {
 | 
						} else if (property == XCB_ATOM_WM_TRANSIENT_FOR) {
 | 
				
			||||||
		read_surface_parent(xwm, xsurface, reply);
 | 
							read_surface_parent(xwm, xsurface, reply);
 | 
				
			||||||
	} else if (property == xwm->atoms[NET_WM_PID]) {
 | 
						} else if (property == xwm->atoms[NET_WM_PID]) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue