Merge pull request #145 from taiyu-len/master

use previous output containers
This commit is contained in:
Drew DeVault 2015-08-28 07:41:36 -04:00
commit 9751fff5c5
4 changed files with 114 additions and 42 deletions

View file

@ -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_handle(wlc_handle handle);
swayc_t *swayc_by_name(const char *name);
swayc_t *swayc_active_output(void); swayc_t *swayc_active_output(void);
swayc_t *swayc_active_workspace(void); swayc_t *swayc_active_workspace(void);
swayc_t *swayc_active_workspace_for(swayc_t *view); swayc_t *swayc_active_workspace_for(swayc_t *view);
@ -102,6 +103,10 @@ swayc_t *swayc_active_workspace_for(swayc_t *view);
bool swayc_is_fullscreen(swayc_t *view); bool swayc_is_fullscreen(swayc_t *view);
bool swayc_is_active(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 // Mapping functions

View file

@ -57,6 +57,19 @@ static void free_swayc(swayc_t *cont) {
swayc_t *new_output(wlc_handle handle) { swayc_t *new_output(wlc_handle handle) {
const struct wlc_size *size = wlc_output_get_resolution(handle); const struct wlc_size *size = wlc_output_get_resolution(handle);
const char *name = wlc_output_get_name(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); sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
struct output_config *oc = NULL; struct output_config *oc = NULL;
@ -329,7 +342,7 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
// Do not destroy if there are children // Do not destroy if there are children
if (workspace->children->length == 0 && workspace->floating->length == 0) { if (workspace->children->length == 0 && workspace->floating->length == 0) {
sway_log(L_DEBUG, "'%s'", workspace->name); sway_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
swayc_t *parent = workspace->parent; swayc_t *parent = workspace->parent;
free_swayc(workspace); free_swayc(workspace);
return parent; return parent;
@ -396,6 +409,17 @@ swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *dat
return NULL; 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) { swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
if (!ASSERT_NONNULL(container)) { if (!ASSERT_NONNULL(container)) {
return NULL; return NULL;
@ -523,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); 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 // 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) {
@ -544,43 +582,72 @@ void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), voi
} }
} }
void set_view_visibility(swayc_t *view, void *data) { void update_visibility_output(swayc_t *container, wlc_handle output) {
if (!ASSERT_NONNULL(view)) { // Inherit visibility
return; 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. // Set visibility and output for view
// if (container->type == C_ROOT) { if (container->type == C_VIEW) {
// container->visible = true; wlc_view_set_output(container->handle, output);
// } else { wlc_view_set_mask(container->handle, container->visible ? VISIBLE : 0);
// // Inherit visibility if (container->visible) {
// swayc_t *parent = container->parent; wlc_view_bring_to_front(container->handle);
// 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);
} else { } 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);
}
}
if (container->floating) {
int i, len = container->floating->length;
for (i = 0; i < len; ++i) {
update_visibility_output(container->floating->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) { void update_visibility(swayc_t *container) {
swayc_t *ws = swayc_active_workspace_for(container); if (!container) return;
// TODO better visibility setting switch (container->type) {
bool visible = (ws->parent->focused == ws); case C_ROOT:
sway_log(L_DEBUG, "Setting visibility of container %p to %s", container, visible ? "visible" : "invisible"); container->visible = true;
container_map(ws, set_view_visibility, &visible); if (container->children) {
int i, len = container->children->length;
for (i = 0; i < len; ++i) {
update_visibility(container->children->items[i]);
}
}
return;
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);
}
}
} }
void reset_gaps(swayc_t *view, void *data) { void reset_gaps(swayc_t *view, void *data) {

View file

@ -14,6 +14,10 @@ static void update_focus(swayc_t *c) {
// Handle if focus switches // Handle if focus switches
swayc_t *parent = c->parent; swayc_t *parent = c->parent;
if (parent->focused != c) { if (parent->focused != c) {
// Get previous focus
swayc_t *prev = parent->focused;
// Set new focus
parent->focused = c;
switch (c->type) { switch (c->type) {
// Shouldnt happen // Shouldnt happen
case C_ROOT: return; case C_ROOT: return;
@ -25,16 +29,13 @@ static void update_focus(swayc_t *c) {
// Case where workspace changes // Case where workspace changes
case C_WORKSPACE: case C_WORKSPACE:
if (parent->focused) { if (prev) {
swayc_t *ws = parent->focused; // update visibility of old workspace
// hide visibility of old workspace update_visibility(prev);
bool visible = false; destroy_workspace(prev);
container_map(ws, set_view_visibility, &visible);
// set visibility of new workspace
visible = true;
container_map(c, set_view_visibility, &visible);
destroy_workspace(ws);
} }
// Update visibility of newly focused workspace
update_visibility(c);
break; break;
default: default:
@ -44,7 +45,6 @@ static void update_focus(swayc_t *c) {
// for example, stacked and tabbing change stuff. // for example, stacked and tabbing change stuff.
break; break;
} }
c->parent->focused = c;
} }
} }

View file

@ -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) { void move_container_to(swayc_t* container, swayc_t* destination) {
if (container == destination) { if (container == destination && swayc_is_parent_of(container, destination)) {
return; return;
} }
swayc_t *parent = remove_child(container); swayc_t *parent = remove_child(container);