summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config1
-rw-r--r--include/config.h1
-rw-r--r--include/input_state.h8
-rw-r--r--sway.5.txt3
-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
12 files changed, 176 insertions, 62 deletions
diff --git a/config b/config
index 7e34c0b9..8e7f7b70 100644
--- a/config
+++ b/config
@@ -32,6 +32,7 @@ set $menu dmenu_run
32 32
33 # Drag floating windows by holding down $mod and left mouse button. 33 # Drag floating windows by holding down $mod and left mouse button.
34 # Resize them with right mouse button + $mod. 34 # Resize them with right mouse button + $mod.
35 # Despite the name, also works for non-floating windows.
35 floating_modifier $mod 36 floating_modifier $mod
36 37
37 # reload the configuration file 38 # reload the configuration file
diff --git a/include/config.h b/include/config.h
index c896b423..6d36eb41 100644
--- a/include/config.h
+++ b/include/config.h
@@ -24,6 +24,7 @@ struct sway_mode {
24 24
25struct output_config { 25struct output_config {
26 char *name; 26 char *name;
27 bool enabled;
27 int width, height; 28 int width, height;
28 int x, y; 29 int x, y;
29}; 30};
diff --git a/include/input_state.h b/include/input_state.h
index 4ab93cd6..d87ae18c 100644
--- a/include/input_state.h
+++ b/include/input_state.h
@@ -6,16 +6,14 @@
6 6
7/* Keyboard state */ 7/* Keyboard state */
8 8
9typedef uint32_t keycode;
10
11// returns true if key has been pressed, otherwise false 9// returns true if key has been pressed, otherwise false
12bool check_key(keycode key); 10bool check_key(uint32_t key_sym, uint32_t key_code);
13 11
14// sets a key as pressed 12// sets a key as pressed
15void press_key(keycode key); 13void press_key(uint32_t key_sym, uint32_t key_code);
16 14
17// unsets a key as pressed 15// unsets a key as pressed
18void release_key(keycode key); 16void release_key(uint32_t key_sym, uint32_t key_code);
19 17
20 18
21/* Pointer state */ 19/* Pointer state */
diff --git a/sway.5.txt b/sway.5.txt
index e0052ee1..15a465c1 100644
--- a/sway.5.txt
+++ b/sway.5.txt
@@ -85,6 +85,9 @@ Commands
85 arranged at the given position in the layout tree. You may omit either of 85 arranged at the given position in the layout tree. You may omit either of
86 these parameters if you only want to set one of them. 86 these parameters if you only want to set one of them.
87 87
88**output** <name> disable::
89 Disables the specified output.
90
88**reload**:: 91**reload**::
89 Reloads the sway config file without restarting sway. 92 Reloads the sway config file without restarting sway.
90 93
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;