mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	Merge 879a696a33 into df8e3d819c
				
					
				
			This commit is contained in:
		
						commit
						5cccad9606
					
				
					 5 changed files with 17 additions and 120 deletions
				
			
		| 
						 | 
					@ -51,6 +51,7 @@ struct xwayland_view {
 | 
				
			||||||
	struct wl_listener set_override_redirect;
 | 
						struct wl_listener set_override_redirect;
 | 
				
			||||||
	struct wl_listener set_strut_partial;
 | 
						struct wl_listener set_strut_partial;
 | 
				
			||||||
	struct wl_listener set_window_type;
 | 
						struct wl_listener set_window_type;
 | 
				
			||||||
 | 
						struct wl_listener set_icon;
 | 
				
			||||||
	struct wl_listener focus_in;
 | 
						struct wl_listener focus_in;
 | 
				
			||||||
	struct wl_listener map_request;
 | 
						struct wl_listener map_request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,9 +51,9 @@ endif
 | 
				
			||||||
add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c')
 | 
					add_project_arguments('-DLABWC_VERSION=@0@'.format(version), language: 'c')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wlroots = dependency(
 | 
					wlroots = dependency(
 | 
				
			||||||
  'wlroots-0.19',
 | 
					  'wlroots-0.20',
 | 
				
			||||||
  default_options: ['default_library=static', 'examples=false'],
 | 
					  default_options: ['default_library=static', 'examples=false'],
 | 
				
			||||||
  version: ['>=0.19.0', '<0.20.0'],
 | 
					  version: ['>=0.20.0', '<0.21.0'],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true'
 | 
					wlroots_has_xwayland = wlroots.get_variable('have_xwayland') == 'true'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -583,7 +583,7 @@ input_method_relay_create(struct seat *seat)
 | 
				
			||||||
	relay->popup_tree = wlr_scene_tree_create(&seat->server->scene->tree);
 | 
						relay->popup_tree = wlr_scene_tree_create(&seat->server->scene->tree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	relay->new_text_input.notify = handle_new_text_input;
 | 
						relay->new_text_input.notify = handle_new_text_input;
 | 
				
			||||||
	wl_signal_add(&seat->server->text_input_manager->events.text_input,
 | 
						wl_signal_add(&seat->server->text_input_manager->events.new_text_input,
 | 
				
			||||||
		&relay->new_text_input);
 | 
							&relay->new_text_input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	relay->new_input_method.notify = handle_new_input_method;
 | 
						relay->new_input_method.notify = handle_new_input_method;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										124
									
								
								src/xwayland.c
									
										
									
									
									
								
							
							
						
						
									
										124
									
								
								src/xwayland.c
									
										
									
									
									
								
							| 
						 | 
					@ -24,20 +24,6 @@
 | 
				
			||||||
#include "window-rules.h"
 | 
					#include "window-rules.h"
 | 
				
			||||||
#include "workspaces.h"
 | 
					#include "workspaces.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum atoms {
 | 
					 | 
				
			||||||
	ATOM_NET_WM_ICON = 0,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ATOM_COUNT,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const char * const atom_names[] = {
 | 
					 | 
				
			||||||
	[ATOM_NET_WM_ICON] = "_NET_WM_ICON",
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static_assert(ARRAY_SIZE(atom_names) == ATOM_COUNT, "atom names out of sync");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static xcb_atom_t atoms[ATOM_COUNT] = {0};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void xwayland_view_unmap(struct view *view, bool client_request);
 | 
					static void xwayland_view_unmap(struct view *view, bool client_request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct xwayland_view *
 | 
					static struct xwayland_view *
 | 
				
			||||||
| 
						 | 
					@ -372,6 +358,7 @@ handle_destroy(struct wl_listener *listener, void *data)
 | 
				
			||||||
	wl_list_remove(&xwayland_view->set_override_redirect.link);
 | 
						wl_list_remove(&xwayland_view->set_override_redirect.link);
 | 
				
			||||||
	wl_list_remove(&xwayland_view->set_strut_partial.link);
 | 
						wl_list_remove(&xwayland_view->set_strut_partial.link);
 | 
				
			||||||
	wl_list_remove(&xwayland_view->set_window_type.link);
 | 
						wl_list_remove(&xwayland_view->set_window_type.link);
 | 
				
			||||||
 | 
						wl_list_remove(&xwayland_view->set_icon.link);
 | 
				
			||||||
	wl_list_remove(&xwayland_view->focus_in.link);
 | 
						wl_list_remove(&xwayland_view->focus_in.link);
 | 
				
			||||||
	wl_list_remove(&xwayland_view->map_request.link);
 | 
						wl_list_remove(&xwayland_view->map_request.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -578,30 +565,19 @@ handle_set_strut_partial(struct wl_listener *listener, void *data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
update_icon(struct xwayland_view *xwayland_view)
 | 
					handle_set_icon(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!xwayland_view->xwayland_surface) {
 | 
						struct xwayland_view *xwayland_view =
 | 
				
			||||||
		return;
 | 
							wl_container_of(listener, xwayland_view, set_icon);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xcb_window_t window_id = xwayland_view->xwayland_surface->window_id;
 | 
						xcb_ewmh_get_wm_icon_reply_t icon_reply = {0};
 | 
				
			||||||
 | 
						if (!wlr_xwayland_surface_fetch_icon(xwayland_view->xwayland_surface,
 | 
				
			||||||
	xcb_connection_t *xcb_conn = wlr_xwayland_get_xwm_connection(
 | 
								&icon_reply)) {
 | 
				
			||||||
		xwayland_view->base.server->xwayland);
 | 
					 | 
				
			||||||
	xcb_get_property_cookie_t cookie = xcb_get_property(xcb_conn, 0,
 | 
					 | 
				
			||||||
		window_id, atoms[ATOM_NET_WM_ICON], XCB_ATOM_CARDINAL, 0, 0x10000);
 | 
					 | 
				
			||||||
	xcb_get_property_reply_t *reply = xcb_get_property_reply(xcb_conn, cookie, NULL);
 | 
					 | 
				
			||||||
	if (!reply) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	xcb_ewmh_get_wm_icon_reply_t icon;
 | 
					 | 
				
			||||||
	if (!xcb_ewmh_get_wm_icon_from_reply(&icon, reply)) {
 | 
					 | 
				
			||||||
		wlr_log(WLR_INFO, "Invalid x11 icon");
 | 
					 | 
				
			||||||
		view_set_icon(&xwayland_view->base, NULL, NULL);
 | 
							view_set_icon(&xwayland_view->base, NULL, NULL);
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&icon);
 | 
						xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&icon_reply);
 | 
				
			||||||
	struct wl_array buffers;
 | 
						struct wl_array buffers;
 | 
				
			||||||
	wl_array_init(&buffers);
 | 
						wl_array_init(&buffers);
 | 
				
			||||||
	for (; iter.rem; xcb_ewmh_get_wm_icon_next(&iter)) {
 | 
						for (; iter.rem; xcb_ewmh_get_wm_icon_next(&iter)) {
 | 
				
			||||||
| 
						 | 
					@ -631,7 +607,7 @@ update_icon(struct xwayland_view *xwayland_view)
 | 
				
			||||||
	wl_array_release(&buffers);
 | 
						wl_array_release(&buffers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	free(reply);
 | 
						xcb_ewmh_get_wm_icon_reply_wipe(&icon_reply);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -1088,6 +1064,7 @@ xwayland_view_create(struct server *server,
 | 
				
			||||||
	CONNECT_SIGNAL(xsurface, xwayland_view, set_override_redirect);
 | 
						CONNECT_SIGNAL(xsurface, xwayland_view, set_override_redirect);
 | 
				
			||||||
	CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial);
 | 
						CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial);
 | 
				
			||||||
	CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type);
 | 
						CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type);
 | 
				
			||||||
 | 
						CONNECT_SIGNAL(xsurface, xwayland_view, set_icon);
 | 
				
			||||||
	CONNECT_SIGNAL(xsurface, xwayland_view, focus_in);
 | 
						CONNECT_SIGNAL(xsurface, xwayland_view, focus_in);
 | 
				
			||||||
	CONNECT_SIGNAL(xsurface, xwayland_view, map_request);
 | 
						CONNECT_SIGNAL(xsurface, xwayland_view, map_request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1120,85 +1097,6 @@ handle_new_surface(struct wl_listener *listener, void *data)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct xwayland_view *
 | 
					 | 
				
			||||||
xwayland_view_from_window_id(struct server *server, xcb_window_t id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct view *view;
 | 
					 | 
				
			||||||
	wl_list_for_each(view, &server->views, link) {
 | 
					 | 
				
			||||||
		if (view->type != LAB_XWAYLAND_VIEW) {
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		struct xwayland_view *xwayland_view = xwayland_view_from_view(view);
 | 
					 | 
				
			||||||
		if (xwayland_view->xwayland_surface
 | 
					 | 
				
			||||||
				&& xwayland_view->xwayland_surface->window_id == id) {
 | 
					 | 
				
			||||||
			return xwayland_view;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f
 | 
					 | 
				
			||||||
static bool
 | 
					 | 
				
			||||||
handle_x11_event(struct wlr_xwayland *wlr_xwayland, xcb_generic_event_t *event)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) {
 | 
					 | 
				
			||||||
	case XCB_PROPERTY_NOTIFY: {
 | 
					 | 
				
			||||||
		xcb_property_notify_event_t *ev = (void *)event;
 | 
					 | 
				
			||||||
		if (ev->atom == atoms[ATOM_NET_WM_ICON]) {
 | 
					 | 
				
			||||||
			struct server *server = wlr_xwayland->data;
 | 
					 | 
				
			||||||
			struct xwayland_view *xwayland_view =
 | 
					 | 
				
			||||||
				xwayland_view_from_window_id(server, ev->window);
 | 
					 | 
				
			||||||
			if (xwayland_view) {
 | 
					 | 
				
			||||||
				update_icon(xwayland_view);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				wlr_log(WLR_DEBUG, "icon property changed for unknown window");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
sync_atoms(struct server *server)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	xcb_connection_t *xcb_conn =
 | 
					 | 
				
			||||||
		wlr_xwayland_get_xwm_connection(server->xwayland);
 | 
					 | 
				
			||||||
	assert(xcb_conn);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wlr_log(WLR_DEBUG, "Syncing X11 atoms");
 | 
					 | 
				
			||||||
	xcb_intern_atom_cookie_t cookies[ATOM_COUNT];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* First request everything and then loop over the results to reduce latency */
 | 
					 | 
				
			||||||
	for (size_t i = 0; i < ATOM_COUNT; i++) {
 | 
					 | 
				
			||||||
		cookies[i] = xcb_intern_atom(xcb_conn, 0,
 | 
					 | 
				
			||||||
			strlen(atom_names[i]), atom_names[i]);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (size_t i = 0; i < ATOM_COUNT; i++) {
 | 
					 | 
				
			||||||
		xcb_generic_error_t *err = NULL;
 | 
					 | 
				
			||||||
		xcb_intern_atom_reply_t *reply =
 | 
					 | 
				
			||||||
			xcb_intern_atom_reply(xcb_conn, cookies[i], &err);
 | 
					 | 
				
			||||||
		if (reply) {
 | 
					 | 
				
			||||||
			atoms[i] = reply->atom;
 | 
					 | 
				
			||||||
			wlr_log(WLR_DEBUG, "Got X11 atom for %s: %u",
 | 
					 | 
				
			||||||
				atom_names[i], reply->atom);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (err) {
 | 
					 | 
				
			||||||
			atoms[i] = XCB_ATOM_NONE;
 | 
					 | 
				
			||||||
			wlr_log(WLR_INFO, "Failed to get X11 atom for %s",
 | 
					 | 
				
			||||||
				atom_names[i]);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		free(reply);
 | 
					 | 
				
			||||||
		free(err);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
handle_server_ready(struct wl_listener *listener, void *data)
 | 
					handle_server_ready(struct wl_listener *listener, void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1207,7 +1105,6 @@ handle_server_ready(struct wl_listener *listener, void *data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct server *server =
 | 
						struct server *server =
 | 
				
			||||||
		wl_container_of(listener, server, xwayland_server_ready);
 | 
							wl_container_of(listener, server, xwayland_server_ready);
 | 
				
			||||||
	sync_atoms(server);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
| 
						 | 
					@ -1242,7 +1139,6 @@ xwayland_server_init(struct server *server, struct wlr_compositor *compositor)
 | 
				
			||||||
		&server->xwayland_xwm_ready);
 | 
							&server->xwayland_xwm_ready);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	server->xwayland->data = server;
 | 
						server->xwayland->data = server;
 | 
				
			||||||
	server->xwayland->user_event_handler = handle_x11_event;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (setenv("DISPLAY", server->xwayland->display_name, true) < 0) {
 | 
						if (setenv("DISPLAY", server->xwayland->display_name, true) < 0) {
 | 
				
			||||||
		wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland");
 | 
							wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
[wrap-git]
 | 
					[wrap-git]
 | 
				
			||||||
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
 | 
					url = https://gitlab.freedesktop.org/wlroots/wlroots.git
 | 
				
			||||||
revision = 0.19
 | 
					revision = 6d8bb66f98700472d05e57b8199d621e1cefe338
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[provide]
 | 
					[provide]
 | 
				
			||||||
dependency_names = wlroots-0.19
 | 
					dependency_names = wlroots-0.20
 | 
				
			||||||
wlroots-0.19=wlroots
 | 
					wlroots-0.20=wlroots
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue