mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	xwm: add support for xwayland minimize
This commit is contained in:
		
							parent
							
								
									751a21d94f
								
							
						
					
					
						commit
						bd387da62d
					
				
					 3 changed files with 81 additions and 1 deletions
				
			
		| 
						 | 
					@ -173,6 +173,7 @@ struct wlr_xwayland_surface {
 | 
				
			||||||
	bool modal;
 | 
						bool modal;
 | 
				
			||||||
	bool fullscreen;
 | 
						bool fullscreen;
 | 
				
			||||||
	bool maximized_vert, maximized_horz;
 | 
						bool maximized_vert, maximized_horz;
 | 
				
			||||||
 | 
						bool minimized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool has_alpha;
 | 
						bool has_alpha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,6 +182,7 @@ struct wlr_xwayland_surface {
 | 
				
			||||||
		struct wl_signal request_configure;
 | 
							struct wl_signal request_configure;
 | 
				
			||||||
		struct wl_signal request_move;
 | 
							struct wl_signal request_move;
 | 
				
			||||||
		struct wl_signal request_resize;
 | 
							struct wl_signal request_resize;
 | 
				
			||||||
 | 
							struct wl_signal request_minimize;
 | 
				
			||||||
		struct wl_signal request_maximize;
 | 
							struct wl_signal request_maximize;
 | 
				
			||||||
		struct wl_signal request_fullscreen;
 | 
							struct wl_signal request_fullscreen;
 | 
				
			||||||
		struct wl_signal request_activate;
 | 
							struct wl_signal request_activate;
 | 
				
			||||||
| 
						 | 
					@ -221,6 +223,11 @@ struct wlr_xwayland_resize_event {
 | 
				
			||||||
	uint32_t edges;
 | 
						uint32_t edges;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_xwayland_minimize_event {
 | 
				
			||||||
 | 
						struct wlr_xwayland_surface *surface;
 | 
				
			||||||
 | 
						bool minimize;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_xwayland_server *wlr_xwayland_server_create(
 | 
					struct wlr_xwayland_server *wlr_xwayland_server_create(
 | 
				
			||||||
	struct wl_display *display, struct wlr_xwayland_server_options *options);
 | 
						struct wl_display *display, struct wlr_xwayland_server_options *options);
 | 
				
			||||||
void wlr_xwayland_server_destroy(struct wlr_xwayland_server *server);
 | 
					void wlr_xwayland_server_destroy(struct wlr_xwayland_server *server);
 | 
				
			||||||
| 
						 | 
					@ -250,6 +257,9 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *surface,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_xwayland_surface_close(struct wlr_xwayland_surface *surface);
 | 
					void wlr_xwayland_surface_close(struct wlr_xwayland_surface *surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface,
 | 
				
			||||||
 | 
						bool minimized);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_xwayland_surface_set_maximized(struct wlr_xwayland_surface *surface,
 | 
					void wlr_xwayland_surface_set_maximized(struct wlr_xwayland_surface *surface,
 | 
				
			||||||
	bool maximized);
 | 
						bool maximized);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,9 @@ enum atom_name {
 | 
				
			||||||
	NET_WM_STATE_FULLSCREEN,
 | 
						NET_WM_STATE_FULLSCREEN,
 | 
				
			||||||
	NET_WM_STATE_MAXIMIZED_VERT,
 | 
						NET_WM_STATE_MAXIMIZED_VERT,
 | 
				
			||||||
	NET_WM_STATE_MAXIMIZED_HORZ,
 | 
						NET_WM_STATE_MAXIMIZED_HORZ,
 | 
				
			||||||
 | 
						NET_WM_STATE_HIDDEN,
 | 
				
			||||||
	NET_WM_PING,
 | 
						NET_WM_PING,
 | 
				
			||||||
 | 
						WM_CHANGE_STATE,
 | 
				
			||||||
	WM_STATE,
 | 
						WM_STATE,
 | 
				
			||||||
	CLIPBOARD,
 | 
						CLIPBOARD,
 | 
				
			||||||
	PRIMARY,
 | 
						PRIMARY,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,9 @@ const char *atom_map[ATOM_LAST] = {
 | 
				
			||||||
	[NET_WM_STATE_FULLSCREEN] = "_NET_WM_STATE_FULLSCREEN",
 | 
						[NET_WM_STATE_FULLSCREEN] = "_NET_WM_STATE_FULLSCREEN",
 | 
				
			||||||
	[NET_WM_STATE_MAXIMIZED_VERT] = "_NET_WM_STATE_MAXIMIZED_VERT",
 | 
						[NET_WM_STATE_MAXIMIZED_VERT] = "_NET_WM_STATE_MAXIMIZED_VERT",
 | 
				
			||||||
	[NET_WM_STATE_MAXIMIZED_HORZ] = "_NET_WM_STATE_MAXIMIZED_HORZ",
 | 
						[NET_WM_STATE_MAXIMIZED_HORZ] = "_NET_WM_STATE_MAXIMIZED_HORZ",
 | 
				
			||||||
 | 
						[NET_WM_STATE_HIDDEN] = "_NET_WM_STATE_HIDDEN",
 | 
				
			||||||
	[NET_WM_PING] = "_NET_WM_PING",
 | 
						[NET_WM_PING] = "_NET_WM_PING",
 | 
				
			||||||
 | 
						[WM_CHANGE_STATE] = "WM_CHANGE_STATE",
 | 
				
			||||||
	[WM_STATE] = "WM_STATE",
 | 
						[WM_STATE] = "WM_STATE",
 | 
				
			||||||
	[CLIPBOARD] = "CLIPBOARD",
 | 
						[CLIPBOARD] = "CLIPBOARD",
 | 
				
			||||||
	[PRIMARY] = "PRIMARY",
 | 
						[PRIMARY] = "PRIMARY",
 | 
				
			||||||
| 
						 | 
					@ -146,6 +148,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create(
 | 
				
			||||||
	wl_signal_init(&surface->events.request_configure);
 | 
						wl_signal_init(&surface->events.request_configure);
 | 
				
			||||||
	wl_signal_init(&surface->events.request_move);
 | 
						wl_signal_init(&surface->events.request_move);
 | 
				
			||||||
	wl_signal_init(&surface->events.request_resize);
 | 
						wl_signal_init(&surface->events.request_resize);
 | 
				
			||||||
 | 
						wl_signal_init(&surface->events.request_minimize);
 | 
				
			||||||
	wl_signal_init(&surface->events.request_maximize);
 | 
						wl_signal_init(&surface->events.request_maximize);
 | 
				
			||||||
	wl_signal_init(&surface->events.request_fullscreen);
 | 
						wl_signal_init(&surface->events.request_fullscreen);
 | 
				
			||||||
	wl_signal_init(&surface->events.request_activate);
 | 
						wl_signal_init(&surface->events.request_activate);
 | 
				
			||||||
| 
						 | 
					@ -290,7 +293,7 @@ static void xwm_surface_activate(struct wlr_xwm *xwm,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
 | 
					static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
 | 
				
			||||||
	struct wlr_xwm *xwm = xsurface->xwm;
 | 
						struct wlr_xwm *xwm = xsurface->xwm;
 | 
				
			||||||
	uint32_t property[4];
 | 
						uint32_t property[5];
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	i = 0;
 | 
						i = 0;
 | 
				
			||||||
| 
						 | 
					@ -306,6 +309,9 @@ static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
 | 
				
			||||||
	if (xsurface->maximized_horz) {
 | 
						if (xsurface->maximized_horz) {
 | 
				
			||||||
		property[i++] = xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ];
 | 
							property[i++] = xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (xsurface->minimized) {
 | 
				
			||||||
 | 
							property[i++] = xwm->atoms[NET_WM_STATE_HIDDEN];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xcb_change_property(xwm->xcb_conn,
 | 
						xcb_change_property(xwm->xcb_conn,
 | 
				
			||||||
		XCB_PROP_MODE_REPLACE,
 | 
							XCB_PROP_MODE_REPLACE,
 | 
				
			||||||
| 
						 | 
					@ -664,6 +670,8 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm,
 | 
				
			||||||
			xsurface->maximized_vert = true;
 | 
								xsurface->maximized_vert = true;
 | 
				
			||||||
		} else if (atom[i] == xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) {
 | 
							} else if (atom[i] == xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) {
 | 
				
			||||||
			xsurface->maximized_horz = true;
 | 
								xsurface->maximized_horz = true;
 | 
				
			||||||
 | 
							} else if (atom[i] == xwm->atoms[NET_WM_STATE_HIDDEN]) {
 | 
				
			||||||
 | 
								xsurface->minimized = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1126,6 +1134,7 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool fullscreen = xsurface->fullscreen;
 | 
						bool fullscreen = xsurface->fullscreen;
 | 
				
			||||||
	bool maximized = xsurface_is_maximized(xsurface);
 | 
						bool maximized = xsurface_is_maximized(xsurface);
 | 
				
			||||||
 | 
						bool minimized = xsurface->minimized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t action = client_message->data.data32[0];
 | 
						uint32_t action = client_message->data.data32[0];
 | 
				
			||||||
	for (size_t i = 0; i < 2; ++i) {
 | 
						for (size_t i = 0; i < 2; ++i) {
 | 
				
			||||||
| 
						 | 
					@ -1143,6 +1152,9 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm,
 | 
				
			||||||
		} else if (property == xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ] &&
 | 
							} else if (property == xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ] &&
 | 
				
			||||||
				update_state(action, &xsurface->maximized_horz)) {
 | 
									update_state(action, &xsurface->maximized_horz)) {
 | 
				
			||||||
			xsurface_set_net_wm_state(xsurface);
 | 
								xsurface_set_net_wm_state(xsurface);
 | 
				
			||||||
 | 
							} else if (property == xwm->atoms[NET_WM_STATE_HIDDEN] &&
 | 
				
			||||||
 | 
									update_state(action, &xsurface->minimized)) {
 | 
				
			||||||
 | 
								xsurface_set_net_wm_state(xsurface);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// client_message->data.data32[3] is the source indication
 | 
						// client_message->data.data32[3] is the source indication
 | 
				
			||||||
| 
						 | 
					@ -1165,6 +1177,19 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		wlr_signal_emit_safe(&xsurface->events.request_maximize, xsurface);
 | 
							wlr_signal_emit_safe(&xsurface->events.request_maximize, xsurface);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (minimized != xsurface->minimized) {
 | 
				
			||||||
 | 
							if (xsurface->minimized) {
 | 
				
			||||||
 | 
								xsurface->saved_width = xsurface->width;
 | 
				
			||||||
 | 
								xsurface->saved_height = xsurface->height;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wlr_xwayland_minimize_event minimize_event = {
 | 
				
			||||||
 | 
								.surface = xsurface,
 | 
				
			||||||
 | 
								.minimize = xsurface->minimized,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							wlr_signal_emit_safe(&xsurface->events.request_minimize, &minimize_event);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xwm_handle_wm_protocols_message(struct wlr_xwm *xwm,
 | 
					static void xwm_handle_wm_protocols_message(struct wlr_xwm *xwm,
 | 
				
			||||||
| 
						 | 
					@ -1202,6 +1227,32 @@ static void xwm_handle_net_active_window_message(struct wlr_xwm *xwm,
 | 
				
			||||||
	wlr_signal_emit_safe(&surface->events.request_activate, surface);
 | 
						wlr_signal_emit_safe(&surface->events.request_activate, surface);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void xwm_handle_wm_change_state_message(struct wlr_xwm *xwm,
 | 
				
			||||||
 | 
							xcb_client_message_event_t *ev) {
 | 
				
			||||||
 | 
						struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window);
 | 
				
			||||||
 | 
						uint32_t detail = ev->data.data32[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (xsurface == NULL) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool minimize;
 | 
				
			||||||
 | 
						if (detail == ICCCM_ICONIC_STATE) {
 | 
				
			||||||
 | 
							minimize = true;
 | 
				
			||||||
 | 
						} else if (detail == ICCCM_NORMAL_STATE) {
 | 
				
			||||||
 | 
							minimize = false;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_log(WLR_DEBUG, "unhandled wm_change_state event %u", detail);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_xwayland_minimize_event minimize_event = {
 | 
				
			||||||
 | 
							.surface = xsurface,
 | 
				
			||||||
 | 
							.minimize = minimize,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						wlr_signal_emit_safe(&xsurface->events.request_minimize, &minimize_event);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void xwm_handle_client_message(struct wlr_xwm *xwm,
 | 
					static void xwm_handle_client_message(struct wlr_xwm *xwm,
 | 
				
			||||||
		xcb_client_message_event_t *ev) {
 | 
							xcb_client_message_event_t *ev) {
 | 
				
			||||||
	wlr_log(WLR_DEBUG, "XCB_CLIENT_MESSAGE (%u)", ev->window);
 | 
						wlr_log(WLR_DEBUG, "XCB_CLIENT_MESSAGE (%u)", ev->window);
 | 
				
			||||||
| 
						 | 
					@ -1216,6 +1267,8 @@ static void xwm_handle_client_message(struct wlr_xwm *xwm,
 | 
				
			||||||
		xwm_handle_wm_protocols_message(xwm, ev);
 | 
							xwm_handle_wm_protocols_message(xwm, ev);
 | 
				
			||||||
	} else if (ev->type == xwm->atoms[NET_ACTIVE_WINDOW]) {
 | 
						} else if (ev->type == xwm->atoms[NET_ACTIVE_WINDOW]) {
 | 
				
			||||||
		xwm_handle_net_active_window_message(xwm, ev);
 | 
							xwm_handle_net_active_window_message(xwm, ev);
 | 
				
			||||||
 | 
						} else if (ev->type == xwm->atoms[WM_CHANGE_STATE]) {
 | 
				
			||||||
 | 
							xwm_handle_wm_change_state_message(xwm, ev);
 | 
				
			||||||
	} else if (!xwm_handle_selection_client_message(xwm, ev)) {
 | 
						} else if (!xwm_handle_selection_client_message(xwm, ev)) {
 | 
				
			||||||
		char *type_name = xwm_get_atom_name(xwm, ev->type);
 | 
							char *type_name = xwm_get_atom_name(xwm, ev->type);
 | 
				
			||||||
		wlr_log(WLR_DEBUG, "unhandled x11 client message %u (%s)", ev->type,
 | 
							wlr_log(WLR_DEBUG, "unhandled x11 client message %u (%s)", ev->type,
 | 
				
			||||||
| 
						 | 
					@ -1768,6 +1821,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
 | 
				
			||||||
		xwm->atoms[NET_WM_STATE_FULLSCREEN],
 | 
							xwm->atoms[NET_WM_STATE_FULLSCREEN],
 | 
				
			||||||
		xwm->atoms[NET_WM_STATE_MAXIMIZED_VERT],
 | 
							xwm->atoms[NET_WM_STATE_MAXIMIZED_VERT],
 | 
				
			||||||
		xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ],
 | 
							xwm->atoms[NET_WM_STATE_MAXIMIZED_HORZ],
 | 
				
			||||||
 | 
							xwm->atoms[NET_WM_STATE_HIDDEN],
 | 
				
			||||||
		xwm->atoms[NET_CLIENT_LIST],
 | 
							xwm->atoms[NET_CLIENT_LIST],
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	xcb_change_property(xwm->xcb_conn,
 | 
						xcb_change_property(xwm->xcb_conn,
 | 
				
			||||||
| 
						 | 
					@ -1799,6 +1853,20 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
 | 
				
			||||||
	return xwm;
 | 
						return xwm;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_xwayland_surface_set_minimized(struct wlr_xwayland_surface *surface,
 | 
				
			||||||
 | 
							bool minimized) {
 | 
				
			||||||
 | 
						surface->minimized = minimized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (minimized) {
 | 
				
			||||||
 | 
							xsurface_set_wm_state(surface, ICCCM_ICONIC_STATE);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							xsurface_set_wm_state(surface, ICCCM_NORMAL_STATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xsurface_set_net_wm_state(surface);
 | 
				
			||||||
 | 
						xcb_flush(surface->xwm->xcb_conn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_xwayland_surface_set_maximized(struct wlr_xwayland_surface *surface,
 | 
					void wlr_xwayland_surface_set_maximized(struct wlr_xwayland_surface *surface,
 | 
				
			||||||
		bool maximized) {
 | 
							bool maximized) {
 | 
				
			||||||
	surface->maximized_horz = maximized;
 | 
						surface->maximized_horz = maximized;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue