mirror of
https://github.com/swaywm/sway.git
synced 2024-11-24 17:01:29 +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);
|
bool swayc_is_fullscreen(swayc_t *view);
|
||||||
|
|
||||||
// Mapping functions
|
// Mapping functions
|
||||||
|
void swayc_map(swayc_t *, void f(swayc_t *));
|
||||||
void container_map(swayc_t *, void (*f)(swayc_t *, void *), void *);
|
void swayc_map_r(swayc_t *, void f(swayc_t *, void *), void *);
|
||||||
|
|
||||||
// Mappings
|
// Mappings
|
||||||
void set_view_visibility(swayc_t *view, void *data);
|
void swayc_show(swayc_t *view);
|
||||||
void reset_gaps(swayc_t *view, void *data);
|
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
|
#endif
|
||||||
|
|
|
@ -26,8 +26,8 @@ void move_container(swayc_t* container,swayc_t* root,enum movement_direction dir
|
||||||
// Layout
|
// Layout
|
||||||
void update_geometry(swayc_t *view);
|
void update_geometry(swayc_t *view);
|
||||||
void arrange_windows(swayc_t *container, double width, double height);
|
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(swayc_t *container, enum movement_direction dir);
|
||||||
swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_direction dir, swayc_t *limit);
|
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);
|
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) {
|
if (container->type == C_VIEW) {
|
||||||
wlc_view_close(container->handle);
|
wlc_view_close(container->handle);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Close all views
|
// Close all views
|
||||||
container_map(&root_container, kill_views, NULL);
|
swayc_map(&root_container, kill_views);
|
||||||
sway_terminate();
|
sway_terminate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ _continue:
|
||||||
|
|
||||||
if (is_active) {
|
if (is_active) {
|
||||||
temp_config->reloading = false;
|
temp_config->reloading = false;
|
||||||
container_map(&root_container, reset_gaps, NULL);
|
swayc_map(&root_container, reset_gaps);
|
||||||
arrange_windows(&root_container, -1, -1);
|
arrange_windows(&root_container, -1, -1);
|
||||||
}
|
}
|
||||||
config = temp_config;
|
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->handle = -1;
|
||||||
c->layout = L_NONE;
|
c->layout = L_NONE;
|
||||||
c->type = type;
|
c->type = type;
|
||||||
|
c->visible = true;
|
||||||
if (type != C_VIEW) {
|
if (type != C_VIEW) {
|
||||||
c->children = create_list();
|
c->children = create_list();
|
||||||
}
|
}
|
||||||
|
@ -477,7 +478,7 @@ swayc_t *swayc_active_workspace_for(swayc_t *cont) {
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
|
|
||||||
case C_OUTPUT:
|
case C_OUTPUT:
|
||||||
cont = cont->focused;
|
cont = cont ? cont->focused : NULL;
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
|
|
||||||
case C_WORKSPACE:
|
case C_WORKSPACE:
|
||||||
|
@ -496,43 +497,96 @@ bool swayc_is_fullscreen(swayc_t *view) {
|
||||||
|
|
||||||
// Mapping
|
// Mapping
|
||||||
|
|
||||||
void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
|
void swayc_map(swayc_t *c, void f(swayc_t *)) {
|
||||||
if (container) {
|
if (c) {
|
||||||
int i;
|
int i, len;
|
||||||
if (container->children) {
|
swayc_t **child;
|
||||||
for (i = 0; i < container->children->length; ++i) {
|
if (c->children) {
|
||||||
swayc_t *child = container->children->items[i];
|
child = (swayc_t **)c->children->items;
|
||||||
f(child, data);
|
len = c->children->length;
|
||||||
container_map(child, f, data);
|
for (i = 0; i < len; ++i, ++child) {
|
||||||
|
f(*child);
|
||||||
|
swayc_map(*child,f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (container->floating) {
|
if (c->floating) {
|
||||||
for (i = 0; i < container->floating->length; ++i) {
|
child = (swayc_t **)c->floating->items;
|
||||||
swayc_t *child = container->floating->items[i];
|
len = c->floating->length;
|
||||||
f(child, data);
|
for (i = 0; i < len; ++i, ++child) {
|
||||||
container_map(child, f, data);
|
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)) {
|
if (!ASSERT_NONNULL(view)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t *p = data;
|
|
||||||
if (view->type == C_VIEW) {
|
if (view->type == C_VIEW) {
|
||||||
wlc_view_set_mask(view->handle, *p);
|
wlc_view_set_mask(view->handle, 1);
|
||||||
if (*p == 2) {
|
|
||||||
wlc_view_bring_to_front(view->handle);
|
|
||||||
} else {
|
|
||||||
wlc_view_send_to_back(view->handle);
|
|
||||||
}
|
}
|
||||||
}
|
view->visible = true;
|
||||||
view->visible = (*p == 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)) {
|
if (!ASSERT_NONNULL(view)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
27
sway/focus.c
27
sway/focus.c
|
@ -28,14 +28,13 @@ static void update_focus(swayc_t *c) {
|
||||||
if (parent->focused) {
|
if (parent->focused) {
|
||||||
swayc_t *ws = parent->focused;
|
swayc_t *ws = parent->focused;
|
||||||
// hide visibility of old workspace
|
// hide visibility of old workspace
|
||||||
uint32_t mask = 1;
|
swayc_hide(ws);
|
||||||
container_map(ws, set_view_visibility, &mask);
|
swayc_map(ws, swayc_inherit_visibility);
|
||||||
// set visibility of new workspace
|
|
||||||
mask = 2;
|
|
||||||
container_map(c, set_view_visibility, &mask);
|
|
||||||
wlc_output_set_mask(parent->handle, 2);
|
|
||||||
destroy_workspace(ws);
|
destroy_workspace(ws);
|
||||||
}
|
}
|
||||||
|
// set visibility of new workspace
|
||||||
|
swayc_show(c);
|
||||||
|
swayc_map(c, swayc_inherit_visibility);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -165,14 +164,16 @@ void set_focused_container_for(swayc_t *a, swayc_t *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swayc_t *get_focused_view(swayc_t *parent) {
|
swayc_t *get_focused_view(swayc_t *parent) {
|
||||||
while (parent && parent->type != C_VIEW) {
|
swayc_t *c = parent;
|
||||||
if (parent->type == C_WORKSPACE && parent->focused == NULL) {
|
while (c && c->type != C_VIEW) {
|
||||||
return parent;
|
if (c->type == C_WORKSPACE && c->focused == NULL) {
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
parent = parent->focused;
|
c = c->focused;
|
||||||
}
|
}
|
||||||
if (parent == NULL) {
|
if (c == NULL) {
|
||||||
return swayc_active_workspace_for(parent);
|
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) {
|
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 = swayc_by_handle(handle);
|
swayc_t *view = swayc_by_handle(handle);
|
||||||
|
swayc_t *focus = get_focused_view(&root_container);
|
||||||
|
|
||||||
switch (wlc_view_get_type(handle)) {
|
switch (wlc_view_get_type(handle)) {
|
||||||
// regular view created regularly
|
// regular view created regularly
|
||||||
|
@ -227,8 +228,11 @@ static void handle_view_destroyed(wlc_handle handle) {
|
||||||
locked_container_focus = false;
|
locked_container_focus = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// get and set new focus
|
||||||
|
if (focus && view == focus) {
|
||||||
set_focused_container(get_focused_view(&root_container));
|
set_focused_container(get_focused_view(&root_container));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_view_focus(wlc_handle view, bool focus) {
|
static void handle_view_focus(wlc_handle view, bool focus) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -209,7 +209,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
case IPC_GET_WORKSPACES:
|
case IPC_GET_WORKSPACES:
|
||||||
{
|
{
|
||||||
list_t *workspaces = create_list();
|
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);
|
char *json = json_list(workspaces);
|
||||||
free_flat_list(workspaces);
|
free_flat_list(workspaces);
|
||||||
ipc_send_reply(client, json, strlen(json));
|
ipc_send_reply(client, json, strlen(json));
|
||||||
|
@ -219,7 +219,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
case IPC_GET_OUTPUTS:
|
case IPC_GET_OUTPUTS:
|
||||||
{
|
{
|
||||||
list_t *outputs = create_list();
|
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);
|
char *json = json_list(outputs);
|
||||||
free_flat_list(outputs);
|
free_flat_list(outputs);
|
||||||
ipc_send_reply(client, json, strlen(json));
|
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) {
|
void update_geometry(swayc_t *container) {
|
||||||
if (container->type != C_VIEW) {
|
if (container->type != C_VIEW) {
|
||||||
return;
|
return;
|
||||||
|
@ -228,7 +290,7 @@ void update_geometry(swayc_t *container) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrange_windows(swayc_t *container, double width, double height) {
|
static void _arrange_windows(swayc_t *container, double width, double height) {
|
||||||
int i;
|
int i;
|
||||||
if (width == -1 || height == -1) {
|
if (width == -1 || height == -1) {
|
||||||
sway_log(L_DEBUG, "Arranging layout for %p", container);
|
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) {
|
for (i = 0; i < container->children->length; ++i) {
|
||||||
swayc_t *child = container->children->items[i];
|
swayc_t *child = container->children->items[i];
|
||||||
sway_log(L_DEBUG, "Arranging output at %d", x);
|
sway_log(L_DEBUG, "Arranging output at %d", x);
|
||||||
arrange_windows(child, -1, -1);
|
_arrange_windows(child, -1, -1);
|
||||||
x += child->width;
|
x += child->width;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -257,7 +319,7 @@ void arrange_windows(swayc_t *container, double width, double height) {
|
||||||
child->width = width - container->gaps * 2;
|
child->width = width - container->gaps * 2;
|
||||||
child->height = height - container->gaps * 2;
|
child->height = height - container->gaps * 2;
|
||||||
sway_log(L_DEBUG, "Arranging workspace #%d at %f, %f", i, child->x, child->y);
|
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;
|
return;
|
||||||
case C_VIEW:
|
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);
|
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->x = x + container->x;
|
||||||
child->y = y + container->y;
|
child->y = y + container->y;
|
||||||
arrange_windows(child, child->width * scale, height);
|
_arrange_windows(child, child->width * scale, height);
|
||||||
x += child->width;
|
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);
|
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->x = x + container->x;
|
||||||
child->y = y + container->y;
|
child->y = y + container->y;
|
||||||
arrange_windows(child, width, child->height * scale);
|
_arrange_windows(child, width, child->height * scale);
|
||||||
y += child->height;
|
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);
|
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;
|
layout_match = container->layout == L_VERT;
|
||||||
}
|
}
|
||||||
if (container->type == C_VIEW) {
|
if (container->type == C_VIEW) {
|
||||||
struct wlc_geometry geometry = {
|
update_geometry(container);
|
||||||
.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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (layout_match) {
|
if (layout_match) {
|
||||||
|
|
Loading…
Reference in a new issue