From 11321ca2dd355be82175213795d88dcbfd0540ee Mon Sep 17 00:00:00 2001 From: taiyu Date: Tue, 18 Aug 2015 00:28:44 -0700 Subject: changed handling of focus, handling of view by type --- sway/focus.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 sway/focus.c (limited to 'sway/focus.c') diff --git a/sway/focus.c b/sway/focus.c new file mode 100644 index 00000000..2999c6d0 --- /dev/null +++ b/sway/focus.c @@ -0,0 +1,186 @@ +#include + +#include "focus.h" +#include "log.h" +#include "workspace.h" + +bool locked_container_focus = false; +bool locked_view_focus = false; + +//switches parent focus to c. will switch it accordingly +//TODO, everything needs a handle, so we can set front/back position properly +static void update_focus(swayc_t *c) { + //Handle if focus switches + swayc_t *parent = c->parent; + if (parent->focused != c) { + switch (c->type) { + case C_ROOT: return; + case C_OUTPUT: + wlc_output_focus(c->parent->handle); + break; + //switching workspaces + case C_WORKSPACE: + if (parent->focused) { + swayc_t *ws = parent->focused; + //hide visibility of old workspace + uint32_t mask = 1; + container_map(ws, set_view_visibility, &mask); + //set visibility of new workspace + mask = 2; + container_map(c, set_view_visibility, &mask); + wlc_output_set_mask(parent->handle, 2); + destroy_workspace(ws); + } + active_workspace = c; + break; + case C_VIEW: + case C_CONTAINER: + //TODO whatever to do when container changes + //for example, stacked and tabbing change whatever. + break; + } + } + c->parent->focused = c; +} + +bool move_focus(enum movement_direction direction) { + if (locked_container_focus) { + return false; + } + swayc_t *current = get_focused_container(&root_container); + swayc_t *parent = current->parent; + + if (direction == MOVE_PARENT) { + if (parent->type == C_OUTPUT) { + sway_log(L_DEBUG, "Focus cannot move to parent"); + return false; + } else { + sway_log(L_DEBUG, "Moving focus from %p:%ld to %p:%ld", + current, current->handle, parent, parent->handle); + set_focused_container(parent); + return true; + } + } + + while (true) { + sway_log(L_DEBUG, "Moving focus away from %p", current); + + // Test if we can even make a difference here + bool can_move = false; + int diff = 0; + if (direction == MOVE_LEFT || direction == MOVE_RIGHT) { + if (parent->layout == L_HORIZ || parent->type == C_ROOT) { + can_move = true; + diff = direction == MOVE_LEFT ? -1 : 1; + } + } else { + if (parent->layout == L_VERT) { + can_move = true; + diff = direction == MOVE_UP ? -1 : 1; + } + } + sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no"); + if (can_move) { + int i; + for (i = 0; i < parent->children->length; ++i) { + swayc_t *child = parent->children->items[i]; + if (child == current) { + break; + } + } + int desired = i + diff; + sway_log(L_DEBUG, "Moving from %d to %d", i, desired); + if (desired < 0 || desired >= parent->children->length) { + can_move = false; + } else { + swayc_t *newview = parent->children->items[desired]; + set_focused_container(get_focused_view(newview)); + return true; + } + } + if (!can_move) { + sway_log(L_DEBUG, "Can't move at current level, moving up tree"); + current = parent; + parent = parent->parent; + if (!parent) { + // Nothing we can do + return false; + } + } + } +} + +swayc_t *get_focused_container(swayc_t *parent) { + while (parent && !parent->is_focused) { + parent = parent->focused; + } + return parent; +} + +void set_focused_container(swayc_t *c) { + if (locked_container_focus || !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; + } + swayc_t *prev_view = get_focused_view(&root_container); + 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 && p != prev_view && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { + if (prev_view) { + wlc_view_set_state(prev_view->handle, WLC_BIT_ACTIVATED, false); + } + wlc_view_focus(p->handle); + wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); + } + } +} + +void set_focused_container_for(swayc_t *a, swayc_t *c) { + if (locked_container_focus || !c) { + return; + } + swayc_t *find = c; + //Ensure that a is an ancestor of c + while (find != a && (find = find->parent)) { + if (find == &root_container) { + return; + } + } + + sway_log(L_DEBUG, "Setting focus for %p:%ld to %p:%ld", + a, a->handle, c, c->handle); + + c->is_focused = true; + swayc_t *p = c; + while (p != a) { + 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_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) { + parent = parent->focused; + } + return parent; +} + -- cgit v1.2.3 From 63bc0d3b5451f4668186c98a1f283f3e0a104cfe Mon Sep 17 00:00:00 2001 From: taiyu Date: Tue, 18 Aug 2015 02:46:14 -0700 Subject: more changes --- include/layout.h | 2 +- sway/container.c | 13 +++++++------ sway/focus.c | 2 +- sway/handlers.c | 6 +++--- sway/layout.c | 9 +++++++-- 5 files changed, 19 insertions(+), 13 deletions(-) (limited to 'sway/focus.c') diff --git a/include/layout.h b/include/layout.h index a7f43fda..26d00ce4 100644 --- a/include/layout.h +++ b/include/layout.h @@ -13,7 +13,7 @@ void add_child(swayc_t *parent, swayc_t *child); //Returns parent container which needs to be rearranged. swayc_t *add_sibling(swayc_t *sibling, swayc_t *child); swayc_t *replace_child(swayc_t *child, swayc_t *new_child); -swayc_t *remove_child(swayc_t *parent, swayc_t *child); +swayc_t *remove_child(swayc_t *child); //Layout void arrange_windows(swayc_t *container, int width, int height); diff --git a/sway/container.c b/sway/container.c index 67132a48..2b9f7554 100644 --- a/sway/container.c +++ b/sway/container.c @@ -27,10 +27,7 @@ static void free_swayc(swayc_t *c) { list_free(c->children); } if (c->parent) { - if (c->parent->focused == c) { - c->parent->focused = NULL; - } - remove_child(c->parent, c); + remove_child(c); } if (c->name) { free(c->name); @@ -118,6 +115,11 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) { //reorder focus cont->focused = workspace->focused; workspace->focused = cont; + //set all children focu to container + int i; + for (i = 0; i < workspace->children->length; ++i) { + ((swayc_t *)workspace->children->items[i])->parent = cont; + } //Swap children list_t *tmp_list = workspace->children; workspace->children = cont->children; @@ -204,7 +206,7 @@ swayc_t *destroy_output(swayc_t *output) { if (output->children->length == 0) { //TODO move workspaces to other outputs } - sway_log(L_DEBUG, "OUTPUT: Destroying output '%u'", (unsigned int)output->handle); + sway_log(L_DEBUG, "OUTPUT: Destroying output '%lu'", output->handle); free_swayc(output); return &root_container; } @@ -246,7 +248,6 @@ swayc_t *destroy_view(swayc_t *view) { if (parent->type == C_CONTAINER) { return destroy_container(parent); } - return parent; } diff --git a/sway/focus.c b/sway/focus.c index 2999c6d0..4f57f252 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -135,7 +135,7 @@ void set_focused_container(swayc_t *c) { if (!locked_view_focus) { p = get_focused_view(c); //Set focus to p - if (p && p != prev_view && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { + 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); } diff --git a/sway/handlers.c b/sway/handlers.c index 2a5113cc..24e8e014 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -38,6 +38,9 @@ static bool pointer_test(swayc_t *view, void *_origin) { swayc_t *container_under_pointer(void) { //root.output->workspace + if (!root_container.focused || !root_container.focused->focused) { + return NULL; + } swayc_t *lookup = root_container.focused->focused; //Case of empty workspace if (lookup->children == 0) { @@ -174,9 +177,6 @@ static void handle_view_destroyed(wlc_handle handle) { if (view) { swayc_t *parent = destroy_view(view); arrange_windows(parent, -1, -1); - if (!focused || focused == view) { - set_focused_container(container_under_pointer()); - } } break; //takes keyboard focus diff --git a/sway/layout.c b/sway/layout.c index de7ef370..8ff5c4b7 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -60,8 +60,9 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) { return parent; } -swayc_t *remove_child(swayc_t *parent, swayc_t *child) { +swayc_t *remove_child(swayc_t *child) { int i; + swayc_t *parent = child->parent; // Special case for floating views if (child->is_floating) { for (i = 0; i < parent->floating->length; ++i) { @@ -79,7 +80,11 @@ swayc_t *remove_child(swayc_t *parent, swayc_t *child) { } } if (parent->focused == child) { - parent->focused = NULL; + if (parent->children->length > 0) { + parent->focused = parent->children->items[i?i-1:0]; + } else { + parent->focused = NULL; + } } return parent; } -- cgit v1.2.3 From b132f67e7bb5017c73658cec8d297060033890e8 Mon Sep 17 00:00:00 2001 From: taiyu Date: Tue, 18 Aug 2015 03:48:41 -0700 Subject: minor fixes --- include/config.h | 8 ++++---- sway/config.c | 2 +- sway/focus.c | 8 +++++++- sway/handlers.c | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) (limited to 'sway/focus.c') diff --git a/include/config.h b/include/config.h index b9511aac..9243bf35 100644 --- a/include/config.h +++ b/include/config.h @@ -33,17 +33,17 @@ struct sway_config { list_t *cmd_queue; list_t *workspace_outputs; struct sway_mode *current_mode; - uint32_t floating_mod; + uint32_t floating_mod; // Flags bool focus_follows_mouse; bool mouse_warping; - bool active; - bool failed; + bool active; + bool failed; bool reloading; }; -bool load_config(); +bool load_config(void); bool read_config(FILE *file, bool is_active); char *do_var_replacement(struct sway_config *config, char *str); diff --git a/sway/config.c b/sway/config.c index f06d55f8..4125f4cd 100644 --- a/sway/config.c +++ b/sway/config.c @@ -126,7 +126,7 @@ static char* get_config_path() { return NULL; } -bool load_config() { +bool load_config(void) { sway_log(L_INFO, "Loading config"); char *path = get_config_path(); diff --git a/sway/focus.c b/sway/focus.c index 4f57f252..14d27184 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -33,10 +33,11 @@ static void update_focus(swayc_t *c) { } active_workspace = c; break; + default: case C_VIEW: case C_CONTAINER: //TODO whatever to do when container changes - //for example, stacked and tabbing change whatever. + //for example, stacked and tabbing change stuff. break; } } @@ -114,6 +115,11 @@ swayc_t *get_focused_container(swayc_t *parent) { while (parent && !parent->is_focused) { parent = parent->focused; } + //just incase + if (parent == NULL) { + sway_log(L_DEBUG, "get_focused_container unable to find container"); + return active_workspace; + } return parent; } diff --git a/sway/handlers.c b/sway/handlers.c index 24e8e014..0157d466 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -252,7 +252,7 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, uint32_t key, uint32_t sym, enum wlc_key_state state) { enum { QSIZE = 32 }; - if (locked_view_focus) { + if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { return false; } static uint8_t head = 0; -- cgit v1.2.3