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