diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-07 18:36:20 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-09 23:38:29 +1000 |
commit | ab8a86369c01c7146991ff4ae2ef04b0a1db06ca (patch) | |
tree | 9ec17bf453a32d7fdd7f621896c9b89c00af8755 /sway/tree/container.c | |
parent | Merge pull request #2226 from emersion/swaylock-daemonize-after-lock (diff) | |
download | sway-ab8a86369c01c7146991ff4ae2ef04b0a1db06ca.tar.gz sway-ab8a86369c01c7146991ff4ae2ef04b0a1db06ca.tar.zst sway-ab8a86369c01c7146991ff4ae2ef04b0a1db06ca.zip |
Implement some floating move commands
This implements the following for floating containers:
* move <direction> <amount>
* move [absolute] position <x> <y>
* move [absolute] position mouse
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r-- | sway/tree/container.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index 5fdcb6e3..2df2332c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -11,11 +11,14 @@ | |||
11 | #include "cairo.h" | 11 | #include "cairo.h" |
12 | #include "pango.h" | 12 | #include "pango.h" |
13 | #include "sway/config.h" | 13 | #include "sway/config.h" |
14 | #include "sway/desktop.h" | ||
15 | #include "sway/desktop/transaction.h" | ||
14 | #include "sway/input/input-manager.h" | 16 | #include "sway/input/input-manager.h" |
15 | #include "sway/input/seat.h" | 17 | #include "sway/input/seat.h" |
16 | #include "sway/ipc-server.h" | 18 | #include "sway/ipc-server.h" |
17 | #include "sway/output.h" | 19 | #include "sway/output.h" |
18 | #include "sway/server.h" | 20 | #include "sway/server.h" |
21 | #include "sway/tree/arrange.h" | ||
19 | #include "sway/tree/layout.h" | 22 | #include "sway/tree/layout.h" |
20 | #include "sway/tree/view.h" | 23 | #include "sway/tree/view.h" |
21 | #include "sway/tree/workspace.h" | 24 | #include "sway/tree/workspace.h" |
@@ -989,3 +992,82 @@ void container_get_box(struct sway_container *container, struct wlr_box *box) { | |||
989 | box->width = container->width; | 992 | box->width = container->width; |
990 | box->height = container->height; | 993 | box->height = container->height; |
991 | } | 994 | } |
995 | |||
996 | /** | ||
997 | * Translate the container's position as well as all children. | ||
998 | */ | ||
999 | static void container_floating_translate(struct sway_container *con, | ||
1000 | double x_amount, double y_amount) { | ||
1001 | con->x += x_amount; | ||
1002 | con->y += y_amount; | ||
1003 | con->current.swayc_x += x_amount; | ||
1004 | con->current.swayc_y += y_amount; | ||
1005 | if (con->type == C_VIEW) { | ||
1006 | con->sway_view->x += x_amount; | ||
1007 | con->sway_view->y += y_amount; | ||
1008 | con->current.view_x += x_amount; | ||
1009 | con->current.view_y += y_amount; | ||
1010 | } else { | ||
1011 | for (int i = 0; i < con->children->length; ++i) { | ||
1012 | struct sway_container *child = con->children->items[i]; | ||
1013 | container_floating_translate(child, x_amount, y_amount); | ||
1014 | } | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | /** | ||
1019 | * Choose an output for the floating container's new position. | ||
1020 | * | ||
1021 | * If the center of the container intersects an output then we'll choose that | ||
1022 | * one, otherwise we'll choose whichever output is closest to the container's | ||
1023 | * center. | ||
1024 | */ | ||
1025 | static struct sway_container *container_floating_find_output( | ||
1026 | struct sway_container *con) { | ||
1027 | double center_x = con->x + con->width / 2; | ||
1028 | double center_y = con->y + con->height / 2; | ||
1029 | struct sway_container *closest_output = NULL; | ||
1030 | double closest_distance = DBL_MAX; | ||
1031 | for (int i = 0; i < root_container.children->length; ++i) { | ||
1032 | struct sway_container *output = root_container.children->items[i]; | ||
1033 | struct wlr_box output_box; | ||
1034 | double closest_x, closest_y; | ||
1035 | container_get_box(output, &output_box); | ||
1036 | wlr_box_closest_point(&output_box, center_x, center_y, | ||
1037 | &closest_x, &closest_y); | ||
1038 | if (center_x == closest_x && center_y == closest_y) { | ||
1039 | // The center of the floating container is on this output | ||
1040 | return output; | ||
1041 | } | ||
1042 | double x_dist = closest_x - center_x; | ||
1043 | double y_dist = closest_y - center_y; | ||
1044 | double distance = x_dist * x_dist + y_dist * y_dist; | ||
1045 | if (distance < closest_distance) { | ||
1046 | closest_output = output; | ||
1047 | closest_distance = distance; | ||
1048 | } | ||
1049 | } | ||
1050 | return closest_output; | ||
1051 | } | ||
1052 | |||
1053 | void container_floating_move_to(struct sway_container *con, | ||
1054 | double lx, double ly) { | ||
1055 | desktop_damage_whole_container(con); | ||
1056 | container_floating_translate(con, lx - con->x, ly - con->y); | ||
1057 | desktop_damage_whole_container(con); | ||
1058 | struct sway_container *old_workspace = container_parent(con, C_WORKSPACE); | ||
1059 | struct sway_container *new_output = container_floating_find_output(con); | ||
1060 | if (!sway_assert(new_output, "Unable to find any output")) { | ||
1061 | return; | ||
1062 | } | ||
1063 | struct sway_container *new_workspace = | ||
1064 | output_get_active_workspace(new_output->sway_output); | ||
1065 | if (old_workspace != new_workspace) { | ||
1066 | container_remove_child(con); | ||
1067 | container_add_child(new_workspace->sway_workspace->floating, con); | ||
1068 | struct sway_transaction *transaction = transaction_create(); | ||
1069 | arrange_windows(old_workspace, transaction); | ||
1070 | arrange_windows(new_workspace, transaction); | ||
1071 | transaction_commit(transaction); | ||
1072 | } | ||
1073 | } | ||