diff options
author | emersion <contact@emersion.fr> | 2018-04-02 15:30:58 -0400 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-04-02 15:30:58 -0400 |
commit | a4a241697ae591289d7c14eff972e1ef787216e2 (patch) | |
tree | d82d3c3eba2946670aa634a62d03feb7102f0bf8 /sway | |
parent | Xwayland unmanaged views aren't views anymore (diff) | |
parent | Merge pull request #1699 from acrisci/seat-fixes (diff) | |
download | sway-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.c | 21 | ||||
-rw-r--r-- | sway/commands/focus.c | 11 | ||||
-rw-r--r-- | sway/commands/move.c | 184 | ||||
-rw-r--r-- | sway/commands/seat.c | 11 | ||||
-rw-r--r-- | sway/commands/workspace.c | 2 | ||||
-rw-r--r-- | sway/config.c | 2 | ||||
-rw-r--r-- | sway/desktop/output.c | 13 | ||||
-rw-r--r-- | sway/input/cursor.c | 10 | ||||
-rw-r--r-- | sway/input/input-manager.c | 144 | ||||
-rw-r--r-- | sway/input/keyboard.c | 6 | ||||
-rw-r--r-- | sway/input/seat.c | 99 | ||||
-rw-r--r-- | sway/ipc-json.c | 8 | ||||
-rw-r--r-- | sway/ipc-server.c | 6 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/server.c | 2 | ||||
-rw-r--r-- | sway/tree/container.c | 20 | ||||
-rw-r--r-- | sway/tree/layout.c | 70 | ||||
-rw-r--r-- | sway/tree/output.c | 11 | ||||
-rw-r--r-- | sway/tree/view.c | 4 | ||||
-rw-r--r-- | sway/tree/workspace.c | 16 |
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 | ||
78 | void apply_seat_config(struct seat_config *seat) { | 78 | void 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 | |||
15 | static 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 | |||
21 | static 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 | |||
49 | static 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 | |||
117 | static 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 | |||
142 | struct 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; | |||
26 | struct sway_seat *input_manager_current_seat(struct sway_input_manager *input) { | 26 | struct 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 | ||
46 | static char *get_device_identifier(struct wlr_input_device *device) { | 46 | static char *get_device_identifier(struct wlr_input_device *device) { |
@@ -83,7 +83,8 @@ static struct sway_input_device *input_sway_device_from_wlr( | |||
83 | static bool input_has_seat_configuration(struct sway_input_manager *input) { | 83 | static 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 | ||
94 | static void sway_input_manager_libinput_config_pointer(struct sway_input_device *input_device) { | 95 | static 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 | ||
259 | struct sway_input_manager *sway_input_manager_create( | 266 | struct 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 | ||
280 | bool sway_input_manager_has_focus(struct sway_input_manager *input, | 287 | bool 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 | ||
292 | void sway_input_manager_set_focus(struct sway_input_manager *input, | 299 | void 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 | ||
300 | void sway_input_manager_apply_input_config(struct sway_input_manager *input, | 307 | void 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 | ||
320 | void sway_input_manager_apply_seat_config(struct sway_input_manager *input, | 324 | void 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 | ||
376 | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { | 382 | void 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 | ||
383 | struct sway_seat *sway_input_manager_get_default_seat( | 389 | struct 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 | |||
400 | struct 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 | ||
28 | void sway_seat_destroy(struct sway_seat *seat) { | 28 | void 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 | ||
113 | struct sway_seat *sway_seat_create(struct sway_input_manager *input, | 114 | struct 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 | ||
182 | static struct sway_seat_device *sway_seat_get_device(struct sway_seat *seat, | 185 | static 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 | ||
194 | void sway_seat_configure_device(struct sway_seat *seat, | 197 | void 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 | ||
222 | void sway_seat_add_device(struct sway_seat *seat, | 220 | void 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 | ||
246 | void sway_seat_remove_device(struct sway_seat *seat, | 244 | void 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 | ||
261 | void sway_seat_configure_xcursor(struct sway_seat *seat) { | 259 | void 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 | ||
295 | void sway_seat_set_focus_warp(struct sway_seat *seat, | 294 | void 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 | ||
375 | void sway_seat_set_focus(struct sway_seat *seat, | 374 | void 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 | ||
380 | struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container) { | 379 | struct 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 | ||
401 | struct sway_container *sway_seat_get_focus(struct sway_seat *seat) { | 401 | struct 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 | ||
408 | struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat, | 408 | struct 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 | ||
418 | void sway_seat_set_config(struct sway_seat *seat, | 419 | void 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 | |||
432 | struct 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 | ||
36 | const 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 | |||
36 | static void notify_new_container(struct sway_container *container) { | 53 | static 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 | ||
141 | void container_move_to(struct sway_container* container, | 143 | void 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 | ||
178 | void container_move(struct sway_container *container, | ||
179 | enum movement_direction dir, int move_amt) { | ||
180 | // TODO | ||
181 | } | ||
182 | |||
157 | enum sway_container_layout container_get_default_layout( | 183 | enum 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 | |||
43 | struct 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) { | |||
158 | struct sway_container *workspace_by_name(const char *name) { | 158 | struct 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) { | |||
389 | bool workspace_is_visible(struct sway_container *ws) { | 389 | bool 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 | } |