mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-10-29 05:40:12 -04:00 
			
		
		
		
	xwayland/xwm: handle deleted properties
X11 clients might delete window properties. In that case, reset our state to the initial value.
This commit is contained in:
		
							parent
							
								
									e752e3ec06
								
							
						
					
					
						commit
						5175b6e94e
					
				
					 1 changed files with 66 additions and 35 deletions
				
			
		
							
								
								
									
										101
									
								
								xwayland/xwm.c
									
										
									
									
									
								
							
							
						
						
									
										101
									
								
								xwayland/xwm.c
									
										
									
									
									
								
							|  | @ -644,8 +644,8 @@ static void xwayland_surface_destroy(struct wlr_xwayland_surface *xsurface) { | |||
| 
 | ||||
| static void read_surface_class(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *surface, 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) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -674,8 +674,8 @@ static void read_surface_class(struct wlr_xwm *xwm, | |||
| static void read_surface_startup_id(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		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) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -713,8 +713,8 @@ static void read_surface_opacity(struct wlr_xwm *xwm, | |||
| static void read_surface_role(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		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) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -734,13 +734,13 @@ static void read_surface_role(struct wlr_xwm *xwm, | |||
| static void read_surface_title(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		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) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	bool is_utf8 = reply->type == xwm->atoms[UTF8_STRING]; | ||||
| 	if (!is_utf8 && xsurface->has_utf8_title) { | ||||
| 	if (!is_utf8 && xsurface->has_utf8_title && reply->type != XCB_ATOM_NONE) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -774,13 +774,13 @@ static bool has_parent(struct wlr_xwayland_surface *parent, | |||
| static void read_surface_parent(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	struct wlr_xwayland_surface *found_parent = NULL; | ||||
| 	if (reply->type != XCB_ATOM_WINDOW) { | ||||
| 	if (reply->type != XCB_ATOM_WINDOW && reply->type != XCB_ATOM_NONE) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_xwayland_surface *found_parent = NULL; | ||||
| 	xcb_window_t *xid = xcb_get_property_value(reply); | ||||
| 	if (xid != NULL) { | ||||
| 	if (reply->type != XCB_ATOM_NONE && xid != NULL) { | ||||
| 		found_parent = lookup_surface(xwm, *xid); | ||||
| 		if (!has_parent(found_parent, xsurface)) { | ||||
| 			xsurface->parent = found_parent; | ||||
|  | @ -792,7 +792,6 @@ static void read_surface_parent(struct wlr_xwm *xwm, | |||
| 		xsurface->parent = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	wl_list_remove(&xsurface->parent_link); | ||||
| 	if (xsurface->parent != NULL) { | ||||
| 		wl_list_insert(&xsurface->parent->children, &xsurface->parent_link); | ||||
|  | @ -806,7 +805,7 @@ static void read_surface_parent(struct wlr_xwm *xwm, | |||
| static void read_surface_window_type(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	if (reply->type != XCB_ATOM_ATOM) { | ||||
| 	if (reply->type != XCB_ATOM_ATOM && reply->type != XCB_ATOM_NONE) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -815,11 +814,15 @@ static void read_surface_window_type(struct wlr_xwm *xwm, | |||
| 	size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; | ||||
| 
 | ||||
| 	free(xsurface->window_type); | ||||
| 	xsurface->window_type = malloc(atoms_size); | ||||
| 	if (xsurface->window_type == NULL) { | ||||
| 		return; | ||||
| 	if (atoms_len > 0) { | ||||
| 		xsurface->window_type = malloc(atoms_size); | ||||
| 		if (xsurface->window_type == NULL) { | ||||
| 			return; | ||||
| 		} | ||||
| 		memcpy(xsurface->window_type, atoms, atoms_size); | ||||
| 	} else { | ||||
| 		xsurface->window_type = NULL; | ||||
| 	} | ||||
| 	memcpy(xsurface->window_type, atoms, atoms_size); | ||||
| 	xsurface->window_type_len = atoms_len; | ||||
| 
 | ||||
| 	wl_signal_emit_mutable(&xsurface->events.set_window_type, NULL); | ||||
|  | @ -828,7 +831,7 @@ static void read_surface_window_type(struct wlr_xwm *xwm, | |||
| static void read_surface_protocols(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	if (reply->type != XCB_ATOM_ATOM) { | ||||
| 	if (reply->type != XCB_ATOM_ATOM && reply->type != XCB_ATOM_NONE) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -837,11 +840,15 @@ static void read_surface_protocols(struct wlr_xwm *xwm, | |||
| 	size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; | ||||
| 
 | ||||
| 	free(xsurface->protocols); | ||||
| 	xsurface->protocols = malloc(atoms_size); | ||||
| 	if (xsurface->protocols == NULL) { | ||||
| 		return; | ||||
| 	if (atoms_len > 0) { | ||||
| 		xsurface->protocols = malloc(atoms_size); | ||||
| 		if (xsurface->protocols == NULL) { | ||||
| 			return; | ||||
| 		} | ||||
| 		memcpy(xsurface->protocols, atoms, atoms_size); | ||||
| 	} else { | ||||
| 		xsurface->protocols = NULL; | ||||
| 	} | ||||
| 	memcpy(xsurface->protocols, atoms, atoms_size); | ||||
| 	xsurface->protocols_len = atoms_len; | ||||
| } | ||||
| 
 | ||||
|  | @ -850,21 +857,26 @@ static void read_surface_hints(struct wlr_xwm *xwm, | |||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	// According to the docs, reply->type == xwm->atoms[WM_HINTS]
 | ||||
| 	// In practice, reply->type == XCB_ATOM_ATOM
 | ||||
| 	if (reply->value_len == 0) { | ||||
| 	if (reply->type != xwm->atoms[WM_HINTS] && reply->type != XCB_ATOM_ATOM && | ||||
| 			reply->type != XCB_ATOM_NONE) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	free(xsurface->hints); | ||||
| 	xsurface->hints = calloc(1, sizeof(*xsurface->hints)); | ||||
| 	if (xsurface->hints == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 	xcb_icccm_get_wm_hints_from_reply(xsurface->hints, reply); | ||||
| 	if (reply->value_len > 0) { | ||||
| 		xsurface->hints = calloc(1, sizeof(*xsurface->hints)); | ||||
| 		if (xsurface->hints == NULL) { | ||||
| 			return; | ||||
| 		} | ||||
| 		xcb_icccm_get_wm_hints_from_reply(xsurface->hints, reply); | ||||
| 
 | ||||
| 	if (!(xsurface->hints->flags & XCB_ICCCM_WM_HINT_INPUT)) { | ||||
| 		// The client didn't specify whether it wants input.
 | ||||
| 		// Assume it does.
 | ||||
| 		xsurface->hints->input = true; | ||||
| 		if (!(xsurface->hints->flags & XCB_ICCCM_WM_HINT_INPUT)) { | ||||
| 			// The client didn't specify whether it wants input.
 | ||||
| 			// Assume it does.
 | ||||
| 			xsurface->hints->input = true; | ||||
| 		} | ||||
| 	} else { | ||||
| 		xsurface->hints = NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_signal_emit_mutable(&xsurface->events.set_hints, NULL); | ||||
|  | @ -873,11 +885,17 @@ static void read_surface_hints(struct wlr_xwm *xwm, | |||
| static void read_surface_normal_hints(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	if (reply->type != xwm->atoms[WM_SIZE_HINTS] || reply->value_len == 0) { | ||||
| 	if (reply->type != xwm->atoms[WM_SIZE_HINTS] && reply->type != XCB_ATOM_NONE) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	free(xsurface->size_hints); | ||||
| 	xsurface->size_hints = NULL; | ||||
| 
 | ||||
| 	if (reply->value_len == 0) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	xsurface->size_hints = calloc(1, sizeof(*xsurface->size_hints)); | ||||
| 	if (xsurface->size_hints == NULL) { | ||||
| 		return; | ||||
|  | @ -919,6 +937,12 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, | |||
| static void read_surface_motif_hints(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	if (reply->value_len == 0) { | ||||
| 		xsurface->decorations = 0; | ||||
| 		wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (reply->value_len < 5) { | ||||
| 		return; | ||||
| 	} | ||||
|  | @ -944,13 +968,20 @@ static void read_surface_motif_hints(struct wlr_xwm *xwm, | |||
| static void read_surface_strut_partial(struct wlr_xwm *xwm, | ||||
| 		struct wlr_xwayland_surface *xsurface, | ||||
| 		xcb_get_property_reply_t *reply) { | ||||
| 	free(xsurface->strut_partial); | ||||
| 	xsurface->strut_partial = NULL; | ||||
| 
 | ||||
| 	if (reply->type == XCB_ATOM_NONE) { | ||||
| 		wl_signal_emit_mutable(&xsurface->events.set_strut_partial, NULL); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (reply->type != XCB_ATOM_CARDINAL || reply->format != 32 || | ||||
| 			xcb_get_property_value_length(reply) != | ||||
| 			sizeof(xcb_ewmh_wm_strut_partial_t)) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	free(xsurface->strut_partial); | ||||
| 	xsurface->strut_partial = calloc(1, sizeof(*xsurface->strut_partial)); | ||||
| 	if (xsurface->strut_partial == NULL) { | ||||
| 		return; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Simon Ser
						Simon Ser