aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-30 21:00:10 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-09-05 18:01:43 +1000
commit7586f150c058997d9dde387ea7c091ffa7a3c3c7 (patch)
tree63d19027974c1db62ce3a74ca1d2314eb6d5049b /sway/desktop/xwayland.c
parentMerge pull request #2569 from RyanDwyer/deny-reload-repeat (diff)
downloadsway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.tar.gz
sway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.tar.zst
sway-7586f150c058997d9dde387ea7c091ffa7a3c3c7.zip
Implement type safe arguments and demote sway_container
This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 94a30239..0d192b76 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -59,8 +59,7 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) {
59 wl_container_of(listener, surface, map); 59 wl_container_of(listener, surface, map);
60 struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface; 60 struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
61 61
62 wl_list_insert(root_container.sway_root->xwayland_unmanaged.prev, 62 wl_list_insert(root->xwayland_unmanaged.prev, &surface->link);
63 &surface->link);
64 63
65 wl_signal_add(&xsurface->surface->events.commit, &surface->commit); 64 wl_signal_add(&xsurface->surface->events.commit, &surface->commit);
66 surface->commit.notify = unmanaged_handle_commit; 65 surface->commit.notify = unmanaged_handle_commit;
@@ -90,11 +89,10 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
90 if (seat->wlr_seat->keyboard_state.focused_surface == 89 if (seat->wlr_seat->keyboard_state.focused_surface ==
91 xsurface->surface) { 90 xsurface->surface) {
92 // Restore focus 91 // Restore focus
93 struct sway_container *previous = 92 struct sway_node *previous = seat_get_focus_inactive(seat, &root->node);
94 seat_get_focus_inactive(seat, &root_container);
95 if (previous) { 93 if (previous) {
96 // Hack to get seat to re-focus the return value of get_focus 94 // Hack to get seat to re-focus the return value of get_focus
97 seat_set_focus(seat, previous->parent); 95 seat_set_focus(seat, NULL);
98 seat_set_focus(seat, previous); 96 seat_set_focus(seat, previous);
99 } 97 }
100 } 98 }
@@ -299,7 +297,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
299 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; 297 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
300 struct wlr_surface_state *state = &xsurface->surface->current; 298 struct wlr_surface_state *state = &xsurface->surface->current;
301 299
302 if (view->swayc->instruction) { 300 if (view->container->node.instruction) {
303 get_geometry(view, &view->geometry); 301 get_geometry(view, &view->geometry);
304 transaction_notify_view_ready_by_size(view, 302 transaction_notify_view_ready_by_size(view,
305 state->width, state->height); 303 state->width, state->height);
@@ -308,7 +306,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
308 get_geometry(view, &new_geo); 306 get_geometry(view, &new_geo);
309 307
310 if ((new_geo.width != view->width || new_geo.height != view->height) && 308 if ((new_geo.width != view->width || new_geo.height != view->height) &&
311 container_is_floating(view->swayc)) { 309 container_is_floating(view->container)) {
312 // A floating view has unexpectedly sent a new size 310 // A floating view has unexpectedly sent a new size
313 // eg. The Firefox "Save As" dialog when downloading a file 311 // eg. The Firefox "Save As" dialog when downloading a file
314 desktop_damage_view(view); 312 desktop_damage_view(view);
@@ -391,11 +389,14 @@ static void handle_map(struct wl_listener *listener, void *data) {
391 view_map(view, xsurface->surface); 389 view_map(view, xsurface->surface);
392 390
393 if (xsurface->fullscreen) { 391 if (xsurface->fullscreen) {
394 container_set_fullscreen(view->swayc, true); 392 container_set_fullscreen(view->container, true);
395 struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); 393 arrange_workspace(view->container->workspace);
396 arrange_windows(ws);
397 } else { 394 } else {
398 arrange_windows(view->swayc->parent); 395 if (view->container->parent) {
396 arrange_container(view->container->parent);
397 } else {
398 arrange_workspace(view->container->workspace);
399 }
399 } 400 }
400 transaction_commit_dirty(); 401 transaction_commit_dirty();
401} 402}
@@ -411,13 +412,14 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
411 ev->width, ev->height); 412 ev->width, ev->height);
412 return; 413 return;
413 } 414 }
414 if (container_is_floating(view->swayc)) { 415 if (container_is_floating(view->container)) {
415 configure(view, view->swayc->current.view_x, 416 configure(view, view->container->current.view_x,
416 view->swayc->current.view_y, ev->width, ev->height); 417 view->container->current.view_y, ev->width, ev->height);
417 } else { 418 } else {
418 configure(view, view->swayc->current.view_x, 419 configure(view, view->container->current.view_x,
419 view->swayc->current.view_y, view->swayc->current.view_width, 420 view->container->current.view_y,
420 view->swayc->current.view_height); 421 view->container->current.view_width,
422 view->container->current.view_height);
421 } 423 }
422} 424}
423 425
@@ -429,10 +431,9 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
429 if (!xsurface->mapped) { 431 if (!xsurface->mapped) {
430 return; 432 return;
431 } 433 }
432 container_set_fullscreen(view->swayc, xsurface->fullscreen); 434 container_set_fullscreen(view->container, xsurface->fullscreen);
433 435
434 struct sway_container *output = container_parent(view->swayc, C_OUTPUT); 436 arrange_workspace(view->container->workspace);
435 arrange_windows(output);
436 transaction_commit_dirty(); 437 transaction_commit_dirty();
437} 438}
438 439
@@ -444,11 +445,11 @@ static void handle_request_move(struct wl_listener *listener, void *data) {
444 if (!xsurface->mapped) { 445 if (!xsurface->mapped) {
445 return; 446 return;
446 } 447 }
447 if (!container_is_floating(view->swayc)) { 448 if (!container_is_floating(view->container)) {
448 return; 449 return;
449 } 450 }
450 struct sway_seat *seat = input_manager_current_seat(input_manager); 451 struct sway_seat *seat = input_manager_current_seat(input_manager);
451 seat_begin_move(seat, view->swayc, seat->last_button); 452 seat_begin_move(seat, view->container, seat->last_button);
452} 453}
453 454
454static void handle_request_resize(struct wl_listener *listener, void *data) { 455static void handle_request_resize(struct wl_listener *listener, void *data) {
@@ -459,12 +460,13 @@ static void handle_request_resize(struct wl_listener *listener, void *data) {
459 if (!xsurface->mapped) { 460 if (!xsurface->mapped) {
460 return; 461 return;
461 } 462 }
462 if (!container_is_floating(view->swayc)) { 463 if (!container_is_floating(view->container)) {
463 return; 464 return;
464 } 465 }
465 struct wlr_xwayland_resize_event *e = data; 466 struct wlr_xwayland_resize_event *e = data;
466 struct sway_seat *seat = input_manager_current_seat(input_manager); 467 struct sway_seat *seat = input_manager_current_seat(input_manager);
467 seat_begin_resize_floating(seat, view->swayc, seat->last_button, e->edges); 468 seat_begin_resize_floating(seat, view->container,
469 seat->last_button, e->edges);
468} 470}
469 471
470static void handle_request_activate(struct wl_listener *listener, void *data) { 472static void handle_request_activate(struct wl_listener *listener, void *data) {