aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/cursor.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/input/cursor.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/input/cursor.c')
-rw-r--r--sway/input/cursor.c158
1 files changed, 75 insertions, 83 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 00240e84..15993265 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -20,6 +20,7 @@
20#include "sway/layers.h" 20#include "sway/layers.h"
21#include "sway/output.h" 21#include "sway/output.h"
22#include "sway/tree/arrange.h" 22#include "sway/tree/arrange.h"
23#include "sway/tree/container.h"
23#include "sway/tree/root.h" 24#include "sway/tree/root.h"
24#include "sway/tree/view.h" 25#include "sway/tree/view.h"
25#include "sway/tree/workspace.h" 26#include "sway/tree/workspace.h"
@@ -50,15 +51,15 @@ static struct wlr_surface *layer_surface_at(struct sway_output *output,
50} 51}
51 52
52/** 53/**
53 * Returns the container at the cursor's position. If there is a surface at that 54 * Returns the node at the cursor's position. If there is a surface at that
54 * location, it is stored in **surface (it may not be a view). 55 * location, it is stored in **surface (it may not be a view).
55 */ 56 */
56static struct sway_container *container_at_coords( 57static struct sway_node *node_at_coords(
57 struct sway_seat *seat, double lx, double ly, 58 struct sway_seat *seat, double lx, double ly,
58 struct wlr_surface **surface, double *sx, double *sy) { 59 struct wlr_surface **surface, double *sx, double *sy) {
59 // check for unmanaged views first 60 // check for unmanaged views first
60#ifdef HAVE_XWAYLAND 61#ifdef HAVE_XWAYLAND
61 struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged; 62 struct wl_list *unmanaged = &root->xwayland_unmanaged;
62 struct sway_xwayland_unmanaged *unmanaged_surface; 63 struct sway_xwayland_unmanaged *unmanaged_surface;
63 wl_list_for_each_reverse(unmanaged_surface, unmanaged, link) { 64 wl_list_for_each_reverse(unmanaged_surface, unmanaged, link) {
64 struct wlr_xwayland_surface *xsurface = 65 struct wlr_xwayland_surface *xsurface =
@@ -75,67 +76,64 @@ static struct sway_container *container_at_coords(
75 } 76 }
76#endif 77#endif
77 // find the output the cursor is on 78 // find the output the cursor is on
78 struct wlr_output_layout *output_layout =
79 root_container.sway_root->output_layout;
80 struct wlr_output *wlr_output = wlr_output_layout_output_at( 79 struct wlr_output *wlr_output = wlr_output_layout_output_at(
81 output_layout, lx, ly); 80 root->output_layout, lx, ly);
82 if (wlr_output == NULL) { 81 if (wlr_output == NULL) {
83 return NULL; 82 return NULL;
84 } 83 }
85 struct sway_output *output = wlr_output->data; 84 struct sway_output *output = wlr_output->data;
86 double ox = lx, oy = ly; 85 double ox = lx, oy = ly;
87 wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy); 86 wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
88 87
89 // find the focused workspace on the output for this seat 88 // find the focused workspace on the output for this seat
90 struct sway_container *ws = seat_get_focus_inactive(seat, output->swayc); 89 struct sway_workspace *ws = output_get_active_workspace(output);
91 if (ws && ws->type != C_WORKSPACE) {
92 ws = container_parent(ws, C_WORKSPACE);
93 }
94 if (!ws) {
95 return output->swayc;
96 }
97 90
98 if ((*surface = layer_surface_at(output, 91 if ((*surface = layer_surface_at(output,
99 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], 92 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
100 ox, oy, sx, sy))) { 93 ox, oy, sx, sy))) {
101 return ws; 94 return &ws->node;
102 } 95 }
103 if (ws->sway_workspace->fullscreen) { 96 if (ws->fullscreen) {
104 return tiling_container_at(ws->sway_workspace->fullscreen, lx, ly, 97 struct sway_container *con =
105 surface, sx, sy); 98 tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy);
99 if (con) {
100 return &con->node;
101 }
102 return NULL;
106 } 103 }
107 if ((*surface = layer_surface_at(output, 104 if ((*surface = layer_surface_at(output,
108 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], 105 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
109 ox, oy, sx, sy))) { 106 ox, oy, sx, sy))) {
110 return ws; 107 return &ws->node;
111 } 108 }
112 109
113 struct sway_container *c; 110 struct sway_container *c;
114 if ((c = container_at(ws, lx, ly, surface, sx, sy))) { 111 if ((c = container_at(ws, lx, ly, surface, sx, sy))) {
115 return c; 112 return &c->node;
116 } 113 }
117 114
118 if ((*surface = layer_surface_at(output, 115 if ((*surface = layer_surface_at(output,
119 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], 116 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
120 ox, oy, sx, sy))) { 117 ox, oy, sx, sy))) {
121 return ws; 118 return &ws->node;
122 } 119 }
123 if ((*surface = layer_surface_at(output, 120 if ((*surface = layer_surface_at(output,
124 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], 121 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
125 ox, oy, sx, sy))) { 122 ox, oy, sx, sy))) {
126 return ws; 123 return &ws->node;
127 } 124 }
128 125
129 c = seat_get_active_child(seat, output->swayc); 126 return &ws->node;
130 if (c) { 127}
131 return c;
132 }
133 if (!c && output->swayc->children->length) {
134 c = output->swayc->children->items[0];
135 return c;
136 }
137 128
138 return output->swayc; 129static struct sway_container *container_at_coords(struct sway_seat *seat,
130 double lx, double ly,
131 struct wlr_surface **surface, double *sx, double *sy) {
132 struct sway_node *node = node_at_coords(seat, lx, ly, surface, sx, sy);
133 if (node && node->type == N_CONTAINER) {
134 return node->sway_container;
135 }
136 return NULL;
139} 137}
140 138
141/** 139/**
@@ -160,13 +158,14 @@ static bool edge_is_external(struct sway_container *cont, enum wlr_edges edge) {
160 158
161 // Iterate the parents until we find one with the layout we want, 159 // Iterate the parents until we find one with the layout we want,
162 // then check if the child has siblings between it and the edge. 160 // then check if the child has siblings between it and the edge.
163 while (cont->type != C_OUTPUT) { 161 while (cont) {
164 if (cont->parent->layout == layout) { 162 if (container_parent_layout(cont) == layout) {
165 int index = list_find(cont->parent->children, cont); 163 list_t *siblings = container_get_siblings(cont);
164 int index = list_find(siblings, cont);
166 if (index > 0 && (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_TOP)) { 165 if (index > 0 && (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_TOP)) {
167 return false; 166 return false;
168 } 167 }
169 if (index < cont->parent->children->length - 1 && 168 if (index < siblings->length - 1 &&
170 (edge == WLR_EDGE_RIGHT || edge == WLR_EDGE_BOTTOM)) { 169 (edge == WLR_EDGE_RIGHT || edge == WLR_EDGE_BOTTOM)) {
171 return false; 170 return false;
172 } 171 }
@@ -178,10 +177,10 @@ static bool edge_is_external(struct sway_container *cont, enum wlr_edges edge) {
178 177
179static enum wlr_edges find_edge(struct sway_container *cont, 178static enum wlr_edges find_edge(struct sway_container *cont,
180 struct sway_cursor *cursor) { 179 struct sway_cursor *cursor) {
181 if (cont->type != C_VIEW) { 180 if (!cont->view) {
182 return WLR_EDGE_NONE; 181 return WLR_EDGE_NONE;
183 } 182 }
184 struct sway_view *view = cont->sway_view; 183 struct sway_view *view = cont->view;
185 if (view->border == B_NONE || !view->border_thickness || view->using_csd) { 184 if (view->border == B_NONE || !view->border_thickness || view->using_csd) {
186 return WLR_EDGE_NONE; 185 return WLR_EDGE_NONE;
187 } 186 }
@@ -219,7 +218,7 @@ static enum wlr_edges find_resize_edge(struct sway_container *cont,
219static void handle_down_motion(struct sway_seat *seat, 218static void handle_down_motion(struct sway_seat *seat,
220 struct sway_cursor *cursor, uint32_t time_msec) { 219 struct sway_cursor *cursor, uint32_t time_msec) {
221 struct sway_container *con = seat->op_container; 220 struct sway_container *con = seat->op_container;
222 if (seat_is_input_allowed(seat, con->sway_view->surface)) { 221 if (seat_is_input_allowed(seat, con->view->surface)) {
223 double moved_x = cursor->cursor->x - seat->op_ref_lx; 222 double moved_x = cursor->cursor->x - seat->op_ref_lx;
224 double moved_y = cursor->cursor->y - seat->op_ref_ly; 223 double moved_y = cursor->cursor->y - seat->op_ref_ly;
225 double sx = seat->op_ref_con_lx + moved_x; 224 double sx = seat->op_ref_con_lx + moved_x;
@@ -260,8 +259,7 @@ static void calculate_floating_constraints(struct sway_container *con,
260 if (config->floating_maximum_width == -1) { // no maximum 259 if (config->floating_maximum_width == -1) { // no maximum
261 *max_width = INT_MAX; 260 *max_width = INT_MAX;
262 } else if (config->floating_maximum_width == 0) { // automatic 261 } else if (config->floating_maximum_width == 0) { // automatic
263 struct sway_container *ws = container_parent(con, C_WORKSPACE); 262 *max_width = con->workspace->width;
264 *max_width = ws->width;
265 } else { 263 } else {
266 *max_width = config->floating_maximum_width; 264 *max_width = config->floating_maximum_width;
267 } 265 }
@@ -269,8 +267,7 @@ static void calculate_floating_constraints(struct sway_container *con,
269 if (config->floating_maximum_height == -1) { // no maximum 267 if (config->floating_maximum_height == -1) { // no maximum
270 *max_height = INT_MAX; 268 *max_height = INT_MAX;
271 } else if (config->floating_maximum_height == 0) { // automatic 269 } else if (config->floating_maximum_height == 0) { // automatic
272 struct sway_container *ws = container_parent(con, C_WORKSPACE); 270 *max_height = con->workspace->height;
273 *max_height = ws->height;
274 } else { 271 } else {
275 *max_height = config->floating_maximum_height; 272 *max_height = config->floating_maximum_height;
276 } 273 }
@@ -314,9 +311,9 @@ static void handle_resize_floating_motion(struct sway_seat *seat,
314 height = fmax(min_height, fmin(height, max_height)); 311 height = fmax(min_height, fmin(height, max_height));
315 312
316 // Apply the view's min/max size 313 // Apply the view's min/max size
317 if (con->type == C_VIEW) { 314 if (con->view) {
318 double view_min_width, view_max_width, view_min_height, view_max_height; 315 double view_min_width, view_max_width, view_min_height, view_max_height;
319 view_get_constraints(con->sway_view, &view_min_width, &view_max_width, 316 view_get_constraints(con->view, &view_min_width, &view_max_width,
320 &view_min_height, &view_max_height); 317 &view_min_height, &view_max_height);
321 width = fmax(view_min_width, fmin(width, view_max_width)); 318 width = fmax(view_min_width, fmin(width, view_max_width));
322 height = fmax(view_min_height, fmin(height, view_max_height)); 319 height = fmax(view_min_height, fmin(height, view_max_height));
@@ -357,15 +354,15 @@ static void handle_resize_floating_motion(struct sway_seat *seat,
357 con->width += relative_grow_width; 354 con->width += relative_grow_width;
358 con->height += relative_grow_height; 355 con->height += relative_grow_height;
359 356
360 if (con->type == C_VIEW) { 357 if (con->view) {
361 struct sway_view *view = con->sway_view; 358 struct sway_view *view = con->view;
362 view->x += relative_grow_x; 359 view->x += relative_grow_x;
363 view->y += relative_grow_y; 360 view->y += relative_grow_y;
364 view->width += relative_grow_width; 361 view->width += relative_grow_width;
365 view->height += relative_grow_height; 362 view->height += relative_grow_height;
366 } 363 }
367 364
368 arrange_windows(con); 365 arrange_container(con);
369} 366}
370 367
371static void handle_resize_tiling_motion(struct sway_seat *seat, 368static void handle_resize_tiling_motion(struct sway_seat *seat,
@@ -435,44 +432,40 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
435 struct wlr_surface *surface = NULL; 432 struct wlr_surface *surface = NULL;
436 double sx, sy; 433 double sx, sy;
437 434
438 // Find the container beneath the pointer's previous position 435 // Find the node beneath the pointer's previous position
439 struct sway_container *prev_c = container_at_coords(seat, 436 struct sway_node *prev_node = node_at_coords(seat,
440 cursor->previous.x, cursor->previous.y, &surface, &sx, &sy); 437 cursor->previous.x, cursor->previous.y, &surface, &sx, &sy);
441 // Update the stored previous position 438 // Update the stored previous position
442 cursor->previous.x = cursor->cursor->x; 439 cursor->previous.x = cursor->cursor->x;
443 cursor->previous.y = cursor->cursor->y; 440 cursor->previous.y = cursor->cursor->y;
444 441
445 struct sway_container *c = container_at_coords(seat, 442 struct sway_node *node = node_at_coords(seat,
446 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); 443 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
447 if (c && config->focus_follows_mouse && allow_refocusing) { 444 if (node && config->focus_follows_mouse && allow_refocusing) {
448 struct sway_container *focus = seat_get_focus(seat); 445 struct sway_node *focus = seat_get_focus(seat);
449 if (focus && c->type == C_WORKSPACE) { 446 if (focus && node->type == N_WORKSPACE) {
450 // Only follow the mouse if it would move to a new output 447 // Only follow the mouse if it would move to a new output
451 // Otherwise we'll focus the workspace, which is probably wrong 448 // Otherwise we'll focus the workspace, which is probably wrong
452 if (focus->type != C_OUTPUT) { 449 struct sway_output *focused_output = node_get_output(focus);
453 focus = container_parent(focus, C_OUTPUT); 450 struct sway_output *output = node_get_output(node);
454 } 451 if (output != focused_output) {
455 struct sway_container *output = c; 452 seat_set_focus_warp(seat, node, false, true);
456 if (output->type != C_OUTPUT) {
457 output = container_parent(c, C_OUTPUT);
458 }
459 if (output != focus) {
460 seat_set_focus_warp(seat, c, false, true);
461 } 453 }
462 } else if (c->type == C_VIEW) { 454 } else if (node->type == N_CONTAINER && node->sway_container->view) {
463 // Focus c if the following are true: 455 // Focus node if the following are true:
464 // - cursor is over a new view, i.e. entered a new window; and 456 // - cursor is over a new view, i.e. entered a new window; and
465 // - the new view is visible, i.e. not hidden in a stack or tab; and 457 // - the new view is visible, i.e. not hidden in a stack or tab; and
466 // - the seat does not have a keyboard grab 458 // - the seat does not have a keyboard grab
467 if (!wlr_seat_keyboard_has_grab(cursor->seat->wlr_seat) && 459 if (!wlr_seat_keyboard_has_grab(cursor->seat->wlr_seat) &&
468 c != prev_c && 460 node != prev_node &&
469 view_is_visible(c->sway_view)) { 461 view_is_visible(node->sway_container->view)) {
470 seat_set_focus_warp(seat, c, false, true); 462 seat_set_focus_warp(seat, node, false, true);
471 } else { 463 } else {
472 struct sway_container *next_focus = 464 struct sway_node *next_focus =
473 seat_get_focus_inactive(seat, &root_container); 465 seat_get_focus_inactive(seat, &root->node);
474 if (next_focus && next_focus->type == C_VIEW && 466 if (next_focus && next_focus->type == N_CONTAINER &&
475 view_is_visible(next_focus->sway_view)) { 467 node->sway_container->view &&
468 view_is_visible(next_focus->sway_container->view)) {
476 seat_set_focus_warp(seat, next_focus, false, true); 469 seat_set_focus_warp(seat, next_focus, false, true);
477 } 470 }
478 } 471 }
@@ -486,12 +479,12 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
486 if (client != cursor->image_client) { 479 if (client != cursor->image_client) {
487 cursor_set_image(cursor, "left_ptr", client); 480 cursor_set_image(cursor, "left_ptr", client);
488 } 481 }
489 } else if (c) { 482 } else if (node && node->type == N_CONTAINER) {
490 // Try a container's resize edge 483 // Try a node's resize edge
491 enum wlr_edges edge = find_resize_edge(c, cursor); 484 enum wlr_edges edge = find_resize_edge(node->sway_container, cursor);
492 if (edge == WLR_EDGE_NONE) { 485 if (edge == WLR_EDGE_NONE) {
493 cursor_set_image(cursor, "left_ptr", NULL); 486 cursor_set_image(cursor, "left_ptr", NULL);
494 } else if (container_is_floating(c)) { 487 } else if (container_is_floating(node->sway_container)) {
495 cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL); 488 cursor_set_image(cursor, wlr_xcursor_get_resize_name(edge), NULL);
496 } else { 489 } else {
497 if (edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)) { 490 if (edge & (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)) {
@@ -684,7 +677,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
684 // Handle tiling resize via border 677 // Handle tiling resize via border
685 if (resize_edge && button == BTN_LEFT && state == WLR_BUTTON_PRESSED && 678 if (resize_edge && button == BTN_LEFT && state == WLR_BUTTON_PRESSED &&
686 !is_floating) { 679 !is_floating) {
687 seat_set_focus(seat, cont); 680 seat_set_focus(seat, &cont->node);
688 seat_begin_resize_tiling(seat, cont, button, edge); 681 seat_begin_resize_tiling(seat, cont, button, edge);
689 return; 682 return;
690 } 683 }
@@ -713,7 +706,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
713 image = "sw-resize"; 706 image = "sw-resize";
714 } 707 }
715 cursor_set_image(seat->cursor, image, NULL); 708 cursor_set_image(seat->cursor, image, NULL);
716 seat_set_focus(seat, cont); 709 seat_set_focus(seat, &cont->node);
717 seat_begin_resize_tiling(seat, cont, button, edge); 710 seat_begin_resize_tiling(seat, cont, button, edge);
718 return; 711 return;
719 } 712 }
@@ -725,7 +718,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
725 uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT; 718 uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
726 if (button == btn_move && state == WLR_BUTTON_PRESSED && 719 if (button == btn_move && state == WLR_BUTTON_PRESSED &&
727 (mod_pressed || on_titlebar)) { 720 (mod_pressed || on_titlebar)) {
728 while (cont->parent->type != C_WORKSPACE) { 721 while (cont->parent) {
729 cont = cont->parent; 722 cont = cont->parent;
730 } 723 }
731 seat_begin_move(seat, cont, button); 724 seat_begin_move(seat, cont, button);
@@ -747,7 +740,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
747 BTN_LEFT : BTN_RIGHT; 740 BTN_LEFT : BTN_RIGHT;
748 if (mod_pressed && button == btn_resize) { 741 if (mod_pressed && button == btn_resize) {
749 struct sway_container *floater = cont; 742 struct sway_container *floater = cont;
750 while (floater->parent->type != C_WORKSPACE) { 743 while (floater->parent) {
751 floater = floater->parent; 744 floater = floater->parent;
752 } 745 }
753 edge = 0; 746 edge = 0;
@@ -762,7 +755,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
762 755
763 // Handle mousedown on a container surface 756 // Handle mousedown on a container surface
764 if (surface && cont && state == WLR_BUTTON_PRESSED) { 757 if (surface && cont && state == WLR_BUTTON_PRESSED) {
765 seat_set_focus(seat, cont); 758 seat_set_focus(seat, &cont->node);
766 seat_pointer_notify_button(seat, time_msec, button, state); 759 seat_pointer_notify_button(seat, time_msec, button, state);
767 seat_begin_down(seat, cont, button, sx, sy); 760 seat_begin_down(seat, cont, button, sx, sy);
768 return; 761 return;
@@ -770,7 +763,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
770 763
771 // Handle clicking a container surface 764 // Handle clicking a container surface
772 if (cont) { 765 if (cont) {
773 seat_set_focus(seat, cont); 766 seat_set_focus(seat, &cont->node);
774 seat_pointer_notify_button(seat, time_msec, button, state); 767 seat_pointer_notify_button(seat, time_msec, button, state);
775 return; 768 return;
776 } 769 }
@@ -1025,8 +1018,7 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) {
1025 cursor->previous.y = wlr_cursor->y; 1018 cursor->previous.y = wlr_cursor->y;
1026 1019
1027 cursor->seat = seat; 1020 cursor->seat = seat;
1028 wlr_cursor_attach_output_layout(wlr_cursor, 1021 wlr_cursor_attach_output_layout(wlr_cursor, root->output_layout);
1029 root_container.sway_root->output_layout);
1030 1022
1031 // input events 1023 // input events
1032 wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); 1024 wl_signal_add(&wlr_cursor->events.motion, &cursor->motion);