diff options
author | Half-Shot <half-shot@molrams.com> | 2015-08-18 21:42:28 +0100 |
---|---|---|
committer | Half-Shot <half-shot@molrams.com> | 2015-08-18 21:42:28 +0100 |
commit | f314d951039031fd7f0bd8772b6916587ebb0846 (patch) | |
tree | 7287a3f02593906ae23aec234fbe6e2ca1b06d1d /sway | |
parent | d6ab5e481be2faa0e911d0b3109ae01fe79eb25f (diff) | |
parent | feb0195341b4caabfc3338bb29acf027b1e53780 (diff) |
Merge branch 'master' of https://github.com/SirCmpwn/sway
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 8 | ||||
-rw-r--r-- | sway/config.c | 5 | ||||
-rw-r--r-- | sway/container.c | 51 | ||||
-rw-r--r-- | sway/focus.c | 79 | ||||
-rw-r--r-- | sway/handlers.c | 42 | ||||
-rw-r--r-- | sway/layout.c | 62 | ||||
-rw-r--r-- | sway/stringop.c | 52 | ||||
-rw-r--r-- | sway/workspace.c | 55 |
8 files changed, 241 insertions, 113 deletions
diff --git a/sway/commands.c b/sway/commands.c index 19704064..9a3ea5d6 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -413,7 +413,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 @@ -512,7 +512,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; @@ -525,7 +525,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 { @@ -543,7 +543,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/container.c b/sway/container.c index e679e823..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); } @@ -37,6 +53,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 +78,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; } @@ -186,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; } @@ -206,6 +230,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; @@ -271,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; @@ -280,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 99cb2570..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->parent->handle); + 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 cd97ab43..534b4e4f 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -57,14 +57,16 @@ 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) { if (pointer_test(lookup->floating->items[i], &mouse_origin)) { lookup = lookup->floating->items[i]; + got_floating = true; break; } } - if (i < len) { + if (got_floating) { continue; } } @@ -106,6 +108,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,9 +328,12 @@ 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) { + if (m1_held && view) { if (view->is_floating) { while (keys_pressed[i++]) { if (keys_pressed[i] == config->floating_mod) { @@ -338,7 +349,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) { @@ -400,7 +411,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 +429,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) { @@ -424,6 +443,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); 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 <stdlib.h> #include <stdbool.h> #include <wlc/wlc.h> -#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/stringop.c b/sway/stringop.c index 00cc32b8..1dff97bf 100644 --- a/sway/stringop.c +++ b/sway/stringop.c @@ -1,38 +1,37 @@ +#include "stringop.h" #include <stdlib.h> #include <stdio.h> -#include <strings.h> -#include <ctype.h> -#include "stringop.h" #include "string.h" #include "list.h" +#include <strings.h> /* 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') { @@ -41,13 +40,14 @@ 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; } } ++i; } + return str; } list_t *split_string(const char *str, const char *delims) { diff --git a/sway/workspace.c b/sway/workspace.c index bc0fa2c8..05a669fe 100644 --- a/sway/workspace.c +++ b/sway/workspace.c @@ -174,36 +174,41 @@ void workspace_prev() { } void workspace_switch(swayc_t *workspace) { - set_focused_container(workspace); + if (!workspace) { + return; + } + sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); + 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'); @@ -212,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"); } } } |