diff options
Diffstat (limited to 'sway/input/seatop_move_tiling.c')
-rw-r--r-- | sway/input/seatop_move_tiling.c | 233 |
1 files changed, 177 insertions, 56 deletions
diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c index 704e7270..c525b77a 100644 --- a/sway/input/seatop_move_tiling.c +++ b/sway/input/seatop_move_tiling.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <limits.h> | 1 | #include <limits.h> |
3 | #include <wlr/types/wlr_cursor.h> | 2 | #include <wlr/types/wlr_cursor.h> |
4 | #include <wlr/util/edges.h> | 3 | #include <wlr/util/edges.h> |
5 | #include "sway/desktop.h" | 4 | #include "sway/desktop/transaction.h" |
6 | #include "sway/input/cursor.h" | 5 | #include "sway/input/cursor.h" |
7 | #include "sway/input/seat.h" | 6 | #include "sway/input/seat.h" |
8 | #include "sway/ipc-server.h" | 7 | #include "sway/ipc-server.h" |
@@ -15,31 +14,25 @@ | |||
15 | // Thickness of the dropzone when dragging to the edge of a layout container | 14 | // Thickness of the dropzone when dragging to the edge of a layout container |
16 | #define DROP_LAYOUT_BORDER 30 | 15 | #define DROP_LAYOUT_BORDER 30 |
17 | 16 | ||
17 | // Thickness of indicator when dropping onto a titlebar. This should be a | ||
18 | // multiple of 2. | ||
19 | #define DROP_SPLIT_INDICATOR 10 | ||
20 | |||
18 | struct seatop_move_tiling_event { | 21 | struct seatop_move_tiling_event { |
19 | struct sway_container *con; | 22 | struct sway_container *con; |
20 | struct sway_node *target_node; | 23 | struct sway_node *target_node; |
21 | enum wlr_edges target_edge; | 24 | enum wlr_edges target_edge; |
22 | struct wlr_box drop_box; | ||
23 | double ref_lx, ref_ly; // cursor's x/y at start of op | 25 | double ref_lx, ref_ly; // cursor's x/y at start of op |
24 | bool threshold_reached; | 26 | bool threshold_reached; |
27 | bool split_target; | ||
28 | bool insert_after_target; | ||
29 | struct wlr_scene_rect *indicator_rect; | ||
25 | }; | 30 | }; |
26 | 31 | ||
27 | static void handle_render(struct sway_seat *seat, | 32 | static void handle_end(struct sway_seat *seat) { |
28 | struct sway_output *output, pixman_region32_t *damage) { | ||
29 | struct seatop_move_tiling_event *e = seat->seatop_data; | 33 | struct seatop_move_tiling_event *e = seat->seatop_data; |
30 | if (!e->threshold_reached) { | 34 | wlr_scene_node_destroy(&e->indicator_rect->node); |
31 | return; | 35 | e->indicator_rect = NULL; |
32 | } | ||
33 | if (e->target_node && node_get_output(e->target_node) == output) { | ||
34 | float color[4]; | ||
35 | memcpy(&color, config->border_colors.focused.indicator, | ||
36 | sizeof(float) * 4); | ||
37 | premultiply_alpha(color, 0.5); | ||
38 | struct wlr_box box; | ||
39 | memcpy(&box, &e->drop_box, sizeof(struct wlr_box)); | ||
40 | scale_box(&box, output->wlr_output->scale); | ||
41 | render_rect(output, damage, &box, color); | ||
42 | } | ||
43 | } | 36 | } |
44 | 37 | ||
45 | static void handle_motion_prethreshold(struct sway_seat *seat) { | 38 | static void handle_motion_prethreshold(struct sway_seat *seat) { |
@@ -60,6 +53,7 @@ static void handle_motion_prethreshold(struct sway_seat *seat) { | |||
60 | 53 | ||
61 | // If the threshold has been exceeded, start the actual drag | 54 | // If the threshold has been exceeded, start the actual drag |
62 | if ((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy) > threshold) { | 55 | if ((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy) > threshold) { |
56 | wlr_scene_node_set_enabled(&e->indicator_rect->node, true); | ||
63 | e->threshold_reached = true; | 57 | e->threshold_reached = true; |
64 | cursor_set_image(seat->cursor, "grab", NULL); | 58 | cursor_set_image(seat->cursor, "grab", NULL); |
65 | } | 59 | } |
@@ -91,15 +85,86 @@ static void resize_box(struct wlr_box *box, enum wlr_edges edge, | |||
91 | } | 85 | } |
92 | } | 86 | } |
93 | 87 | ||
88 | static void split_border(double pos, int offset, int len, int n_children, | ||
89 | int avoid, int *out_pos, bool *out_after) { | ||
90 | int region = 2 * n_children * (pos - offset) / len; | ||
91 | // If the cursor is over the right side of a left-adjacent titlebar, or the | ||
92 | // left side of a right-adjacent titlebar, it's position when dropped will | ||
93 | // be the same. To avoid this, shift the region for adjacent containers. | ||
94 | if (avoid >= 0) { | ||
95 | if (region == 2 * avoid - 1 || region == 2 * avoid) { | ||
96 | region--; | ||
97 | } else if (region == 2 * avoid + 1 || region == 2 * avoid + 2) { | ||
98 | region++; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | int child_index = (region + 1) / 2; | ||
103 | *out_after = region % 2; | ||
104 | // When dropping at the beginning or end of a container, show the drop | ||
105 | // region within the container boundary, otherwise show it on top of the | ||
106 | // border between two titlebars. | ||
107 | if (child_index == 0) { | ||
108 | *out_pos = offset; | ||
109 | } else if (child_index == n_children) { | ||
110 | *out_pos = offset + len - DROP_SPLIT_INDICATOR; | ||
111 | } else { | ||
112 | *out_pos = offset + child_index * len / n_children - | ||
113 | DROP_SPLIT_INDICATOR / 2; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | static bool split_titlebar(struct sway_node *node, struct sway_container *avoid, | ||
118 | struct wlr_cursor *cursor, struct wlr_box *title_box, bool *after) { | ||
119 | struct sway_container *con = node->sway_container; | ||
120 | struct sway_node *parent = &con->pending.parent->node; | ||
121 | int title_height = container_titlebar_height(); | ||
122 | struct wlr_box box; | ||
123 | int n_children, avoid_index; | ||
124 | enum sway_container_layout layout = | ||
125 | parent ? node_get_layout(parent) : L_NONE; | ||
126 | if (layout == L_TABBED || layout == L_STACKED) { | ||
127 | node_get_box(parent, &box); | ||
128 | n_children = node_get_children(parent)->length; | ||
129 | avoid_index = list_find(node_get_children(parent), avoid); | ||
130 | } else { | ||
131 | node_get_box(node, &box); | ||
132 | n_children = 1; | ||
133 | avoid_index = -1; | ||
134 | } | ||
135 | if (layout == L_STACKED && cursor->y < box.y + title_height * n_children) { | ||
136 | // Drop into stacked titlebars. | ||
137 | title_box->width = box.width; | ||
138 | title_box->height = DROP_SPLIT_INDICATOR; | ||
139 | title_box->x = box.x; | ||
140 | split_border(cursor->y, box.y, title_height * n_children, | ||
141 | n_children, avoid_index, &title_box->y, after); | ||
142 | return true; | ||
143 | } else if (layout != L_STACKED && cursor->y < box.y + title_height) { | ||
144 | // Drop into side-by-side titlebars. | ||
145 | title_box->width = DROP_SPLIT_INDICATOR; | ||
146 | title_box->height = title_height; | ||
147 | title_box->y = box.y; | ||
148 | split_border(cursor->x, box.x, box.width, n_children, | ||
149 | avoid_index, &title_box->x, after); | ||
150 | return true; | ||
151 | } | ||
152 | return false; | ||
153 | } | ||
154 | |||
155 | static void update_indicator(struct seatop_move_tiling_event *e, struct wlr_box *box) { | ||
156 | wlr_scene_node_set_position(&e->indicator_rect->node, box->x, box->y); | ||
157 | wlr_scene_rect_set_size(e->indicator_rect, box->width, box->height); | ||
158 | } | ||
159 | |||
94 | static void handle_motion_postthreshold(struct sway_seat *seat) { | 160 | static void handle_motion_postthreshold(struct sway_seat *seat) { |
95 | struct seatop_move_tiling_event *e = seat->seatop_data; | 161 | struct seatop_move_tiling_event *e = seat->seatop_data; |
162 | e->split_target = false; | ||
96 | struct wlr_surface *surface = NULL; | 163 | struct wlr_surface *surface = NULL; |
97 | double sx, sy; | 164 | double sx, sy; |
98 | struct sway_cursor *cursor = seat->cursor; | 165 | struct sway_cursor *cursor = seat->cursor; |
99 | struct sway_node *node = node_at_coords(seat, | 166 | struct sway_node *node = node_at_coords(seat, |
100 | cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); | 167 | cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); |
101 | // Damage the old location | ||
102 | desktop_damage_box(&e->drop_box); | ||
103 | 168 | ||
104 | if (!node) { | 169 | if (!node) { |
105 | // Eg. hovered over a layer surface such as swaybar | 170 | // Eg. hovered over a layer surface such as swaybar |
@@ -112,41 +177,77 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | |||
112 | // Empty workspace | 177 | // Empty workspace |
113 | e->target_node = node; | 178 | e->target_node = node; |
114 | e->target_edge = WLR_EDGE_NONE; | 179 | e->target_edge = WLR_EDGE_NONE; |
115 | workspace_get_box(node->sway_workspace, &e->drop_box); | 180 | |
116 | desktop_damage_box(&e->drop_box); | 181 | struct wlr_box drop_box; |
182 | workspace_get_box(node->sway_workspace, &drop_box); | ||
183 | update_indicator(e, &drop_box); | ||
117 | return; | 184 | return; |
118 | } | 185 | } |
119 | 186 | ||
120 | // Deny moving within own workspace if this is the only child | 187 | // Deny moving within own workspace if this is the only child |
121 | struct sway_container *con = node->sway_container; | 188 | struct sway_container *con = node->sway_container; |
122 | if (workspace_num_tiling_views(e->con->workspace) == 1 && | 189 | if (workspace_num_tiling_views(e->con->pending.workspace) == 1 && |
123 | con->workspace == e->con->workspace) { | 190 | con->pending.workspace == e->con->pending.workspace) { |
124 | e->target_node = NULL; | 191 | e->target_node = NULL; |
125 | e->target_edge = WLR_EDGE_NONE; | 192 | e->target_edge = WLR_EDGE_NONE; |
126 | return; | 193 | return; |
127 | } | 194 | } |
128 | 195 | ||
196 | struct wlr_box drop_box = { | ||
197 | .x = con->pending.content_x, | ||
198 | .y = con->pending.content_y, | ||
199 | .width = con->pending.content_width, | ||
200 | .height = con->pending.content_height, | ||
201 | }; | ||
202 | |||
203 | // Check if the cursor is over a tilebar only if the destination | ||
204 | // container is not a descendant of the source container. | ||
205 | if (!surface && !container_has_ancestor(con, e->con) && | ||
206 | split_titlebar(node, e->con, cursor->cursor, | ||
207 | &drop_box, &e->insert_after_target)) { | ||
208 | // Don't allow dropping over the source container's titlebar | ||
209 | // to give users a chance to cancel a drag operation. | ||
210 | if (con == e->con) { | ||
211 | e->target_node = NULL; | ||
212 | } else { | ||
213 | e->target_node = node; | ||
214 | e->split_target = true; | ||
215 | } | ||
216 | e->target_edge = WLR_EDGE_NONE; | ||
217 | update_indicator(e, &drop_box); | ||
218 | return; | ||
219 | } | ||
220 | |||
129 | // Traverse the ancestors, trying to find a layout container perpendicular | 221 | // Traverse the ancestors, trying to find a layout container perpendicular |
130 | // to the edge. Eg. close to the top or bottom of a horiz layout. | 222 | // to the edge. Eg. close to the top or bottom of a horiz layout. |
223 | int thresh_top = con->pending.content_y + DROP_LAYOUT_BORDER; | ||
224 | int thresh_bottom = con->pending.content_y + | ||
225 | con->pending.content_height - DROP_LAYOUT_BORDER; | ||
226 | int thresh_left = con->pending.content_x + DROP_LAYOUT_BORDER; | ||
227 | int thresh_right = con->pending.content_x + | ||
228 | con->pending.content_width - DROP_LAYOUT_BORDER; | ||
131 | while (con) { | 229 | while (con) { |
132 | enum wlr_edges edge = WLR_EDGE_NONE; | 230 | enum wlr_edges edge = WLR_EDGE_NONE; |
133 | enum sway_container_layout layout = container_parent_layout(con); | 231 | enum sway_container_layout layout = container_parent_layout(con); |
134 | struct wlr_box parent; | 232 | struct wlr_box box; |
135 | con->parent ? container_get_box(con->parent, &parent) : | 233 | node_get_box(node_get_parent(&con->node), &box); |
136 | workspace_get_box(con->workspace, &parent); | ||
137 | if (layout == L_HORIZ || layout == L_TABBED) { | 234 | if (layout == L_HORIZ || layout == L_TABBED) { |
138 | if (cursor->cursor->y < parent.y + DROP_LAYOUT_BORDER) { | 235 | if (cursor->cursor->y < thresh_top) { |
139 | edge = WLR_EDGE_TOP; | 236 | edge = WLR_EDGE_TOP; |
140 | } else if (cursor->cursor->y > parent.y + parent.height | 237 | box.height = thresh_top - box.y; |
141 | - DROP_LAYOUT_BORDER) { | 238 | } else if (cursor->cursor->y > thresh_bottom) { |
142 | edge = WLR_EDGE_BOTTOM; | 239 | edge = WLR_EDGE_BOTTOM; |
240 | box.height = box.y + box.height - thresh_bottom; | ||
241 | box.y = thresh_bottom; | ||
143 | } | 242 | } |
144 | } else if (layout == L_VERT || layout == L_STACKED) { | 243 | } else if (layout == L_VERT || layout == L_STACKED) { |
145 | if (cursor->cursor->x < parent.x + DROP_LAYOUT_BORDER) { | 244 | if (cursor->cursor->x < thresh_left) { |
146 | edge = WLR_EDGE_LEFT; | 245 | edge = WLR_EDGE_LEFT; |
147 | } else if (cursor->cursor->x > parent.x + parent.width | 246 | box.width = thresh_left - box.x; |
148 | - DROP_LAYOUT_BORDER) { | 247 | } else if (cursor->cursor->x > thresh_right) { |
149 | edge = WLR_EDGE_RIGHT; | 248 | edge = WLR_EDGE_RIGHT; |
249 | box.width = box.x + box.width - thresh_right; | ||
250 | box.x = thresh_right; | ||
150 | } | 251 | } |
151 | } | 252 | } |
152 | if (edge) { | 253 | if (edge) { |
@@ -155,12 +256,10 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | |||
155 | e->target_node = node_get_parent(e->target_node); | 256 | e->target_node = node_get_parent(e->target_node); |
156 | } | 257 | } |
157 | e->target_edge = edge; | 258 | e->target_edge = edge; |
158 | node_get_box(e->target_node, &e->drop_box); | 259 | update_indicator(e, &box); |
159 | resize_box(&e->drop_box, edge, DROP_LAYOUT_BORDER); | ||
160 | desktop_damage_box(&e->drop_box); | ||
161 | return; | 260 | return; |
162 | } | 261 | } |
163 | con = con->parent; | 262 | con = con->pending.parent; |
164 | } | 263 | } |
165 | 264 | ||
166 | // Use the hovered view - but we must be over the actual surface | 265 | // Use the hovered view - but we must be over the actual surface |
@@ -173,23 +272,23 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | |||
173 | } | 272 | } |
174 | 273 | ||
175 | // Find the closest edge | 274 | // Find the closest edge |
176 | size_t thickness = fmin(con->content_width, con->content_height) * 0.3; | 275 | size_t thickness = fmin(con->pending.content_width, con->pending.content_height) * 0.3; |
177 | size_t closest_dist = INT_MAX; | 276 | size_t closest_dist = INT_MAX; |
178 | size_t dist; | 277 | size_t dist; |
179 | e->target_edge = WLR_EDGE_NONE; | 278 | e->target_edge = WLR_EDGE_NONE; |
180 | if ((dist = cursor->cursor->y - con->y) < closest_dist) { | 279 | if ((dist = cursor->cursor->y - con->pending.y) < closest_dist) { |
181 | closest_dist = dist; | 280 | closest_dist = dist; |
182 | e->target_edge = WLR_EDGE_TOP; | 281 | e->target_edge = WLR_EDGE_TOP; |
183 | } | 282 | } |
184 | if ((dist = cursor->cursor->x - con->x) < closest_dist) { | 283 | if ((dist = cursor->cursor->x - con->pending.x) < closest_dist) { |
185 | closest_dist = dist; | 284 | closest_dist = dist; |
186 | e->target_edge = WLR_EDGE_LEFT; | 285 | e->target_edge = WLR_EDGE_LEFT; |
187 | } | 286 | } |
188 | if ((dist = con->x + con->width - cursor->cursor->x) < closest_dist) { | 287 | if ((dist = con->pending.x + con->pending.width - cursor->cursor->x) < closest_dist) { |
189 | closest_dist = dist; | 288 | closest_dist = dist; |
190 | e->target_edge = WLR_EDGE_RIGHT; | 289 | e->target_edge = WLR_EDGE_RIGHT; |
191 | } | 290 | } |
192 | if ((dist = con->y + con->height - cursor->cursor->y) < closest_dist) { | 291 | if ((dist = con->pending.y + con->pending.height - cursor->cursor->y) < closest_dist) { |
193 | closest_dist = dist; | 292 | closest_dist = dist; |
194 | e->target_edge = WLR_EDGE_BOTTOM; | 293 | e->target_edge = WLR_EDGE_BOTTOM; |
195 | } | 294 | } |
@@ -199,12 +298,8 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | |||
199 | } | 298 | } |
200 | 299 | ||
201 | e->target_node = node; | 300 | e->target_node = node; |
202 | e->drop_box.x = con->content_x; | 301 | resize_box(&drop_box, e->target_edge, thickness); |
203 | e->drop_box.y = con->content_y; | 302 | update_indicator(e, &drop_box); |
204 | e->drop_box.width = con->content_width; | ||
205 | e->drop_box.height = con->content_height; | ||
206 | resize_box(&e->drop_box, e->target_edge, thickness); | ||
207 | desktop_damage_box(&e->drop_box); | ||
208 | } | 303 | } |
209 | 304 | ||
210 | static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) { | 305 | static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) { |
@@ -214,6 +309,7 @@ static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) { | |||
214 | } else { | 309 | } else { |
215 | handle_motion_prethreshold(seat); | 310 | handle_motion_prethreshold(seat); |
216 | } | 311 | } |
312 | transaction_commit_dirty(); | ||
217 | } | 313 | } |
218 | 314 | ||
219 | static bool is_parallel(enum sway_container_layout layout, | 315 | static bool is_parallel(enum sway_container_layout layout, |
@@ -232,14 +328,15 @@ static void finalize_move(struct sway_seat *seat) { | |||
232 | } | 328 | } |
233 | 329 | ||
234 | struct sway_container *con = e->con; | 330 | struct sway_container *con = e->con; |
235 | struct sway_container *old_parent = con->parent; | 331 | struct sway_container *old_parent = con->pending.parent; |
236 | struct sway_workspace *old_ws = con->workspace; | 332 | struct sway_workspace *old_ws = con->pending.workspace; |
237 | struct sway_node *target_node = e->target_node; | 333 | struct sway_node *target_node = e->target_node; |
238 | struct sway_workspace *new_ws = target_node->type == N_WORKSPACE ? | 334 | struct sway_workspace *new_ws = target_node->type == N_WORKSPACE ? |
239 | target_node->sway_workspace : target_node->sway_container->workspace; | 335 | target_node->sway_workspace : target_node->sway_container->pending.workspace; |
240 | enum wlr_edges edge = e->target_edge; | 336 | enum wlr_edges edge = e->target_edge; |
241 | int after = edge != WLR_EDGE_TOP && edge != WLR_EDGE_LEFT; | 337 | int after = edge != WLR_EDGE_TOP && edge != WLR_EDGE_LEFT; |
242 | bool swap = edge == WLR_EDGE_NONE && target_node->type == N_CONTAINER; | 338 | bool swap = edge == WLR_EDGE_NONE && target_node->type == N_CONTAINER && |
339 | !e->split_target; | ||
243 | 340 | ||
244 | if (!swap) { | 341 | if (!swap) { |
245 | container_detach(con); | 342 | container_detach(con); |
@@ -248,6 +345,14 @@ static void finalize_move(struct sway_seat *seat) { | |||
248 | // Moving container into empty workspace | 345 | // Moving container into empty workspace |
249 | if (target_node->type == N_WORKSPACE && edge == WLR_EDGE_NONE) { | 346 | if (target_node->type == N_WORKSPACE && edge == WLR_EDGE_NONE) { |
250 | con = workspace_add_tiling(new_ws, con); | 347 | con = workspace_add_tiling(new_ws, con); |
348 | } else if (e->split_target) { | ||
349 | struct sway_container *target = target_node->sway_container; | ||
350 | enum sway_container_layout layout = container_parent_layout(target); | ||
351 | if (layout != L_TABBED && layout != L_STACKED) { | ||
352 | container_split(target, L_TABBED); | ||
353 | } | ||
354 | container_add_sibling(target, con, e->insert_after_target); | ||
355 | ipc_event_window(con, "move"); | ||
251 | } else if (target_node->type == N_CONTAINER) { | 356 | } else if (target_node->type == N_CONTAINER) { |
252 | // Moving container before/after another | 357 | // Moving container before/after another |
253 | struct sway_container *target = target_node->sway_container; | 358 | struct sway_container *target = target_node->sway_container; |
@@ -283,8 +388,8 @@ static void finalize_move(struct sway_seat *seat) { | |||
283 | int index = list_find(siblings, con); | 388 | int index = list_find(siblings, con); |
284 | struct sway_container *sibling = index == 0 ? | 389 | struct sway_container *sibling = index == 0 ? |
285 | siblings->items[1] : siblings->items[index - 1]; | 390 | siblings->items[1] : siblings->items[index - 1]; |
286 | con->width = sibling->width; | 391 | con->pending.width = sibling->pending.width; |
287 | con->height = sibling->height; | 392 | con->pending.height = sibling->pending.height; |
288 | con->width_fraction = sibling->width_fraction; | 393 | con->width_fraction = sibling->width_fraction; |
289 | con->height_fraction = sibling->height_fraction; | 394 | con->height_fraction = sibling->height_fraction; |
290 | } | 395 | } |
@@ -294,12 +399,13 @@ static void finalize_move(struct sway_seat *seat) { | |||
294 | arrange_workspace(new_ws); | 399 | arrange_workspace(new_ws); |
295 | } | 400 | } |
296 | 401 | ||
402 | transaction_commit_dirty(); | ||
297 | seatop_begin_default(seat); | 403 | seatop_begin_default(seat); |
298 | } | 404 | } |
299 | 405 | ||
300 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, | 406 | static void handle_button(struct sway_seat *seat, uint32_t time_msec, |
301 | struct wlr_input_device *device, uint32_t button, | 407 | struct wlr_input_device *device, uint32_t button, |
302 | enum wlr_button_state state) { | 408 | enum wl_pointer_button_state state) { |
303 | if (seat->cursor->pressed_button_count == 0) { | 409 | if (seat->cursor->pressed_button_count == 0) { |
304 | finalize_move(seat); | 410 | finalize_move(seat); |
305 | } | 411 | } |
@@ -328,7 +434,7 @@ static const struct sway_seatop_impl seatop_impl = { | |||
328 | .pointer_motion = handle_pointer_motion, | 434 | .pointer_motion = handle_pointer_motion, |
329 | .tablet_tool_tip = handle_tablet_tool_tip, | 435 | .tablet_tool_tip = handle_tablet_tool_tip, |
330 | .unref = handle_unref, | 436 | .unref = handle_unref, |
331 | .render = handle_render, | 437 | .end = handle_end, |
332 | }; | 438 | }; |
333 | 439 | ||
334 | void seatop_begin_move_tiling_threshold(struct sway_seat *seat, | 440 | void seatop_begin_move_tiling_threshold(struct sway_seat *seat, |
@@ -340,6 +446,20 @@ void seatop_begin_move_tiling_threshold(struct sway_seat *seat, | |||
340 | if (!e) { | 446 | if (!e) { |
341 | return; | 447 | return; |
342 | } | 448 | } |
449 | |||
450 | const float *indicator = config->border_colors.focused.indicator; | ||
451 | float color[4] = { | ||
452 | indicator[0] * .5, | ||
453 | indicator[1] * .5, | ||
454 | indicator[2] * .5, | ||
455 | indicator[3] * .5, | ||
456 | }; | ||
457 | e->indicator_rect = wlr_scene_rect_create(seat->scene_tree, 0, 0, color); | ||
458 | if (!e->indicator_rect) { | ||
459 | free(e); | ||
460 | return; | ||
461 | } | ||
462 | |||
343 | e->con = con; | 463 | e->con = con; |
344 | e->ref_lx = seat->cursor->cursor->x; | 464 | e->ref_lx = seat->cursor->cursor->x; |
345 | e->ref_ly = seat->cursor->cursor->y; | 465 | e->ref_ly = seat->cursor->cursor->y; |
@@ -348,6 +468,7 @@ void seatop_begin_move_tiling_threshold(struct sway_seat *seat, | |||
348 | seat->seatop_data = e; | 468 | seat->seatop_data = e; |
349 | 469 | ||
350 | container_raise_floating(con); | 470 | container_raise_floating(con); |
471 | transaction_commit_dirty(); | ||
351 | wlr_seat_pointer_notify_clear_focus(seat->wlr_seat); | 472 | wlr_seat_pointer_notify_clear_focus(seat->wlr_seat); |
352 | } | 473 | } |
353 | 474 | ||