diff options
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r-- | sway/desktop/xwayland.c | 91 |
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 | ||
18 | static 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 | |||
18 | static void unmanaged_handle_request_configure(struct wl_listener *listener, | 26 | static 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 | ||
201 | static bool wants_floating(struct sway_view *view) { | 210 | static 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 | ||
315 | static void handle_request_fullscreen(struct wl_listener *listener, void *data) { | 345 | static 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 | |||
445 | void 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 | } | ||