aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-08-09 20:10:26 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-08-09 20:10:26 -0400
commit9f091c7f82a73144b4eb4ca4f5f800c811fbab46 (patch)
tree76726b112e18cc537e080568c7e5df30520a3ed9 /sway
parentDestroy containers when all views are removed (diff)
downloadsway-9f091c7f82a73144b4eb4ca4f5f800c811fbab46.tar.gz
sway-9f091c7f82a73144b4eb4ca4f5f800c811fbab46.tar.zst
sway-9f091c7f82a73144b4eb4ca4f5f800c811fbab46.zip
Add movement support
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c19
-rw-r--r--sway/layout.c18
-rw-r--r--sway/layout.h1
-rw-r--r--sway/list.c1
-rw-r--r--sway/movement.c58
-rw-r--r--sway/movement.h16
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
101int 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
100int cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) { 118int 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
240void focus_view(swayc_t *view) { 242void 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);
49void destroy_output(wlc_handle output); 49void destroy_output(wlc_handle output);
50void destroy_view(swayc_t *view); 50void destroy_view(swayc_t *view);
51void add_view(wlc_handle view); 51void add_view(wlc_handle view);
52void unfocus_all(swayc_t *container);
52void focus_view(swayc_t *view); 53void focus_view(swayc_t *view);
53void arrange_windows(swayc_t *container, int width, int height); 54void arrange_windows(swayc_t *container, int width, int height);
54swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data); 55swayc_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
30void list_insert(list_t *list, int index, void *item) { 30void 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
8void 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
7enum movement_direction{
8 MOVE_LEFT,
9 MOVE_RIGHT,
10 MOVE_UP,
11 MOVE_DOWN
12};
13
14void move_focus(enum movement_direction direction);
15
16#endif