proper view ordering

This commit is contained in:
taiyu 2015-08-20 16:12:35 -07:00
parent cc5713aee6
commit b93f068611
6 changed files with 269 additions and 209 deletions

View file

@ -82,6 +82,7 @@ swayc_t *destroy_view(swayc_t *view);
swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types); swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types);
swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts); swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts);
swayc_t *swayc_by_handle(wlc_handle handle);
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data); swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data);
void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *); void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);

View file

@ -26,7 +26,6 @@ void focus_view(swayc_t *view);
void focus_view_for(swayc_t *ancestor, swayc_t *container); void focus_view_for(swayc_t *ancestor, swayc_t *container);
swayc_t *get_focused_container(swayc_t *parent); swayc_t *get_focused_container(swayc_t *parent);
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent);
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir); swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir);
#endif #endif

View file

@ -11,11 +11,17 @@
#define ASSERT_NONNULL(PTR) \ #define ASSERT_NONNULL(PTR) \
sway_assert (PTR, "%s: " #PTR "must be non-null", __func__) sway_assert (PTR, "%s: " #PTR "must be non-null", __func__)
static swayc_t *new_swayc(enum swayc_types type) { static swayc_t *new_swayc(enum swayc_types type, wlc_handle handle) {
swayc_t *c = calloc(1, sizeof(swayc_t)); swayc_t *c = calloc(1, sizeof(swayc_t));
c->handle = -1; if (handle > 0) {
c->handle = handle;
wlc_handle_set_user_data(handle, c);
} else {
c->handle = 0;
}
c->layout = L_NONE; c->layout = L_NONE;
c->type = type; c->type = type;
c->gaps = 0;
if (type != C_VIEW) { if (type != C_VIEW) {
c->children = create_list(); c->children = create_list();
} }
@ -26,6 +32,9 @@ static void free_swayc(swayc_t *cont) {
if (!ASSERT_NONNULL(cont)) { if (!ASSERT_NONNULL(cont)) {
return; return;
} }
if (cont->handle > 0) {
wlc_handle_set_user_data(cont->handle, 0);
}
// TODO does not properly handle containers with children, // TODO does not properly handle containers with children,
// TODO but functions that call this usually check for that // TODO but functions that call this usually check for that
if (cont->children) { if (cont->children) {
@ -58,7 +67,7 @@ static void free_swayc(swayc_t *cont) {
// New containers // New containers
static bool workspace_test(swayc_t *view, void *name) { static bool workspace_test(swayc_t *view, void *name) {
return strcasecmp(view->name, (char *)name) == 0; return strcasecmp(view->name, name) == 0;
} }
swayc_t *new_output(wlc_handle handle) { swayc_t *new_output(wlc_handle handle) {
@ -66,12 +75,10 @@ swayc_t *new_output(wlc_handle handle) {
const char *name = wlc_output_get_name(handle); const char *name = wlc_output_get_name(handle);
sway_log(L_DEBUG, "Added output %lu:%s", handle, name); sway_log(L_DEBUG, "Added output %lu:%s", handle, name);
swayc_t *output = new_swayc(C_OUTPUT); swayc_t *output = new_swayc(C_OUTPUT, handle);
output->width = size->w; output->width = size->w;
output->height = size->h; output->height = size->h;
output->handle = handle;
output->name = name ? strdup(name) : NULL; output->name = name ? strdup(name) : NULL;
output->gaps = config->gaps_outer + config->gaps_inner / 2;
add_child(&root_container, output); add_child(&root_container, output);
@ -112,13 +119,14 @@ swayc_t *new_workspace(swayc_t *output, const char *name) {
return NULL; return NULL;
} }
sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle); sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle);
swayc_t *workspace = new_swayc(C_WORKSPACE); swayc_t *workspace = new_swayc(C_WORKSPACE, 0);
workspace->layout = L_HORIZ; // TODO: default layout workspace->layout = L_HORIZ; // TODO: default layout
workspace->x = output->x; workspace->x = output->x;
workspace->y = output->y; workspace->y = output->y;
workspace->width = output->width; workspace->width = output->width;
workspace->height = output->height; workspace->height = output->height;
workspace->gaps = config->gaps_outer;
workspace->name = strdup(name); workspace->name = strdup(name);
workspace->visible = true; workspace->visible = true;
workspace->floating = create_list(); workspace->floating = create_list();
@ -131,7 +139,7 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
if (!ASSERT_NONNULL(child)) { if (!ASSERT_NONNULL(child)) {
return NULL; return NULL;
} }
swayc_t *cont = new_swayc(C_CONTAINER); swayc_t *cont = new_swayc(C_CONTAINER, 0);
sway_log(L_DEBUG, "creating container %p around %p", cont, child); sway_log(L_DEBUG, "creating container %p around %p", cont, child);
@ -177,11 +185,10 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
return NULL; return NULL;
} }
const char *title = wlc_view_get_title(handle); const char *title = wlc_view_get_title(handle);
swayc_t *view = new_swayc(C_VIEW); swayc_t *view = new_swayc(C_VIEW, handle);
sway_log(L_DEBUG, "Adding new view %lu:%s to container %p %d", sway_log(L_DEBUG, "Adding new view %lu:%s to container %p %d",
handle, title, sibling, sibling ? sibling->type : 0); handle, title, sibling, sibling ? sibling->type : 0);
// Setup values // Setup values
view->handle = handle;
view->name = title ? strdup(title) : NULL; view->name = title ? strdup(title) : NULL;
view->visible = true; view->visible = true;
view->is_focused = true; view->is_focused = true;
@ -208,11 +215,10 @@ swayc_t *new_view(swayc_t *sibling, wlc_handle handle) {
swayc_t *new_floating_view(wlc_handle handle) { swayc_t *new_floating_view(wlc_handle handle) {
const char *title = wlc_view_get_title(handle); const char *title = wlc_view_get_title(handle);
swayc_t *view = new_swayc(C_VIEW); swayc_t *view = new_swayc(C_VIEW, handle);
sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view", sway_log(L_DEBUG, "Adding new view %lu:%x:%s as a floating view",
handle, wlc_view_get_type(handle), title); handle, wlc_view_get_type(handle), title);
// Setup values // Setup values
view->handle = handle;
view->name = title ? strdup(title) : NULL; view->name = title ? strdup(title) : NULL;
view->visible = true; view->visible = true;
@ -241,7 +247,8 @@ swayc_t *new_floating_view(wlc_handle handle) {
// Destroy container // Destroy container
swayc_t *destroy_output(swayc_t *output) { #define DESTROY_FUNC __attribute__((nonnull)) swayc_t *
DESTROY_FUNC destroy_output(swayc_t *output) {
if (!ASSERT_NONNULL(output)) { if (!ASSERT_NONNULL(output)) {
return NULL; return NULL;
} }
@ -253,7 +260,7 @@ swayc_t *destroy_output(swayc_t *output) {
return &root_container; return &root_container;
} }
swayc_t *destroy_workspace(swayc_t *workspace) { DESTROY_FUNC destroy_workspace(swayc_t *workspace) {
if (!ASSERT_NONNULL(workspace)) { if (!ASSERT_NONNULL(workspace)) {
return NULL; return NULL;
} }
@ -276,7 +283,7 @@ swayc_t *destroy_workspace(swayc_t *workspace) {
return NULL; return NULL;
} }
swayc_t *destroy_container(swayc_t *container) { DESTROY_FUNC destroy_container(swayc_t *container) {
if (!ASSERT_NONNULL(container)) { if (!ASSERT_NONNULL(container)) {
return NULL; return NULL;
} }
@ -289,7 +296,7 @@ swayc_t *destroy_container(swayc_t *container) {
return container; return container;
} }
swayc_t *destroy_view(swayc_t *view) { DESTROY_FUNC destroy_view(swayc_t *view) {
if (!ASSERT_NONNULL(view)) { if (!ASSERT_NONNULL(view)) {
return NULL; return NULL;
} }
@ -303,6 +310,7 @@ swayc_t *destroy_view(swayc_t *view) {
} }
return parent; return parent;
} }
#undef DESTROY_FUNC
// Container lookup // Container lookup
@ -332,6 +340,11 @@ swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) {
return container; return container;
} }
swayc_t *swayc_by_handle(wlc_handle handle) {
return wlc_handle_get_user_data(handle);
}
swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) { swayc_t *find_container(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
if (!container->children) { if (!container->children) {
return NULL; return NULL;
@ -398,10 +411,11 @@ void reset_gaps(swayc_t *view, void *data) {
if (!ASSERT_NONNULL(view)) { if (!ASSERT_NONNULL(view)) {
return; return;
} }
if (view->type == C_OUTPUT) { if (view->type == C_WORKSPACE) {
view->gaps = config->gaps_outer; view->gaps = config->gaps_outer;
} }
if (view->type == C_VIEW) { if (view->type == C_VIEW) {
view->gaps = config->gaps_inner; view->gaps = config->gaps_inner;
} }
} }

View file

@ -113,7 +113,7 @@ static void handle_output_destroyed(wlc_handle output) {
static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) { static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h); sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
swayc_t *c = get_swayc_for_handle(output, &root_container); swayc_t *c = swayc_by_handle(output);
if (!c) return; if (!c) return;
c->width = to->w; c->width = to->w;
c->height = to->h; c->height = to->h;
@ -121,7 +121,7 @@ static void handle_output_resolution_change(wlc_handle output, const struct wlc_
} }
static void handle_output_focused(wlc_handle output, bool focus) { static void handle_output_focused(wlc_handle output, bool focus) {
swayc_t *c = get_swayc_for_handle(output, &root_container); swayc_t *c = swayc_by_handle(output);
// if for some reason this output doesnt exist, create it. // if for some reason this output doesnt exist, create it.
if (!c) { if (!c) {
handle_output_created(output); handle_output_created(output);
@ -139,7 +139,7 @@ static bool handle_view_created(wlc_handle handle) {
// Get parent container, to add view in // Get parent container, to add view in
if (parent) { if (parent) {
focused = get_swayc_for_handle(parent, &root_container); focused = swayc_by_handle(parent);
} }
if (!focused || focused->type == C_OUTPUT) { if (!focused || focused->type == C_OUTPUT) {
focused = get_focused_container(&root_container); focused = get_focused_container(&root_container);
@ -196,7 +196,7 @@ static bool handle_view_created(wlc_handle handle) {
static void handle_view_destroyed(wlc_handle handle) { static void handle_view_destroyed(wlc_handle handle) {
sway_log(L_DEBUG, "Destroying window %lu", handle); sway_log(L_DEBUG, "Destroying window %lu", handle);
swayc_t *view = get_swayc_for_handle(handle, &root_container); swayc_t *view = swayc_by_handle(handle);
switch (wlc_view_get_type(handle)) { switch (wlc_view_get_type(handle)) {
// regular view created regularly // regular view created regularly
@ -230,7 +230,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
// If the view is floating, then apply the geometry. // If the view is floating, then apply the geometry.
// Otherwise save the desired width/height for the view. // Otherwise save the desired width/height for the view.
// This will not do anything for the time being as WLC improperly sends geometry requests // This will not do anything for the time being as WLC improperly sends geometry requests
swayc_t *view = get_swayc_for_handle(handle, &root_container); swayc_t *view = swayc_by_handle(handle);
if (view) { if (view) {
view->desired_width = geometry->size.w; view->desired_width = geometry->size.w;
view->desired_height = geometry->size.h; view->desired_height = geometry->size.h;
@ -246,7 +246,7 @@ static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geo
} }
static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) { static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
swayc_t *c = get_swayc_for_handle(view, &root_container); swayc_t *c = swayc_by_handle(view);
switch (state) { switch (state) {
case WLC_BIT_FULLSCREEN: case WLC_BIT_FULLSCREEN:
// i3 just lets it become fullscreen // i3 just lets it become fullscreen

View file

@ -18,6 +18,8 @@ void init_layout(void) {
root_container.handle = -1; root_container.handle = -1;
} }
// Children of container functions
static int index_child(swayc_t *parent, swayc_t *child) { static int index_child(swayc_t *parent, swayc_t *child) {
int i; int i;
for (i = 0; i < parent->children->length; ++i) { for (i = 0; i < parent->children->length; ++i) {
@ -108,211 +110,254 @@ swayc_t *remove_child(swayc_t *child) {
return parent; return parent;
} }
// Fitting functions
#define FIT_FUNC __attribute__((nonnull)) static void
void arrange_windows(swayc_t *container, int width, int height) { FIT_FUNC _fit_view(swayc_t *view) {
int i; sway_log(L_DEBUG, "%s:%p: (%dx%d@%dx%d)", __func__, view,
if (width == -1 || height == -1) { view->width, view->height, view->x, view->y);
sway_log(L_DEBUG, "Arranging layout for %p", container); struct wlc_geometry geo;
width = container->width; if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) {
height = container->height; swayc_t *op = swayc_parent_by_type(view, C_OUTPUT);
} geo = (struct wlc_geometry){
.origin = { .x = 0, .y = 0 },
int x = 0, y = 0; .size = { .w = op->width, .h = op->height }
switch (container->type) { };
case C_ROOT: } else {
for (i = 0; i < container->children->length; ++i) { if (view->is_floating) {
swayc_t *child = container->children->items[i]; geo = (struct wlc_geometry){
sway_log(L_DEBUG, "Arranging output at %d", x);
child->x = x;
child->y = y;
arrange_windows(child, -1, -1);
// Removed for now because wlc works with relative positions
// Addition can be reconsidered once wlc positions are changed
// x += child->width;
}
return;
case C_OUTPUT:
container->width = width;
container->height = height;
// These lines make x/y negative and result in stuff glitching out
// Their addition can be reconsidered once wlc positions are changed
// x -= container->x;
// y -= container->y;
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
child->x = x + container->gaps;
child->y = y + container->gaps;
child->width = width - container->gaps * 2;
child->height = height - container->gaps * 2;
sway_log(L_DEBUG, "Arranging workspace #%d at %d, %d", i, child->x, child->y);
arrange_windows(child, -1, -1);
}
return;
case C_VIEW:
{
struct wlc_geometry geometry = {
.origin = { .origin = {
.x = container->x + container->gaps / 2, .x = view->x,
.y = container->y + container->gaps / 2 .y = view->y,
}, },
.size = { .size = {
.w = width - container->gaps, .w = view->width,
.h = height - container->gaps .h = view->height,
} }
}; };
if (wlc_view_get_state(container->handle) & WLC_BIT_FULLSCREEN) { } else {
swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); geo = (struct wlc_geometry){
geometry.origin.x = 0; .origin = {
geometry.origin.y = 0; .x = view->x + view->gaps / 2,
geometry.size.w = parent->width; .y = view->y + view->gaps / 2,
geometry.size.h = parent->height; },
wlc_view_set_geometry(container->handle, 0, &geometry); .size = {
wlc_view_bring_to_front(container->handle); .w = view->width - view->gaps,
} else { .h = view->height - view->gaps
wlc_view_set_geometry(container->handle, 0, &geometry); }
container->width = width; };
container->height = height; }
}
wlc_view_set_geometry(view->handle, 0, &geo);
}
FIT_FUNC _fit_container(swayc_t *container) {
sway_log(L_DEBUG, "%s:%p: (%dx%d@%dx%d)", __func__, container,
container->width, container->height, container->x, container->y);
swayc_t **child = (swayc_t **)container->children->items;
int i, len = container->children->length;
// geometry
int x = container->x;
int y = container->y;
int w = container->width;
int h = container->height;
// scaling
double s = 0;
switch (container->layout) {
default:
case L_HORIZ:
// Find scaling amount required to fit children in parent
for (i = 0; i < len; ++i, ++child) {
int *prev_w = &(*child)->width;
if (*prev_w <= 0) {
*prev_w = w / (len > 1 ? len - 1 : 1);
} }
sway_log(L_DEBUG, "Set view to %d x %d @ %d, %d", geometry.size.w, geometry.size.h, s += *prev_w;
geometry.origin.x, geometry.origin.y); }
sway_log(L_DEBUG,"s:%f",s);
if (s < 0.001) {
return;
}
s = w / s;
child = (swayc_t **)container->children->items;
for (i = 0; i < len; ++i, ++child) {
// Set geometry
(*child)->x = x;
(*child)->y = y;
// Scale width to fit in container
(*child)->width *= s;
(*child)->height = h;
// Increment x offset
x += (*child)->width;
// Recursibly resize children, depending on its type
((*child)->type == C_VIEW ? _fit_view : _fit_container)(*child);
} }
return; return;
default:
container->width = width;
container->height = height;
break;
}
x = y = 0;
double scale = 0;
switch (container->layout) {
case L_HORIZ:
default:
// Calculate total width
for (i = 0; i < container->children->length; ++i) {
int *old_width = &((swayc_t *)container->children->items[i])->width;
if (*old_width <= 0) {
if (container->children->length > 1) {
*old_width = width / (container->children->length - 1);
} else {
*old_width = width;
}
}
scale += *old_width;
}
// Resize windows
if (scale > 0.1) {
scale = width / scale;
sway_log(L_DEBUG, "Arranging %p horizontally", container);
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, width, scale);
child->x = x + container->x;
child->y = y + container->y;
arrange_windows(child, child->width * scale, height);
x += child->width;
}
}
break;
case L_VERT: case L_VERT:
// Calculate total height // Find scaling amount required to fit children in parent
for (i = 0; i < container->children->length; ++i) { for (i = 0; i < len; ++i, ++child) {
int *old_height = &((swayc_t *)container->children->items[i])->height; int *prev_h = &(*child)->height;
if (*old_height <= 0) { if (*prev_h <= 0) {
if (container->children->length > 1) { *prev_h = h / (len > 1 ? len - 1 : 1);
*old_height = height / (container->children->length - 1);
} else {
*old_height = height;
}
} }
scale += *old_height; s += *prev_h;
} }
// Resize if (s < 0.001) {
if (scale > 0.1) { return;
scale = height / scale;
sway_log(L_DEBUG, "Arranging %p vertically", container);
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %d by %f)", child, child->type, height, scale);
child->x = x + container->x;
child->y = y + container->y;
arrange_windows(child, width, child->height * scale);
y += child->height;
}
} }
break; s = h / s;
child = (swayc_t **)container->children->items;
for (i = 0; i < len; ++i, ++child) {
// Set geometry
(*child)->x = x;
(*child)->y = y;
// Scale height to fit in container
(*child)->height *= s;
(*child)->width = w;
// Increment y offset
y += (*child)->height;
// Recursibly resize children, depending on its type
((*child)->type == C_VIEW ? _fit_view : _fit_container)(*child);
}
return;
}
}
FIT_FUNC _fit_workspace(swayc_t *workspace) {
workspace->x += workspace->gaps;
workspace->y += workspace->gaps;
workspace->width -= workspace->gaps * 2;
workspace->height -= workspace->gaps * 2;
sway_log(L_DEBUG, "%s:%p: (%dx%d@%dx%d)", __func__, workspace,
workspace->width, workspace->height, workspace->x,workspace->y);
// workspace is treated same as container for tiling
_fit_container(workspace);
// Handle floating containers
swayc_t **child = (swayc_t **)workspace->floating->items;
int i, len = workspace->floating->length;
for (i = 0; i < len; ++i, ++child) {
// Fit floating depending on view
((*child)->type == C_VIEW ? _fit_view : _fit_container)(*child);
}
}
FIT_FUNC _fit_output(swayc_t *output) {
sway_log(L_DEBUG, "%s:%p: (%dx%d@%dx%d)", __func__, output, output->width,
output->height, output->x,output->y);
swayc_t **child = (swayc_t **)output->children->items;
int i, len = output->children->length;
int x = output->x;
int y = output->y;
int w = output->width;
int h = output->height;
for (i = 0; i < len; ++i, ++child) {
// Set geometry with gaps
(*child)->x = x;
(*child)->y = y;
(*child)->width = w;
(*child)->height = h;
// recursivly fit children
_fit_workspace(*child);
}
}
FIT_FUNC _fit_root(swayc_t *root) {
sway_log(L_DEBUG, "%s:%p: (%dx%d@%dx%d)", __func__, root, root->width,
root->height, root->x,root->y);
swayc_t **child = (swayc_t **)root->children->items;
int i, len = root->children->length;
for (i = 0; i < len; ++i, ++child) {
(*child)->x = 0;
(*child)->y = 0;
_fit_output(*child);
}
}
FIT_FUNC fit_children_in(swayc_t *swayc) {
switch (swayc->type) {
case C_ROOT: _fit_root(swayc); return;
case C_WORKSPACE: swayc = swayc->parent;
case C_OUTPUT: _fit_output(swayc); return;
case C_VIEW: swayc = swayc->parent;
case C_CONTAINER: _fit_container(swayc); return;
default: sway_assert(false, "%s: invalid type", __func__);
}
}
#undef FIT_FUNC
__attribute__((nonnull)) static wlc_handle order_children(swayc_t *swayc, wlc_handle top) {
// return handle
if (swayc->type == C_VIEW) {
return swayc->handle;
}
// return if no focus
if (swayc->focused == NULL) {
return 0;
} }
// Arrage floating layouts for workspaces last // TODO fix floating implementation.
if (container->type == C_WORKSPACE) { // Recurse and get handle of focused container
for (i = 0; i < container->floating->length; ++i) { wlc_handle bottom = order_children(swayc->focused, top);
swayc_t *view = container->floating->items[i];
if (view->type == C_VIEW) { // TODO Used properly in workspace case
// Set the geometry wlc_handle topmost = bottom;
struct wlc_geometry geometry = { (void) topmost;
.origin = {
.x = view->x, // Put handle below current top, or if there is no top, set it as bottom
.y = view->y if (top) {
}, wlc_view_send_below(bottom, top);
.size = { } else {
.w = view->width, top = bottom;
.h = view->height }
}
}; // recurse for all children with the current bottom handle as their top.
if (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN) { int i, len = swayc->children->length;
swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); swayc_t **child = (swayc_t **)swayc->children->items;
geometry.origin.x = 0; for (i = 0; i < len; ++i, ++child) {
geometry.origin.y = 0; // Skip over the focused child
geometry.size.w = parent->width; if (*child == swayc->focused) {
geometry.size.h = parent->height; continue;
wlc_view_set_geometry(view->handle, 0, &geometry); }
wlc_view_bring_to_front(view->handle); // Update current top, send it below previous bottom, and set new bottom
} else { top = order_children(*child, bottom);
wlc_view_set_geometry(view->handle, 0, &geometry); wlc_view_send_below(top, bottom);
// Bring the views to the front in order of the list, the list bottom = top;
// 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 // TODO fix floating implementation.
if (!container->focused // If we are at a workspace, put floating containers above topmost
|| !(wlc_view_get_state(container->focused->handle) & WLC_BIT_FULLSCREEN)) { if (swayc->type == C_WORKSPACE) {
wlc_view_bring_to_front(view->handle); // TODO using the same hacky implementation as before.
} // send floating windows to front
} len = swayc->children->length;
child = (swayc_t **)swayc->floating->items;
// chekc whether to send floating windows to the back or front
swayc_t *focused = get_focused_view(swayc);
bool tofront = swayc->parent->focused == swayc || (focused->type == C_VIEW
&& (wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN));
for (i = 0; i < len; ++i) {
if (tofront) {
wlc_view_bring_to_front((*child)->handle);
} else {
wlc_view_send_to_back((*child)->handle);
} }
} }
} }
// Return the bottom of this, which shall be the top of others,
return bottom;
}
// Arrange layout
void arrange_windows(swayc_t *container, int width, int height) {
fit_children_in(container);
order_children(container, 0);
layout_log(&root_container, 0); layout_log(&root_container, 0);
return;
} }
swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
if (parent->children == NULL) {
return NULL;
}
// Search for floating workspaces
int i;
if (parent->type == C_WORKSPACE) {
for (i = 0; i < parent->floating->length; ++i) {
swayc_t *child = parent->floating->items[i];
if (child->handle == handle) {
return child;
}
}
}
for (i = 0; i < parent->children->length; ++i) {
swayc_t *child = parent->children->items[i];
if (child->handle == handle) {
return child;
} else {
swayc_t *res;
if ((res = get_swayc_for_handle(handle, child))) {
return res;
}
}
}
return NULL;
}
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) { swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) {
swayc_t *parent = container->parent; swayc_t *parent = container->parent;

View file

@ -16,7 +16,7 @@ static const char *verbosity_colors[] = {
"", // L_SILENT "", // L_SILENT
"\x1B[1;31m", // L_ERROR "\x1B[1;31m", // L_ERROR
"\x1B[1;34m", // L_INFO "\x1B[1;34m", // L_INFO
"\x1B[1;30m", // L_DEBUG "\x1B[1;32m", // L_DEBUG
}; };
void init_log(int verbosity) { void init_log(int verbosity) {
@ -151,6 +151,7 @@ static void container_log(const swayc_t *c) {
void layout_log(const swayc_t *c, int depth) { void layout_log(const swayc_t *c, int depth) {
int i, d; int i, d;
int e = c->children ? c->children->length : 0; int e = c->children ? c->children->length : 0;
if (L_DEBUG > v) return;
container_log(c); container_log(c);
if (e) { if (e) {
for (i = 0; i < e; ++i) { for (i = 0; i < e; ++i) {