aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-06-18 22:49:28 +0100
committerLibravatar emersion <contact@emersion.fr>2018-06-18 22:52:10 +0100
commitcda66e9a263d8467b6d1857808305d5e9f7bc3cd (patch)
tree7e773d03ea9cecf959ba75598fd1a2d18dbd604c /sway/desktop/xwayland.c
parentMerge pull request #2143 from vilhalmer/mark-pool-buffers-busy (diff)
downloadsway-cda66e9a263d8467b6d1857808305d5e9f7bc3cd.tar.gz
sway-cda66e9a263d8467b6d1857808305d5e9f7bc3cd.tar.zst
sway-cda66e9a263d8467b6d1857808305d5e9f7bc3cd.zip
Automatically float xwayland windows
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c83
1 files changed, 73 insertions, 10 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 6447b711..2c3848cd 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
@@ -411,3 +437,40 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
411 wl_signal_add(&xsurface->events.map, &xwayland_view->map); 437 wl_signal_add(&xsurface->events.map, &xwayland_view->map);
412 xwayland_view->map.notify = handle_map; 438 xwayland_view->map.notify = handle_map;
413} 439}
440
441void handle_xwayland_ready(struct wl_listener *listener, void *data) {
442 struct sway_server *server =
443 wl_container_of(listener, server, xwayland_ready);
444 struct sway_xwayland *xwayland = &server->xwayland;
445
446 xcb_connection_t *xcb_conn = xcb_connect(NULL, NULL);
447 int err = xcb_connection_has_error(xcb_conn);
448 if (err) {
449 wlr_log(L_ERROR, "XCB connect failed: %d", err);
450 return;
451 }
452
453 xcb_intern_atom_cookie_t cookies[ATOM_LAST];
454 for (size_t i = 0; i < ATOM_LAST; i++) {
455 cookies[i] =
456 xcb_intern_atom(xcb_conn, 0, strlen(atom_map[i]), atom_map[i]);
457 }
458 for (size_t i = 0; i < ATOM_LAST; i++) {
459 xcb_generic_error_t *error = NULL;
460 xcb_intern_atom_reply_t *reply =
461 xcb_intern_atom_reply(xcb_conn, cookies[i], &error);
462 if (reply != NULL && error == NULL) {
463 xwayland->atoms[i] = reply->atom;
464 }
465 free(reply);
466
467 if (error != NULL) {
468 wlr_log(L_ERROR, "could not resolve atom %s, X11 error code %d",
469 atom_map[i], error->error_code);
470 free(error);
471 break;
472 }
473 }
474
475 xcb_disconnect(xcb_conn);
476}