From eac0920f49a728ad6a3809528c4757b73e4cd8af Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 22 Aug 2015 14:44:47 -0400 Subject: Set x/y positions for output containers --- sway/container.c | 19 ++++++++++++++++++- sway/layout.c | 9 ++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/sway/container.c b/sway/container.c index 5d544934..41d21c3b 100644 --- a/sway/container.c +++ b/sway/container.c @@ -59,7 +59,7 @@ swayc_t *new_output(wlc_handle handle) { const char *name = wlc_output_get_name(handle); sway_log(L_DEBUG, "Added output %lu:%s", handle, name); - struct output_config *oc ; + struct output_config *oc = NULL; int i; for (i = 0; i < config->output_configs->length; ++i) { oc = config->output_configs->items[i]; @@ -83,6 +83,23 @@ swayc_t *new_output(wlc_handle handle) { output->handle = handle; output->name = name ? strdup(name) : NULL; output->gaps = config->gaps_outer + config->gaps_inner / 2; + + // Find position for it + if (oc && oc->x != -1 && oc->y != -1) { + output->x = oc->x; + output->y = oc->y; + } else { + int x = 0; + for (i = 0; i < root_container.children->length; ++i) { + swayc_t *c = root_container.children->items[i]; + if (c->type == C_OUTPUT) { + if (c->width + c->x > x) { + x = c->width + c->x; + } + } + } + output->x = x; + } add_child(&root_container, output); diff --git a/sway/layout.c b/sway/layout.c index 18ecb1e7..7f3adc31 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -172,18 +172,13 @@ void arrange_windows(swayc_t *container, double width, double height) { child->x = x; child->y = y; arrange_windows(child, -1, -1); - // Removed for now because wlc works with relative positions - // Addition can be reconsidered once wlc positions are changed - // x += child->width; + x += child->width; } return; case C_OUTPUT: container->width = width; container->height = height; - // These lines make x/y negative and result in stuff glitching out - // Their addition can be reconsidered once wlc positions are changed - // x -= container->x; - // y -= container->y; + x = 0, y = 0; for (i = 0; i < container->children->length; ++i) { swayc_t *child = container->children->items[i]; child->x = x + container->gaps; -- cgit v1.2.3-54-g00ecf From 07229edfe627762df9c27ed2700d737f74bb7b88 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 22 Aug 2015 15:19:02 -0400 Subject: Implement output positioning :tada: --- sway/container.c | 1 + sway/layout.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/sway/container.c b/sway/container.c index 41d21c3b..67a34551 100644 --- a/sway/container.c +++ b/sway/container.c @@ -86,6 +86,7 @@ swayc_t *new_output(wlc_handle handle) { // Find position for it if (oc && oc->x != -1 && oc->y != -1) { + sway_log(L_DEBUG, "Set %s position to %d, %d", name, oc->x, oc->y); output->x = oc->x; output->y = oc->y; } else { diff --git a/sway/layout.c b/sway/layout.c index 7f3adc31..7a7ccc0e 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -169,8 +169,6 @@ void arrange_windows(swayc_t *container, double width, double height) { for (i = 0; i < container->children->length; ++i) { swayc_t *child = container->children->items[i]; sway_log(L_DEBUG, "Arranging output at %d", x); - child->x = x; - child->y = y; arrange_windows(child, -1, -1); x += child->width; } @@ -340,19 +338,79 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) // Test if we can even make a difference here bool can_move = false; int diff = 0; - if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { - if (parent->layout == L_HORIZ || parent->type == C_ROOT) { + int i; + if (parent->type == C_ROOT) { + // Find the next output + int target = -1, max_x = 0, max_y = 0, self = -1; + sway_log(L_DEBUG, "Moving between outputs"); + + for (i = 0; i < parent->children->length; ++i) { + swayc_t *next = parent->children->items[i]; + if (next == container) { + self = i; + sway_log(L_DEBUG, "self is %p %d", next, self); + continue; + } + if (next->type == C_OUTPUT) { + sway_log(L_DEBUG, "Testing with %p %d (dir %d)", next, i, dir); + // Check if it's more extreme + if (dir == MOVE_RIGHT) { + if (container->x + container->width <= next->x) { + if (target == -1 || next->x < max_x) { + target = i; + max_x = next->x; + } + } + } else if (dir == MOVE_LEFT) { + sway_log(L_DEBUG, "next->x: %d, next->width: %d, container->x: %d", + (int)next->x, (int)next->width, (int)container->x); + if (container->x > next->x + next->width) { + sway_log(L_DEBUG, "match"); + if (target == -1 || max_x < next->x) { + sway_log(L_DEBUG, "hit"); + target = i; + max_x = next->x; + } + } + } else if (dir == MOVE_DOWN) { + if (container->y + container->height <= next->y) { + if (target == -1 || next->y < max_y) { + target = i; + max_y = next->y; + } + } + } else if (dir == MOVE_UP) { + if (container->y > next->y + next->height) { + if (target == -1 || max_y < next->y) { + target = i; + max_y = next->y; + } + } + } + } + } + + if (target == -1) { + can_move = false; + } else { can_move = true; - diff = dir == MOVE_LEFT ? -1 : 1; + diff = target - self; } } else { - if (parent->layout == L_VERT) { - can_move = true; - diff = dir == MOVE_UP ? -1 : 1; + if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { + if (parent->layout == L_HORIZ) { + can_move = true; + diff = dir == MOVE_LEFT ? -1 : 1; + } + } else { + if (parent->layout == L_VERT) { + can_move = true; + diff = dir == MOVE_UP ? -1 : 1; + } } } + if (can_move) { - int i; for (i = 0; i < parent->children->length; ++i) { swayc_t *child = parent->children->items[i]; if (child == container) { -- cgit v1.2.3-54-g00ecf From 1fd5962aeb5bab722a26182ad39fddecf43c6f95 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 22 Aug 2015 15:21:56 -0400 Subject: Fix minor bug with output positioning --- sway/layout.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sway/layout.c b/sway/layout.c index 7a7ccc0e..035fea34 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -362,12 +362,8 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) } } } else if (dir == MOVE_LEFT) { - sway_log(L_DEBUG, "next->x: %d, next->width: %d, container->x: %d", - (int)next->x, (int)next->width, (int)container->x); - if (container->x > next->x + next->width) { - sway_log(L_DEBUG, "match"); + if (container->x >= next->x + next->width) { if (target == -1 || max_x < next->x) { - sway_log(L_DEBUG, "hit"); target = i; max_x = next->x; } @@ -380,7 +376,7 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) } } } else if (dir == MOVE_UP) { - if (container->y > next->y + next->height) { + if (container->y >= next->y + next->height) { if (target == -1 || max_y < next->y) { target = i; max_y = next->y; -- cgit v1.2.3-54-g00ecf From 36cd180f02cf032fa1d041540fff236061c3df5a Mon Sep 17 00:00:00 2001 From: taiyu Date: Sat, 22 Aug 2015 18:25:05 -0700 Subject: fixed vanishing floating view --- sway/container.c | 17 ++++++++++------- sway/focus.c | 1 - 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sway/container.c b/sway/container.c index 67a34551..127e1ecd 100644 --- a/sway/container.c +++ b/sway/container.c @@ -299,7 +299,8 @@ swayc_t *destroy_workspace(swayc_t *workspace) { return NULL; } - if (workspace->children->length == 0) { + // Do not destroy if there are children + if (workspace->children->length == 0 && workspace->floating->length == 0) { sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name); swayc_t *parent = workspace->parent; free_swayc(workspace); @@ -466,14 +467,16 @@ bool swayc_is_fullscreen(swayc_t *view) { // Mapping void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { - if (container && container->children && container->children->length) { + if (container) { int i; - for (i = 0; i < container->children->length; ++i) { - swayc_t *child = container->children->items[i]; - f(child, data); - container_map(child, f, data); + if (container->children) { + for (i = 0; i < container->children->length; ++i) { + swayc_t *child = container->children->items[i]; + f(child, data); + container_map(child, f, data); + } } - if (container->type == C_WORKSPACE) { + if (container->floating) { for (i = 0; i < container->floating->length; ++i) { swayc_t *child = container->floating->items[i]; 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) { mask = 2; container_map(c, set_view_visibility, &mask); wlc_output_set_mask(parent->handle, 2); - c->parent->focused = c; destroy_workspace(ws); } break; -- cgit v1.2.3-54-g00ecf From 1e18ba9f2d170c89c4cf202a9dfd7b87da4fa769 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 23 Aug 2015 11:27:16 -0400 Subject: Add note to config about floating_modifier --- config | 1 + 1 file changed, 1 insertion(+) diff --git a/config b/config index 7e34c0b9..8e7f7b70 100644 --- a/config +++ b/config @@ -32,6 +32,7 @@ set $menu dmenu_run # Drag floating windows by holding down $mod and left mouse button. # Resize them with right mouse button + $mod. + # Despite the name, also works for non-floating windows. floating_modifier $mod # reload the configuration file -- cgit v1.2.3-54-g00ecf From ac2034df99e1ec19e8bca60a802cd9f9d8fbbf83 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 23 Aug 2015 13:08:04 -0400 Subject: Handle wlc log events --- sway/handlers.c | 1 - sway/main.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sway/handlers.c b/sway/handlers.c index cb42196f..e4018811 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -498,7 +498,6 @@ static void handle_wlc_ready(void) { config->active = true; } - struct wlc_interface interface = { .output = { .created = handle_output_created, diff --git a/sway/main.c b/sway/main.c index ffbcdbdf..f8959009 100644 --- a/sway/main.c +++ b/sway/main.c @@ -21,6 +21,16 @@ void sway_terminate(void) { static void sigchld_handle(int signal); +static void wlc_log_handler(enum wlc_log_type type, const char *str) { + if (type == WLC_LOG_ERROR) { + sway_log(L_ERROR, "%s", str); + } else if (type == WLC_LOG_WARN) { + sway_log(L_INFO, "%s", str); + } else { + sway_log(L_DEBUG, "%s", str); + } +} + int main(int argc, char **argv) { static int verbose = 0, debug = 0, validate = 0; @@ -38,6 +48,8 @@ int main(int argc, char **argv) { setenv("WLC_DIM", "0", 0); + wlc_log_set_handler(wlc_log_handler); + /* Changing code earlier than this point requires detailed review */ if (!wlc_init(&interface, argc, argv)) { return 1; -- cgit v1.2.3-54-g00ecf From e2322414666488945ffcbcab06f9cca95ff731d3 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 23 Aug 2015 13:16:37 -0400 Subject: Do not log with colors unless stdout is a tty --- sway/log.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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, ...) { c = sizeof(verbosity_colors) / sizeof(char *) - 1; } - if (colored) { + if (colored && isatty(STDERR_FILENO)) { fprintf(stderr, "%s", verbosity_colors[c]); } @@ -62,7 +62,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) { vfprintf(stderr, format, args); va_end(args); - if (colored) { + if (colored && isatty(STDERR_FILENO)) { fprintf(stderr, "\x1B[0m"); } fprintf(stderr, "\n"); @@ -76,7 +76,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) { c = sizeof(verbosity_colors) / sizeof(char *) - 1; } - if (colored) { + if (colored && isatty(STDERR_FILENO)) { fprintf(stderr, "%s", verbosity_colors[c]); } @@ -90,7 +90,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) { strerror_r(errno, error, sizeof(error)); fprintf(stderr, "%s", error); - if (colored) { + if (colored && isatty(STDERR_FILENO)) { fprintf(stderr, "\x1B[0m"); } fprintf(stderr, "\n"); -- cgit v1.2.3-54-g00ecf From 98fad060e28c81c8340afbb473615f7889a6097a Mon Sep 17 00:00:00 2001 From: Luminarys Date: Sun, 23 Aug 2015 12:22:33 -0500 Subject: Added in glitchy disabling --- include/config.h | 1 + sway/commands.c | 5 +++++ sway/container.c | 4 ++++ sway/handlers.c | 11 +++++++++++ 4 files changed, 21 insertions(+) diff --git a/include/config.h b/include/config.h index c896b423..3d501cbe 100644 --- a/include/config.h +++ b/include/config.h @@ -24,6 +24,7 @@ struct sway_mode { struct output_config { char *name; + bool enabled; int width, height; int x, y; }; diff --git a/sway/commands.c b/sway/commands.c index 5de1fb0c..9a0bc076 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) { struct output_config *output = calloc(1, sizeof(struct output_config)); output->x = output->y = output->width = output->height = -1; output->name = strdup(argv[0]); + output->enabled = true; // TODO: atoi doesn't handle invalid numbers + + if (strcmp(argv[1], "disable") == 0) { + output->enabled = false; + } int i; for (i = 1; i < argc; ++i) { diff --git a/sway/container.c b/sway/container.c index 127e1ecd..6debeea3 100644 --- a/sway/container.c +++ b/sway/container.c @@ -70,6 +70,10 @@ swayc_t *new_output(wlc_handle handle) { oc = NULL; } + if (oc && !oc->enabled) { + return NULL; + } + swayc_t *output = new_swayc(C_OUTPUT); if (oc && oc->width != -1 && oc->height != -1) { output->width = oc->width; diff --git a/sway/handlers.c b/sway/handlers.c index e4018811..9fca6387 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -86,11 +86,22 @@ swayc_t *container_under_pointer(void) { static bool handle_output_created(wlc_handle output) { swayc_t *op = new_output(output); + if (!op) { + return false; + } + + wlc_output_focus(output); // Switch to workspace if we need to if (swayc_active_workspace() == NULL) { + sway_log(L_INFO, "Focus switch"); swayc_t *ws = op->children->items[0]; workspace_switch(ws); } + /* + if (wlc_output_get_sleep(wlc_get_focused_output())) { + wlc_output_focus(output); + } + */ return true; } -- cgit v1.2.3-54-g00ecf From e01cf0b56654ff459a98a90e5e35615ad8d9203e Mon Sep 17 00:00:00 2001 From: Luminarys Date: Sun, 23 Aug 2015 12:22:45 -0500 Subject: Added in glitchy disabling --- sway/commands.c | 10 +++++----- sway/container.c | 6 +++--- sway/handlers.c | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sway/commands.c b/sway/commands.c index 9a0bc076..ae75ec67 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -372,13 +372,13 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) { struct output_config *output = calloc(1, sizeof(struct output_config)); output->x = output->y = output->width = output->height = -1; output->name = strdup(argv[0]); - output->enabled = true; + output->enabled = true; // TODO: atoi doesn't handle invalid numbers - - if (strcmp(argv[1], "disable") == 0) { - output->enabled = false; - } + + if (strcmp(argv[1], "disable") == 0) { + output->enabled = false; + } int i; for (i = 1; i < argc; ++i) { diff --git a/sway/container.c b/sway/container.c index 6debeea3..d4f7c693 100644 --- a/sway/container.c +++ b/sway/container.c @@ -70,9 +70,9 @@ swayc_t *new_output(wlc_handle handle) { oc = NULL; } - if (oc && !oc->enabled) { - return NULL; - } + if (oc && !oc->enabled) { + return NULL; + } swayc_t *output = new_swayc(C_OUTPUT); if (oc && oc->width != -1 && oc->height != -1) { diff --git a/sway/handlers.c b/sway/handlers.c index 9fca6387..1ff430f2 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -86,22 +86,22 @@ swayc_t *container_under_pointer(void) { static bool handle_output_created(wlc_handle output) { swayc_t *op = new_output(output); - if (!op) { - return false; - } + if (!op) { + return false; + } - wlc_output_focus(output); + wlc_output_focus(output); // Switch to workspace if we need to if (swayc_active_workspace() == NULL) { - sway_log(L_INFO, "Focus switch"); + sway_log(L_INFO, "Focus switch"); swayc_t *ws = op->children->items[0]; workspace_switch(ws); } - /* - if (wlc_output_get_sleep(wlc_get_focused_output())) { - wlc_output_focus(output); - } - */ + /* + if (wlc_output_get_sleep(wlc_get_focused_output())) { + wlc_output_focus(output); + } + */ return true; } -- cgit v1.2.3-54-g00ecf From e78221e6a0413b8cccd41f75288798ae15b792b6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 23 Aug 2015 13:31:16 -0400 Subject: Prefix log events from wlc with [wlc] --- sway/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sway/main.c b/sway/main.c index f8959009..3f2fcd94 100644 --- a/sway/main.c +++ b/sway/main.c @@ -23,11 +23,11 @@ static void sigchld_handle(int signal); static void wlc_log_handler(enum wlc_log_type type, const char *str) { if (type == WLC_LOG_ERROR) { - sway_log(L_ERROR, "%s", str); + sway_log(L_ERROR, "[wlc] %s", str); } else if (type == WLC_LOG_WARN) { - sway_log(L_INFO, "%s", str); + sway_log(L_INFO, "[wlc] %s", str); } else { - sway_log(L_DEBUG, "%s", str); + sway_log(L_DEBUG, "[wlc] %s", str); } } -- cgit v1.2.3-54-g00ecf From 5bfed9b2131761f29e2cc095fbdf2083d2665848 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Sun, 23 Aug 2015 13:18:07 -0500 Subject: Cleanup and minor adjustments to disabling --- sway/handlers.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/sway/handlers.c b/sway/handlers.c index 1ff430f2..23db5c15 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -90,18 +90,11 @@ static bool handle_output_created(wlc_handle output) { return false; } - wlc_output_focus(output); // Switch to workspace if we need to if (swayc_active_workspace() == NULL) { - sway_log(L_INFO, "Focus switch"); swayc_t *ws = op->children->items[0]; workspace_switch(ws); } - /* - if (wlc_output_get_sleep(wlc_get_focused_output())) { - wlc_output_focus(output); - } - */ return true; } @@ -115,6 +108,8 @@ static void handle_output_destroyed(wlc_handle output) { } if (i < list->length) { destroy_output(list->items[i]); + } else { + return; } if (list->length > 0) { // switch to other outputs active workspace -- cgit v1.2.3-54-g00ecf From a65dca04e89282822fbda01aee00aadac8fb2540 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Sun, 23 Aug 2015 13:19:47 -0500 Subject: Style fix --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index 3d501cbe..6d36eb41 100644 --- a/include/config.h +++ b/include/config.h @@ -24,7 +24,7 @@ struct sway_mode { struct output_config { char *name; - bool enabled; + bool enabled; int width, height; int x, y; }; -- cgit v1.2.3-54-g00ecf From 3f1bb40769df708de8f488d432d56d8bce6edb5a Mon Sep 17 00:00:00 2001 From: Luminarys Date: Sun, 23 Aug 2015 13:27:37 -0500 Subject: Man page update --- sway.5.txt | 3 +++ 1 file changed, 3 insertions(+) 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 arranged at the given position in the layout tree. You may omit either of these parameters if you only want to set one of them. +**output** disable:: + Disables the specified output. + **reload**:: Reloads the sway config file without restarting sway. -- cgit v1.2.3-54-g00ecf From 7a213889974daad72fd6b925edc3dc2cf1a394a1 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Sun, 23 Aug 2015 13:32:47 -0500 Subject: Minor fix --- sway/commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index ae75ec67..7ee8c558 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -376,7 +376,7 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) { // TODO: atoi doesn't handle invalid numbers - if (strcmp(argv[1], "disable") == 0) { + if (strcasecmp(argv[1], "disable") == 0) { output->enabled = false; } -- cgit v1.2.3-54-g00ecf From 1ac0c8cd47f734809c20bf6a6a0a7278680ed597 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 23 Aug 2015 15:28:49 -0400 Subject: Refactor keyboard to consider modified keysyms Press Shift Press 0 # Reads as ')' Release Shift Release 0 # Reads as '0' but we now recognize it as the same --- include/input_state.h | 8 +++----- sway/handlers.c | 16 +++------------ sway/input_state.c | 54 ++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/include/input_state.h b/include/input_state.h index 04fde42d..29064fd0 100644 --- a/include/input_state.h +++ b/include/input_state.h @@ -6,16 +6,14 @@ /* Keyboard state */ -typedef uint32_t keycode; - // returns true if key has been pressed, otherwise false -bool check_key(keycode key); +bool check_key(uint32_t key_sym, uint32_t key_code); // sets a key as pressed -void press_key(keycode key); +void press_key(uint32_t key_sym, uint32_t key_code); // unsets a key as pressed -void release_key(keycode key); +void release_key(uint32_t key_sym, uint32_t key_code); /* Pointer state */ diff --git a/sway/handlers.c b/sway/handlers.c index 23db5c15..acf3e6a4 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -295,22 +295,12 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier struct sway_mode *mode = config->current_mode; - if (sym < 70000 /* bullshit made up number */) { - if (!isalnum(sym) && sym != ' ' && sym != XKB_KEY_Escape && sym != XKB_KEY_Tab) { - // God fucking dammit - return false; - } - } - - // Lowercase if necessary - sym = tolower(sym); - int i; if (state == WLC_KEY_STATE_PRESSED) { - press_key(sym); + press_key(sym, key); } else { // WLC_KEY_STATE_RELEASED - release_key(sym); + release_key(sym, key); } // TODO: reminder to check conflicts with mod+q+a versus mod+q @@ -322,7 +312,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier int j; for (j = 0; j < binding->keys->length; ++j) { xkb_keysym_t *key = binding->keys->items[j]; - if ((match = check_key(*key)) == false) { + if ((match = check_key(*key, 0)) == false) { break; } } diff --git a/sway/input_state.c b/sway/input_state.c index e2f3c754..9e065e60 100644 --- a/sway/input_state.c +++ b/sway/input_state.c @@ -1,50 +1,76 @@ #include #include #include +#include "log.h" #include "input_state.h" #define KEY_STATE_MAX_LENGTH 64 -static keycode key_state_array[KEY_STATE_MAX_LENGTH]; +struct key_state { + /* + * Aims to store state regardless of modifiers. + * If you press a key, then hold shift, then release the key, we'll + * get two different key syms, but the same key code. This handles + * that scenario and makes sure we can use the right bindings. + */ + uint32_t key_sym; + uint32_t alt_sym; + uint32_t key_code; +}; + +static struct key_state key_state_array[KEY_STATE_MAX_LENGTH]; void input_init(void) { int i; for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) { - key_state_array[i] = 0; + struct key_state none = { 0, 0, 0 }; + key_state_array[i] = none; } } -static uint8_t find_key(keycode key) { +static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) { int i; for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) { - if (key_state_array[i] == key) { + if (0 == key_sym && 0 == key_code && key_state_array[i].key_sym == 0) { + break; + } + if (key_state_array[i].key_sym == key_sym + || key_state_array[i].alt_sym == key_sym) { + break; + } + if (update && key_state_array[i].key_code == key_code) { + key_state_array[i].alt_sym = key_sym; break; } } return i; } -bool check_key(keycode key) { - return find_key(key) < KEY_STATE_MAX_LENGTH; +bool check_key(uint32_t key_sym, uint32_t key_code) { + return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH; } -void press_key(keycode key) { +void press_key(uint32_t key_sym, uint32_t key_code) { + if (key_code == 0) { + return; + } // Check if key exists - if (!check_key(key)) { + if (!check_key(key_sym, key_code)) { // Check that we dont exceed buffer length - int insert = find_key(0); + int insert = find_key(0, 0, true); if (insert < KEY_STATE_MAX_LENGTH) { - key_state_array[insert] = key; + key_state_array[insert].key_sym = key_sym; + key_state_array[insert].key_code = key_code; } } } -void release_key(keycode key) { - uint8_t index = find_key(key); +void release_key(uint32_t key_sym, uint32_t key_code) { + uint8_t index = find_key(key_sym, key_code, true); if (index < KEY_STATE_MAX_LENGTH) { - // shift it over and remove key - key_state_array[index] = 0; + struct key_state none = { 0, 0, 0 }; + key_state_array[index] = none; } } -- cgit v1.2.3-54-g00ecf