This commit is contained in:
taiyu 2015-08-23 12:34:18 -07:00
commit 51ab3c9180
12 changed files with 176 additions and 62 deletions

1
config
View file

@ -32,6 +32,7 @@ set $menu dmenu_run
# Drag floating windows by holding down $mod and left mouse button. # Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod. # Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
floating_modifier $mod floating_modifier $mod
# reload the configuration file # reload the configuration file

View file

@ -24,6 +24,7 @@ struct sway_mode {
struct output_config { struct output_config {
char *name; char *name;
bool enabled;
int width, height; int width, height;
int x, y; int x, y;
}; };

View file

@ -6,16 +6,14 @@
/* Keyboard state */ /* Keyboard state */
typedef uint32_t keycode;
// returns true if key has been pressed, otherwise false // 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 // 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 // unsets a key as pressed
void release_key(keycode key); void release_key(uint32_t key_sym, uint32_t key_code);
/* Pointer state */ /* Pointer state */

View file

@ -85,6 +85,9 @@ Commands
arranged at the given position in the layout tree. You may omit either of 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. these parameters if you only want to set one of them.
**output** <name> disable::
Disables the specified output.
**reload**:: **reload**::
Reloads the sway config file without restarting sway. Reloads the sway config file without restarting sway.

View file

@ -372,9 +372,14 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) {
struct output_config *output = calloc(1, sizeof(struct output_config)); struct output_config *output = calloc(1, sizeof(struct output_config));
output->x = output->y = output->width = output->height = -1; output->x = output->y = output->width = output->height = -1;
output->name = strdup(argv[0]); output->name = strdup(argv[0]);
output->enabled = true;
// TODO: atoi doesn't handle invalid numbers // TODO: atoi doesn't handle invalid numbers
if (strcasecmp(argv[1], "disable") == 0) {
output->enabled = false;
}
int i; int i;
for (i = 1; i < argc; ++i) { for (i = 1; i < argc; ++i) {
if (strcasecmp(argv[i], "resolution") == 0 || strcasecmp(argv[i], "res") == 0) { if (strcasecmp(argv[i], "resolution") == 0 || strcasecmp(argv[i], "res") == 0) {

View file

@ -59,7 +59,7 @@ swayc_t *new_output(wlc_handle handle) {
const char *name = wlc_output_get_name(handle); const char *name = wlc_output_get_name(handle);
sway_log(L_DEBUG, "Added output %lu:%s", handle, name); sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
struct output_config *oc ; struct output_config *oc = NULL;
int i; int i;
for (i = 0; i < config->output_configs->length; ++i) { for (i = 0; i < config->output_configs->length; ++i) {
oc = config->output_configs->items[i]; oc = config->output_configs->items[i];
@ -70,6 +70,10 @@ swayc_t *new_output(wlc_handle handle) {
oc = NULL; oc = NULL;
} }
if (oc && !oc->enabled) {
return NULL;
}
swayc_t *output = new_swayc(C_OUTPUT); swayc_t *output = new_swayc(C_OUTPUT);
if (oc && oc->width != -1 && oc->height != -1) { if (oc && oc->width != -1 && oc->height != -1) {
output->width = oc->width; output->width = oc->width;
@ -84,6 +88,24 @@ swayc_t *new_output(wlc_handle handle) {
output->name = name ? strdup(name) : NULL; output->name = name ? strdup(name) : NULL;
output->gaps = config->gaps_outer + config->gaps_inner / 2; output->gaps = config->gaps_outer + config->gaps_inner / 2;
// 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 {
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); add_child(&root_container, output);
// Create workspace // Create workspace
@ -281,7 +303,8 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
return NULL; 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); sway_log(L_DEBUG, "%s: '%s'", __func__, workspace->name);
swayc_t *parent = workspace->parent; swayc_t *parent = workspace->parent;
free_swayc(workspace); free_swayc(workspace);
@ -448,14 +471,16 @@ bool swayc_is_fullscreen(swayc_t *view) {
// Mapping // Mapping
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { 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; int i;
for (i = 0; i < container->children->length; ++i) { if (container->children) {
swayc_t *child = container->children->items[i]; for (i = 0; i < container->children->length; ++i) {
f(child, data); swayc_t *child = container->children->items[i];
container_map(child, f, data); f(child, data);
container_map(child, f, data);
}
} }
if (container->type == C_WORKSPACE) { if (container->floating) {
for (i = 0; i < container->floating->length; ++i) { for (i = 0; i < container->floating->length; ++i) {
swayc_t *child = container->floating->items[i]; swayc_t *child = container->floating->items[i];
f(child, data); f(child, data);

View file

@ -34,7 +34,6 @@ static void update_focus(swayc_t *c) {
mask = 2; mask = 2;
container_map(c, set_view_visibility, &mask); container_map(c, set_view_visibility, &mask);
wlc_output_set_mask(parent->handle, 2); wlc_output_set_mask(parent->handle, 2);
c->parent->focused = c;
destroy_workspace(ws); destroy_workspace(ws);
} }
break; break;

View file

@ -90,6 +90,10 @@ swayc_t *container_under_pointer(void) {
static bool handle_output_created(wlc_handle output) { static bool handle_output_created(wlc_handle output) {
swayc_t *op = new_output(output); swayc_t *op = new_output(output);
if (!op) {
return false;
}
// Switch to workspace if we need to // Switch to workspace if we need to
if (swayc_active_workspace() == NULL) { if (swayc_active_workspace() == NULL) {
swayc_t *ws = op->children->items[0]; swayc_t *ws = op->children->items[0];
@ -108,6 +112,8 @@ static void handle_output_destroyed(wlc_handle output) {
} }
if (i < list->length) { if (i < list->length) {
destroy_output(list->items[i]); destroy_output(list->items[i]);
} else {
return;
} }
if (list->length > 0) { if (list->length > 0) {
// switch to other outputs active workspace // switch to other outputs active workspace
@ -292,22 +298,12 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
struct sway_mode *mode = config->current_mode; 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 EVENT_PASSTHROUGH;
}
}
// Lowercase if necessary
sym = tolower(sym);
int i; int i;
if (state == WLC_KEY_STATE_PRESSED) { if (state == WLC_KEY_STATE_PRESSED) {
press_key(sym); press_key(sym, key);
} else { // WLC_KEY_STATE_RELEASED } else { // WLC_KEY_STATE_RELEASED
release_key(sym); release_key(sym, key);
} }
// TODO: reminder to check conflicts with mod+q+a versus mod+q // 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
int j; int j;
for (j = 0; j < binding->keys->length; ++j) { for (j = 0; j < binding->keys->length; ++j) {
xkb_keysym_t *key = binding->keys->items[j]; xkb_keysym_t *key = binding->keys->items[j];
if ((match = check_key(*key)) == false) { if ((match = check_key(*key, 0)) == false) {
break; break;
} }
} }
@ -467,7 +463,6 @@ static void handle_wlc_ready(void) {
config->active = true; config->active = true;
} }
struct wlc_interface interface = { struct wlc_interface interface = {
.output = { .output = {
.created = handle_output_created, .created = handle_output_created,

View file

@ -1,50 +1,76 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <ctype.h> #include <ctype.h>
#include "log.h"
#include "input_state.h" #include "input_state.h"
#define KEY_STATE_MAX_LENGTH 64 #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) { void input_init(void) {
int i; int i;
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++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; int i;
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++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; break;
} }
} }
return i; return i;
} }
bool check_key(keycode key) { bool check_key(uint32_t key_sym, uint32_t key_code) {
return find_key(key) < KEY_STATE_MAX_LENGTH; 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 // Check if key exists
if (!check_key(key)) { if (!check_key(key_sym, key_code)) {
// Check that we dont exceed buffer length // 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) { 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) { void release_key(uint32_t key_sym, uint32_t key_code) {
uint8_t index = find_key(key); uint8_t index = find_key(key_sym, key_code, true);
if (index < KEY_STATE_MAX_LENGTH) { if (index < KEY_STATE_MAX_LENGTH) {
// shift it over and remove key struct key_state none = { 0, 0, 0 };
key_state_array[index] = 0; key_state_array[index] = none;
} }
} }

View file

@ -242,21 +242,14 @@ void arrange_windows(swayc_t *container, double width, double height) {
for (i = 0; i < container->children->length; ++i) { for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i]; swayc_t *child = container->children->items[i];
sway_log(L_DEBUG, "Arranging output at %d", x); sway_log(L_DEBUG, "Arranging output at %d", x);
child->x = x;
child->y = y;
arrange_windows(child, -1, -1); arrange_windows(child, -1, -1);
// Removed for now because wlc works with relative positions x += child->width;
// Addition can be reconsidered once wlc positions are changed
// x += child->width;
} }
return; return;
case C_OUTPUT: case C_OUTPUT:
container->width = width; container->width = width;
container->height = height; container->height = height;
// These lines make x/y negative and result in stuff glitching out x = 0, y = 0;
// Their addition can be reconsidered once wlc positions are changed
// x -= container->x;
// y -= container->y;
for (i = 0; i < container->children->length; ++i) { for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i]; swayc_t *child = container->children->items[i];
child->x = x + container->gaps; child->x = x + container->gaps;
@ -375,19 +368,75 @@ swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir)
// Test if we can even make a difference here // Test if we can even make a difference here
bool can_move = false; bool can_move = false;
int diff = 0; int diff = 0;
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { int i;
if (parent->layout == L_HORIZ || parent->type == C_ROOT) { 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) {
if (container->x >= next->x + next->width) {
if (target == -1 || max_x < next->x) {
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; can_move = true;
diff = dir == MOVE_LEFT ? -1 : 1; diff = target - self;
} }
} else { } else {
if (parent->layout == L_VERT) { if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
can_move = true; if (parent->layout == L_HORIZ) {
diff = dir == MOVE_UP ? -1 : 1; 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) { if (can_move) {
int i;
for (i = 0; i < parent->children->length; ++i) { for (i = 0; i < parent->children->length; ++i) {
swayc_t *child = parent->children->items[i]; swayc_t *child = parent->children->items[i];
if (child == container) { if (child == container) {

View file

@ -53,7 +53,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) {
c = sizeof(verbosity_colors) / sizeof(char *) - 1; c = sizeof(verbosity_colors) / sizeof(char *) - 1;
} }
if (colored) { if (colored && isatty(STDERR_FILENO)) {
fprintf(stderr, "%s", verbosity_colors[c]); fprintf(stderr, "%s", verbosity_colors[c]);
} }
@ -62,7 +62,7 @@ void sway_log(log_importance_t verbosity, const char* format, ...) {
vfprintf(stderr, format, args); vfprintf(stderr, format, args);
va_end(args); va_end(args);
if (colored) { if (colored && isatty(STDERR_FILENO)) {
fprintf(stderr, "\x1B[0m"); fprintf(stderr, "\x1B[0m");
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -76,7 +76,7 @@ void sway_log_errno(log_importance_t verbosity, char* format, ...) {
c = sizeof(verbosity_colors) / sizeof(char *) - 1; c = sizeof(verbosity_colors) / sizeof(char *) - 1;
} }
if (colored) { if (colored && isatty(STDERR_FILENO)) {
fprintf(stderr, "%s", verbosity_colors[c]); 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)); strerror_r(errno, error, sizeof(error));
fprintf(stderr, "%s", error); fprintf(stderr, "%s", error);
if (colored) { if (colored && isatty(STDERR_FILENO)) {
fprintf(stderr, "\x1B[0m"); fprintf(stderr, "\x1B[0m");
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");

View file

@ -21,6 +21,16 @@ void sway_terminate(void) {
static void sigchld_handle(int signal); 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, "[wlc] %s", str);
} else if (type == WLC_LOG_WARN) {
sway_log(L_INFO, "[wlc] %s", str);
} else {
sway_log(L_DEBUG, "[wlc] %s", str);
}
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
static int verbose = 0, debug = 0, validate = 0; static int verbose = 0, debug = 0, validate = 0;
@ -38,6 +48,8 @@ int main(int argc, char **argv) {
setenv("WLC_DIM", "0", 0); setenv("WLC_DIM", "0", 0);
wlc_log_set_handler(wlc_log_handler);
/* Changing code earlier than this point requires detailed review */ /* Changing code earlier than this point requires detailed review */
if (!wlc_init(&interface, argc, argv)) { if (!wlc_init(&interface, argc, argv)) {
return 1; return 1;