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.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index fcc8164f..6e63c505 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -7,10 +7,12 @@
7#include <wlr/xwayland.h> 7#include <wlr/xwayland.h>
8#include "log.h" 8#include "log.h"
9#include "sway/desktop.h" 9#include "sway/desktop.h"
10#include "sway/desktop/transaction.h"
10#include "sway/input/input-manager.h" 11#include "sway/input/input-manager.h"
11#include "sway/input/seat.h" 12#include "sway/input/seat.h"
12#include "sway/output.h" 13#include "sway/output.h"
13#include "sway/server.h" 14#include "sway/server.h"
15#include "sway/tree/arrange.h"
14#include "sway/tree/container.h" 16#include "sway/tree/container.h"
15#include "sway/tree/layout.h" 17#include "sway/tree/layout.h"
16#include "sway/tree/view.h" 18#include "sway/tree/view.h"
@@ -176,19 +178,18 @@ static uint32_t get_int_prop(struct sway_view *view, enum sway_view_prop prop) {
176 } 178 }
177} 179}
178 180
179static void configure(struct sway_view *view, double lx, double ly, int width, 181static uint32_t configure(struct sway_view *view, double lx, double ly, int width,
180 int height) { 182 int height) {
181 struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); 183 struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view);
182 if (xwayland_view == NULL) { 184 if (xwayland_view == NULL) {
183 return; 185 return 0;
184 } 186 }
185 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; 187 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
186 188
187 xwayland_view->pending_lx = lx;
188 xwayland_view->pending_ly = ly;
189 xwayland_view->pending_width = width;
190 xwayland_view->pending_height = height;
191 wlr_xwayland_surface_configure(xsurface, lx, ly, width, height); 189 wlr_xwayland_surface_configure(xsurface, lx, ly, width, height);
190
191 // xwayland doesn't give us a serial for the configure
192 return 0;
192} 193}
193 194
194static void set_activated(struct sway_view *view, bool activated) { 195static void set_activated(struct sway_view *view, bool activated) {
@@ -257,14 +258,6 @@ static void destroy(struct sway_view *view) {
257 if (xwayland_view == NULL) { 258 if (xwayland_view == NULL) {
258 return; 259 return;
259 } 260 }
260 wl_list_remove(&xwayland_view->destroy.link);
261 wl_list_remove(&xwayland_view->request_configure.link);
262 wl_list_remove(&xwayland_view->request_fullscreen.link);
263 wl_list_remove(&xwayland_view->set_title.link);
264 wl_list_remove(&xwayland_view->set_class.link);
265 wl_list_remove(&xwayland_view->set_window_type.link);
266 wl_list_remove(&xwayland_view->map.link);
267 wl_list_remove(&xwayland_view->unmap.link);
268 free(xwayland_view); 261 free(xwayland_view);
269} 262}
270 263
@@ -285,22 +278,27 @@ static void handle_commit(struct wl_listener *listener, void *data) {
285 wl_container_of(listener, xwayland_view, commit); 278 wl_container_of(listener, xwayland_view, commit);
286 struct sway_view *view = &xwayland_view->view; 279 struct sway_view *view = &xwayland_view->view;
287 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; 280 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
288 if (view->swayc && container_is_floating(view->swayc)) { 281 struct wlr_surface_state *surface_state = xsurface->surface->current;
289 view_update_size(view, xsurface->width, xsurface->height); 282
290 } else { 283 if (view->swayc->instructions->length) {
291 view_update_size(view, xwayland_view->pending_width, 284 transaction_notify_view_ready_by_size(view,
292 xwayland_view->pending_height); 285 surface_state->width, surface_state->height);
293 } 286 }
294 view_update_position(view,
295 xwayland_view->pending_lx, xwayland_view->pending_ly);
296 view_damage_from(view); 287 view_damage_from(view);
297} 288}
298 289
299static void handle_unmap(struct wl_listener *listener, void *data) { 290static void handle_unmap(struct wl_listener *listener, void *data) {
300 struct sway_xwayland_view *xwayland_view = 291 struct sway_xwayland_view *xwayland_view =
301 wl_container_of(listener, xwayland_view, unmap); 292 wl_container_of(listener, xwayland_view, unmap);
293 struct sway_view *view = &xwayland_view->view;
294
295 if (!sway_assert(view->surface, "Cannot unmap unmapped view")) {
296 return;
297 }
298
299 view_unmap(view);
300
302 wl_list_remove(&xwayland_view->commit.link); 301 wl_list_remove(&xwayland_view->commit.link);
303 view_unmap(&xwayland_view->view);
304} 302}
305 303
306static void handle_map(struct wl_listener *listener, void *data) { 304static void handle_map(struct wl_listener *listener, void *data) {
@@ -322,12 +320,31 @@ static void handle_map(struct wl_listener *listener, void *data) {
322 320
323 if (xsurface->fullscreen) { 321 if (xsurface->fullscreen) {
324 view_set_fullscreen(view, true); 322 view_set_fullscreen(view, true);
323 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
324 arrange_and_commit(ws);
325 } else {
326 arrange_and_commit(view->swayc->parent);
325 } 327 }
326} 328}
327 329
328static void handle_destroy(struct wl_listener *listener, void *data) { 330static void handle_destroy(struct wl_listener *listener, void *data) {
329 struct sway_xwayland_view *xwayland_view = 331 struct sway_xwayland_view *xwayland_view =
330 wl_container_of(listener, xwayland_view, destroy); 332 wl_container_of(listener, xwayland_view, destroy);
333 struct sway_view *view = &xwayland_view->view;
334
335 if (view->surface) {
336 view_unmap(view);
337 wl_list_remove(&xwayland_view->commit.link);
338 }
339
340 wl_list_remove(&xwayland_view->destroy.link);
341 wl_list_remove(&xwayland_view->request_configure.link);
342 wl_list_remove(&xwayland_view->request_fullscreen.link);
343 wl_list_remove(&xwayland_view->set_title.link);
344 wl_list_remove(&xwayland_view->set_class.link);
345 wl_list_remove(&xwayland_view->set_window_type.link);
346 wl_list_remove(&xwayland_view->map.link);
347 wl_list_remove(&xwayland_view->unmap.link);
331 view_destroy(&xwayland_view->view); 348 view_destroy(&xwayland_view->view);
332} 349}
333 350
@@ -343,10 +360,12 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
343 return; 360 return;
344 } 361 }
345 if (container_is_floating(view->swayc)) { 362 if (container_is_floating(view->swayc)) {
346 configure(view, view->x, view->y, ev->width, ev->height); 363 configure(view, view->swayc->current.view_x,
364 view->swayc->current.view_y, ev->width, ev->height);
347 } else { 365 } else {
348 configure(view, view->x, view->y, 366 configure(view, view->swayc->current.view_x,
349 view->width, view->height); 367 view->swayc->current.view_y, view->swayc->current.view_width,
368 view->swayc->current.view_height);
350 } 369 }
351} 370}
352 371
@@ -359,6 +378,9 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
359 return; 378 return;
360 } 379 }
361 view_set_fullscreen(view, xsurface->fullscreen); 380 view_set_fullscreen(view, xsurface->fullscreen);
381
382 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
383 arrange_and_commit(ws);
362} 384}
363 385
364static void handle_set_title(struct wl_listener *listener, void *data) { 386static void handle_set_title(struct wl_listener *listener, void *data) {