aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar taiyu <taiyu.len@gmail.com>2015-08-23 12:34:18 -0700
committerLibravatar taiyu <taiyu.len@gmail.com>2015-08-23 12:34:18 -0700
commit51ab3c918030565cefbb82dc8e899f324e6c5a21 (patch)
tree1a9e633ead0ff50f55987310621dab39531d2305 /sway
parentstyle (diff)
parentRefactor keyboard to consider modified keysyms (diff)
downloadsway-51ab3c918030565cefbb82dc8e899f324e6c5a21.tar.gz
sway-51ab3c918030565cefbb82dc8e899f324e6c5a21.tar.zst
sway-51ab3c918030565cefbb82dc8e899f324e6c5a21.zip
merge
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c5
-rw-r--r--sway/container.c41
-rw-r--r--sway/focus.c1
-rw-r--r--sway/handlers.c23
-rw-r--r--sway/input_state.c54
-rw-r--r--sway/layout.c81
-rw-r--r--sway/log.c8
-rw-r--r--sway/main.c12
8 files changed, 168 insertions, 57 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 5de1fb0c..7ee8c558 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -372,8 +372,13 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) {
372 struct output_config *output = calloc(1, sizeof(struct output_config)); 372 struct output_config *output = calloc(1, sizeof(struct output_config));
373 output->x = output->y = output->width = output->height = -1; 373 output->x = output->y = output->width = output->height = -1;
374 output->name = strdup(argv[0]); 374 output->name = strdup(argv[0]);
375 output->enabled = true;
375 376
376 // TODO: atoi doesn't handle invalid numbers 377 // TODO: atoi doesn't handle invalid numbers
378
379 if (strcasecmp(argv[1], "disable") == 0) {
380 output->enabled = false;
381 }
377 382
378 int i; 383 int i;
379 for (i = 1; i < argc; ++i) { 384 for (i = 1; i < argc; ++i) {
diff --git a/sway/container.c b/sway/container.c
index 5d544934..d4f7c693 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -59,7 +59,7 @@ swayc_t *new_output(wlc_handle handle) {
59 const char *name = wlc_output_get_name(handle); 59 const char *name = wlc_output_get_name(handle);
60 sway_log(L_DEBUG, "Added output %lu:%s", handle, name); 60 sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
61 61
62 struct output_config *oc ; 62 struct output_config *oc = NULL;
63 int i; 63 int i;
64 for (i = 0; i < config->output_configs->length; ++i) { 64 for (i = 0; i < config->output_configs->length; ++i) {
65 oc = config->output_configs->items[i]; 65 oc = config->output_configs->items[i];
@@ -70,6 +70,10 @@ swayc_t *new_output(wlc_handle handle) {
70 oc = NULL; 70 oc = NULL;
71 } 71 }
72 72
73 if (oc && !oc->enabled) {
74 return NULL;
75 }
76
73 swayc_t *output = new_swayc(C_OUTPUT); 77 swayc_t *output = new_swayc(C_OUTPUT);
74 if (oc && oc->width != -1 && oc->height != -1) { 78 if (oc && oc->width != -1 && oc->height != -1) {
75 output->width = oc->width; 79 output->width = oc->width;
@@ -83,6 +87,24 @@ swayc_t *new_output(wlc_handle handle) {
83 output->handle = handle; 87 output->handle = handle;
84 output->name = name ? strdup(name) : NULL; 88 output->name = name ? strdup(name) : NULL;
85 output->gaps = config->gaps_outer + config->gaps_inner / 2; 89 output->gaps = config->gaps_outer + config->gaps_inner / 2;
90
91 // Find position for it
92 if (oc && oc->x != -1 && oc->y != -1) {
93 sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y);
94 output->x = oc->x;
95 output->y = oc->y;
96 } else {
97 int x = 0;
98 for (i = 0; i < root_container.children->length; ++i) {
99 swayc_t *c = root_container.children->items[i];
100 if (c->type == C_OUTPUT) {
101 if (c->width + c->x > x) {
102 x = c->width + c->x;
103 }
104 }
105 }
106 output->x = x;
107 }
86 108
87 add_child(&root_container, output); 109 add_child(&root_container, output);
88 110
@@ -281,7 +303,8 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
281 return NULL; 303 return NULL;
282 } 304 }
283 305
284 if (workspace->children->length == 0) { 306 // Do not destroy if there are children
307 if (workspace->children->length == 0 && workspace->floating->length == 0) {
285 sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name); 308 sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name);
286 swayc_t *parent = workspace->parent; 309 swayc_t *parent = workspace->parent;
287 free_swayc(workspace); 310 free_swayc(workspace);
@@ -448,14 +471,16 @@ bool swayc_is_fullscreen(swayc_t *view) {
448// Mapping 471// Mapping
449 472
450void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 473void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
451 if (container && container->children && container->children->length) { 474 if (container) {
452 int i; 475 int i;
453 for (i = 0; i < container->children->length; ++i) { 476 if (container->children) {
454 swayc_t *child = container->children->items[i]; 477 for (i = 0; i < container->children->length; ++i) {
455 f(child, data); 478 swayc_t *child = container->children->items[i];
456 container_map(child, f, data); 479 f(child, data);
480 container_map(child, f, data);
481 }
457 } 482 }
458 if (container->type == C_WORKSPACE) { 483 if (container->floating) {
459 for (i = 0; i < container->floating->length; ++i) { 484 for (i = 0; i < container->floating->length; ++i) {
460 swayc_t *child = container->floating->items[i]; 485 swayc_t *child = container->floating->items[i];
461 f(child, data); 486 f(child, data);
diff --git a/sway/focus.c b/sway/focus.c
index a3e5e77a..e369de30 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -34,7 +34,6 @@ static void update_focus(swayc_t *c) {
34 mask = 2; 34 mask = 2;
35 container_map(c, set_view_visibility, &mask); 35 container_map(c, set_view_visibility, &mask);
36 wlc_output_set_mask(parent->handle, 2); 36 wlc_output_set_mask(parent->handle, 2);
37 c->parent->focused = c;
38 destroy_workspace(ws); 37 destroy_workspace(ws);
39 } 38 }
40 break; 39 break;
diff --git a/sway/handlers.c b/sway/handlers.c
index 0bb4f613..27f6d294 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -90,6 +90,10 @@ swayc_t *container_under_pointer(void) {
90static bool handle_output_created(wlc_handle output) { 90static bool handle_output_created(wlc_handle output) {
91 swayc_t *op = new_output(output); 91 swayc_t *op = new_output(output);
92 92
93 if (!op) {
94 return false;
95 }
96
93 // Switch to workspace if we need to 97 // Switch to workspace if we need to
94 if (swayc_active_workspace() == NULL) { 98 if (swayc_active_workspace() == NULL) {
95 swayc_t *ws = op->children->items[0]; 99 swayc_t *ws = op->children->items[0];
@@ -108,6 +112,8 @@ static void handle_output_destroyed(wlc_handle output) {
108 } 112 }
109 if (i < list->length) { 113 if (i < list->length) {
110 destroy_output(list->items[i]); 114 destroy_output(list->items[i]);
115 } else {
116 return;
111 } 117 }
112 if (list->length > 0) { 118 if (list->length > 0) {
113 // switch to other outputs active workspace 119 // switch to other outputs active workspace
@@ -292,22 +298,12 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
292 298
293 struct sway_mode *mode = config->current_mode; 299 struct sway_mode *mode = config->current_mode;
294 300
295 if (sym < 70000 /* bullshit made up number */) {
296 if (!isalnum(sym) && sym != ' ' && sym != XKB_KEY_Escape && sym != XKB_KEY_Tab) {
297 // God fucking dammit
298 return EVENT_PASSTHROUGH;
299 }
300 }
301
302 // Lowercase if necessary
303 sym = tolower(sym);
304
305 int i; 301 int i;
306 302
307 if (state == WLC_KEY_STATE_PRESSED) { 303 if (state == WLC_KEY_STATE_PRESSED) {
308 press_key(sym); 304 press_key(sym, key);
309 } else { // WLC_KEY_STATE_RELEASED 305 } else { // WLC_KEY_STATE_RELEASED
310 release_key(sym); 306 release_key(sym, key);
311 } 307 }
312 308
313 // TODO: reminder to check conflicts with mod+q+a versus mod+q 309 // TODO: reminder to check conflicts with mod+q+a versus mod+q
@@ -319,7 +315,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
319 int j; 315 int j;
320 for (j = 0; j < binding->keys->length; ++j) { 316 for (j = 0; j < binding->keys->length; ++j) {
321 xkb_keysym_t *key = binding->keys->items[j]; 317 xkb_keysym_t *key = binding->keys->items[j];
322 if ((match = check_key(*key)) == false) { 318 if ((match = check_key(*key, 0)) == false) {
323 break; 319 break;
324 } 320 }
325 } 321 }
@@ -467,7 +463,6 @@ static void handle_wlc_ready(void) {
467 config->active = true; 463 config->active = true;
468} 464}
469 465
470
471struct wlc_interface interface = { 466struct wlc_interface interface = {
472 .output = { 467 .output = {
473 .created = handle_output_created, 468 .created = handle_output_created,
diff --git a/sway/input_state.c b/sway/input_state.c
index acf90d75..e911d9cf 100644
--- a/sway/input_state.c
+++ b/sway/input_state.c
@@ -1,50 +1,76 @@
1#include <string.h> 1#include <string.h>
2#include <stdbool.h> 2#include <stdbool.h>
3#include <ctype.h> 3#include <ctype.h>
4#include "log.h"
4 5
5#include "input_state.h" 6#include "input_state.h"
6 7
7#define KEY_STATE_MAX_LENGTH 64 8#define KEY_STATE_MAX_LENGTH 64
8 9
9static keycode key_state_array[KEY_STATE_MAX_LENGTH]; 10struct key_state {
11 /*
12 * Aims to store state regardless of modifiers.
13 * If you press a key, then hold shift, then release the key, we'll
14 * get two different key syms, but the same key code. This handles
15 * that scenario and makes sure we can use the right bindings.
16 */
17 uint32_t key_sym;
18 uint32_t alt_sym;
19 uint32_t key_code;
20};
21
22static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
10 23
11void input_init(void) { 24void input_init(void) {
12 int i; 25 int i;
13 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) { 26 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
14 key_state_array[i] = 0; 27 struct key_state none = { 0, 0, 0 };
28 key_state_array[i] = none;
15 } 29 }
16} 30}
17 31
18static uint8_t find_key(keycode key) { 32static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {
19 int i; 33 int i;
20 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) { 34 for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
21 if (key_state_array[i] == key) { 35 if (0 == key_sym && 0 == key_code && key_state_array[i].key_sym == 0) {
36 break;
37 }
38 if (key_state_array[i].key_sym == key_sym
39 || key_state_array[i].alt_sym == key_sym) {
40 break;
41 }
42 if (update && key_state_array[i].key_code == key_code) {
43 key_state_array[i].alt_sym = key_sym;
22 break; 44 break;
23 } 45 }
24 } 46 }
25 return i; 47 return i;
26} 48}
27 49
28bool check_key(keycode key) { 50bool check_key(uint32_t key_sym, uint32_t key_code) {
29 return find_key(key) < KEY_STATE_MAX_LENGTH; 51 return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
30} 52}
31 53
32void press_key(keycode key) { 54void press_key(uint32_t key_sym, uint32_t key_code) {
55 if (key_code == 0) {
56 return;
57 }
33 // Check if key exists 58 // Check if key exists
34 if (!check_key(key)) { 59 if (!check_key(key_sym, key_code)) {
35 // Check that we dont exceed buffer length 60 // Check that we dont exceed buffer length
36 int insert = find_key(0); 61 int insert = find_key(0, 0, true);
37 if (insert < KEY_STATE_MAX_LENGTH) { 62 if (insert < KEY_STATE_MAX_LENGTH) {
38 key_state_array[insert] = key; 63 key_state_array[insert].key_sym = key_sym;
64 key_state_array[insert].key_code = key_code;
39 } 65 }
40 } 66 }
41} 67}
42 68
43void release_key(keycode key) { 69void release_key(uint32_t key_sym, uint32_t key_code) {
44 uint8_t index = find_key(key); 70 uint8_t index = find_key(key_sym, key_code, true);
45 if (index < KEY_STATE_MAX_LENGTH) { 71 if (index < KEY_STATE_MAX_LENGTH) {
46 // shift it over and remove key 72 struct key_state none = { 0, 0, 0 };
47 key_state_array[index] = 0; 73 key_state_array[index] = none;
48 } 74 }
49} 75}
50 76
diff --git a/sway/layout.c b/sway/layout.c
index 4d738433..bc12b9b1 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -242,21 +242,14 @@ void arrange_windows(swayc_t *container, double width, double height) {
242 for (i = 0; i < container->children->length; ++i) { 242 for (i = 0; i < container->children->length; ++i) {
243 swayc_t *child = container->children->items[i]; 243 swayc_t *child = container->children->items[i];
244 sway_log(L_DEBUG, "Arranging output at %d", x); 244 sway_log(L_DEBUG, "Arranging output at %d", x);
245 child->x = x;
246 child->y = y;
247 arrange_windows(child, -1, -1); 245 arrange_windows(child, -1, -1);
248 // Removed for now because wlc works with relative positions 246 x += child->width;
249 // Addition can be reconsidered once wlc positions are changed
250 // x += child->width;
251 } 247 }
252 return; 248 return;
253 case C_OUTPUT: 249 case C_OUTPUT:
254 container->width = width; 250 container->width = width;
255 container->height = height; 251 container->height = height;
256 // These lines make x/y negative and result in stuff glitching out 252 x = 0, y = 0;
257 // Their addition can be reconsidered once wlc positions are changed
258 // x -= container->x;
259 // y -= container->y;
260 for (i = 0; i < container->children->length; ++i) { 253 for (i = 0; i < container->children->length; ++i) {
261 swayc_t *child = container->children->items[i]; 254 swayc_t *child = container->children->items[i];
262 child->x = x + container->gaps; 255 child->x = x + container->gaps;
@@ -375,19 +368,75 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
375 // Test if we can even make a difference here 368 // Test if we can even make a difference here
376 bool can_move = false; 369 bool can_move = false;
377 int diff = 0; 370 int diff = 0;
378 if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { 371 int i;
379 if (parent->layout == L_HORIZ || parent->type == C_ROOT) { 372 if (parent->type == C_ROOT) {
373 // Find the next output
374 int target = -1, max_x = 0, max_y = 0, self = -1;
375 sway_log(L_DEBUG, "Moving between outputs");
376
377 for (i = 0; i < parent->children->length; ++i) {
378 swayc_t *next = parent->children->items[i];
379 if (next == container) {
380 self = i;
381 sway_log(L_DEBUG, "self is %p %d", next, self);
382 continue;
383 }
384 if (next->type == C_OUTPUT) {
385 sway_log(L_DEBUG, "Testing with %p %d (dir %d)", next, i, dir);
386 // Check if it's more extreme
387 if (dir == MOVE_RIGHT) {
388 if (container->x + container->width <= next->x) {
389 if (target == -1 || next->x < max_x) {
390 target = i;
391 max_x = next->x;
392 }
393 }
394 } else if (dir == MOVE_LEFT) {
395 if (container->x >= next->x + next->width) {
396 if (target == -1 || max_x < next->x) {
397 target = i;
398 max_x = next->x;
399 }
400 }
401 } else if (dir == MOVE_DOWN) {
402 if (container->y + container->height <= next->y) {
403 if (target == -1 || next->y < max_y) {
404 target = i;
405 max_y = next->y;
406 }
407 }
408 } else if (dir == MOVE_UP) {
409 if (container->y >= next->y + next->height) {
410 if (target == -1 || max_y < next->y) {
411 target = i;
412 max_y = next->y;
413 }
414 }
415 }
416 }
417 }
418
419 if (target == -1) {
420 can_move = false;
421 } else {
380 can_move = true; 422 can_move = true;
381 diff = dir == MOVE_LEFT ? -1 : 1; 423 diff = target - self;
382 } 424 }
383 } else { 425 } else {
384 if (parent->layout == L_VERT) { 426 if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
385 can_move = true; 427 if (parent->layout == L_HORIZ) {
386 diff = dir == MOVE_UP ? -1 : 1; 428 can_move = true;
429 diff = dir == MOVE_LEFT ? -1 : 1;
430 }
431 } else {
432 if (parent->layout == L_VERT) {
433 can_move = true;
434 diff = dir == MOVE_UP ? -1 : 1;
435 }
387 } 436 }
388 } 437 }
438
389 if (can_move) { 439 if (can_move) {
390 int i;
391 for (i = 0; i < parent->children->length; ++i) { 440 for (i = 0; i < parent->children->length; ++i) {
392 swayc_t *child = parent->children->items[i]; 441 swayc_t *child = parent->children->items[i];
393 if (child == container) { 442 if (child == container) {
diff --git a/sway/log.c b/sway/log.c
index 4a047eef..a7d73d5c 100644
--- a/sway/log.c
+++ b/sway/log.c
@@ -53,7 +53,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) {
53 c = sizeof(verbosity_colors) / sizeof(char *) - 1; 53 c = sizeof(verbosity_colors) / sizeof(char *) - 1;
54 } 54 }
55 55
56 if (colored) { 56 if (colored && isatty(STDERR_FILENO)) {
57 fprintf(stderr, "%s", verbosity_colors[c]); 57 fprintf(stderr, "%s", verbosity_colors[c]);
58 } 58 }
59 59
@@ -62,7 +62,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) {
62 vfprintf(stderr, format, args); 62 vfprintf(stderr, format, args);
63 va_end(args); 63 va_end(args);
64 64
65 if (colored) { 65 if (colored && isatty(STDERR_FILENO)) {
66 fprintf(stderr, "\x1B[0m"); 66 fprintf(stderr, "\x1B[0m");
67 } 67 }
68 fprintf(stderr, "\n"); 68 fprintf(stderr, "\n");
@@ -76,7 +76,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) {
76 c = sizeof(verbosity_colors) / sizeof(char *) - 1; 76 c = sizeof(verbosity_colors) / sizeof(char *) - 1;
77 } 77 }
78 78
79 if (colored) { 79 if (colored && isatty(STDERR_FILENO)) {
80 fprintf(stderr, "%s", verbosity_colors[c]); 80 fprintf(stderr, "%s", verbosity_colors[c]);
81 } 81 }
82 82
@@ -90,7 +90,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) {
90 strerror_r(errno, error, sizeof(error)); 90 strerror_r(errno, error, sizeof(error));
91 fprintf(stderr, "%s", error); 91 fprintf(stderr, "%s", error);
92 92
93 if (colored) { 93 if (colored && isatty(STDERR_FILENO)) {
94 fprintf(stderr, "\x1B[0m"); 94 fprintf(stderr, "\x1B[0m");
95 } 95 }
96 fprintf(stderr, "\n"); 96 fprintf(stderr, "\n");
diff --git a/sway/main.c b/sway/main.c
index ffbcdbdf..3f2fcd94 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -21,6 +21,16 @@ void sway_terminate(void) {
21 21
22static void sigchld_handle(int signal); 22static void sigchld_handle(int signal);
23 23
24static void wlc_log_handler(enum wlc_log_type type, const char *str) {
25 if (type == WLC_LOG_ERROR) {
26 sway_log(L_ERROR, "[wlc] %s", str);
27 } else if (type == WLC_LOG_WARN) {
28 sway_log(L_INFO, "[wlc] %s", str);
29 } else {
30 sway_log(L_DEBUG, "[wlc] %s", str);
31 }
32}
33
24int main(int argc, char **argv) { 34int main(int argc, char **argv) {
25 static int verbose = 0, debug = 0, validate = 0; 35 static int verbose = 0, debug = 0, validate = 0;
26 36
@@ -38,6 +48,8 @@ int main(int argc, char **argv) {
38 48
39 setenv("WLC_DIM", "0", 0); 49 setenv("WLC_DIM", "0", 0);
40 50
51 wlc_log_set_handler(wlc_log_handler);
52
41 /* Changing code earlier than this point requires detailed review */ 53 /* Changing code earlier than this point requires detailed review */
42 if (!wlc_init(&interface, argc, argv)) { 54 if (!wlc_init(&interface, argc, argv)) {
43 return 1; 55 return 1;