From da79bd65de159730b1468e466b2c31d46fcc0238 Mon Sep 17 00:00:00 2001 From: taiyu Date: Thu, 27 Aug 2015 20:32:56 -0700 Subject: [PATCH 1/4] use previous outputs --- include/container.h | 1 + sway/container.c | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/container.h b/include/container.h index 6c0de104..29f75f45 100644 --- a/include/container.h +++ b/include/container.h @@ -94,6 +94,7 @@ swayc_t *swayc_focus_by_layout(swayc_t *container, enum swayc_layouts); swayc_t *swayc_by_handle(wlc_handle handle); +swayc_t *swayc_by_name(const char *name); swayc_t *swayc_active_output(void); swayc_t *swayc_active_workspace(void); swayc_t *swayc_active_workspace_for(swayc_t *view); diff --git a/sway/container.c b/sway/container.c index abbd5504..416b8db8 100644 --- a/sway/container.c +++ b/sway/container.c @@ -57,6 +57,19 @@ static void free_swayc(swayc_t *cont) { 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); + // Find current outputs to see if this already exists + { + int i, len = root_container.children->length; + for (i = 0; i < len; ++i) { + swayc_t *op = root_container.children->items[i]; + const char *op_name = op->name; + if (op_name && name && strcmp(op_name, name) == 0) { + sway_log(L_DEBUG, "restoring output %lu:%s", handle, op_name); + return op; + } + } + } + sway_log(L_DEBUG, "Added output %lu:%s", handle, name); struct output_config *oc = NULL; @@ -329,7 +342,7 @@ swayc_t *destroy_workspace(swayc_t *workspace) { // Do not destroy if there are children if (workspace->children->length == 0 && workspace->floating->length == 0) { - sway_log(L_DEBUG, "'%s'", workspace->name); + sway_log(L_DEBUG, "destroying '%s'", workspace->name); swayc_t *parent = workspace->parent; free_swayc(workspace); return parent; @@ -396,6 +409,17 @@ swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *dat return NULL; } +static bool test_name(swayc_t *view, void *data) { + if (!view && !view->name) { + return false; + } + return strcmp(view->name, data) == 0; +} + +swayc_t *swayc_by_name(const char *name) { + return swayc_by_test(&root_container, test_name, (void *)name); +} + swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) { if (!ASSERT_NONNULL(container)) { return NULL; From dfe0dda8d02a3cce27f3fa68e00293e32e90b6a7 Mon Sep 17 00:00:00 2001 From: taiyu Date: Thu, 27 Aug 2015 20:55:48 -0700 Subject: [PATCH 2/4] proper visibility update --- sway/container.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/sway/container.c b/sway/container.c index 416b8db8..d6d27033 100644 --- a/sway/container.c +++ b/sway/container.c @@ -342,7 +342,7 @@ swayc_t *destroy_workspace(swayc_t *workspace) { // Do not destroy if there are children if (workspace->children->length == 0 && workspace->floating->length == 0) { - sway_log(L_DEBUG, "destroying '%s'", workspace->name); + sway_log(L_DEBUG, "destroying workspace '%s'", workspace->name); swayc_t *parent = workspace->parent; free_swayc(workspace); return parent; @@ -600,7 +600,22 @@ void set_view_visibility(swayc_t *view, void *data) { } void update_visibility(swayc_t *container) { - swayc_t *ws = swayc_active_workspace_for(container); + if (!container) { + return; + } + swayc_t *ws; + if (container->type == C_ROOT || container->type == C_OUTPUT) { + int i, len = container->children->length; + for (i = 0; i < len; ++i) { + update_visibility(container->children->items[i]); + } + return; + } else if (container->type == C_WORKSPACE) { + container->visible = container->parent->focused == container; + ws = container; + } else { + ws = swayc_active_workspace_for(container); + } // TODO better visibility setting bool visible = (ws->parent->focused == ws); sway_log(L_DEBUG, "Setting visibility of container %p to %s", container, visible ? "visible" : "invisible"); From 5678d824e43d1ae2e2abaa1bc9a03391a4683a86 Mon Sep 17 00:00:00 2001 From: taiyu Date: Thu, 27 Aug 2015 23:18:28 -0700 Subject: [PATCH 3/4] update visibility + container info functions --- include/container.h | 4 ++ sway/container.c | 104 ++++++++++++++++++++++++++------------------ sway/focus.c | 20 ++++----- sway/layout.c | 2 +- 4 files changed, 77 insertions(+), 53 deletions(-) diff --git a/include/container.h b/include/container.h index 29f75f45..cfb2e868 100644 --- a/include/container.h +++ b/include/container.h @@ -103,6 +103,10 @@ swayc_t *swayc_active_workspace_for(swayc_t *view); bool swayc_is_fullscreen(swayc_t *view); bool swayc_is_active(swayc_t *view); +// Is `parent` the parent of `child` +bool swayc_is_parent_of(swayc_t *parent, swayc_t *child); +// Is `child` a child of `parent` +bool swayc_is_child_of(swayc_t *child, swayc_t *parent); // Mapping functions diff --git a/sway/container.c b/sway/container.c index d6d27033..19a40090 100644 --- a/sway/container.c +++ b/sway/container.c @@ -547,6 +547,20 @@ bool swayc_is_active(swayc_t *view) { return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_ACTIVATED); } +bool swayc_is_parent_of(swayc_t *parent, swayc_t *child) { + while (child != &root_container) { + child = child->parent; + if (child == parent) { + return true; + } + } + return false; +} + +bool swayc_is_child_of(swayc_t *child, swayc_t *parent) { + return swayc_is_parent_of(parent, child); +} + // Mapping void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) { @@ -568,58 +582,64 @@ void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), voi } } -void set_view_visibility(swayc_t *view, void *data) { - if (!ASSERT_NONNULL(view)) { - return; +void update_visibility_output(swayc_t *container, wlc_handle output) { + // Inherit visibility + swayc_t *parent = container->parent; + container->visible = parent->visible; + // special cases where visibility depends on focus + if (parent->type == C_OUTPUT + || parent->layout == L_TABBED + || parent->layout == L_STACKED) { + container->visible = parent->focused == container; } - // TODO add something like this. -// if (container->type == C_ROOT) { -// container->visible = true; -// } else { -// // Inherit visibility -// swayc_t *parent = container->parent; -// container->visible = parent->visible; -// // special cases where visibility depends on focus -// if (parent->type == C_OUTPUT || parent->layout == L_TABBED || -// parent->layout == L_STACKED) { -// container->visible = parent->focused == container; -// } -// } - bool visible = *(bool *)data; - if (view->type == C_VIEW) { - wlc_view_set_output(view->handle, swayc_parent_by_type(view, C_OUTPUT)->handle); - wlc_view_set_mask(view->handle, visible ? VISIBLE : 0); - if (visible) { - wlc_view_bring_to_front(view->handle); + // Set visibility and output for view + if (container->type == C_VIEW) { + wlc_view_set_output(container->handle, output); + wlc_view_set_mask(container->handle, container->visible ? VISIBLE : 0); + if (container->visible) { + wlc_view_bring_to_front(container->handle); } else { - wlc_view_send_to_back(view->handle); + wlc_view_send_to_back(container->handle); + } + } + // Update visibility for children + else if (container->children) { + int i, len = container->children->length; + for (i = 0; i < len; ++i) { + update_visibility_output(container->children->items[i], output); } } - view->visible = visible; - sway_log(L_DEBUG, "Container %p is now %s", view, visible ? "visible" : "invisible"); } void update_visibility(swayc_t *container) { - if (!container) { - return; - } - swayc_t *ws; - if (container->type == C_ROOT || container->type == C_OUTPUT) { - int i, len = container->children->length; - for (i = 0; i < len; ++i) { - update_visibility(container->children->items[i]); + if (!container) return; + switch (container->type) { + case C_ROOT: + container->visible = true; + if (container->children) { + int i, len = container->children->length; + for (i = 0; i < len; ++i) { + update_visibility(container->children->items[i]); + } } return; - } else if (container->type == C_WORKSPACE) { - container->visible = container->parent->focused == container; - ws = container; - } else { - ws = swayc_active_workspace_for(container); + + case C_OUTPUT: + container->visible = true; + if (container->children) { + int i, len = container->children->length; + for (i = 0; i < len; ++i) { + update_visibility_output(container->children->items[i], container->handle); + } + } + return; + + default: + { + swayc_t *op = swayc_parent_by_type(container, C_OUTPUT); + update_visibility_output(container, op->handle); + } } - // TODO better visibility setting - bool visible = (ws->parent->focused == ws); - sway_log(L_DEBUG, "Setting visibility of container %p to %s", container, visible ? "visible" : "invisible"); - container_map(ws, set_view_visibility, &visible); } void reset_gaps(swayc_t *view, void *data) { diff --git a/sway/focus.c b/sway/focus.c index f7b55b27..45108a11 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -14,6 +14,10 @@ static void update_focus(swayc_t *c) { // Handle if focus switches swayc_t *parent = c->parent; if (parent->focused != c) { + // Get previous focus + swayc_t *prev = parent->focused; + // Set new focus + parent->focused = c; switch (c->type) { // Shouldnt happen case C_ROOT: return; @@ -25,16 +29,13 @@ static void update_focus(swayc_t *c) { // Case where workspace changes case C_WORKSPACE: - if (parent->focused) { - swayc_t *ws = parent->focused; - // hide visibility of old workspace - bool visible = false; - container_map(ws, set_view_visibility, &visible); - // set visibility of new workspace - visible = true; - container_map(c, set_view_visibility, &visible); - destroy_workspace(ws); + if (prev) { + // update visibility of old workspace + update_visibility(prev); + destroy_workspace(prev); } + // Update visibility of newly focused workspace + update_visibility(c); break; default: @@ -44,7 +45,6 @@ static void update_focus(swayc_t *c) { // for example, stacked and tabbing change stuff. break; } - c->parent->focused = c; } } diff --git a/sway/layout.c b/sway/layout.c index 5ade5e63..f04007ed 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -221,7 +221,7 @@ void move_container(swayc_t *container,swayc_t* root,enum movement_direction dir } void move_container_to(swayc_t* container, swayc_t* destination) { - if (container == destination) { + if (container == destination && swayc_is_parent_of(container, destination)) { return; } swayc_t *parent = remove_child(container); From 4757ea6a1212dab6ee82421a20b152d1f16e44fb Mon Sep 17 00:00:00 2001 From: taiyu Date: Thu, 27 Aug 2015 23:42:26 -0700 Subject: [PATCH 4/4] forgot visibility of floating containers --- sway/container.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sway/container.c b/sway/container.c index 19a40090..d60aa6ff 100644 --- a/sway/container.c +++ b/sway/container.c @@ -603,10 +603,18 @@ void update_visibility_output(swayc_t *container, wlc_handle output) { } } // Update visibility for children - else if (container->children) { - int i, len = container->children->length; - for (i = 0; i < len; ++i) { - update_visibility_output(container->children->items[i], output); + else { + if (container->children) { + int i, len = container->children->length; + for (i = 0; i < len; ++i) { + update_visibility_output(container->children->items[i], output); + } + } + if (container->floating) { + int i, len = container->floating->length; + for (i = 0; i < len; ++i) { + update_visibility_output(container->floating->items[i], output); + } } } }