order layouts, view_visibility, some renames

This commit is contained in:
taiyu 2015-08-25 09:49:38 -07:00
parent dbad30a409
commit 4c78ed7d17
9 changed files with 185 additions and 64 deletions

View file

@ -99,11 +99,15 @@ swayc_t *swayc_active_workspace_for(swayc_t *view);
bool swayc_is_fullscreen(swayc_t *view);
// Mapping functions
void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
void swayc_map(swayc_t *, void f(swayc_t *));
void swayc_map_r(swayc_t *, void f(swayc_t *, void *), void *);
// Mappings
void set_view_visibility(swayc_t *view, void *data);
void reset_gaps(swayc_t *view, void *data);
void swayc_show(swayc_t *view);
void swayc_hide(swayc_t *view);
// Sets visibility depending on parent
void swayc_inherit_visibility(swayc_t *view);
void reset_gaps(swayc_t *view);
#endif

View file

@ -26,8 +26,8 @@ void move_container(swayc_t* container,swayc_t* root,enum movement_direction dir
// Layout
void update_geometry(swayc_t *view);
void arrange_windows(swayc_t *container, double width, double height);
void order_windows(swayc_t *container);
swayc_t *get_focused_container(swayc_t *parent);
swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir);
swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_direction dir, swayc_t *limit);

View file

@ -176,7 +176,7 @@ static bool cmd_exec(struct sway_config *config, int argc, char **argv) {
return cmd_exec_always(config, argc, argv);
}
static void kill_views(swayc_t *container, void *data) {
static void kill_views(swayc_t *container) {
if (container->type == C_VIEW) {
wlc_view_close(container->handle);
}
@ -187,7 +187,7 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
return false;
}
// Close all views
container_map(&root_container, kill_views, NULL);
swayc_map(&root_container, kill_views);
sway_terminate();
return true;
}

View file

@ -237,7 +237,7 @@ _continue:
if (is_active) {
temp_config->reloading = false;
container_map(&root_container, reset_gaps, NULL);
swayc_map(&root_container, reset_gaps);
arrange_windows(&root_container, -1, -1);
}
config = temp_config;

View file

@ -16,6 +16,7 @@ static swayc_t *new_swayc(enum swayc_types type) {
c->handle = -1;
c->layout = L_NONE;
c->type = type;
c->visible = true;
if (type != C_VIEW) {
c->children = create_list();
}
@ -477,7 +478,7 @@ swayc_t *swayc_active_workspace_for(swayc_t *cont) {
/* Fallthrough */
case C_OUTPUT:
cont = cont->focused;
cont = cont ? cont->focused : NULL;
/* Fallthrough */
case C_WORKSPACE:
@ -496,43 +497,96 @@ bool swayc_is_fullscreen(swayc_t *view) {
// Mapping
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
if (container) {
int i;
if (container->children) {
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
f(child, data);
container_map(child, f, data);
void swayc_map(swayc_t *c, void f(swayc_t *)) {
if (c) {
int i, len;
swayc_t **child;
if (c->children) {
child = (swayc_t **)c->children->items;
len = c->children->length;
for (i = 0; i < len; ++i, ++child) {
f(*child);
swayc_map(*child,f);
}
}
if (container->floating) {
for (i = 0; i < container->floating->length; ++i) {
swayc_t *child = container->floating->items[i];
f(child, data);
container_map(child, f, data);
if (c->floating) {
child = (swayc_t **)c->floating->items;
len = c->floating->length;
for (i = 0; i < len; ++i, ++child) {
f(*child);
swayc_map(*child,f);
}
}
}
}
void set_view_visibility(swayc_t *view, void *data) {
void swayc_map_r(swayc_t *c, void f(swayc_t *, void *), void *data) {
if (c) {
int i, len;
swayc_t **child;
if (c->children) {
child = (swayc_t **)c->children->items;
len = c->children->length;
for (i = 0; i < len; ++i, ++child) {
f(*child, data);
swayc_map_r(*child, f, data);
}
}
if (c->floating) {
child = (swayc_t **)c->floating->items;
len = c->floating->length;
for (i = 0; i < len; ++i, ++child) {
f(*child, data);
swayc_map_r(*child, f, data);
}
}
}
}
// Set bitmask to 1
void swayc_show(swayc_t *view) {
if (!ASSERT_NONNULL(view)) {
return;
}
uint32_t *p = data;
if (view->type == C_VIEW) {
wlc_view_set_mask(view->handle, *p);
if (*p == 2) {
wlc_view_bring_to_front(view->handle);
} else {
wlc_view_send_to_back(view->handle);
}
wlc_view_set_mask(view->handle, 1);
}
view->visible = (*p == 2);
view->visible = true;
}
void reset_gaps(swayc_t *view, void *data) {
// Set bitmask to 0
void swayc_hide(swayc_t *view) {
if (!ASSERT_NONNULL(view)) {
return;
}
if (view->type == C_VIEW) {
wlc_view_set_mask(view->handle, 0);
}
view->visible = false;
}
void swayc_inherit_visibility(swayc_t *view) {
if (!view || view->type == C_ROOT || view->type == C_OUTPUT) {
return;
}
swayc_t *parent = view->parent;
// inherit parent if invisible
if ((view->visible = parent->visible)) {
// Hide or show depending on parent layout
if (parent->layout == L_STACKED || parent->layout == L_TABBED) {
view->visible = parent->focused == view;
} else {
view->visible = true;
}
}
if (view->visible) {
swayc_show(view);
} else {
swayc_hide(view);
}
}
void reset_gaps(swayc_t *view) {
if (!ASSERT_NONNULL(view)) {
return;
}

View file

@ -28,14 +28,13 @@ static void update_focus(swayc_t *c) {
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);
swayc_hide(ws);
swayc_map(ws, swayc_inherit_visibility);
destroy_workspace(ws);
}
// set visibility of new workspace
swayc_show(c);
swayc_map(c, swayc_inherit_visibility);
break;
default:
@ -165,14 +164,16 @@ void set_focused_container_for(swayc_t *a, swayc_t *c) {
}
swayc_t *get_focused_view(swayc_t *parent) {
while (parent && parent->type != C_VIEW) {
if (parent->type == C_WORKSPACE && parent->focused == NULL) {
return parent;
swayc_t *c = parent;
while (c && c->type != C_VIEW) {
if (c->type == C_WORKSPACE && c->focused == NULL) {
return c;
}
parent = parent->focused;
c = c->focused;
}
if (parent == NULL) {
return swayc_active_workspace_for(parent);
if (c == NULL) {
c = swayc_active_workspace_for(parent);
}
return parent;
return c;
}

View file

@ -207,6 +207,7 @@ static bool handle_view_created(wlc_handle handle) {
static void handle_view_destroyed(wlc_handle handle) {
sway_log(L_DEBUG, "Destroying window %lu", handle);
swayc_t *view = swayc_by_handle(handle);
swayc_t *focus = get_focused_view(&root_container);
switch (wlc_view_get_type(handle)) {
// regular view created regularly
@ -227,7 +228,10 @@ static void handle_view_destroyed(wlc_handle handle) {
locked_container_focus = false;
break;
}
set_focused_container(get_focused_view(&root_container));
// get and set new focus
if (focus && view == focus) {
set_focused_container(get_focused_view(&root_container));
}
}
static void handle_view_focus(wlc_handle view, bool focus) {

View file

@ -209,7 +209,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
case IPC_GET_WORKSPACES:
{
list_t *workspaces = create_list();
container_map(&root_container, ipc_get_workspaces_callback, workspaces);
swayc_map_r(&root_container, ipc_get_workspaces_callback, workspaces);
char *json = json_list(workspaces);
free_flat_list(workspaces);
ipc_send_reply(client, json, strlen(json));
@ -219,7 +219,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
case IPC_GET_OUTPUTS:
{
list_t *outputs = create_list();
container_map(&root_container, ipc_get_outputs_callback, outputs);
swayc_map_r(&root_container, ipc_get_outputs_callback, outputs);
char *json = json_list(outputs);
free_flat_list(outputs);
ipc_send_reply(client, json, strlen(json));

View file

@ -203,6 +203,68 @@ void move_container(swayc_t *container,swayc_t* root,enum movement_direction dir
}
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;
}
// Recurse and get handle of focused container
wlc_handle bottom = _order_children(swayc->focused, top);
// Put handle below current top, or if there is no top, set it as bottom
if (top) {
wlc_view_send_below(bottom, top);
} else {
top = bottom;
}
// recurse for all children with the current bottom handle as their top.
int i, len = swayc->children->length;
swayc_t **child = (swayc_t **)swayc->children->items;
for (i = 0; i < len; ++i, ++child) {
// Skip over the focused child
if (*child == swayc->focused) {
continue;
}
// Update current top, send it below previous bottom, and set new bottom
top = _order_children(*child, bottom);
wlc_view_send_below(top, bottom);
bottom = top;
}
// If we are at a workspace, put floating containers above topmost
if (swayc->type == C_WORKSPACE) {
// 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;
}
void order_windows(swayc_t *swayc) {
_order_children(swayc, 0);
}
void update_geometry(swayc_t *container) {
if (container->type != C_VIEW) {
return;
@ -228,7 +290,7 @@ void update_geometry(swayc_t *container) {
return;
}
void arrange_windows(swayc_t *container, double width, double height) {
static void _arrange_windows(swayc_t *container, double width, double height) {
int i;
if (width == -1 || height == -1) {
sway_log(L_DEBUG, "Arranging layout for %p", container);
@ -242,7 +304,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
for (i = 0; i < container->children->length; ++i) {
swayc_t *child = container->children->items[i];
sway_log(L_DEBUG, "Arranging output at %d", x);
arrange_windows(child, -1, -1);
_arrange_windows(child, -1, -1);
x += child->width;
}
return;
@ -257,7 +319,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
child->width = width - container->gaps * 2;
child->height = height - container->gaps * 2;
sway_log(L_DEBUG, "Arranging workspace #%d at %f, %f", i, child->x, child->y);
arrange_windows(child, -1, -1);
_arrange_windows(child, -1, -1);
}
return;
case C_VIEW:
@ -301,7 +363,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, width, scale);
child->x = x + container->x;
child->y = y + container->y;
arrange_windows(child, child->width * scale, height);
_arrange_windows(child, child->width * scale, height);
x += child->width;
}
}
@ -328,7 +390,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
sway_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, height, scale);
child->x = x + container->x;
child->y = y + container->y;
arrange_windows(child, width, child->height * scale);
_arrange_windows(child, width, child->height * scale);
y += child->height;
}
}
@ -350,6 +412,12 @@ void arrange_windows(swayc_t *container, double width, double height) {
}
}
}
}
void arrange_windows(swayc_t *container, double width, double height) {
_arrange_windows(container, width, height);
order_windows(container);
swayc_map(container, swayc_inherit_visibility);
layout_log(&root_container, 0);
}
@ -476,17 +544,7 @@ void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge ed
layout_match = container->layout == L_VERT;
}
if (container->type == C_VIEW) {
struct wlc_geometry geometry = {
.origin = {
.x = container->x + container->gaps / 2,
.y = container->y + container->gaps / 2
},
.size = {
.w = container->width - container->gaps,
.h = container->height - container->gaps
}
};
wlc_view_set_geometry(container->handle, edge, &geometry);
update_geometry(container);
return;
}
if (layout_match) {