|  |  | @ -36,6 +36,9 @@ const char *atom_map[ATOM_LAST] = { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	"_NET_WM_MOVERESIZE", |  |  |  | 	"_NET_WM_MOVERESIZE", | 
			
		
	
		
		
			
				
					
					|  |  |  | 	"_NET_WM_NAME", |  |  |  | 	"_NET_WM_NAME", | 
			
		
	
		
		
			
				
					
					|  |  |  | 	"_NET_SUPPORTING_WM_CHECK", |  |  |  | 	"_NET_SUPPORTING_WM_CHECK", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	"_NET_WM_STATE_FULLSCREEN", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	"_NET_WM_STATE_MAXIMIZED_VERT", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	"_NET_WM_STATE_MAXIMIZED_HORZ", | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /* General helpers */ |  |  |  | /* General helpers */ | 
			
		
	
	
		
		
			
				
					|  |  | @ -150,6 +153,30 @@ void xwm_surface_activate(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xcb_flush(xwm->xcb_conn); |  |  |  | 	xcb_flush(xwm->xcb_conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	struct wlr_xwm *xwm = xsurface->xwm; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	uint32_t property[3]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int i; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	i = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (xsurface->fullscreen) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		property[i++] = xwm->atoms[_NET_WM_STATE_FULLSCREEN]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (xsurface->maximized_vert) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		property[i++] = xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (xsurface->maximized_horz) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		property[i++] = xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	xcb_change_property(xwm->xcb_conn, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		XCB_PROP_MODE_REPLACE, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		xsurface->window_id, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		xwm->atoms[NET_WM_STATE], | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		XCB_ATOM_ATOM, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		32, // format
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		i, property); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) { |  |  |  | static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_signal_emit(&surface->events.destroy, surface); |  |  |  | 	wl_signal_emit(&surface->events.destroy, surface); | 
			
		
	
	
		
		
			
				
					|  |  | @ -271,44 +298,6 @@ static void read_surface_parent(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_signal_emit(&surface->events.set_parent, surface); |  |  |  | 	wl_signal_emit(&surface->events.set_parent, surface); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void handle_surface_state(struct wlr_xwm *xwm, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wlr_xwayland_surface *surface, xcb_atom_t *state, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		size_t state_len, enum net_wm_state_action action) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	for (size_t i = 0; i < state_len; i++) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xcb_atom_t atom = state[i]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		bool found = false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		for (size_t j = 0; j < surface->state->length; j++) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			xcb_atom_t *cur = surface->state->items[j]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			if (atom == *cur) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				found = true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				if (action == NET_WM_STATE_REMOVE || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 						action == NET_WM_STATE_TOGGLE) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 					free(surface->state->items[j]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 					wlr_list_del(surface->state, j); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (!found && (action == NET_WM_STATE_ADD || |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				action == NET_WM_STATE_TOGGLE)) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			xcb_atom_t *atom_ptr = malloc(sizeof(xcb_atom_t)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			*atom_ptr = atom; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wlr_list_add(surface->state, atom_ptr); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_log(L_DEBUG, "NET_WM_STATE (%zu)", state_len); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_signal_emit(&surface->events.set_state, surface); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void read_surface_state(struct wlr_xwm *xwm, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	// reply->type == XCB_ATOM_ANY
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	handle_surface_state(xwm, surface, xcb_get_property_value(reply), |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		reply->value_len, NET_WM_STATE_ADD); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void read_surface_pid(struct wlr_xwm *xwm, |  |  |  | static void read_surface_pid(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { |  |  |  | 		struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (reply->type != XCB_ATOM_CARDINAL) { |  |  |  | 	if (reply->type != XCB_ATOM_CARDINAL) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -480,7 +469,7 @@ static void read_surface_property(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else if (property == xwm->atoms[WM_PROTOCOLS]) { |  |  |  | 	} else if (property == xwm->atoms[WM_PROTOCOLS]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		read_surface_protocols(xwm, surface, reply); |  |  |  | 		read_surface_protocols(xwm, surface, reply); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else if (property == xwm->atoms[NET_WM_STATE]) { |  |  |  | 	} else if (property == xwm->atoms[NET_WM_STATE]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		read_surface_state(xwm, surface, reply); |  |  |  | 		wlr_log(L_DEBUG, "TODO: read _NET_WM_STATE property"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	} else if (property == xwm->atoms[WM_HINTS]) { |  |  |  | 	} else if (property == xwm->atoms[WM_HINTS]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		read_surface_hints(xwm, surface, reply); |  |  |  | 		read_surface_hints(xwm, surface, reply); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else if (property == xwm->atoms[WM_NORMAL_HINTS]) { |  |  |  | 	} else if (property == xwm->atoms[WM_NORMAL_HINTS]) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -645,6 +634,7 @@ static void handle_map_request(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xsurface_set_wm_state(xsurface, ICCCM_NORMAL_STATE); |  |  |  | 	xsurface_set_wm_state(xsurface, ICCCM_NORMAL_STATE); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	xsurface_set_net_wm_state(xsurface); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xcb_map_window(xwm->xcb_conn, ev->window); |  |  |  | 	xcb_map_window(xwm->xcb_conn, ev->window); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -716,16 +706,6 @@ static void handle_surface_id_message(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void handle_net_wm_state_message(struct wlr_xwm *xwm, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xcb_client_message_event_t *ev) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (xsurface == NULL) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	handle_surface_state(xwm, xsurface, &ev->data.data32[1], 2, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		ev->data.data32[0]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static void handle_net_wm_moveresize_message(struct wlr_xwm *xwm, |  |  |  | static void handle_net_wm_moveresize_message(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		xcb_client_message_event_t *ev) { |  |  |  | 		xcb_client_message_event_t *ev) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_log(L_DEBUG, "TODO: handle moveresize"); |  |  |  | 	wlr_log(L_DEBUG, "TODO: handle moveresize"); | 
			
		
	
	
		
		
			
				
					|  |  | @ -738,7 +718,7 @@ static void handle_client_message(struct wlr_xwm *xwm, | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (ev->type == xwm->atoms[WL_SURFACE_ID]) { |  |  |  | 	if (ev->type == xwm->atoms[WL_SURFACE_ID]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		handle_surface_id_message(xwm, ev); |  |  |  | 		handle_surface_id_message(xwm, ev); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else if (ev->type == xwm->atoms[NET_WM_STATE]) { |  |  |  | 	} else if (ev->type == xwm->atoms[NET_WM_STATE]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		handle_net_wm_state_message(xwm, ev); |  |  |  | 		wlr_log(L_DEBUG, "TODO: handle _NET_WM_STATE client message"); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	} else if (ev->type == xwm->atoms[_NET_WM_MOVERESIZE]) { |  |  |  | 	} else if (ev->type == xwm->atoms[_NET_WM_MOVERESIZE]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		handle_net_wm_moveresize_message(xwm, ev); |  |  |  | 		handle_net_wm_moveresize_message(xwm, ev); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} else { |  |  |  | 	} else { | 
			
		
	
	
		
		
			
				
					|  |  | @ -1075,6 +1055,8 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		sizeof(supported)/sizeof(*supported), |  |  |  | 		sizeof(supported)/sizeof(*supported), | 
			
		
	
		
		
			
				
					
					|  |  |  | 		supported); |  |  |  | 		supported); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	xcb_flush(xwm->xcb_conn); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xwm_set_net_active_window(xwm, XCB_WINDOW_NONE); |  |  |  | 	xwm_set_net_active_window(xwm, XCB_WINDOW_NONE); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	xwm->compositor_surface_create.notify = handle_compositor_surface_create; |  |  |  | 	xwm->compositor_surface_create.notify = handle_compositor_surface_create; | 
			
		
	
	
		
		
			
				
					|  |  | 
 |