From 868cb3ca71713014cc613b49f8521c01e60f366e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 18 Aug 2015 08:05:34 -0400 Subject: [PATCH 01/12] Revert "config handles comments better" This reverts commit e9c3a9016f1df5877404721043967431afb2f5c7. --- sway/stringop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/stringop.c b/sway/stringop.c index 00cc32b8..624c8401 100644 --- a/sway/stringop.c +++ b/sway/stringop.c @@ -41,7 +41,7 @@ void strip_comments(char *str) { } else if (str[i] == '\'' && !in_string) { in_character = !in_character; } else if (!in_character && !in_string) { - if (str[i] == '#') { + if (str[i] == '#' && i == 0) { str[i] = '\0'; break; } From a64b10df83f84e7ee8933ac139f10c59bfd76466 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 18 Aug 2015 08:20:59 -0400 Subject: [PATCH 02/12] Fix switching between focused outputs --- sway/container.c | 20 ++++++++++++++++++++ sway/focus.c | 2 +- sway/workspace.c | 11 +++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/sway/container.c b/sway/container.c index e679e823..c83cd720 100644 --- a/sway/container.c +++ b/sway/container.c @@ -37,6 +37,10 @@ static void free_swayc(swayc_t *c) { /* New containers */ +static bool workspace_test(swayc_t *view, void *name) { + return strcasecmp(view->name, (char *)name); +} + swayc_t *new_output(wlc_handle handle) { const struct wlc_size* size = wlc_output_get_resolution(handle); const char *name = wlc_output_get_name(handle); @@ -58,6 +62,10 @@ swayc_t *new_output(wlc_handle handle) { struct workspace_output *wso = config->workspace_outputs->items[i]; if (strcasecmp(wso->output, name) == 0) { sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output); + // Check if any other workspaces are using this name + if (find_container(&root_container, workspace_test, wso->workspace)) { + break; + } ws_name = strdup(wso->workspace); break; } @@ -206,6 +214,18 @@ swayc_t *destroy_workspace(swayc_t *workspace) { // NOTE: This is called from elsewhere without checking children length // TODO move containers to other workspaces? // for now just dont delete + + // Do not destroy this if it's the last workspace on this output + swayc_t *output = workspace->parent; + while (output && output->type != C_OUTPUT) { + output = output->parent; + } + if (output) { + if (output->children->length == 1) { + return NULL; + } + } + if (workspace->children->length == 0) { sway_log(L_DEBUG, "Workspace: Destroying workspace '%s'", workspace->name); swayc_t *parent = workspace->parent; diff --git a/sway/focus.c b/sway/focus.c index 99cb2570..7e3af56c 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -16,7 +16,7 @@ static void update_focus(swayc_t *c) { switch (c->type) { case C_ROOT: return; case C_OUTPUT: - wlc_output_focus(c->parent->handle); + wlc_output_focus(c->handle); break; // switching workspaces case C_WORKSPACE: diff --git a/sway/workspace.c b/sway/workspace.c index bc0fa2c8..ed545804 100644 --- a/sway/workspace.c +++ b/sway/workspace.c @@ -174,6 +174,17 @@ void workspace_prev() { } void workspace_switch(swayc_t *workspace) { + if (!workspace) { + return; + } + sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + + // Remove focus from current view + swayc_t *current = get_focused_view(&root_container); + if (current && current->type == C_VIEW) { + wlc_view_set_state(current->handle, WLC_BIT_ACTIVATED, false); + } + set_focused_container(workspace); active_workspace = workspace; } From 85a573dab73654fb4462dd8fe48ef16400770f04 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 18 Aug 2015 08:39:26 -0400 Subject: [PATCH 03/12] Revert "enhanced whitespace remover" This reverts commit abd0afb03a2929931cb684e5aaeac312affe6e5f. --- include/stringop.h | 4 ++-- sway/commands.c | 6 +++--- sway/config.c | 5 +++-- sway/stringop.c | 50 +++++++++++++++++++++++----------------------- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/include/stringop.h b/include/stringop.h index 03387345..a5346829 100644 --- a/include/stringop.h +++ b/include/stringop.h @@ -2,8 +2,8 @@ #define _SWAY_STRINGOP_H #include "list.h" -void strip_whitespace(char *str); -void strip_comments(char *str); +char *strip_whitespace(char *str, int *trimmed_start); +char *strip_comments(char *str); list_t *split_string(const char *str, const char *delims); void free_flat_list(list_t *list); char *code_strchr(const char *string, char delimiter); diff --git a/sway/commands.c b/sway/commands.c index 51de7a50..ae0bdbe4 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -506,7 +506,7 @@ static char **split_directive(char *line, int *argc) { if (!*line) return parts; int in_string = 0, in_character = 0; - int i, j; + int i, j, _; for (i = 0, j = 0; line[i]; ++i) { if (line[i] == '\\') { ++i; @@ -519,7 +519,7 @@ static char **split_directive(char *line, int *argc) { char *item = malloc(i - j + 1); strncpy(item, line + j, i - j); item[i - j] = '\0'; - strip_whitespace(item); + item = strip_whitespace(item, &_); if (item[0] == '\0') { free(item); } else { @@ -537,7 +537,7 @@ static char **split_directive(char *line, int *argc) { char *item = malloc(i - j + 1); strncpy(item, line + j, i - j); item[i - j] = '\0'; - strip_whitespace(item); + item = strip_whitespace(item, &_); if (*argc == capacity) { capacity++; parts = realloc(parts, sizeof(char *) * capacity); diff --git a/sway/config.c b/sway/config.c index 6d39839d..f1de6080 100644 --- a/sway/config.c +++ b/sway/config.c @@ -186,9 +186,10 @@ bool read_config(FILE *file, bool is_active) { int temp_depth = 0; // Temporary: skip all config sections with depth while (!feof(file)) { + int _; char *line = read_line(file); - strip_comments(line); - strip_whitespace(line); + line = strip_comments(line); + line = strip_whitespace(line, &_); if (!line[0]) { goto _continue; } diff --git a/sway/stringop.c b/sway/stringop.c index 624c8401..1dff97bf 100644 --- a/sway/stringop.c +++ b/sway/stringop.c @@ -1,38 +1,37 @@ +#include "stringop.h" #include #include -#include -#include -#include "stringop.h" #include "string.h" #include "list.h" +#include /* Note: This returns 8 characters for trimmed_start per tab character. */ -void strip_whitespace(char *str) { - int shift = 0; - int bpair = 1; - int in_str = 0, in_ch = 0; - while (*str) { - str[-shift] = str[0]; - if (*str == '"' && !in_ch) { - in_str = !in_str; - } else if (*str == '\'' && !in_str) { - in_ch = !in_ch; - } else if (!in_ch && !in_str) { - if (isblank(*str)) { - if (bpair) { - ++shift; - } - bpair=1; - } else { - bpair = 0; - } +char *strip_whitespace(char *_str, int *trimmed_start) { + *trimmed_start = 0; + if (*_str == '\0') + return _str; + char *strold = _str; + while (*_str == ' ' || *_str == '\t') { + if (*_str == '\t') { + *trimmed_start += 8; + } else { + *trimmed_start += 1; } - ++str; + _str++; } - str[-shift-bpair] = 0; + char *str = malloc(strlen(_str) + 1); + strcpy(str, _str); + free(strold); + int i; + for (i = 0; str[i] != '\0'; ++i); + do { + i--; + } while (i >= 0 && (str[i] == ' ' || str[i] == '\t')); + str[i + 1] = '\0'; + return str; } -void strip_comments(char *str) { +char *strip_comments(char *str) { int in_string = 0, in_character = 0; int i = 0; while (str[i] != '\0') { @@ -48,6 +47,7 @@ void strip_comments(char *str) { } ++i; } + return str; } list_t *split_string(const char *str, const char *delims) { From 23b90d8e69d203697c5548fdd140bf3052749dfa Mon Sep 17 00:00:00 2001 From: Luminarys Date: Tue, 18 Aug 2015 10:39:37 -0500 Subject: [PATCH 04/12] Fixed mouse clicks from triggering a segfault --- sway/handlers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway/handlers.c b/sway/handlers.c index cd97ab43..4980f65c 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -322,7 +322,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct int i = 0; // Do checks to determine if proper keys are being held swayc_t *view = active_workspace->focused; - if (m1_held) { + if (m1_held && view) { if (view->is_floating) { while (keys_pressed[i++]) { if (keys_pressed[i] == config->floating_mod) { @@ -338,7 +338,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } } - } else if (m2_held) { + } else if (m2_held && view) { if (view->is_floating) { while (keys_pressed[i++]) { if (keys_pressed[i] == config->floating_mod) { From 03e83c7ef94e90a78390209af8d9c2a0c0adb237 Mon Sep 17 00:00:00 2001 From: taiyu Date: Tue, 18 Aug 2015 11:22:52 -0700 Subject: [PATCH 05/12] restored fullscreen/focus behavior --- sway/commands.c | 2 +- sway/container.c | 31 ++++++++++++++++--- sway/focus.c | 77 +++++++++++++++++++++++++++++++++++------------- sway/handlers.c | 19 +++++++++++- sway/layout.c | 62 ++++++++++++++++++++++++-------------- sway/workspace.c | 58 +++++++++++++++--------------------- 6 files changed, 166 insertions(+), 83 deletions(-) diff --git a/sway/commands.c b/sway/commands.c index ae0bdbe4..6c3efb3b 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -408,7 +408,7 @@ static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) { return false; } - swayc_t *container = get_focused_container(&root_container); + swayc_t *container = get_focused_view(&root_container); bool current = (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) > 0; wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current); //Resize workspace if going from fullscreen -> notfullscreen diff --git a/sway/container.c b/sway/container.c index c83cd720..62c5bda0 100644 --- a/sway/container.c +++ b/sway/container.c @@ -4,6 +4,7 @@ #include "config.h" #include "container.h" #include "workspace.h" +#include "focus.h" #include "layout.h" #include "log.h" @@ -21,11 +22,26 @@ static swayc_t *new_swayc(enum swayc_types type) { } static void free_swayc(swayc_t *c) { - //TODO does not properly handle containers with children, - //TODO but functions that call this usually check for that + // TODO does not properly handle containers with children, + // TODO but functions that call this usually check for that if (c->children) { + if (c->children->length) { + int i; + for (i = 0; i < c->children->length; ++i) { + free_swayc(c->children->items[i]); + } + } list_free(c->children); } + if (c->floating) { + if (c->floating->length) { + int i; + for (i = 0; i < c->floating->length; ++i) { + free_swayc(c->floating->items[i]); + } + } + list_free(c->floating); + } if (c->parent) { remove_child(c); } @@ -194,7 +210,7 @@ swayc_t *new_floating_view(wlc_handle handle) { list_add(active_workspace->floating, view); view->parent = active_workspace; if (active_workspace->focused == NULL) { - active_workspace->focused = view; + set_focused_container_for(active_workspace, view); } return view; } @@ -291,7 +307,7 @@ swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *da } void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { - if (!container->children || !container->children->length) { + if (!container || !container->children || !container->children->length) { return; } int i; @@ -300,6 +316,13 @@ void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), voi f(child, data); container_map(child, f, data); } + if (container->type == C_WORKSPACE) { + for (i = 0; i < container->floating->length; ++i) { + swayc_t *child = container->floating->items[i]; + f(child, data); + container_map(child, f, data); + } + } } void set_view_visibility(swayc_t *view, void *data) { diff --git a/sway/focus.c b/sway/focus.c index 7e3af56c..628316dd 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -14,11 +14,15 @@ static void update_focus(swayc_t *c) { swayc_t *parent = c->parent; if (parent->focused != c) { switch (c->type) { + // Shouldnt happen case C_ROOT: return; + + // Case where output changes case C_OUTPUT: wlc_output_focus(c->handle); break; - // switching workspaces + + // Case where workspace changes case C_WORKSPACE: if (parent->focused) { swayc_t *ws = parent->focused; @@ -29,10 +33,12 @@ 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); } active_workspace = c; break; + default: case C_VIEW: case C_CONTAINER: @@ -49,6 +55,10 @@ bool move_focus(enum movement_direction direction) { return false; } swayc_t *current = get_focused_container(&root_container); + if (current->type == C_VIEW + && wlc_view_get_state(current->handle) & WLC_BIT_FULLSCREEN) { + return false; + } swayc_t *parent = current->parent; if (direction == MOVE_PARENT) { @@ -128,23 +138,39 @@ void set_focused_container(swayc_t *c) { return; } sway_log(L_DEBUG, "Setting focus to %p:%ld", c, c->handle); - if (c->type != C_ROOT && c->type != C_OUTPUT) { - c->is_focused = true; + + // Find previous focused view, and the new focused view, if they are the same return + swayc_t *focused = get_focused_view(&root_container); + swayc_t *workspace = active_workspace; + if (focused == get_focused_view(c)) { + return; } - swayc_t *prev_view = get_focused_view(&root_container); + + // update container focus from here to root, making necessary changes along + // the way swayc_t *p = c; while (p != &root_container) { update_focus(p); p = p->parent; p->is_focused = false; } - if (!locked_view_focus) { - p = get_focused_view(c); - // Set focus to p - if (p && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { - if (prev_view) { - wlc_view_set_state(prev_view->handle, WLC_BIT_ACTIVATED, false); - } + + // if the workspace is the same, and previous focus is fullscreen, dont + // change focus + if (workspace == active_workspace + && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) { + return; + } + + // get new focused view and set focus to it. + p = get_focused_view(c); + if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { + // unactivate previous focus + if (focused->type == C_VIEW) { + wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); + } + // activate current focus + if (p->type == C_VIEW) { wlc_view_focus(p->handle); wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); } @@ -156,12 +182,25 @@ void set_focused_container_for(swayc_t *a, swayc_t *c) { return; } swayc_t *find = c; - //Ensure that a is an ancestor of c + // Ensure that a is an ancestor of c while (find != a && (find = find->parent)) { if (find == &root_container) { return; } } + // Check if we changing a parent container that will see chnage + bool effective = true; + while (find != &root_container) { + if (find->parent->focused != find) { + effective = false; + } + find = find->parent; + } + if (effective) { + // Go to set_focused_container + set_focused_container(c); + return; + } sway_log(L_DEBUG, "Setting focus for %p:%ld to %p:%ld", a, a->handle, c, c->handle); @@ -173,19 +212,17 @@ void set_focused_container_for(swayc_t *a, swayc_t *c) { p = p->parent; p->is_focused = false; } - if (!locked_view_focus) { - p = get_focused_view(c); - // Set focus to p - if (p) { - wlc_view_focus(p->handle); - wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); - } - } } swayc_t *get_focused_view(swayc_t *parent) { while (parent && parent->type != C_VIEW) { + if (parent->type == C_WORKSPACE && parent->focused == NULL) { + return parent; + } parent = parent->focused; } + if (parent == NULL) { + return active_workspace; + } return parent; } diff --git a/sway/handlers.c b/sway/handlers.c index 4980f65c..ec2b123e 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -106,6 +106,12 @@ static void handle_output_destroyed(wlc_handle output) { if (i < list->length) { destroy_output(list->items[i]); } + if (list->length == 0) { + active_workspace = NULL; + } else { + //switch to other outputs active workspace + workspace_switch(((swayc_t *)root_container.children->items[0])->focused); + } } static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { @@ -320,6 +326,9 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct mouse_origin = *origin; bool changed_floating = false; int i = 0; + if (!active_workspace) { + return false; + } // Do checks to determine if proper keys are being held swayc_t *view = active_workspace->focused; if (m1_held && view) { @@ -400,7 +409,11 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } } if (config->focus_follows_mouse && prev_handle != handle) { - set_focused_container(container_under_pointer()); + //Dont change focus if fullscreen + swayc_t *focused = get_focused_view(view); + if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN)) { + set_focused_container(container_under_pointer()); + } } prev_handle = handle; prev_pos = mouse_origin; @@ -414,6 +427,10 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, uint32_t button, enum wlc_button_state state) { swayc_t *focused = get_focused_container(&root_container); + //dont change focus if fullscreen + if (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) { + return false; + } if (state == WLC_BUTTON_STATE_PRESSED) { sway_log(L_DEBUG, "Mouse button %u pressed", button); if (button == 272) { diff --git a/sway/layout.c b/sway/layout.c index e2ea46a7..105359d2 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -1,11 +1,12 @@ #include #include #include -#include "list.h" -#include "log.h" #include "layout.h" +#include "log.h" +#include "list.h" #include "container.h" #include "workspace.h" +#include "focus.h" swayc_t root_container; @@ -79,9 +80,10 @@ swayc_t *remove_child(swayc_t *child) { } } } + //Set focused to new container if (parent->focused == child) { if (parent->children->length > 0) { - parent->focused = parent->children->items[i?i-1:0]; + set_focused_container_for(parent, parent->children->items[i?i-1:0]); } else { parent->focused = NULL; } @@ -209,26 +211,42 @@ void arrange_windows(swayc_t *container, int width, int height) { if (container->type == C_WORKSPACE) { for (i = 0; i < container->floating->length; ++i) { swayc_t *view = container->floating->items[i]; - // Set the geometry - struct wlc_geometry geometry = { - .origin = { - .x = view->x, - .y = view->y - }, - .size = { - .w = view->width, - .h = view->height + if (view->type == C_VIEW) { + // Set the geometry + struct wlc_geometry geometry = { + .origin = { + .x = view->x, + .y = view->y + }, + .size = { + .w = view->width, + .h = view->height + } + }; + if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) { + swayc_t *parent = view; + while (parent->type != C_OUTPUT) { + parent = parent->parent; + } + geometry.origin.x = 0; + geometry.origin.y = 0; + geometry.size.w = parent->width; + geometry.size.h = parent->height; + wlc_view_set_geometry(view->handle, &geometry); + wlc_view_bring_to_front(view->handle); + } else { + wlc_view_set_geometry(view->handle, &geometry); + view->width = width; + view->height = height; + // Bring the views to the front in order of the list, the list + // will be kept up to date so that more recently focused views + // have higher indexes + // This is conditional on there not being a fullscreen view in the workspace + if (!container->focused + || !(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) { + wlc_view_bring_to_front(view->handle); + } } - }; - wlc_view_set_geometry(view->handle, &geometry); - - // Bring the views to the front in order of the list, the list - // will be kept up to date so that more recently focused views - // have higher indexes - // This is conditional on there not being a fullscreen view in the workspace - if (!container->focused - || !(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) { - wlc_view_bring_to_front(view->handle); } } } diff --git a/sway/workspace.c b/sway/workspace.c index ed545804..05a669fe 100644 --- a/sway/workspace.c +++ b/sway/workspace.c @@ -178,43 +178,37 @@ void workspace_switch(swayc_t *workspace) { return; } sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - - // Remove focus from current view - swayc_t *current = get_focused_view(&root_container); - if (current && current->type == C_VIEW) { - wlc_view_set_state(current->handle, WLC_BIT_ACTIVATED, false); - } - - set_focused_container(workspace); + set_focused_container(get_focused_view(workspace)); + arrange_windows(workspace, -1, -1); active_workspace = workspace; } /* XXX:DEBUG:XXX */ static void container_log(const swayc_t *c) { fprintf(stderr, "focus:%c|", - c->is_focused ? 'F' : //Focused - c == active_workspace ? 'W' : //active workspace - c == &root_container ? 'R' : //root - 'X');//not any others + c->is_focused ? 'F' : //Focused + c == active_workspace ? 'W' : //active workspace + c == &root_container ? 'R' : //root + 'X');//not any others fprintf(stderr,"(%p)",c); fprintf(stderr,"(p:%p)",c->parent); fprintf(stderr,"(f:%p)",c->focused); fprintf(stderr,"(h:%ld)",c->handle); fprintf(stderr,"Type:"); fprintf(stderr, - c->type == C_ROOT ? "Root|" : - c->type == C_OUTPUT ? "Output|" : - c->type == C_WORKSPACE ? "Workspace|" : - c->type == C_CONTAINER ? "Container|" : - c->type == C_VIEW ? "View|" : "Unknown|"); + c->type == C_ROOT ? "Root|" : + c->type == C_OUTPUT ? "Output|" : + c->type == C_WORKSPACE ? "Workspace|" : + c->type == C_CONTAINER ? "Container|" : + c->type == C_VIEW ? "View|" : "Unknown|"); fprintf(stderr,"layout:"); fprintf(stderr, - c->layout == L_NONE ? "NONE|" : - c->layout == L_HORIZ ? "Horiz|": - c->layout == L_VERT ? "Vert|": - c->layout == L_STACKED ? "Stacked|": - c->layout == L_FLOATING ? "Floating|": - "Unknown|"); + c->layout == L_NONE ? "NONE|" : + c->layout == L_HORIZ ? "Horiz|": + c->layout == L_VERT ? "Vert|": + c->layout == L_STACKED ? "Stacked|": + c->layout == L_FLOATING ? "Floating|": + "Unknown|"); fprintf(stderr, "w:%d|h:%d|", c->width, c->height); fprintf(stderr, "x:%d|y:%d|", c->x, c->y); fprintf(stderr, "vis:%c|", c->visible?'t':'f'); @@ -223,30 +217,24 @@ static void container_log(const swayc_t *c) { fprintf(stderr, "children:%d\n",c->children?c->children->length:0); } void layout_log(const swayc_t *c, int depth) { - int i; - int e = c->children?c->children->length:0; - for (i = 0; i < depth; ++i) fputc(' ', stderr); + int i, d; + int e = c->children ? c->children->length : 0; container_log(c); if (e) { - for (i = 0; i < depth; ++i) fputc(' ', stderr); - fprintf(stderr,"(\n"); for (i = 0; i < e; ++i) { + fputc('|',stderr); + for (d = 0; d < depth; ++d) fputc('-', stderr); layout_log(c->children->items[i], depth + 1); } - for (i = 0; i < depth; ++i) fputc(' ', stderr); - fprintf(stderr,")\n"); } if (c->type == C_WORKSPACE) { e = c->floating?c->floating->length:0; - for (i = 0; i < depth; ++i) fputc(' ', stderr); if (e) { - for (i = 0; i < depth; ++i) fputc(' ', stderr); - fprintf(stderr,"(\n"); for (i = 0; i < e; ++i) { + fputc('|',stderr); + for (d = 0; d < depth; ++d) fputc('-', stderr); layout_log(c->floating->items[i], depth + 1); } - for (i = 0; i < depth; ++i) fputc(' ', stderr); - fprintf(stderr,")\n"); } } } From 01c6caced600921eecb00767347caef1b9a282a0 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Tue, 18 Aug 2015 13:52:57 -0500 Subject: [PATCH 06/12] Added in proper focus handling for floating windows --- sway/handlers.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/sway/handlers.c b/sway/handlers.c index ec2b123e..b2ead56c 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -57,20 +57,25 @@ swayc_t *container_under_pointer(void) { } // if workspace, search floating if (lookup->type == C_WORKSPACE) { - len = lookup->floating->length; - for (i = 0; i < len; ++i) { + i = len = lookup->floating->length; + bool got_floating = false; + while (--i > -1) { + sway_log(L_DEBUG, "Checking index %d of floating items", i); if (pointer_test(lookup->floating->items[i], &mouse_origin)) { + sway_log(L_DEBUG, "Got hit for floatin on %d", i); lookup = lookup->floating->items[i]; + got_floating = true; break; } } - if (i < len) { + if (got_floating) { continue; } } // search children len = lookup->children->length; for (i = 0; i < len; ++i) { + sway_log(L_DEBUG, "Checking index %d of standard children", i); if (pointer_test(lookup->children->items[i], &mouse_origin)) { lookup = lookup->children->items[i]; break; @@ -441,6 +446,17 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w } swayc_t *pointer = container_under_pointer(); set_focused_container(pointer); + if (pointer->is_floating) { + int i; + for (i = 0; i < pointer->parent->floating->length; i++) { + if (pointer->parent->floating->items[i] == pointer) { + list_del(pointer->parent->floating, i); + list_add(pointer->parent->floating, pointer); + break; + } + } + arrange_windows(pointer->parent, -1, -1); + } return (pointer && pointer != focused); } else { sway_log(L_DEBUG, "Mouse button %u released", button); From 7756f423c3449e58746dfc66517b389abee8b88f Mon Sep 17 00:00:00 2001 From: Luminarys Date: Tue, 18 Aug 2015 13:54:52 -0500 Subject: [PATCH 07/12] Removed unnecessary debugging lines --- sway/handlers.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sway/handlers.c b/sway/handlers.c index b2ead56c..534b4e4f 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -60,9 +60,7 @@ swayc_t *container_under_pointer(void) { i = len = lookup->floating->length; bool got_floating = false; while (--i > -1) { - sway_log(L_DEBUG, "Checking index %d of floating items", i); if (pointer_test(lookup->floating->items[i], &mouse_origin)) { - sway_log(L_DEBUG, "Got hit for floatin on %d", i); lookup = lookup->floating->items[i]; got_floating = true; break; @@ -75,7 +73,6 @@ swayc_t *container_under_pointer(void) { // search children len = lookup->children->length; for (i = 0; i < len; ++i) { - sway_log(L_DEBUG, "Checking index %d of standard children", i); if (pointer_test(lookup->children->items[i], &mouse_origin)) { lookup = lookup->children->items[i]; break; From be871731e127d695d7c79dff185d55be95e20cf5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 18 Aug 2015 16:16:13 -0400 Subject: [PATCH 08/12] Improve README --- README.md | 45 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 8c312984..664cd1bf 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ # sway -"**S**irCmpwn's **Way**land window manager" +"**S**irCmpwn's **Way**land window manager" is a **work in progress** +i3-compatible window manager for [Wayland](http://wayland.freedesktop.org/). -sway is a **work in progress** i3-compatible window manager for -[Wayland](http://wayland.freedesktop.org/). +[FAQ & wiki](https://github.com/SirCmpwn/sway/wiki) ![](https://sr.ht/qxGE.png) -Chat on #sway on irc.freenode.net - ## Rationale I use i3 on xorg. Wayland is coming, and [i3way](http://i3way.org/) still has @@ -20,44 +18,39 @@ zero lines of source code after two years. ## Installation -### Arch Linux +### From Packages -Install [aur/sway-git](https://aur.archlinux.org/packages/sway-git/). +sway is not supported by many distributions yet. Here's a list of packages +available for you to install: -### Manual +* [Arch Linux](https://aur.archlinux.org/packages/sway-git/). -Dependencies: +### Compiling from Source + +Install dependencies: * cmake * [wlc](https://github.com/Cloudef/wlc) * xwayland * asciidoc -Compiling: +Run these commands: cmake . make - # sudo make install - -Binary shows up in `./bin` (or `/usr/local/bin` if you `make install`). + sudo make install ## Configuration - mkdir ~/.config/sway - cp ~/.config/i3/config ~/.config/sway/ - -Or if you don't already use i3: - - mkdir ~/.config/sway - cp /etc/sway/config ~/.config/sway/ - -Edit to your liking. - -[See also](http://i3wm.org/docs/) +If you already use i3, then copy your i3 config to `~/.config/sway/config` and +it'll work out of the box. Otherwise, copy `/etc/sway/config` to +`~/.config/sway/config`. Run `man 5 sway` for information on the configuration. ## Running +Run this from a tty (instead of starting x): + sway -If you run this while xorg is running, it'll run inside of an x window (useful -for testing). Otherwise, it'll run wayland properly. +If you run it from within x, it will spawn x windows instead of using your +hardware directly (useful for development). From feb0195341b4caabfc3338bb29acf027b1e53780 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 18 Aug 2015 16:18:15 -0400 Subject: [PATCH 09/12] Improve README (more) --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 664cd1bf..a51a0a86 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ "**S**irCmpwn's **Way**land window manager" is a **work in progress** i3-compatible window manager for [Wayland](http://wayland.freedesktop.org/). - -[FAQ & wiki](https://github.com/SirCmpwn/sway/wiki) +Read the [FAQ](https://github.com/SirCmpwn/sway/wiki). ![](https://sr.ht/qxGE.png) From a7c045a520811cc6a58c3ee605af16e9c9a96390 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Tue, 18 Aug 2015 16:24:01 -0500 Subject: [PATCH 10/12] Patched for wlc updates --- sway/layout.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sway/layout.c b/sway/layout.c index 105359d2..a6a241f4 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -152,10 +152,10 @@ void arrange_windows(swayc_t *container, int width, int height) { geometry.origin.y = 0; geometry.size.w = parent->width; geometry.size.h = parent->height; - wlc_view_set_geometry(container->handle, &geometry); + wlc_view_set_geometry(container->handle, 0, &geometry); wlc_view_bring_to_front(container->handle); } else { - wlc_view_set_geometry(container->handle, &geometry); + wlc_view_set_geometry(container->handle, 0, &geometry); container->width = width; container->height = height; } @@ -232,10 +232,10 @@ void arrange_windows(swayc_t *container, int width, int height) { geometry.origin.y = 0; geometry.size.w = parent->width; geometry.size.h = parent->height; - wlc_view_set_geometry(view->handle, &geometry); + wlc_view_set_geometry(view->handle, 0, &geometry); wlc_view_bring_to_front(view->handle); } else { - wlc_view_set_geometry(view->handle, &geometry); + wlc_view_set_geometry(view->handle, 0, &geometry); view->width = width; view->height = height; // Bring the views to the front in order of the list, the list From 5b6e48987204c0d2298dda2d9b30b4208abdd8d5 Mon Sep 17 00:00:00 2001 From: Luminarys Date: Tue, 18 Aug 2015 16:28:24 -0500 Subject: [PATCH 11/12] More patches for wlc compat --- sway/handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/handlers.c b/sway/handlers.c index 534b4e4f..1fe2dc27 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -427,7 +427,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, - uint32_t button, enum wlc_button_state state) { + uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { swayc_t *focused = get_focused_container(&root_container); //dont change focus if fullscreen if (focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) { From faccaf6112d923533512e1dd868ec4bf0d30e1b5 Mon Sep 17 00:00:00 2001 From: minus Date: Tue, 18 Aug 2015 23:38:34 +0200 Subject: [PATCH 12/12] added sway_assert function returns false on a failed assertion in release mode and raises SIGABRT in debug mode --- CMakeLists.txt | 1 - include/log.h | 6 ++++-- sway/log.c | 22 ++++++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba2f8be3..d190cd8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,6 @@ project(sway C) set(CMAKE_C_FLAGS "-g") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/") add_definitions("-Wall") -set(CMAKE_BUILD_TYPE Debug) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake) find_package(XKBCommon REQUIRED) diff --git a/include/log.h b/include/log.h index d35b2a54..44f84940 100644 --- a/include/log.h +++ b/include/log.h @@ -1,5 +1,6 @@ #ifndef _SWAY_LOG_H #define _SWAY_LOG_H +#include typedef enum { L_SILENT = 0, @@ -10,7 +11,8 @@ typedef enum { void init_log(int verbosity); void sway_log_colors(int mode); -void sway_log(int verbosity, char* format, ...) __attribute__((format(printf,2,3))); -void sway_abort(char* format, ...)__attribute__((format(printf,1,2))); +void sway_log(int verbosity, const char* format, ...) __attribute__((format(printf,2,3))); +void sway_abort(const char* format, ...) __attribute__((format(printf,1,2))); +bool sway_assert(bool condition, const char* format, ...) __attribute__((format(printf,2,3))); #endif diff --git a/sway/log.c b/sway/log.c index 8e380ffe..5bd3c8dc 100644 --- a/sway/log.c +++ b/sway/log.c @@ -4,6 +4,7 @@ #include #include #include +#include int colored = 1; int v = 0; @@ -32,7 +33,7 @@ void sway_log_colors(int mode) { colored = (mode == 1) ? 1 : 0; } -void sway_abort(char *format, ...) { +void sway_abort(const char *format, ...) { fprintf(stderr, "ERROR: "); va_list args; va_start(args, format); @@ -42,7 +43,7 @@ void sway_abort(char *format, ...) { exit(1); } -void sway_log(int verbosity, char* format, ...) { +void sway_log(int verbosity, const char* format, ...) { if (verbosity <= v) { int c = verbosity; if (c > sizeof(verbosity_colors) / sizeof(char *)) { @@ -64,3 +65,20 @@ void sway_log(int verbosity, char* format, ...) { fprintf(stderr, "\n"); } } + +bool sway_assert(bool condition, const char* format, ...) { + if (condition) { + return true; + } + +#ifndef NDEBUG + raise(SIGABRT); +#endif + + va_list args; + va_start(args, format); + sway_log(L_ERROR, format, args); + va_end(args); + + return false; +}