summaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-04-02 15:30:58 -0400
committerLibravatar emersion <contact@emersion.fr>2018-04-02 15:30:58 -0400
commita4a241697ae591289d7c14eff972e1ef787216e2 (patch)
treed82d3c3eba2946670aa634a62d03feb7102f0bf8 /sway
parentXwayland unmanaged views aren't views anymore (diff)
parentMerge pull request #1699 from acrisci/seat-fixes (diff)
downloadsway-a4a241697ae591289d7c14eff972e1ef787216e2.tar.gz
sway-a4a241697ae591289d7c14eff972e1ef787216e2.tar.zst
sway-a4a241697ae591289d7c14eff972e1ef787216e2.zip
Merge branch 'wlroots' into view-redesign
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c21
-rw-r--r--sway/commands/focus.c11
-rw-r--r--sway/commands/move.c184
-rw-r--r--sway/commands/seat.c11
-rw-r--r--sway/commands/workspace.c2
-rw-r--r--sway/config.c2
-rw-r--r--sway/desktop/output.c13
-rw-r--r--sway/input/cursor.c10
-rw-r--r--sway/input/input-manager.c144
-rw-r--r--sway/input/keyboard.c6
-rw-r--r--sway/input/seat.c99
-rw-r--r--sway/ipc-json.c8
-rw-r--r--sway/ipc-server.c6
-rw-r--r--sway/meson.build1
-rw-r--r--sway/server.c2
-rw-r--r--sway/tree/container.c20
-rw-r--r--sway/tree/layout.c70
-rw-r--r--sway/tree/output.c11
-rw-r--r--sway/tree/view.c4
-rw-r--r--sway/tree/workspace.c16
20 files changed, 444 insertions, 197 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 90544220..9ba252b0 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -72,23 +72,23 @@ void apply_input_config(struct input_config *input) {
72 list_add(config->input_configs, input); 72 list_add(config->input_configs, input);
73 } 73 }
74 74
75 sway_input_manager_apply_input_config(input_manager, input); 75 input_manager_apply_input_config(input_manager, input);
76} 76}
77 77
78void apply_seat_config(struct seat_config *seat) { 78void apply_seat_config(struct seat_config *seat_config) {
79 int i; 79 int i;
80 i = list_seq_find(config->seat_configs, seat_name_cmp, seat->name); 80 i = list_seq_find(config->seat_configs, seat_name_cmp, seat_config->name);
81 if (i >= 0) { 81 if (i >= 0) {
82 // merge existing config 82 // merge existing config
83 struct seat_config *sc = config->seat_configs->items[i]; 83 struct seat_config *sc = config->seat_configs->items[i];
84 merge_seat_config(sc, seat); 84 merge_seat_config(sc, seat_config);
85 free_seat_config(seat); 85 free_seat_config(seat_config);
86 seat = sc; 86 seat_config = sc;
87 } else { 87 } else {
88 list_add(config->seat_configs, seat); 88 list_add(config->seat_configs, seat_config);
89 } 89 }
90 90
91 sway_input_manager_apply_seat_config(input_manager, seat); 91 input_manager_apply_seat_config(input_manager, seat_config);
92} 92}
93 93
94/* Keep alphabetized */ 94/* Keep alphabetized */
@@ -162,6 +162,7 @@ static struct cmd_handler command_handlers[] = {
162 { "focus", cmd_focus }, 162 { "focus", cmd_focus },
163 { "kill", cmd_kill }, 163 { "kill", cmd_kill },
164 { "layout", cmd_layout }, 164 { "layout", cmd_layout },
165 { "move", cmd_move },
165 { "reload", cmd_reload }, 166 { "reload", cmd_reload },
166}; 167};
167 168
@@ -262,7 +263,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
262 263
263 if (seat == NULL) { 264 if (seat == NULL) {
264 // passing a NULL seat means we just pick the default seat 265 // passing a NULL seat means we just pick the default seat
265 seat = sway_input_manager_get_default_seat(input_manager); 266 seat = input_manager_get_default_seat(input_manager);
266 if (!sway_assert(seat, "could not find a seat to run the command on")) { 267 if (!sway_assert(seat, "could not find a seat to run the command on")) {
267 return NULL; 268 return NULL;
268 } 269 }
@@ -340,7 +341,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
340 // without criteria, the command acts upon the focused 341 // without criteria, the command acts upon the focused
341 // container 342 // container
342 config->handler_context.current_container = 343 config->handler_context.current_container =
343 sway_seat_get_focus_inactive(seat, &root_container); 344 seat_get_focus_inactive(seat, &root_container);
344 if (!sway_assert(config->handler_context.current_container, 345 if (!sway_assert(config->handler_context.current_container,
345 "could not get focus-inactive for root container")) { 346 "could not get focus-inactive for root container")) {
346 return NULL; 347 return NULL;
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 64f079f4..74d9d535 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -20,10 +20,6 @@ static bool parse_movement_direction(const char *name,
20 *out = MOVE_PARENT; 20 *out = MOVE_PARENT;
21 } else if (strcasecmp(name, "child") == 0) { 21 } else if (strcasecmp(name, "child") == 0) {
22 *out = MOVE_CHILD; 22 *out = MOVE_CHILD;
23 } else if (strcasecmp(name, "next") == 0) {
24 *out = MOVE_NEXT;
25 } else if (strcasecmp(name, "prev") == 0) {
26 *out = MOVE_PREV;
27 } else { 23 } else {
28 return false; 24 return false;
29 } 25 }
@@ -40,7 +36,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
40 } 36 }
41 37
42 if (argc == 0) { 38 if (argc == 0) {
43 sway_seat_set_focus(seat, con); 39 seat_set_focus(seat, con);
44 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 40 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
45 } 41 }
46 42
@@ -51,9 +47,10 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
51 "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'"); 47 "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'");
52 } 48 }
53 49
54 struct sway_container *next_focus = container_get_in_direction(con, seat, direction); 50 struct sway_container *next_focus = container_get_in_direction(
51 con, seat, direction);
55 if (next_focus) { 52 if (next_focus) {
56 sway_seat_set_focus(seat, next_focus); 53 seat_set_focus(seat, next_focus);
57 } 54 }
58 55
59 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 56 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/move.c b/sway/commands/move.c
new file mode 100644
index 00000000..644c622b
--- /dev/null
+++ b/sway/commands/move.c
@@ -0,0 +1,184 @@
1#include <string.h>
2#include <strings.h>
3#include <wlr/types/wlr_output.h>
4#include <wlr/types/wlr_output_layout.h>
5#include <wlr/util/log.h>
6#include "sway/commands.h"
7#include "sway/input/seat.h"
8#include "sway/output.h"
9#include "sway/tree/container.h"
10#include "sway/tree/layout.h"
11#include "sway/tree/workspace.h"
12#include "stringop.h"
13#include "list.h"
14
15static const char* expected_syntax =
16 "Expected 'move <left|right|up|down> <[px] px>' or "
17 "'move <container|window> to workspace <name>' or "
18 "'move <container|window|workspace> to output <name|direction>' or "
19 "'move position mouse'";
20
21static struct sway_container *output_in_direction(const char *direction,
22 struct wlr_output *reference, int ref_ox, int ref_oy) {
23 int ref_lx = ref_ox + reference->lx,
24 ref_ly = ref_oy + reference->ly;
25 struct {
26 char *name;
27 enum wlr_direction direction;
28 } names[] = {
29 { "up", WLR_DIRECTION_UP },
30 { "down", WLR_DIRECTION_DOWN },
31 { "left", WLR_DIRECTION_LEFT },
32 { "right", WLR_DIRECTION_RIGHT },
33 };
34 for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); ++i) {
35 if (strcasecmp(names[i].name, direction) == 0) {
36 struct wlr_output *adjacent = wlr_output_layout_adjacent_output(
37 root_container.sway_root->output_layout,
38 names[i].direction, reference, ref_lx, ref_ly);
39 if (adjacent) {
40 struct sway_output *sway_output = adjacent->data;
41 return sway_output->swayc;
42 }
43 break;
44 }
45 }
46 return output_by_name(direction);
47}
48
49static struct cmd_results *cmd_move_container(struct sway_container *current,
50 int argc, char **argv) {
51 struct cmd_results *error = NULL;
52 if ((error = checkarg(argc, "move container/window",
53 EXPECTED_AT_LEAST, 4))) {
54 return error;
55 } else if (strcasecmp(argv[1], "to") == 0
56 && strcasecmp(argv[2], "workspace") == 0) {
57 // move container to workspace x
58 if (current->type == C_WORKSPACE) {
59 // TODO: Wrap children in a container and move that
60 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
61 } else if (current->type != C_CONTAINER && current->type != C_VIEW) {
62 return cmd_results_new(CMD_FAILURE, "move",
63 "Can only move containers and views.");
64 }
65 struct sway_container *ws;
66 const char *num_name = NULL;
67 char *ws_name = NULL;
68 if (argc == 5 && strcasecmp(argv[3], "number") == 0) {
69 // move "container to workspace number x"
70 num_name = argv[4];
71 ws = workspace_by_number(num_name);
72 } else {
73 ws_name = join_args(argv + 3, argc - 3);
74 ws = workspace_by_name(ws_name);
75 }
76 if (!ws) {
77 ws = workspace_create(ws_name ? ws_name : num_name);
78 }
79 free(ws_name);
80 struct sway_container *old_parent = current->parent;
81 struct sway_container *focus = seat_get_focus_inactive(
82 config->handler_context.seat, ws);
83 container_move_to(current, focus);
84 seat_set_focus(config->handler_context.seat, old_parent);
85 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
86 } else if (strcasecmp(argv[1], "to") == 0
87 && strcasecmp(argv[2], "output") == 0) {
88 if (current->type == C_WORKSPACE) {
89 // TODO: Wrap children in a container and move that
90 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
91 } else if (current->type != C_CONTAINER
92 && current->type != C_VIEW) {
93 return cmd_results_new(CMD_FAILURE, "move",
94 "Can only move containers and views.");
95 }
96 struct sway_container *source = container_parent(current, C_OUTPUT);
97 struct sway_container *destination = output_in_direction(argv[3],
98 source->sway_output->wlr_output, current->x, current->y);
99 if (!destination) {
100 return cmd_results_new(CMD_FAILURE, "move workspace",
101 "Can't find output with name/direction '%s'", argv[3]);
102 }
103 struct sway_container *focus = seat_get_focus_inactive(
104 config->handler_context.seat, destination);
105 if (!focus) {
106 // We've never been to this output before
107 focus = destination->children->items[0];
108 }
109 struct sway_container *old_parent = current->parent;
110 container_move_to(current, focus);
111 seat_set_focus(config->handler_context.seat, old_parent);
112 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
113 }
114 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
115}
116
117static struct cmd_results *cmd_move_workspace(struct sway_container *current,
118 int argc, char **argv) {
119 struct cmd_results *error = NULL;
120 if ((error = checkarg(argc, "move workspace", EXPECTED_EQUAL_TO, 4))) {
121 return error;
122 } else if (strcasecmp(argv[1], "to") != 0
123 || strcasecmp(argv[2], "output") != 0) {
124 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
125 }
126 struct sway_container *source = container_parent(current, C_OUTPUT);
127 int center_x = current->width / 2 + current->x,
128 center_y = current->height / 2 + current->y;
129 struct sway_container *destination = output_in_direction(argv[3],
130 source->sway_output->wlr_output, center_x, center_y);
131 if (!destination) {
132 return cmd_results_new(CMD_FAILURE, "move workspace",
133 "Can't find output with name/direction '%s'", argv[3]);
134 }
135 if (current->type != C_WORKSPACE) {
136 current = container_parent(current, C_WORKSPACE);
137 }
138 container_move_to(current, destination);
139 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
140}
141
142struct cmd_results *cmd_move(int argc, char **argv) {
143 struct cmd_results *error = NULL;
144 int move_amt = 10;
145 if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
146 return error;
147 }
148 struct sway_container *current = config->handler_context.current_container;
149
150 if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0)) {
151 char *inv;
152 move_amt = (int)strtol(argv[1], &inv, 10);
153 if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
154 return cmd_results_new(CMD_FAILURE, "move",
155 "Invalid distance specified");
156 }
157 }
158
159 if (strcasecmp(argv[0], "left") == 0) {
160 container_move(current, MOVE_LEFT, move_amt);
161 } else if (strcasecmp(argv[0], "right") == 0) {
162 container_move(current, MOVE_RIGHT, move_amt);
163 } else if (strcasecmp(argv[0], "up") == 0) {
164 container_move(current, MOVE_UP, move_amt);
165 } else if (strcasecmp(argv[0], "down") == 0) {
166 container_move(current, MOVE_DOWN, move_amt);
167 } else if (strcasecmp(argv[0], "container") == 0
168 || strcasecmp(argv[0], "window") == 0) {
169 return cmd_move_container(current, argc, argv);
170 } else if (strcasecmp(argv[0], "workspace") == 0) {
171 return cmd_move_workspace(current, argc, argv);
172 } else if (strcasecmp(argv[0], "scratchpad") == 0
173 || (strcasecmp(argv[0], "to") == 0
174 && strcasecmp(argv[1], "scratchpad") == 0)) {
175 // TODO: scratchpad
176 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
177 } else if (strcasecmp(argv[0], "position") == 0) {
178 // TODO: floating
179 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
180 } else {
181 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
182 }
183 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
184}
diff --git a/sway/commands/seat.c b/sway/commands/seat.c
index 45079616..819b769c 100644
--- a/sway/commands/seat.c
+++ b/sway/commands/seat.c
@@ -14,7 +14,8 @@ struct cmd_results *cmd_seat(int argc, char **argv) {
14 free_seat_config(config->handler_context.seat_config); 14 free_seat_config(config->handler_context.seat_config);
15 config->handler_context.seat_config = new_seat_config(argv[0]); 15 config->handler_context.seat_config = new_seat_config(argv[0]);
16 if (!config->handler_context.seat_config) { 16 if (!config->handler_context.seat_config) {
17 return cmd_results_new(CMD_FAILURE, NULL, "Couldn't allocate config"); 17 return cmd_results_new(CMD_FAILURE, NULL,
18 "Couldn't allocate config");
18 } 19 }
19 wlr_log(L_DEBUG, "entering seat block: %s", argv[0]); 20 wlr_log(L_DEBUG, "entering seat block: %s", argv[0]);
20 return cmd_results_new(CMD_BLOCK_SEAT, NULL, NULL); 21 return cmd_results_new(CMD_BLOCK_SEAT, NULL, NULL);
@@ -28,7 +29,8 @@ struct cmd_results *cmd_seat(int argc, char **argv) {
28 if (!has_context) { 29 if (!has_context) {
29 config->handler_context.seat_config = new_seat_config(argv[0]); 30 config->handler_context.seat_config = new_seat_config(argv[0]);
30 if (!config->handler_context.seat_config) { 31 if (!config->handler_context.seat_config) {
31 return cmd_results_new(CMD_FAILURE, NULL, "Couldn't allocate config"); 32 return cmd_results_new(CMD_FAILURE, NULL,
33 "Couldn't allocate config");
32 } 34 }
33 } 35 }
34 36
@@ -41,7 +43,10 @@ struct cmd_results *cmd_seat(int argc, char **argv) {
41 } else if (strcasecmp("fallback", argv[1]) == 0) { 43 } else if (strcasecmp("fallback", argv[1]) == 0) {
42 res = seat_cmd_fallback(argc_new, argv_new); 44 res = seat_cmd_fallback(argc_new, argv_new);
43 } else { 45 } else {
44 res = cmd_results_new(CMD_INVALID, "seat <name>", "Unknown command %s", argv[1]); 46 res =
47 cmd_results_new(CMD_INVALID,
48 "seat <name>", "Unknown command %s",
49 argv[1]);
45 } 50 }
46 51
47 if (!has_context) { 52 if (!has_context) {
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index 8f39e5fc..aa4096f7 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -91,7 +91,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
91 } 91 }
92 workspace_switch(ws); 92 workspace_switch(ws);
93 current_container = 93 current_container =
94 sway_seat_get_focus(config->handler_context.seat); 94 seat_get_focus(config->handler_context.seat);
95 struct sway_container *new_output = container_parent(current_container, C_OUTPUT); 95 struct sway_container *new_output = container_parent(current_container, C_OUTPUT);
96 96
97 if (config->mouse_warping && old_output != new_output) { 97 if (config->mouse_warping && old_output != new_output) {
diff --git a/sway/config.c b/sway/config.c
index 0eecf7f6..90b833ab 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -125,7 +125,7 @@ static void destroy_removed_seats(struct sway_config *old_config,
125 seat_name_cmp, seat_config->name) < 0) { 125 seat_name_cmp, seat_config->name) < 0) {
126 seat = input_manager_get_seat(input_manager, 126 seat = input_manager_get_seat(input_manager,
127 seat_config->name); 127 seat_config->name);
128 sway_seat_destroy(seat); 128 seat_destroy(seat);
129 } 129 }
130 } 130 }
131} 131}
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 352f4af3..10ed1f6d 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -245,10 +245,13 @@ static void render_output(struct sway_output *output, struct timespec *when,
245 245
246 struct sway_seat *seat = input_manager_current_seat(input_manager); 246 struct sway_seat *seat = input_manager_current_seat(input_manager);
247 struct sway_container *focus = 247 struct sway_container *focus =
248 sway_seat_get_focus_inactive(seat, output->swayc); 248 seat_get_focus_inactive(seat, output->swayc);
249 struct sway_container *workspace = (focus->type == C_WORKSPACE ? 249 if (!focus) {
250 focus : 250 // We've never been to this output before
251 container_parent(focus, C_WORKSPACE)); 251 focus = output->swayc->children->items[0];
252 }
253 struct sway_container *workspace = focus->type == C_WORKSPACE ?
254 focus : container_parent(focus, C_WORKSPACE);
252 255
253 struct render_data rdata = { 256 struct render_data rdata = {
254 .output = output, 257 .output = output,
@@ -393,7 +396,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
393 wl_list_init(&output->layers[i]); 396 wl_list_init(&output->layers[i]);
394 } 397 }
395 398
396 sway_input_manager_configure_xcursor(input_manager); 399 input_manager_configure_xcursor(input_manager);
397 400
398 wl_signal_add(&wlr_output->events.destroy, &output->destroy); 401 wl_signal_add(&wlr_output->events.destroy, &output->destroy);
399 output->destroy.notify = handle_destroy; 402 output->destroy.notify = handle_destroy;
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 77ab9e31..97b4473c 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -85,7 +85,7 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor,
85 85
86 // find the focused workspace on the output for this seat 86 // find the focused workspace on the output for this seat
87 struct sway_container *ws = 87 struct sway_container *ws =
88 sway_seat_get_focus_inactive(cursor->seat, output->swayc); 88 seat_get_focus_inactive(cursor->seat, output->swayc);
89 if (ws && ws->type != C_WORKSPACE) { 89 if (ws && ws->type != C_WORKSPACE) {
90 ws = container_parent(ws, C_WORKSPACE); 90 ws = container_parent(ws, C_WORKSPACE);
91 } 91 }
@@ -130,7 +130,7 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor,
130 double sx, sy; 130 double sx, sy;
131 struct sway_container *c = container_at_cursor(cursor, &surface, &sx, &sy); 131 struct sway_container *c = container_at_cursor(cursor, &surface, &sx, &sy);
132 if (c && config->focus_follows_mouse) { 132 if (c && config->focus_follows_mouse) {
133 sway_seat_set_focus_warp(cursor->seat, c, false); 133 seat_set_focus_warp(cursor->seat, c, false);
134 } 134 }
135 135
136 // reset cursor if switching between clients 136 // reset cursor if switching between clients
@@ -192,15 +192,15 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
192 if (new_ws && new_ws->type != C_WORKSPACE) { 192 if (new_ws && new_ws->type != C_WORKSPACE) {
193 new_ws = container_parent(new_ws, C_WORKSPACE); 193 new_ws = container_parent(new_ws, C_WORKSPACE);
194 } 194 }
195 struct sway_container *old_ws = sway_seat_get_focus(cursor->seat); 195 struct sway_container *old_ws = seat_get_focus(cursor->seat);
196 if (old_ws && old_ws->type != C_WORKSPACE) { 196 if (old_ws && old_ws->type != C_WORKSPACE) {
197 old_ws = container_parent(old_ws, C_WORKSPACE); 197 old_ws = container_parent(old_ws, C_WORKSPACE);
198 } 198 }
199 if (new_ws != old_ws) { 199 if (new_ws != old_ws) {
200 sway_seat_set_focus(cursor->seat, cont); 200 seat_set_focus(cursor->seat, cont);
201 } 201 }
202 } else { 202 } else {
203 sway_seat_set_focus(cursor->seat, cont); 203 seat_set_focus(cursor->seat, cont);
204 } 204 }
205 205
206 wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec, 206 wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, event->time_msec,
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index d421a03f..c3507f65 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -26,7 +26,7 @@ struct seat_config *current_seat_config = NULL;
26struct sway_seat *input_manager_current_seat(struct sway_input_manager *input) { 26struct sway_seat *input_manager_current_seat(struct sway_input_manager *input) {
27 struct sway_seat *seat = config->handler_context.seat; 27 struct sway_seat *seat = config->handler_context.seat;
28 if (!seat) { 28 if (!seat) {
29 seat = sway_input_manager_get_default_seat(input_manager); 29 seat = input_manager_get_default_seat(input_manager);
30 } 30 }
31 return seat; 31 return seat;
32} 32}
@@ -40,7 +40,7 @@ struct sway_seat *input_manager_get_seat(
40 } 40 }
41 } 41 }
42 42
43 return sway_seat_create(input, seat_name); 43 return seat_create(input, seat_name);
44} 44}
45 45
46static char *get_device_identifier(struct wlr_input_device *device) { 46static char *get_device_identifier(struct wlr_input_device *device) {
@@ -83,7 +83,8 @@ static struct sway_input_device *input_sway_device_from_wlr(
83static bool input_has_seat_configuration(struct sway_input_manager *input) { 83static bool input_has_seat_configuration(struct sway_input_manager *input) {
84 struct sway_seat *seat = NULL; 84 struct sway_seat *seat = NULL;
85 wl_list_for_each(seat, &input->seats, link) { 85 wl_list_for_each(seat, &input->seats, link) {
86 if (seat->config) { 86 struct seat_config *seat_config = seat_get_config(seat);
87 if (seat_config) {
87 return true; 88 return true;
88 } 89 }
89 } 90 }
@@ -91,9 +92,10 @@ static bool input_has_seat_configuration(struct sway_input_manager *input) {
91 return false; 92 return false;
92} 93}
93 94
94static void sway_input_manager_libinput_config_pointer(struct sway_input_device *input_device) { 95static void input_manager_libinput_config_pointer(
96 struct sway_input_device *input_device) {
95 struct wlr_input_device *wlr_device = input_device->wlr_device; 97 struct wlr_input_device *wlr_device = input_device->wlr_device;
96 struct input_config *ic = input_device->config; 98 struct input_config *ic = input_device_get_config(input_device);
97 struct libinput_device *libinput_device; 99 struct libinput_device *libinput_device;
98 100
99 if (!ic || !wlr_input_device_is_libinput(wlr_device)) { 101 if (!ic || !wlr_input_device_is_libinput(wlr_device)) {
@@ -101,22 +103,27 @@ static void sway_input_manager_libinput_config_pointer(struct sway_input_device
101 } 103 }
102 104
103 libinput_device = wlr_libinput_get_device_handle(wlr_device); 105 libinput_device = wlr_libinput_get_device_handle(wlr_device);
104 wlr_log(L_DEBUG, "sway_input_manager_libinput_config_pointer(%s)", ic->identifier); 106 wlr_log(L_DEBUG, "input_manager_libinput_config_pointer(%s)",
107 ic->identifier);
105 108
106 if (ic->accel_profile != INT_MIN) { 109 if (ic->accel_profile != INT_MIN) {
107 wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)", 110 wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)",
108 ic->identifier, ic->accel_profile); 111 ic->identifier, ic->accel_profile);
109 libinput_device_config_accel_set_profile(libinput_device, ic->accel_profile); 112 libinput_device_config_accel_set_profile(libinput_device,
113 ic->accel_profile);
110 } 114 }
111 if (ic->click_method != INT_MIN) { 115 if (ic->click_method != INT_MIN) {
112 wlr_log(L_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)", 116 wlr_log(L_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)",
113 ic->identifier, ic->click_method); 117 ic->identifier, ic->click_method);
114 libinput_device_config_click_set_method(libinput_device, ic->click_method); 118 libinput_device_config_click_set_method(libinput_device,
119 ic->click_method);
115 } 120 }
116 if (ic->drag_lock != INT_MIN) { 121 if (ic->drag_lock != INT_MIN) {
117 wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)", 122 wlr_log(L_DEBUG,
123 "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)",
118 ic->identifier, ic->click_method); 124 ic->identifier, ic->click_method);
119 libinput_device_config_tap_set_drag_lock_enabled(libinput_device, ic->drag_lock); 125 libinput_device_config_tap_set_drag_lock_enabled(libinput_device,
126 ic->drag_lock);
120 } 127 }
121 if (ic->dwt != INT_MIN) { 128 if (ic->dwt != INT_MIN) {
122 wlr_log(L_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)", 129 wlr_log(L_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)",
@@ -124,34 +131,43 @@ static void sway_input_manager_libinput_config_pointer(struct sway_input_device
124 libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt); 131 libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt);
125 } 132 }
126 if (ic->left_handed != INT_MIN) { 133 if (ic->left_handed != INT_MIN) {
127 wlr_log(L_DEBUG, "libinput_config_pointer(%s) left_handed_set_enabled(%d)", 134 wlr_log(L_DEBUG,
135 "libinput_config_pointer(%s) left_handed_set_enabled(%d)",
128 ic->identifier, ic->left_handed); 136 ic->identifier, ic->left_handed);
129 libinput_device_config_left_handed_set(libinput_device, ic->left_handed); 137 libinput_device_config_left_handed_set(libinput_device,
138 ic->left_handed);
130 } 139 }
131 if (ic->middle_emulation != INT_MIN) { 140 if (ic->middle_emulation != INT_MIN) {
132 wlr_log(L_DEBUG, "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)", 141 wlr_log(L_DEBUG,
142 "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)",
133 ic->identifier, ic->middle_emulation); 143 ic->identifier, ic->middle_emulation);
134 libinput_device_config_middle_emulation_set_enabled(libinput_device, ic->middle_emulation); 144 libinput_device_config_middle_emulation_set_enabled(libinput_device,
145 ic->middle_emulation);
135 } 146 }
136 if (ic->natural_scroll != INT_MIN) { 147 if (ic->natural_scroll != INT_MIN) {
137 wlr_log(L_DEBUG, "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)", 148 wlr_log(L_DEBUG,
149 "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)",
138 ic->identifier, ic->natural_scroll); 150 ic->identifier, ic->natural_scroll);
139 libinput_device_config_scroll_set_natural_scroll_enabled(libinput_device, ic->natural_scroll); 151 libinput_device_config_scroll_set_natural_scroll_enabled(
152 libinput_device, ic->natural_scroll);
140 } 153 }
141 if (ic->pointer_accel != FLT_MIN) { 154 if (ic->pointer_accel != FLT_MIN) {
142 wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)", 155 wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)",
143 ic->identifier, ic->pointer_accel); 156 ic->identifier, ic->pointer_accel);
144 libinput_device_config_accel_set_speed(libinput_device, ic->pointer_accel); 157 libinput_device_config_accel_set_speed(libinput_device,
158 ic->pointer_accel);
145 } 159 }
146 if (ic->scroll_method != INT_MIN) { 160 if (ic->scroll_method != INT_MIN) {
147 wlr_log(L_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)", 161 wlr_log(L_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)",
148 ic->identifier, ic->scroll_method); 162 ic->identifier, ic->scroll_method);
149 libinput_device_config_scroll_set_method(libinput_device, ic->scroll_method); 163 libinput_device_config_scroll_set_method(libinput_device,
164 ic->scroll_method);
150 } 165 }
151 if (ic->send_events != INT_MIN) { 166 if (ic->send_events != INT_MIN) {
152 wlr_log(L_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)", 167 wlr_log(L_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)",
153 ic->identifier, ic->send_events); 168 ic->identifier, ic->send_events);
154 libinput_device_config_send_events_set_mode(libinput_device, ic->send_events); 169 libinput_device_config_send_events_set_mode(libinput_device,
170 ic->send_events);
155 } 171 }
156 if (ic->tap != INT_MIN) { 172 if (ic->tap != INT_MIN) {
157 wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)", 173 wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)",
@@ -175,12 +191,11 @@ static void handle_device_destroy(struct wl_listener *listener, void *data) {
175 191
176 struct sway_seat *seat = NULL; 192 struct sway_seat *seat = NULL;
177 wl_list_for_each(seat, &input_manager->seats, link) { 193 wl_list_for_each(seat, &input_manager->seats, link) {
178 sway_seat_remove_device(seat, input_device); 194 seat_remove_device(seat, input_device);
179 } 195 }
180 196
181 wl_list_remove(&input_device->link); 197 wl_list_remove(&input_device->link);
182 wl_list_remove(&input_device->device_destroy.link); 198 wl_list_remove(&input_device->device_destroy.link);
183 free_input_config(input_device->config);
184 free(input_device->identifier); 199 free(input_device->identifier);
185 free(input_device); 200 free(input_device);
186} 201}
@@ -203,44 +218,36 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
203 wlr_log(L_DEBUG, "adding device: '%s'", 218 wlr_log(L_DEBUG, "adding device: '%s'",
204 input_device->identifier); 219 input_device->identifier);
205 220
206 // find config
207 for (int i = 0; i < config->input_configs->length; ++i) {
208 struct input_config *input_config = config->input_configs->items[i];
209 if (strcmp(input_config->identifier, input_device->identifier) == 0) {
210 free_input_config(input_device->config);
211 input_device->config = copy_input_config(input_config);
212 break;
213 }
214 }
215
216 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { 221 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) {
217 sway_input_manager_libinput_config_pointer(input_device); 222 input_manager_libinput_config_pointer(input_device);
218 } 223 }
219 224
220 struct sway_seat *seat = NULL; 225 struct sway_seat *seat = NULL;
221 if (!input_has_seat_configuration(input)) { 226 if (!input_has_seat_configuration(input)) {
222 wlr_log(L_DEBUG, "no seat configuration, using default seat"); 227 wlr_log(L_DEBUG, "no seat configuration, using default seat");
223 seat = input_manager_get_seat(input, default_seat); 228 seat = input_manager_get_seat(input, default_seat);
224 sway_seat_add_device(seat, input_device); 229 seat_add_device(seat, input_device);
225 return; 230 return;
226 } 231 }
227 232
228 bool added = false; 233 bool added = false;
229 wl_list_for_each(seat, &input->seats, link) { 234 wl_list_for_each(seat, &input->seats, link) {
230 bool has_attachment = seat->config && 235 struct seat_config *seat_config = seat_get_config(seat);
231 (seat_config_get_attachment(seat->config, input_device->identifier) || 236 bool has_attachment = seat_config &&
232 seat_config_get_attachment(seat->config, "*")); 237 (seat_config_get_attachment(seat_config, input_device->identifier) ||
238 seat_config_get_attachment(seat_config, "*"));
233 239
234 if (has_attachment) { 240 if (has_attachment) {
235 sway_seat_add_device(seat, input_device); 241 seat_add_device(seat, input_device);
236 added = true; 242 added = true;
237 } 243 }
238 } 244 }
239 245
240 if (!added) { 246 if (!added) {
241 wl_list_for_each(seat, &input->seats, link) { 247 wl_list_for_each(seat, &input->seats, link) {
242 if (seat->config && seat->config->fallback == 1) { 248 struct seat_config *seat_config = seat_get_config(seat);
243 sway_seat_add_device(seat, input_device); 249 if (seat_config && seat_config->fallback == 1) {
250 seat_add_device(seat, input_device);
244 added = true; 251 added = true;
245 } 252 }
246 } 253 }
@@ -256,7 +263,7 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
256 input_device->device_destroy.notify = handle_device_destroy; 263 input_device->device_destroy.notify = handle_device_destroy;
257} 264}
258 265
259struct sway_input_manager *sway_input_manager_create( 266struct sway_input_manager *input_manager_create(
260 struct sway_server *server) { 267 struct sway_server *server) {
261 struct sway_input_manager *input = 268 struct sway_input_manager *input =
262 calloc(1, sizeof(struct sway_input_manager)); 269 calloc(1, sizeof(struct sway_input_manager));
@@ -277,11 +284,11 @@ struct sway_input_manager *sway_input_manager_create(
277 return input; 284 return input;
278} 285}
279 286
280bool sway_input_manager_has_focus(struct sway_input_manager *input, 287bool input_manager_has_focus(struct sway_input_manager *input,
281 struct sway_container *container) { 288 struct sway_container *container) {
282 struct sway_seat *seat = NULL; 289 struct sway_seat *seat = NULL;
283 wl_list_for_each(seat, &input->seats, link) { 290 wl_list_for_each(seat, &input->seats, link) {
284 if (sway_seat_get_focus(seat) == container) { 291 if (seat_get_focus(seat) == container) {
285 return true; 292 return true;
286 } 293 }
287 } 294 }
@@ -289,35 +296,32 @@ bool sway_input_manager_has_focus(struct sway_input_manager *input,
289 return false; 296 return false;
290} 297}
291 298
292void sway_input_manager_set_focus(struct sway_input_manager *input, 299void input_manager_set_focus(struct sway_input_manager *input,
293 struct sway_container *container) { 300 struct sway_container *container) {
294 struct sway_seat *seat ; 301 struct sway_seat *seat ;
295 wl_list_for_each(seat, &input->seats, link) { 302 wl_list_for_each(seat, &input->seats, link) {
296 sway_seat_set_focus(seat, container); 303 seat_set_focus(seat, container);
297 } 304 }
298} 305}
299 306
300void sway_input_manager_apply_input_config(struct sway_input_manager *input, 307void input_manager_apply_input_config(struct sway_input_manager *input,
301 struct input_config *input_config) { 308 struct input_config *input_config) {
302 struct sway_input_device *input_device = NULL; 309 struct sway_input_device *input_device = NULL;
303 wl_list_for_each(input_device, &input->devices, link) { 310 wl_list_for_each(input_device, &input->devices, link) {
304 if (strcmp(input_device->identifier, input_config->identifier) == 0) { 311 if (strcmp(input_device->identifier, input_config->identifier) == 0) {
305 free_input_config(input_device->config);
306 input_device->config = copy_input_config(input_config);
307
308 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { 312 if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) {
309 sway_input_manager_libinput_config_pointer(input_device); 313 input_manager_libinput_config_pointer(input_device);
310 } 314 }
311 315
312 struct sway_seat *seat = NULL; 316 struct sway_seat *seat = NULL;
313 wl_list_for_each(seat, &input->seats, link) { 317 wl_list_for_each(seat, &input->seats, link) {
314 sway_seat_configure_device(seat, input_device); 318 seat_configure_device(seat, input_device);
315 } 319 }
316 } 320 }
317 } 321 }
318} 322}
319 323
320void sway_input_manager_apply_seat_config(struct sway_input_manager *input, 324void input_manager_apply_seat_config(struct sway_input_manager *input,
321 struct seat_config *seat_config) { 325 struct seat_config *seat_config) {
322 wlr_log(L_DEBUG, "applying new seat config for seat %s", 326 wlr_log(L_DEBUG, "applying new seat config for seat %s",
323 seat_config->name); 327 seat_config->name);
@@ -326,7 +330,7 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input,
326 return; 330 return;
327 } 331 }
328 332
329 sway_seat_set_config(seat, seat_config); 333 seat_apply_config(seat, seat_config);
330 334
331 // for every device, try to add it to a seat and if no seat has it 335 // for every device, try to add it to a seat and if no seat has it
332 // attached, add it to the fallback seats. 336 // attached, add it to the fallback seats.
@@ -335,11 +339,12 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input,
335 list_t *seat_list = create_list(); 339 list_t *seat_list = create_list();
336 struct sway_seat *seat = NULL; 340 struct sway_seat *seat = NULL;
337 wl_list_for_each(seat, &input->seats, link) { 341 wl_list_for_each(seat, &input->seats, link) {
338 if (!seat->config) { 342 struct seat_config *seat_config = seat_get_config(seat);
343 if (!seat_config) {
339 continue; 344 continue;
340 } 345 }
341 if (seat_config_get_attachment(seat->config, "*") || 346 if (seat_config_get_attachment(seat_config, "*") ||
342 seat_config_get_attachment(seat->config, 347 seat_config_get_attachment(seat_config,
343 input_device->identifier)) { 348 input_device->identifier)) {
344 list_add(seat_list, seat); 349 list_add(seat_list, seat);
345 } 350 }
@@ -355,17 +360,18 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input,
355 } 360 }
356 } 361 }
357 if (attached) { 362 if (attached) {
358 sway_seat_add_device(seat, input_device); 363 seat_add_device(seat, input_device);
359 } else { 364 } else {
360 sway_seat_remove_device(seat, input_device); 365 seat_remove_device(seat, input_device);
361 } 366 }
362 } 367 }
363 } else { 368 } else {
364 wl_list_for_each(seat, &input->seats, link) { 369 wl_list_for_each(seat, &input->seats, link) {
365 if (seat->config && seat->config->fallback == 1) { 370 struct seat_config *seat_config = seat_get_config(seat);
366 sway_seat_add_device(seat, input_device); 371 if (seat_config && seat_config->fallback == 1) {
372 seat_add_device(seat, input_device);
367 } else { 373 } else {
368 sway_seat_remove_device(seat, input_device); 374 seat_remove_device(seat, input_device);
369 } 375 }
370 } 376 }
371 } 377 }
@@ -373,14 +379,14 @@ void sway_input_manager_apply_seat_config(struct sway_input_manager *input,
373 } 379 }
374} 380}
375 381
376void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { 382void input_manager_configure_xcursor(struct sway_input_manager *input) {
377 struct sway_seat *seat = NULL; 383 struct sway_seat *seat = NULL;
378 wl_list_for_each(seat, &input->seats, link) { 384 wl_list_for_each(seat, &input->seats, link) {
379 sway_seat_configure_xcursor(seat); 385 seat_configure_xcursor(seat);
380 } 386 }
381} 387}
382 388
383struct sway_seat *sway_input_manager_get_default_seat( 389struct sway_seat *input_manager_get_default_seat(
384 struct sway_input_manager *input) { 390 struct sway_input_manager *input) {
385 struct sway_seat *seat = NULL; 391 struct sway_seat *seat = NULL;
386 wl_list_for_each(seat, &input->seats, link) { 392 wl_list_for_each(seat, &input->seats, link) {
@@ -390,3 +396,15 @@ struct sway_seat *sway_input_manager_get_default_seat(
390 } 396 }
391 return seat; 397 return seat;
392} 398}
399
400struct input_config *input_device_get_config(struct sway_input_device *device) {
401 struct input_config *input_config = NULL;
402 for (int i = 0; i < config->input_configs->length; ++i) {
403 input_config = config->input_configs->items[i];
404 if (strcmp(input_config->identifier, device->identifier) == 0) {
405 return input_config;
406 }
407 }
408
409 return NULL;
410}
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 99685052..dbb0c359 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -97,8 +97,8 @@ static void keyboard_execute_command(struct sway_keyboard *keyboard,
97 config->handler_context.seat = keyboard->seat_device->sway_seat; 97 config->handler_context.seat = keyboard->seat_device->sway_seat;
98 struct cmd_results *results = execute_command(binding->command, NULL); 98 struct cmd_results *results = execute_command(binding->command, NULL);
99 if (results->status != CMD_SUCCESS) { 99 if (results->status != CMD_SUCCESS) {
100 wlr_log(L_DEBUG, "could not run command for binding: %s", 100 wlr_log(L_DEBUG, "could not run command for binding: %s (%s)",
101 binding->command); 101 binding->command, results->error);
102 } 102 }
103 free_cmd_results(results); 103 free_cmd_results(results);
104} 104}
@@ -428,7 +428,7 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
428 struct xkb_rule_names rules; 428 struct xkb_rule_names rules;
429 memset(&rules, 0, sizeof(rules)); 429 memset(&rules, 0, sizeof(rules));
430 struct input_config *input_config = 430 struct input_config *input_config =
431 keyboard->seat_device->input_device->config; 431 input_device_get_config(keyboard->seat_device->input_device);
432 struct wlr_input_device *wlr_device = 432 struct wlr_input_device *wlr_device =
433 keyboard->seat_device->input_device->wlr_device; 433 keyboard->seat_device->input_device->wlr_device;
434 434
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 9aa34aca..27636c1e 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -25,7 +25,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
25 free(seat_device); 25 free(seat_device);
26} 26}
27 27
28void sway_seat_destroy(struct sway_seat *seat) { 28void seat_destroy(struct sway_seat *seat) {
29 struct sway_seat_device *seat_device, *next; 29 struct sway_seat_device *seat_device, *next;
30 wl_list_for_each_safe(seat_device, next, &seat->devices, link) { 30 wl_list_for_each_safe(seat_device, next, &seat->devices, link) {
31 seat_device_destroy(seat_device); 31 seat_device_destroy(seat_device);
@@ -42,18 +42,19 @@ static void handle_seat_container_destroy(struct wl_listener *listener,
42 struct sway_seat *seat = seat_con->seat; 42 struct sway_seat *seat = seat_con->seat;
43 struct sway_container *con = seat_con->container; 43 struct sway_container *con = seat_con->container;
44 44
45 bool is_focus = (sway_seat_get_focus(seat) == con); 45 bool is_focus = (seat_get_focus(seat) == con);
46 46
47 wl_list_remove(&seat_con->link); 47 wl_list_remove(&seat_con->link);
48 48
49 if (is_focus) { 49 if (is_focus) {
50 // pick next focus 50 // pick next focus
51 sway_seat_set_focus(seat, NULL); 51 seat_set_focus(seat, NULL);
52 struct sway_container *next = sway_seat_get_focus_inactive(seat, con->parent); 52 struct sway_container *next =
53 seat_get_focus_inactive(seat, con->parent);
53 if (next == NULL) { 54 if (next == NULL) {
54 next = con->parent; 55 next = con->parent;
55 } 56 }
56 sway_seat_set_focus(seat, next); 57 seat_set_focus(seat, next);
57 } 58 }
58 59
59 wl_list_remove(&seat_con->destroy.link); 60 wl_list_remove(&seat_con->destroy.link);
@@ -110,7 +111,7 @@ static void collect_focus_iter(struct sway_container *con, void *data) {
110 wl_list_insert(&seat->focus_stack, &seat_con->link); 111 wl_list_insert(&seat->focus_stack, &seat_con->link);
111} 112}
112 113
113struct sway_seat *sway_seat_create(struct sway_input_manager *input, 114struct sway_seat *seat_create(struct sway_input_manager *input,
114 const char *seat_name) { 115 const char *seat_name) {
115 struct sway_seat *seat = calloc(1, sizeof(struct sway_seat)); 116 struct sway_seat *seat = calloc(1, sizeof(struct sway_seat));
116 if (!seat) { 117 if (!seat) {
@@ -133,7 +134,8 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input,
133 // init the focus stack 134 // init the focus stack
134 wl_list_init(&seat->focus_stack); 135 wl_list_init(&seat->focus_stack);
135 136
136 container_for_each_descendant_dfs(&root_container, collect_focus_iter, seat); 137 container_for_each_descendant_dfs(&root_container,
138 collect_focus_iter, seat);
137 139
138 wl_signal_add(&root_container.sway_root->events.new_container, 140 wl_signal_add(&root_container.sway_root->events.new_container,
139 &seat->new_container); 141 &seat->new_container);
@@ -147,7 +149,7 @@ struct sway_seat *sway_seat_create(struct sway_input_manager *input,
147 WL_SEAT_CAPABILITY_POINTER | 149 WL_SEAT_CAPABILITY_POINTER |
148 WL_SEAT_CAPABILITY_TOUCH); 150 WL_SEAT_CAPABILITY_TOUCH);
149 151
150 sway_seat_configure_xcursor(seat); 152 seat_configure_xcursor(seat);
151 153
152 wl_list_insert(&input->seats, &seat->link); 154 wl_list_insert(&input->seats, &seat->link);
153 155
@@ -165,11 +167,12 @@ static void seat_configure_keyboard(struct sway_seat *seat,
165 if (!seat_device->keyboard) { 167 if (!seat_device->keyboard) {
166 sway_keyboard_create(seat, seat_device); 168 sway_keyboard_create(seat, seat_device);
167 } 169 }
168 struct wlr_keyboard *wlr_keyboard = seat_device->input_device->wlr_device->keyboard; 170 struct wlr_keyboard *wlr_keyboard =
171 seat_device->input_device->wlr_device->keyboard;
169 sway_keyboard_configure(seat_device->keyboard); 172 sway_keyboard_configure(seat_device->keyboard);
170 wlr_seat_set_keyboard(seat->wlr_seat, 173 wlr_seat_set_keyboard(seat->wlr_seat,
171 seat_device->input_device->wlr_device); 174 seat_device->input_device->wlr_device);
172 struct sway_container *focus = sway_seat_get_focus(seat); 175 struct sway_container *focus = seat_get_focus(seat);
173 if (focus && focus->type == C_VIEW) { 176 if (focus && focus->type == C_VIEW) {
174 // force notify reenter to pick up the new configuration 177 // force notify reenter to pick up the new configuration
175 wlr_seat_keyboard_clear_focus(seat->wlr_seat); 178 wlr_seat_keyboard_clear_focus(seat->wlr_seat);
@@ -179,7 +182,7 @@ static void seat_configure_keyboard(struct sway_seat *seat,
179 } 182 }
180} 183}
181 184
182static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat, 185static struct sway_seat_device *seat_get_device(struct sway_seat *seat,
183 struct sway_input_device *input_device) { 186 struct sway_input_device *input_device) {
184 struct sway_seat_device *seat_device = NULL; 187 struct sway_seat_device *seat_device = NULL;
185 wl_list_for_each(seat_device, &seat->devices, link) { 188 wl_list_for_each(seat_device, &seat->devices, link) {
@@ -191,19 +194,14 @@ static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat,
191 return NULL; 194 return NULL;
192} 195}
193 196
194void sway_seat_configure_device(struct sway_seat *seat, 197void seat_configure_device(struct sway_seat *seat,
195 struct sway_input_device *input_device) { 198 struct sway_input_device *input_device) {
196 struct sway_seat_device *seat_device = 199 struct sway_seat_device *seat_device =
197 sway_seat_get_device(seat, input_device); 200 seat_get_device(seat, input_device);
198 if (!seat_device) { 201 if (!seat_device) {
199 return; 202 return;
200 } 203 }
201 204
202 if (seat->config) {
203 seat_device->attachment_config =
204 seat_config_get_attachment(seat->config, input_device->identifier);
205 }
206
207 switch (input_device->wlr_device->type) { 205 switch (input_device->wlr_device->type) {
208 case WLR_INPUT_DEVICE_POINTER: 206 case WLR_INPUT_DEVICE_POINTER:
209 seat_configure_pointer(seat, seat_device); 207 seat_configure_pointer(seat, seat_device);
@@ -219,10 +217,10 @@ void sway_seat_configure_device(struct sway_seat *seat,
219 } 217 }
220} 218}
221 219
222void sway_seat_add_device(struct sway_seat *seat, 220void seat_add_device(struct sway_seat *seat,
223 struct sway_input_device *input_device) { 221 struct sway_input_device *input_device) {
224 if (sway_seat_get_device(seat, input_device)) { 222 if (seat_get_device(seat, input_device)) {
225 sway_seat_configure_device(seat, input_device); 223 seat_configure_device(seat, input_device);
226 return; 224 return;
227 } 225 }
228 226
@@ -240,13 +238,13 @@ void sway_seat_add_device(struct sway_seat *seat,
240 seat_device->input_device = input_device; 238 seat_device->input_device = input_device;
241 wl_list_insert(&seat->devices, &seat_device->link); 239 wl_list_insert(&seat->devices, &seat_device->link);
242 240
243 sway_seat_configure_device(seat, input_device); 241 seat_configure_device(seat, input_device);
244} 242}
245 243
246void sway_seat_remove_device(struct sway_seat *seat, 244void seat_remove_device(struct sway_seat *seat,
247 struct sway_input_device *input_device) { 245 struct sway_input_device *input_device) {
248 struct sway_seat_device *seat_device = 246 struct sway_seat_device *seat_device =
249 sway_seat_get_device(seat, input_device); 247 seat_get_device(seat, input_device);
250 248
251 if (!seat_device) { 249 if (!seat_device) {
252 return; 250 return;
@@ -258,7 +256,7 @@ void sway_seat_remove_device(struct sway_seat *seat,
258 seat_device_destroy(seat_device); 256 seat_device_destroy(seat_device);
259} 257}
260 258
261void sway_seat_configure_xcursor(struct sway_seat *seat) { 259void seat_configure_xcursor(struct sway_seat *seat) {
262 // TODO configure theme and size 260 // TODO configure theme and size
263 const char *cursor_theme = NULL; 261 const char *cursor_theme = NULL;
264 262
@@ -273,7 +271,8 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) {
273 } 271 }
274 272
275 for (int i = 0; i < root_container.children->length; ++i) { 273 for (int i = 0; i < root_container.children->length; ++i) {
276 struct sway_container *output_container = root_container.children->items[i]; 274 struct sway_container *output_container =
275 root_container.children->items[i];
277 struct wlr_output *output = 276 struct wlr_output *output =
278 output_container->sway_output->wlr_output; 277 output_container->sway_output->wlr_output;
279 bool result = 278 bool result =
@@ -292,9 +291,9 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) {
292 seat->cursor->cursor->y); 291 seat->cursor->cursor->y);
293} 292}
294 293
295void sway_seat_set_focus_warp(struct sway_seat *seat, 294void seat_set_focus_warp(struct sway_seat *seat,
296 struct sway_container *container, bool warp) { 295 struct sway_container *container, bool warp) {
297 struct sway_container *last_focus = sway_seat_get_focus(seat); 296 struct sway_container *last_focus = seat_get_focus(seat);
298 297
299 if (container && last_focus == container) { 298 if (container && last_focus == container) {
300 return; 299 return;
@@ -364,7 +363,7 @@ void sway_seat_set_focus_warp(struct sway_seat *seat,
364 } 363 }
365 364
366 if (last_focus && last_focus->type == C_VIEW && 365 if (last_focus && last_focus->type == C_VIEW &&
367 !sway_input_manager_has_focus(seat->input, last_focus)) { 366 !input_manager_has_focus(seat->input, last_focus)) {
368 struct sway_view *view = last_focus->sway_view; 367 struct sway_view *view = last_focus->sway_view;
369 view_set_activated(view, false); 368 view_set_activated(view, false);
370 } 369 }
@@ -372,12 +371,13 @@ void sway_seat_set_focus_warp(struct sway_seat *seat,
372 seat->has_focus = (container != NULL); 371 seat->has_focus = (container != NULL);
373} 372}
374 373
375void sway_seat_set_focus(struct sway_seat *seat, 374void seat_set_focus(struct sway_seat *seat,
376 struct sway_container *container) { 375 struct sway_container *container) {
377 sway_seat_set_focus_warp(seat, container, true); 376 seat_set_focus_warp(seat, container, true);
378} 377}
379 378
380struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container) { 379struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
380 struct sway_container *container) {
381 struct sway_seat_container *current = NULL; 381 struct sway_seat_container *current = NULL;
382 struct sway_container *parent = NULL; 382 struct sway_container *parent = NULL;
383 wl_list_for_each(current, &seat->focus_stack, link) { 383 wl_list_for_each(current, &seat->focus_stack, link) {
@@ -398,16 +398,17 @@ struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, stru
398 return NULL; 398 return NULL;
399} 399}
400 400
401struct sway_container *sway_seat_get_focus(struct sway_seat *seat) { 401struct sway_container *seat_get_focus(struct sway_seat *seat) {
402 if (!seat->has_focus) { 402 if (!seat->has_focus) {
403 return NULL; 403 return NULL;
404 } 404 }
405 return sway_seat_get_focus_inactive(seat, &root_container); 405 return seat_get_focus_inactive(seat, &root_container);
406} 406}
407 407
408struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, 408struct sway_container *seat_get_focus_by_type(struct sway_seat *seat,
409 enum sway_container_type type) { 409 enum sway_container_type type) {
410 struct sway_container *focus = sway_seat_get_focus_inactive(seat, &root_container); 410 struct sway_container *focus =
411 seat_get_focus_inactive(seat, &root_container);
411 if (focus->type == type) { 412 if (focus->type == type) {
412 return focus; 413 return focus;
413 } 414 }
@@ -415,25 +416,27 @@ struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat,
415 return container_parent(focus, type); 416 return container_parent(focus, type);
416} 417}
417 418
418void sway_seat_set_config(struct sway_seat *seat, 419void seat_apply_config(struct sway_seat *seat,
419 struct seat_config *seat_config) { 420 struct seat_config *seat_config) {
420 // clear configs
421 free_seat_config(seat->config);
422 seat->config = NULL;
423
424 struct sway_seat_device *seat_device = NULL; 421 struct sway_seat_device *seat_device = NULL;
425 wl_list_for_each(seat_device, &seat->devices, link) {
426 seat_device->attachment_config = NULL;
427 }
428 422
429 if (!seat_config) { 423 if (!seat_config) {
430 return; 424 return;
431 } 425 }
432 426
433 // add configs
434 seat->config = copy_seat_config(seat_config);
435
436 wl_list_for_each(seat_device, &seat->devices, link) { 427 wl_list_for_each(seat_device, &seat->devices, link) {
437 sway_seat_configure_device(seat, seat_device->input_device); 428 seat_configure_device(seat, seat_device->input_device);
438 } 429 }
439} 430}
431
432struct seat_config *seat_get_config(struct sway_seat *seat) {
433 struct seat_config *seat_config = NULL;
434 for (int i = 0; i < config->seat_configs->length; ++i ) {
435 seat_config = config->seat_configs->items[i];
436 if (strcmp(seat->wlr_seat->name, seat_config->name) == 0) {
437 return seat_config;
438 }
439 }
440
441 return NULL;
442}
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index 7c5f7304..3427c8ec 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -88,11 +88,11 @@ static void ipc_json_describe_output(struct sway_container *container, json_obje
88 json_object_new_string( 88 json_object_new_string(
89 ipc_json_get_output_transform(wlr_output->transform))); 89 ipc_json_get_output_transform(wlr_output->transform)));
90 90
91 struct sway_seat *seat = sway_input_manager_get_default_seat(input_manager); 91 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
92 const char *ws = NULL; 92 const char *ws = NULL;
93 if (seat) { 93 if (seat) {
94 struct sway_container *focus = 94 struct sway_container *focus =
95 sway_seat_get_focus_inactive(seat, container); 95 seat_get_focus_inactive(seat, container);
96 if (focus && focus->type != C_WORKSPACE) { 96 if (focus && focus->type != C_WORKSPACE) {
97 focus = container_parent(focus, C_WORKSPACE); 97 focus = container_parent(focus, C_WORKSPACE);
98 } 98 }
@@ -139,8 +139,8 @@ json_object *ipc_json_describe_container(struct sway_container *c) {
139 return NULL; 139 return NULL;
140 } 140 }
141 141
142 struct sway_seat *seat = sway_input_manager_get_default_seat(input_manager); 142 struct sway_seat *seat = input_manager_get_default_seat(input_manager);
143 bool focused = sway_seat_get_focus(seat) == c; 143 bool focused = seat_get_focus(seat) == c;
144 144
145 json_object *object = json_object_new_object(); 145 json_object *object = json_object_new_object();
146 146
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 869f1ed0..df5fb699 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -388,8 +388,8 @@ static void ipc_get_workspaces_callback(struct sway_container *workspace,
388 // override the default focused indicator because 388 // override the default focused indicator because
389 // it's set differently for the get_workspaces reply 389 // it's set differently for the get_workspaces reply
390 struct sway_seat *seat = 390 struct sway_seat *seat =
391 sway_input_manager_get_default_seat(input_manager); 391 input_manager_get_default_seat(input_manager);
392 struct sway_container *focused_ws = sway_seat_get_focus(seat); 392 struct sway_container *focused_ws = seat_get_focus(seat);
393 if (focused_ws != NULL && focused_ws->type != C_WORKSPACE) { 393 if (focused_ws != NULL && focused_ws->type != C_WORKSPACE) {
394 focused_ws = container_parent(focused_ws, C_WORKSPACE); 394 focused_ws = container_parent(focused_ws, C_WORKSPACE);
395 } 395 }
@@ -399,7 +399,7 @@ static void ipc_get_workspaces_callback(struct sway_container *workspace,
399 json_object_new_boolean(focused)); 399 json_object_new_boolean(focused));
400 json_object_array_add((json_object *)data, workspace_json); 400 json_object_array_add((json_object *)data, workspace_json);
401 401
402 focused_ws = sway_seat_get_focus_inactive(seat, workspace->parent); 402 focused_ws = seat_get_focus_inactive(seat, workspace->parent);
403 if (focused_ws->type != C_WORKSPACE) { 403 if (focused_ws->type != C_WORKSPACE) {
404 focused_ws = container_parent(focused_ws, C_WORKSPACE); 404 focused_ws = container_parent(focused_ws, C_WORKSPACE);
405 } 405 }
diff --git a/sway/meson.build b/sway/meson.build
index 0cc620ea..38945b4c 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -19,6 +19,7 @@ sway_sources = files(
19 'commands/input.c', 19 'commands/input.c',
20 'commands/layout.c', 20 'commands/layout.c',
21 'commands/mode.c', 21 'commands/mode.c',
22 'commands/move.c',
22 'commands/seat.c', 23 'commands/seat.c',
23 'commands/seat/attach.c', 24 'commands/seat/attach.c',
24 'commands/seat/fallback.c', 25 'commands/seat/fallback.c',
diff --git a/sway/server.c b/sway/server.c
index f5cc199c..54945312 100644
--- a/sway/server.c
+++ b/sway/server.c
@@ -109,7 +109,7 @@ bool server_init(struct sway_server *server) {
109 return false; 109 return false;
110 } 110 }
111 111
112 input_manager = sway_input_manager_create(server); 112 input_manager = input_manager_create(server);
113 return true; 113 return true;
114} 114}
115 115
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 746dbf1f..ea0b7d5c 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -33,6 +33,23 @@ static list_t *get_bfs_queue() {
33 return bfs_queue; 33 return bfs_queue;
34} 34}
35 35
36const char *container_type_to_str(enum sway_container_type type) {
37 switch (type) {
38 case C_ROOT:
39 return "C_ROOT";
40 case C_OUTPUT:
41 return "C_OUTPUT";
42 case C_WORKSPACE:
43 return "C_WORKSPACE";
44 case C_CONTAINER:
45 return "C_CONTAINER";
46 case C_VIEW:
47 return "C_VIEW";
48 default:
49 return "C_UNKNOWN";
50 }
51}
52
36static void notify_new_container(struct sway_container *container) { 53static void notify_new_container(struct sway_container *container) {
37 wl_signal_emit(&root_container.sway_root->events.new_container, container); 54 wl_signal_emit(&root_container.sway_root->events.new_container, container);
38 ipc_event_window(container, "new"); 55 ipc_event_window(container, "new");
@@ -54,6 +71,7 @@ static struct sway_container *container_create(enum sway_container_type type) {
54 } 71 }
55 72
56 wl_signal_init(&c->events.destroy); 73 wl_signal_init(&c->events.destroy);
74 wl_signal_init(&c->events.reparent);
57 75
58 return c; 76 return c;
59} 77}
@@ -144,7 +162,7 @@ struct sway_container *container_output_create(
144 struct sway_seat *seat = NULL; 162 struct sway_seat *seat = NULL;
145 wl_list_for_each(seat, &input_manager->seats, link) { 163 wl_list_for_each(seat, &input_manager->seats, link) {
146 if (!seat->has_focus) { 164 if (!seat->has_focus) {
147 sway_seat_set_focus(seat, ws); 165 seat_set_focus(seat, ws);
148 } 166 }
149 } 167 }
150 168
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 122ea494..3333f9f1 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -106,8 +106,10 @@ struct sway_container *container_reap_empty(struct sway_container *container) {
106 if (!sway_assert(container, "reaping null container")) { 106 if (!sway_assert(container, "reaping null container")) {
107 return NULL; 107 return NULL;
108 } 108 }
109 wlr_log(L_DEBUG, "reaping %p %s", container, container->name); 109 wlr_log(L_DEBUG, "Reaping %p %s '%s'", container,
110 while (container != &root_container && container->children->length == 0) { 110 container_type_to_str(container->type), container->name);
111 while (container->type != C_ROOT && container->type != C_OUTPUT
112 && container->children->length == 0) {
111 if (container->type == C_WORKSPACE) { 113 if (container->type == C_WORKSPACE) {
112 if (!workspace_is_visible(container)) { 114 if (!workspace_is_visible(container)) {
113 struct sway_container *parent = container->parent; 115 struct sway_container *parent = container->parent;
@@ -138,22 +140,46 @@ struct sway_container *container_remove_child(struct sway_container *child) {
138 return container_reap_empty(parent); 140 return container_reap_empty(parent);
139} 141}
140 142
141void container_move_to(struct sway_container* container, 143void container_move_to(struct sway_container *container,
142 struct sway_container* destination) { 144 struct sway_container *destination) {
143 if (container == destination 145 if (container == destination
144 || container_has_anscestor(container, destination)) { 146 || container_has_anscestor(container, destination)) {
145 return; 147 return;
146 } 148 }
147 struct sway_container *old_parent = container_remove_child(container); 149 struct sway_container *old_parent = container_remove_child(container);
148 container->width = container->height = 0; 150 container->width = container->height = 0;
149 struct sway_container *new_parent = 151 struct sway_container *new_parent;
150 container_add_sibling(destination, container); 152 if (destination->type == C_VIEW) {
153 new_parent = container_add_sibling(destination, container);
154 } else {
155 new_parent = destination;
156 container_add_child(destination, container);
157 }
158 wl_signal_emit(&container->events.reparent, old_parent);
159 if (container->type == C_WORKSPACE) {
160 struct sway_seat *seat = input_manager_get_default_seat(
161 input_manager);
162 if (old_parent->children->length == 0) {
163 char *ws_name = workspace_next_name(old_parent->name);
164 struct sway_container *ws =
165 container_workspace_create(old_parent, ws_name);
166 free(ws_name);
167 seat_set_focus(seat, ws);
168 }
169 container_sort_workspaces(new_parent);
170 seat_set_focus(seat, new_parent);
171 }
151 if (old_parent) { 172 if (old_parent) {
152 arrange_windows(old_parent, -1, -1); 173 arrange_windows(old_parent, -1, -1);
153 } 174 }
154 arrange_windows(new_parent, -1, -1); 175 arrange_windows(new_parent, -1, -1);
155} 176}
156 177
178void container_move(struct sway_container *container,
179 enum movement_direction dir, int move_amt) {
180 // TODO
181}
182
157enum sway_container_layout container_get_default_layout( 183enum sway_container_layout container_get_default_layout(
158 struct sway_container *output) { 184 struct sway_container *output) {
159 if (config->default_layout != L_NONE) { 185 if (config->default_layout != L_NONE) {
@@ -248,8 +274,8 @@ void arrange_windows(struct sway_container *container,
248 struct wlr_box *area = &output->sway_output->usable_area; 274 struct wlr_box *area = &output->sway_output->usable_area;
249 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", 275 wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d",
250 area->width, area->height, area->x, area->y); 276 area->width, area->height, area->x, area->y);
251 container->width = area->width; 277 container->width = width = area->width;
252 container->height = area->height; 278 container->height = height = area->height;
253 container->x = x = area->x; 279 container->x = x = area->x;
254 container->y = y = area->y; 280 container->y = y = area->y;
255 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", 281 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f",
@@ -406,7 +432,7 @@ static struct sway_container *get_swayc_in_output_direction(
406 return NULL; 432 return NULL;
407 } 433 }
408 434
409 struct sway_container *ws = sway_seat_get_focus_inactive(seat, output); 435 struct sway_container *ws = seat_get_focus_inactive(seat, output);
410 if (ws->type != C_WORKSPACE) { 436 if (ws->type != C_WORKSPACE) {
411 ws = container_parent(ws, C_WORKSPACE); 437 ws = container_parent(ws, C_WORKSPACE);
412 } 438 }
@@ -427,7 +453,7 @@ static struct sway_container *get_swayc_in_output_direction(
427 case MOVE_UP: 453 case MOVE_UP:
428 case MOVE_DOWN: { 454 case MOVE_DOWN: {
429 struct sway_container *focused = 455 struct sway_container *focused =
430 sway_seat_get_focus_inactive(seat, ws); 456 seat_get_focus_inactive(seat, ws);
431 if (focused && focused->parent) { 457 if (focused && focused->parent) {
432 struct sway_container *parent = focused->parent; 458 struct sway_container *parent = focused->parent;
433 if (parent->layout == L_VERT) { 459 if (parent->layout == L_VERT) {
@@ -511,7 +537,7 @@ static struct sway_container *get_swayc_in_direction_under(
511 struct sway_container *container, enum movement_direction dir, 537 struct sway_container *container, enum movement_direction dir,
512 struct sway_seat *seat, struct sway_container *limit) { 538 struct sway_seat *seat, struct sway_container *limit) {
513 if (dir == MOVE_CHILD) { 539 if (dir == MOVE_CHILD) {
514 return sway_seat_get_focus_inactive(seat, container); 540 return seat_get_focus_inactive(seat, container);
515 } 541 }
516 542
517 struct sway_container *parent = container->parent; 543 struct sway_container *parent = container->parent;
@@ -523,26 +549,6 @@ static struct sway_container *get_swayc_in_direction_under(
523 } 549 }
524 } 550 }
525 551
526 if (dir == MOVE_PREV || dir == MOVE_NEXT) {
527 int focused_idx = index_child(container);
528 if (focused_idx == -1) {
529 return NULL;
530 } else {
531 int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) %
532 parent->children->length;
533 if (desired < 0) {
534 desired += parent->children->length;
535 }
536 return parent->children->items[desired];
537 }
538 }
539
540 // If moving to an adjacent output we need a starting position (since this
541 // output might border to multiple outputs).
542 //struct wlc_point abs_pos;
543 //get_layout_center_position(container, &abs_pos);
544
545
546 // TODO WLR fullscreen 552 // TODO WLR fullscreen
547 /* 553 /*
548 if (container->type == C_VIEW && swayc_is_fullscreen(container)) { 554 if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
@@ -591,7 +597,7 @@ static struct sway_container *get_swayc_in_direction_under(
591 } 597 }
592 if (next->children && next->children->length) { 598 if (next->children && next->children->length) {
593 // TODO consider floating children as well 599 // TODO consider floating children as well
594 return sway_seat_get_focus_inactive(seat, next); 600 return seat_get_focus_inactive(seat, next);
595 } else { 601 } else {
596 return next; 602 return next;
597 } 603 }
diff --git a/sway/tree/output.c b/sway/tree/output.c
index 80a36ac7..0509db23 100644
--- a/sway/tree/output.c
+++ b/sway/tree/output.c
@@ -1,3 +1,4 @@
1#include <strings.h>
1#include "sway/tree/container.h" 2#include "sway/tree/container.h"
2#include "sway/tree/layout.h" 3#include "sway/tree/layout.h"
3#include "sway/output.h" 4#include "sway/output.h"
@@ -38,3 +39,13 @@ struct sway_container *container_output_destroy(struct sway_container *output) {
38 container_destroy(output); 39 container_destroy(output);
39 return &root_container; 40 return &root_container;
40} 41}
42
43struct sway_container *output_by_name(const char *name) {
44 for (int i = 0; i < root_container.children->length; ++i) {
45 struct sway_container *output = root_container.children->items[i];
46 if (strcasecmp(output->name, name) == 0){
47 return output;
48 }
49 }
50 return NULL;
51}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 8f044621..09c804e4 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -139,7 +139,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
139 } 139 }
140 140
141 struct sway_seat *seat = input_manager_current_seat(input_manager); 141 struct sway_seat *seat = input_manager_current_seat(input_manager);
142 struct sway_container *focus = sway_seat_get_focus_inactive(seat, 142 struct sway_container *focus = seat_get_focus_inactive(seat,
143 &root_container); 143 &root_container);
144 struct sway_container *cont = container_view_create(focus, view); 144 struct sway_container *cont = container_view_create(focus, view);
145 145
@@ -147,7 +147,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
147 view->swayc = cont; 147 view->swayc = cont;
148 148
149 arrange_windows(cont->parent, -1, -1); 149 arrange_windows(cont->parent, -1, -1);
150 sway_input_manager_set_focus(input_manager, cont); 150 input_manager_set_focus(input_manager, cont);
151 151
152 view_damage_whole(view); 152 view_damage_whole(view);
153 view_update_outputs(view, NULL); 153 view_update_outputs(view, NULL);
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index c629f1f1..74330884 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -158,7 +158,7 @@ static bool _workspace_by_name(struct sway_container *view, void *data) {
158struct sway_container *workspace_by_name(const char *name) { 158struct sway_container *workspace_by_name(const char *name) {
159 struct sway_seat *seat = input_manager_current_seat(input_manager); 159 struct sway_seat *seat = input_manager_current_seat(input_manager);
160 struct sway_container *current_workspace = NULL, *current_output = NULL; 160 struct sway_container *current_workspace = NULL, *current_output = NULL;
161 struct sway_container *focus = sway_seat_get_focus(seat); 161 struct sway_container *focus = seat_get_focus(seat);
162 if (focus) { 162 if (focus) {
163 current_workspace = container_parent(focus, C_WORKSPACE); 163 current_workspace = container_parent(focus, C_WORKSPACE);
164 current_output = container_parent(focus, C_OUTPUT); 164 current_output = container_parent(focus, C_OUTPUT);
@@ -200,7 +200,7 @@ struct sway_container *workspace_create(const char *name) {
200 // Otherwise create a new one 200 // Otherwise create a new one
201 struct sway_seat *seat = input_manager_current_seat(input_manager); 201 struct sway_seat *seat = input_manager_current_seat(input_manager);
202 struct sway_container *focus = 202 struct sway_container *focus =
203 sway_seat_get_focus_inactive(seat, &root_container); 203 seat_get_focus_inactive(seat, &root_container);
204 parent = focus; 204 parent = focus;
205 parent = container_parent(parent, C_OUTPUT); 205 parent = container_parent(parent, C_OUTPUT);
206 struct sway_container *new_ws = container_workspace_create(parent, name); 206 struct sway_container *new_ws = container_workspace_create(parent, name);
@@ -260,7 +260,7 @@ struct sway_container *workspace_output_prev_next_impl(
260 } 260 }
261 261
262 struct sway_seat *seat = input_manager_current_seat(input_manager); 262 struct sway_seat *seat = input_manager_current_seat(input_manager);
263 struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); 263 struct sway_container *focus = seat_get_focus_inactive(seat, output);
264 struct sway_container *workspace = (focus->type == C_WORKSPACE ? 264 struct sway_container *workspace = (focus->type == C_WORKSPACE ?
265 focus : 265 focus :
266 container_parent(focus, C_WORKSPACE)); 266 container_parent(focus, C_WORKSPACE));
@@ -345,13 +345,13 @@ bool workspace_switch(struct sway_container *workspace) {
345 } 345 }
346 struct sway_seat *seat = input_manager_current_seat(input_manager); 346 struct sway_seat *seat = input_manager_current_seat(input_manager);
347 struct sway_container *focus = 347 struct sway_container *focus =
348 sway_seat_get_focus_inactive(seat, &root_container); 348 seat_get_focus_inactive(seat, &root_container);
349 if (!seat || !focus) { 349 if (!seat || !focus) {
350 return false; 350 return false;
351 } 351 }
352 struct sway_container *active_ws = focus; 352 struct sway_container *active_ws = focus;
353 if (active_ws->type != C_WORKSPACE) { 353 if (active_ws->type != C_WORKSPACE) {
354 container_parent(focus, C_WORKSPACE); 354 active_ws = container_parent(focus, C_WORKSPACE);
355 } 355 }
356 356
357 if (config->auto_back_and_forth 357 if (config->auto_back_and_forth
@@ -376,11 +376,11 @@ bool workspace_switch(struct sway_container *workspace) {
376 376
377 wlr_log(L_DEBUG, "Switching to workspace %p:%s", 377 wlr_log(L_DEBUG, "Switching to workspace %p:%s",
378 workspace, workspace->name); 378 workspace, workspace->name);
379 struct sway_container *next = sway_seat_get_focus_inactive(seat, workspace); 379 struct sway_container *next = seat_get_focus_inactive(seat, workspace);
380 if (next == NULL) { 380 if (next == NULL) {
381 next = workspace; 381 next = workspace;
382 } 382 }
383 sway_seat_set_focus(seat, next); 383 seat_set_focus(seat, next);
384 struct sway_container *output = container_parent(workspace, C_OUTPUT); 384 struct sway_container *output = container_parent(workspace, C_OUTPUT);
385 arrange_windows(output, -1, -1); 385 arrange_windows(output, -1, -1);
386 return true; 386 return true;
@@ -389,7 +389,7 @@ bool workspace_switch(struct sway_container *workspace) {
389bool workspace_is_visible(struct sway_container *ws) { 389bool workspace_is_visible(struct sway_container *ws) {
390 struct sway_container *output = container_parent(ws, C_OUTPUT); 390 struct sway_container *output = container_parent(ws, C_OUTPUT);
391 struct sway_seat *seat = input_manager_current_seat(input_manager); 391 struct sway_seat *seat = input_manager_current_seat(input_manager);
392 struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); 392 struct sway_container *focus = seat_get_focus_inactive(seat, output);
393 if (focus->type != C_WORKSPACE) { 393 if (focus->type != C_WORKSPACE) {
394 focus = container_parent(focus, C_WORKSPACE); 394 focus = container_parent(focus, C_WORKSPACE);
395 } 395 }