summaryrefslogtreecommitdiffstats
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c91
1 files changed, 79 insertions, 12 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 6447b711..eb39dc4b 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -15,6 +15,14 @@
15#include "sway/tree/layout.h" 15#include "sway/tree/layout.h"
16#include "sway/tree/view.h" 16#include "sway/tree/view.h"
17 17
18static const char *atom_map[ATOM_LAST] = {
19 "_NET_WM_WINDOW_TYPE_DIALOG",
20 "_NET_WM_WINDOW_TYPE_UTILITY",
21 "_NET_WM_WINDOW_TYPE_TOOLBAR",
22 "_NET_WM_WINDOW_TYPE_SPLASH",
23 "_NET_WM_STATE_MODAL",
24};
25
18static void unmanaged_handle_request_configure(struct wl_listener *listener, 26static void unmanaged_handle_request_configure(struct wl_listener *listener,
19 void *data) { 27 void *data) {
20 struct sway_xwayland_unmanaged *surface = 28 struct sway_xwayland_unmanaged *surface =
@@ -61,7 +69,8 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) {
61 69
62 if (!wlr_xwayland_surface_is_unmanaged(xsurface)) { 70 if (!wlr_xwayland_surface_is_unmanaged(xsurface)) {
63 struct sway_seat *seat = input_manager_current_seat(input_manager); 71 struct sway_seat *seat = input_manager_current_seat(input_manager);
64 struct wlr_xwayland *xwayland = seat->input->server->xwayland; 72 struct wlr_xwayland *xwayland =
73 seat->input->server->xwayland.wlr_xwayland;
65 wlr_xwayland_set_seat(xwayland, seat->wlr_seat); 74 wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
66 seat_set_focus_surface(seat, xsurface->surface); 75 seat_set_focus_surface(seat, xsurface->surface);
67 } 76 }
@@ -199,15 +208,32 @@ static void set_fullscreen(struct sway_view *view, bool fullscreen) {
199} 208}
200 209
201static bool wants_floating(struct sway_view *view) { 210static bool wants_floating(struct sway_view *view) {
202 // TODO: 211 if (xwayland_view_from_view(view) == NULL) {
203 // We want to return true if the window type contains any of these: 212 return false;
204 // NET_WM_WINDOW_TYPE_DIALOG 213 }
205 // NET_WM_WINDOW_TYPE_UTILITY 214 struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface;
206 // NET_WM_WINDOW_TYPE_TOOLBAR 215 struct sway_xwayland *xwayland = &server.xwayland;
207 // NET_WM_WINDOW_TYPE_SPLASH 216
208 // 217 // TODO: return true if the NET_WM_STATE is MODAL
209 // We also want to return true if the NET_WM_STATE is MODAL. 218
210 // wlroots doesn't appear to provide all this information at the moment. 219 for (size_t i = 0; i < surface->window_type_len; ++i) {
220 xcb_atom_t type = surface->window_type[i];
221 if (type == xwayland->atoms[NET_WM_WINDOW_TYPE_DIALOG] ||
222 type == xwayland->atoms[NET_WM_WINDOW_TYPE_UTILITY] ||
223 type == xwayland->atoms[NET_WM_WINDOW_TYPE_TOOLBAR] ||
224 type == xwayland->atoms[NET_WM_WINDOW_TYPE_SPLASH]) {
225 return true;
226 }
227 }
228
229 struct wlr_xwayland_surface_size_hints *size_hints = surface->size_hints;
230 if (size_hints != NULL &&
231 size_hints->min_width != 0 && size_hints->min_height != 0 &&
232 size_hints->max_width == size_hints->min_width &&
233 size_hints->max_height == size_hints->min_height) {
234 return true;
235 }
236
211 return false; 237 return false;
212} 238}
213 239
@@ -308,8 +334,12 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
308 ev->width, ev->height); 334 ev->width, ev->height);
309 return; 335 return;
310 } 336 }
311 // TODO: Let floating views do whatever 337 if (container_is_floating(view->swayc)) {
312 configure(view, view->swayc->x, view->swayc->y, view->width, view->height); 338 configure(view, view->swayc->x, view->swayc->y, ev->width, ev->height);
339 } else {
340 configure(view, view->swayc->x, view->swayc->y,
341 view->width, view->height);
342 }
313} 343}
314 344
315static void handle_request_fullscreen(struct wl_listener *listener, void *data) { 345static void handle_request_fullscreen(struct wl_listener *listener, void *data) {
@@ -411,3 +441,40 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
411 wl_signal_add(&xsurface->events.map, &xwayland_view->map); 441 wl_signal_add(&xsurface->events.map, &xwayland_view->map);
412 xwayland_view->map.notify = handle_map; 442 xwayland_view->map.notify = handle_map;
413} 443}
444
445void handle_xwayland_ready(struct wl_listener *listener, void *data) {
446 struct sway_server *server =
447 wl_container_of(listener, server, xwayland_ready);
448 struct sway_xwayland *xwayland = &server->xwayland;
449
450 xcb_connection_t *xcb_conn = xcb_connect(NULL, NULL);
451 int err = xcb_connection_has_error(xcb_conn);
452 if (err) {
453 wlr_log(L_ERROR, "XCB connect failed: %d", err);
454 return;
455 }
456
457 xcb_intern_atom_cookie_t cookies[ATOM_LAST];
458 for (size_t i = 0; i < ATOM_LAST; i++) {
459 cookies[i] =
460 xcb_intern_atom(xcb_conn, 0, strlen(atom_map[i]), atom_map[i]);
461 }
462 for (size_t i = 0; i < ATOM_LAST; i++) {
463 xcb_generic_error_t *error = NULL;
464 xcb_intern_atom_reply_t *reply =
465 xcb_intern_atom_reply(xcb_conn, cookies[i], &error);
466 if (reply != NULL && error == NULL) {
467 xwayland->atoms[i] = reply->atom;
468 }
469 free(reply);
470
471 if (error != NULL) {
472 wlr_log(L_ERROR, "could not resolve atom %s, X11 error code %d",
473 atom_map[i], error->error_code);
474 free(error);
475 break;
476 }
477 }
478
479 xcb_disconnect(xcb_conn);
480}