mirror of
https://github.com/swaywm/sway.git
synced 2024-11-24 08:51:27 +00:00
order layouts, view_visibility, some renames
This commit is contained in:
parent
dbad30a409
commit
4c78ed7d17
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
102
sway/container.c
102
sway/container.c
|
@ -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;
|
||||
}
|
||||
|
|
27
sway/focus.c
27
sway/focus.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,8 +228,11 @@ static void handle_view_destroyed(wlc_handle handle) {
|
|||
locked_container_focus = false;
|
||||
break;
|
||||
}
|
||||
// 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) {
|
||||
return;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue