diff options
author | Drew DeVault <sir@cmpwn.com> | 2015-08-09 20:10:26 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2015-08-09 20:10:26 -0400 |
commit | 9f091c7f82a73144b4eb4ca4f5f800c811fbab46 (patch) | |
tree | 76726b112e18cc537e080568c7e5df30520a3ed9 | |
parent | Destroy containers when all views are removed (diff) | |
download | sway-9f091c7f82a73144b4eb4ca4f5f800c811fbab46.tar.gz sway-9f091c7f82a73144b4eb4ca4f5f800c811fbab46.tar.zst sway-9f091c7f82a73144b4eb4ca4f5f800c811fbab46.zip |
Add movement support
-rw-r--r-- | sway/commands.c | 19 | ||||
-rw-r--r-- | sway/layout.c | 18 | ||||
-rw-r--r-- | sway/layout.h | 1 | ||||
-rw-r--r-- | sway/list.c | 1 | ||||
-rw-r--r-- | sway/movement.c | 58 | ||||
-rw-r--r-- | sway/movement.h | 16 |
6 files changed, 108 insertions, 5 deletions
diff --git a/sway/commands.c b/sway/commands.c index 322c9519..12d38244 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <ctype.h> | 8 | #include <ctype.h> |
9 | #include "stringop.h" | 9 | #include "stringop.h" |
10 | #include "layout.h" | 10 | #include "layout.h" |
11 | #include "movement.h" | ||
11 | #include "log.h" | 12 | #include "log.h" |
12 | #include "commands.h" | 13 | #include "commands.h" |
13 | 14 | ||
@@ -97,6 +98,23 @@ int cmd_exit(struct sway_config *config, int argc, char **argv) { | |||
97 | return 0; | 98 | return 0; |
98 | } | 99 | } |
99 | 100 | ||
101 | int cmd_focus(struct sway_config *config, int argc, char **argv) { | ||
102 | if (argc != 1) { | ||
103 | sway_log(L_ERROR, "Invalid focus command (expected 1 arguments, got %d)", argc); | ||
104 | return 1; | ||
105 | } | ||
106 | if (strcasecmp(argv[0], "left") == 0) { | ||
107 | move_focus(MOVE_LEFT); | ||
108 | } else if (strcasecmp(argv[0], "right") == 0) { | ||
109 | move_focus(MOVE_RIGHT); | ||
110 | } else if (strcasecmp(argv[0], "up") == 0) { | ||
111 | move_focus(MOVE_UP); | ||
112 | } else if (strcasecmp(argv[0], "down") == 0) { | ||
113 | move_focus(MOVE_DOWN); | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | |||
100 | int cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) { | 118 | int cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) { |
101 | if (argc != 1) { | 119 | if (argc != 1) { |
102 | sway_log(L_ERROR, "Invalid focus_follows_mouse command (expected 1 arguments, got %d)", argc); | 120 | sway_log(L_ERROR, "Invalid focus_follows_mouse command (expected 1 arguments, got %d)", argc); |
@@ -184,6 +202,7 @@ struct cmd_handler handlers[] = { | |||
184 | { "bindsym", cmd_bindsym }, | 202 | { "bindsym", cmd_bindsym }, |
185 | { "exec", cmd_exec }, | 203 | { "exec", cmd_exec }, |
186 | { "exit", cmd_exit }, | 204 | { "exit", cmd_exit }, |
205 | { "focus", cmd_focus }, | ||
187 | { "focus_follows_mouse", cmd_focus_follows_mouse }, | 206 | { "focus_follows_mouse", cmd_focus_follows_mouse }, |
188 | { "layout", cmd_layout }, | 207 | { "layout", cmd_layout }, |
189 | { "set", cmd_set }, | 208 | { "set", cmd_set }, |
diff --git a/sway/layout.c b/sway/layout.c index 6bb19d63..b320e8ad 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -163,6 +163,7 @@ void add_view(wlc_handle view_handle) { | |||
163 | view->type = C_VIEW; | 163 | view->type = C_VIEW; |
164 | add_child(parent, view); | 164 | add_child(parent, view); |
165 | 165 | ||
166 | unfocus_all(&root_container); | ||
166 | focus_view(view); | 167 | focus_view(view); |
167 | 168 | ||
168 | arrange_windows(parent, -1, -1); | 169 | arrange_windows(parent, -1, -1); |
@@ -209,6 +210,7 @@ void destroy_view(swayc_t *view) { | |||
209 | parent->focused = NULL; | 210 | parent->focused = NULL; |
210 | } | 211 | } |
211 | 212 | ||
213 | unfocus_all(&root_container); | ||
212 | if (parent->children->length != 0) { | 214 | if (parent->children->length != 0) { |
213 | focus_view(parent->children->items[0]); | 215 | focus_view(parent->children->items[0]); |
214 | } else { | 216 | } else { |
@@ -238,12 +240,17 @@ void unfocus_all(swayc_t *container) { | |||
238 | } | 240 | } |
239 | 241 | ||
240 | void focus_view(swayc_t *view) { | 242 | void focus_view(swayc_t *view) { |
241 | if (view->type == C_VIEW) { | 243 | sway_log(L_DEBUG, "Setting focus for %p", view); |
242 | unfocus_all(&root_container); | ||
243 | wlc_view_set_state(view->handle, WLC_BIT_ACTIVATED, true); | ||
244 | wlc_view_focus(view->handle); | ||
245 | } | ||
246 | if (view == &root_container) { | 244 | if (view == &root_container) { |
245 | // Propegate wayland focus down | ||
246 | swayc_t *child = view->focused; | ||
247 | while (child && child->type != C_VIEW) { | ||
248 | child = child->focused; | ||
249 | } | ||
250 | if (child) { | ||
251 | wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, true); | ||
252 | wlc_view_focus(child->handle); | ||
253 | } | ||
247 | return; | 254 | return; |
248 | } | 255 | } |
249 | view->parent->focused = view; | 256 | view->parent->focused = view; |
@@ -285,6 +292,7 @@ void add_output(wlc_handle output) { | |||
285 | add_child(container, workspace); | 292 | add_child(container, workspace); |
286 | 293 | ||
287 | if (root_container.focused == NULL) { | 294 | if (root_container.focused == NULL) { |
295 | unfocus_all(&root_container); | ||
288 | focus_view(workspace); | 296 | focus_view(workspace); |
289 | } | 297 | } |
290 | } | 298 | } |
diff --git a/sway/layout.h b/sway/layout.h index 08f3f78b..b0aec42f 100644 --- a/sway/layout.h +++ b/sway/layout.h | |||
@@ -49,6 +49,7 @@ void add_output(wlc_handle output); | |||
49 | void destroy_output(wlc_handle output); | 49 | void destroy_output(wlc_handle output); |
50 | void destroy_view(swayc_t *view); | 50 | void destroy_view(swayc_t *view); |
51 | void add_view(wlc_handle view); | 51 | void add_view(wlc_handle view); |
52 | void unfocus_all(swayc_t *container); | ||
52 | void focus_view(swayc_t *view); | 53 | void focus_view(swayc_t *view); |
53 | void arrange_windows(swayc_t *container, int width, int height); | 54 | void arrange_windows(swayc_t *container, int width, int height); |
54 | swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data); | 55 | swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data); |
diff --git a/sway/list.c b/sway/list.c index 55052f85..52943efe 100644 --- a/sway/list.c +++ b/sway/list.c | |||
@@ -28,6 +28,7 @@ void list_add(list_t *list, void *item) { | |||
28 | } | 28 | } |
29 | 29 | ||
30 | void list_insert(list_t *list, int index, void *item) { | 30 | void list_insert(list_t *list, int index, void *item) { |
31 | // TODO: Implement this properly | ||
31 | if (list->length == list->capacity) { | 32 | if (list->length == list->capacity) { |
32 | list->capacity += 10; | 33 | list->capacity += 10; |
33 | list->items = realloc(list->items, sizeof(void*) * list->capacity); | 34 | list->items = realloc(list->items, sizeof(void*) * list->capacity); |
diff --git a/sway/movement.c b/sway/movement.c new file mode 100644 index 00000000..197df7b2 --- /dev/null +++ b/sway/movement.c | |||
@@ -0,0 +1,58 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <stdbool.h> | ||
3 | #include "list.h" | ||
4 | #include "log.h" | ||
5 | #include "layout.h" | ||
6 | #include "movement.h" | ||
7 | |||
8 | void move_focus(enum movement_direction direction) { | ||
9 | swayc_t *current = get_focused_container(&root_container); | ||
10 | swayc_t *parent = current->parent; | ||
11 | |||
12 | while (true) { | ||
13 | sway_log(L_DEBUG, "Moving focus away from %p", current); | ||
14 | |||
15 | // Test if we can even make a difference here | ||
16 | bool can_move = false; | ||
17 | int diff = 0; | ||
18 | if (direction == MOVE_LEFT || direction == MOVE_RIGHT) { | ||
19 | if (parent->layout == L_HORIZ) { | ||
20 | can_move = true; | ||
21 | diff = direction == MOVE_LEFT ? -1 : 1; | ||
22 | } | ||
23 | } else { | ||
24 | if (parent->layout == L_VERT) { | ||
25 | can_move = true; | ||
26 | diff = direction == MOVE_UP ? -1 : 1; | ||
27 | } | ||
28 | } | ||
29 | sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no"); | ||
30 | if (can_move) { | ||
31 | int i; | ||
32 | for (i = 0; i < parent->children->length; ++i) { | ||
33 | swayc_t *child = parent->children->items[i]; | ||
34 | if (child == current) { | ||
35 | break; | ||
36 | } | ||
37 | } | ||
38 | int desired = i + diff; | ||
39 | sway_log(L_DEBUG, "Moving from %d to %d", i, desired); | ||
40 | if (desired < 0 || desired >= parent->children->length) { | ||
41 | can_move = false; | ||
42 | } else { | ||
43 | unfocus_all(&root_container); | ||
44 | focus_view(parent->children->items[desired]); | ||
45 | return; | ||
46 | } | ||
47 | } | ||
48 | if (!can_move) { | ||
49 | sway_log(L_DEBUG, "Can't move at current level, moving up tree"); | ||
50 | current = parent; | ||
51 | parent = parent->parent; | ||
52 | if (parent->type == C_ROOT) { | ||
53 | // Nothing we can do | ||
54 | return; | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | } | ||
diff --git a/sway/movement.h b/sway/movement.h new file mode 100644 index 00000000..c88b44bd --- /dev/null +++ b/sway/movement.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _SWAY_MOVEMENT_H | ||
2 | #define _SWAY_MOVEMENT_H | ||
3 | |||
4 | #include <wlc/wlc.h> | ||
5 | #include "list.h" | ||
6 | |||
7 | enum movement_direction{ | ||
8 | MOVE_LEFT, | ||
9 | MOVE_RIGHT, | ||
10 | MOVE_UP, | ||
11 | MOVE_DOWN | ||
12 | }; | ||
13 | |||
14 | void move_focus(enum movement_direction direction); | ||
15 | |||
16 | #endif | ||