mirror of
https://github.com/swaywm/sway.git
synced 2025-11-09 13:29:49 -05:00
Implement type safe arguments and demote sway_container
This commit changes the meaning of sway_container so that it only refers to layout containers and view containers. Workspaces, outputs and the root are no longer known as containers. Instead, root, outputs, workspaces and containers are all a type of node, and containers come in two types: layout containers and view containers. In addition to the above, this implements type safe variables. This means we use specific types such as sway_output and sway_workspace instead of generic containers or nodes. However, it's worth noting that in a few places places (eg. seat focus and transactions) referring to them in a generic way is unavoidable which is why we still use nodes in some places. If you want a TL;DR, look at node.h, as well as the struct definitions for root, output, workspace and container. Note that sway_output now contains a workspaces list, and workspaces now contain a tiling and floating list, and containers now contain a pointer back to the workspace. There are now functions for seat_get_focused_workspace and seat_get_focused_container. The latter will return NULL if a workspace itself is focused. Most other seat functions like seat_get_focus and seat_set_focus now accept and return nodes. In the config->handler_context struct, current_container has been replaced with three pointers: node, container and workspace. node is the same as what current_container was, while workspace is the workspace that the node resides on and container is the actual container, which may be NULL if a workspace itself is focused. The global root_container variable has been replaced with one simply called root, which is a pointer to the sway_root instance. The way outputs are created, enabled, disabled and destroyed has changed. Previously we'd wrap the sway_output in a container when it is enabled, but as we don't have containers any more it needs a different approach. The output_create and output_destroy functions previously created/destroyed the container, but now they create/destroy the sway_output. There is a new function output_disable to disable an output without destroying it. Containers have a new view property. If this is populated then the container is a view container, otherwise it's a layout container. Like before, this property is immutable for the life of the container. Containers have both a `sway_container *parent` and `sway_workspace *workspace`. As we use specific types now, parent cannot point to a workspace so it'll be NULL for containers which are direct children of the workspace. The workspace property is set for all containers, except those which are hidden in the scratchpad as they have no workspace. In some cases we need to refer to workspaces in a container-like way. For example, workspaces have layout and children, but when using specific types this makes it difficult. Likewise, it's difficult for a container to get its parent's layout when the parent could be another container or a workspace. To make it easier, some helper functions have been created: container_parent_layout and container_get_siblings. container_remove_child has been renamed to container_detach and container_replace_child has been renamed to container_replace. `container_handle_fullscreen_reparent(con, old_parent)` has had the old_parent removed. We now unfullscreen the workspace when detaching the container, so this function is simplified and only needs one argument now. container_notify_subtree_changed has been renamed to container_update_representation. This is more descriptive of its purpose. I also wanted to be able to call it with whatever container was changed rather than the container's parent, which makes bubbling up to the workspace easier. There are now state structs per node thing. ie. sway_output_state, sway_workspace_state and sway_container_state. The focus, move and layout commands have been completely refactored to work with the specific types. I considered making these a separate PR, but I'd be backporting my changes only to replace them again, and it's easier just to test everything at once.
This commit is contained in:
parent
309fcf2300
commit
7586f150c0
68 changed files with 3515 additions and 3509 deletions
|
|
@ -13,13 +13,12 @@ struct cmd_results *cmd_border(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type != C_VIEW) {
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
if (!container->view) {
|
||||
return cmd_results_new(CMD_INVALID, "border",
|
||||
"Only views can have borders");
|
||||
}
|
||||
struct sway_view *view = container->sway_view;
|
||||
struct sway_view *view = container->view;
|
||||
|
||||
if (strcmp(argv[0], "none") == 0) {
|
||||
view->border = B_NONE;
|
||||
|
|
@ -38,11 +37,11 @@ struct cmd_results *cmd_border(int argc, char **argv) {
|
|||
view->border_thickness = atoi(argv[1]);
|
||||
}
|
||||
|
||||
if (container_is_floating(view->swayc)) {
|
||||
container_set_geometry_from_floating_view(view->swayc);
|
||||
if (container_is_floating(view->container)) {
|
||||
container_set_geometry_from_floating_view(view->container);
|
||||
}
|
||||
|
||||
arrange_windows(view->swayc);
|
||||
arrange_container(view->container);
|
||||
|
||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||
if (seat->cursor) {
|
||||
|
|
|
|||
|
|
@ -15,24 +15,23 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type == C_WORKSPACE && container->children->length == 0) {
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
struct sway_workspace *workspace = config->handler_context.workspace;
|
||||
if (!container && workspace->tiling->length == 0) {
|
||||
return cmd_results_new(CMD_INVALID, "floating",
|
||||
"Can't float an empty workspace");
|
||||
}
|
||||
if (container->type == C_WORKSPACE) {
|
||||
if (!container) {
|
||||
// Wrap the workspace's children in a container so we can float it
|
||||
struct sway_container *workspace = container;
|
||||
container = workspace_wrap_children(container);
|
||||
container = workspace_wrap_children(workspace);
|
||||
workspace->layout = L_HORIZ;
|
||||
seat_set_focus(config->handler_context.seat, container);
|
||||
seat_set_focus(config->handler_context.seat, &container->node);
|
||||
}
|
||||
|
||||
// If the container is in a floating split container,
|
||||
// operate on the split container instead of the child.
|
||||
if (container_is_floating_or_child(container)) {
|
||||
while (container->parent->type != C_WORKSPACE) {
|
||||
while (container->parent) {
|
||||
container = container->parent;
|
||||
}
|
||||
}
|
||||
|
|
@ -51,8 +50,7 @@ struct cmd_results *cmd_floating(int argc, char **argv) {
|
|||
|
||||
container_set_floating(container, wants_floating);
|
||||
|
||||
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
||||
arrange_windows(workspace);
|
||||
arrange_workspace(container->workspace);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,211 +34,139 @@ static bool parse_movement_direction(const char *name,
|
|||
}
|
||||
|
||||
/**
|
||||
* Get swayc in the direction of newly entered output.
|
||||
* Get node in the direction of newly entered output.
|
||||
*/
|
||||
static struct sway_container *get_swayc_in_output_direction(
|
||||
struct sway_container *output, enum movement_direction dir,
|
||||
struct sway_seat *seat) {
|
||||
if (!output) {
|
||||
return NULL;
|
||||
static struct sway_node *get_node_in_output_direction(
|
||||
struct sway_output *output, enum movement_direction dir) {
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
struct sway_workspace *ws = output_get_active_workspace(output);
|
||||
if (ws->fullscreen) {
|
||||
return seat_get_focus_inactive(seat, &ws->fullscreen->node);
|
||||
}
|
||||
struct sway_container *container = NULL;
|
||||
|
||||
struct sway_container *ws = seat_get_focus_inactive(seat, output);
|
||||
if (ws->type != C_WORKSPACE) {
|
||||
ws = container_parent(ws, C_WORKSPACE);
|
||||
}
|
||||
|
||||
if (ws == NULL) {
|
||||
wlr_log(WLR_ERROR, "got an output without a workspace");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ws->children->length > 0) {
|
||||
if (ws->tiling->length > 0) {
|
||||
switch (dir) {
|
||||
case MOVE_LEFT:
|
||||
if (ws->layout == L_HORIZ || ws->layout == L_TABBED) {
|
||||
// get most right child of new output
|
||||
return ws->children->items[ws->children->length-1];
|
||||
container = ws->tiling->items[ws->tiling->length-1];
|
||||
} else {
|
||||
return seat_get_focus_inactive(seat, ws);
|
||||
container = seat_get_focus_inactive_tiling(seat, ws);
|
||||
}
|
||||
return &container->node;
|
||||
case MOVE_RIGHT:
|
||||
if (ws->layout == L_HORIZ || ws->layout == L_TABBED) {
|
||||
// get most left child of new output
|
||||
return ws->children->items[0];
|
||||
container = ws->tiling->items[0];
|
||||
} else {
|
||||
return seat_get_focus_inactive(seat, ws);
|
||||
container = seat_get_focus_inactive_tiling(seat, ws);
|
||||
}
|
||||
return &container->node;
|
||||
case MOVE_UP:
|
||||
case MOVE_DOWN: {
|
||||
struct sway_container *focused =
|
||||
seat_get_focus_inactive(seat, ws);
|
||||
if (focused && focused->parent) {
|
||||
struct sway_container *parent = focused->parent;
|
||||
if (parent->layout == L_VERT) {
|
||||
if (dir == MOVE_UP) {
|
||||
// get child furthest down on new output
|
||||
int idx = parent->children->length - 1;
|
||||
return parent->children->items[idx];
|
||||
} else if (dir == MOVE_DOWN) {
|
||||
// get child furthest up on new output
|
||||
return parent->children->items[0];
|
||||
}
|
||||
}
|
||||
return focused;
|
||||
if (ws->layout == L_VERT || ws->layout == L_STACKED) {
|
||||
// get most bottom child of new output
|
||||
container = ws->tiling->items[ws->tiling->length-1];
|
||||
} else {
|
||||
container = seat_get_focus_inactive_tiling(seat, ws);
|
||||
}
|
||||
break;
|
||||
return &container->node;
|
||||
case MOVE_DOWN: {
|
||||
if (ws->layout == L_VERT || ws->layout == L_STACKED) {
|
||||
// get most top child of new output
|
||||
container = ws->tiling->items[0];
|
||||
} else {
|
||||
container = seat_get_focus_inactive_tiling(seat, ws);
|
||||
}
|
||||
return &container->node;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ws;
|
||||
return &ws->node;
|
||||
}
|
||||
|
||||
static struct sway_container *container_get_in_direction(
|
||||
struct sway_container *container, struct sway_seat *seat,
|
||||
enum movement_direction dir) {
|
||||
struct sway_container *parent = container->parent;
|
||||
|
||||
static struct sway_node *node_get_in_direction(struct sway_container *container,
|
||||
struct sway_seat *seat, enum movement_direction dir) {
|
||||
if (dir == MOVE_CHILD) {
|
||||
return seat_get_focus_inactive(seat, container);
|
||||
return seat_get_active_child(seat, &container->node);
|
||||
}
|
||||
if (container->is_fullscreen) {
|
||||
if (dir == MOVE_PARENT) {
|
||||
return NULL;
|
||||
}
|
||||
container = container_parent(container, C_OUTPUT);
|
||||
parent = container->parent;
|
||||
} else {
|
||||
if (dir == MOVE_PARENT) {
|
||||
if (parent->type == C_OUTPUT || container_is_floating(container)) {
|
||||
return NULL;
|
||||
} else {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
// Fullscreen container with a direction - go straight to outputs
|
||||
struct sway_output *output = container->workspace->output;
|
||||
struct sway_output *new_output = output_get_in_direction(output, dir);
|
||||
return get_node_in_output_direction(new_output, dir);
|
||||
}
|
||||
if (dir == MOVE_PARENT) {
|
||||
return node_get_parent(&container->node);
|
||||
}
|
||||
|
||||
struct sway_container *wrap_candidate = NULL;
|
||||
while (true) {
|
||||
struct sway_container *current = container;
|
||||
while (current) {
|
||||
bool can_move = false;
|
||||
int desired;
|
||||
int idx = list_find(container->parent->children, container);
|
||||
if (idx == -1) {
|
||||
return NULL;
|
||||
}
|
||||
if (parent->type == C_ROOT) {
|
||||
enum wlr_direction wlr_dir = 0;
|
||||
if (!sway_assert(sway_dir_to_wlr(dir, &wlr_dir),
|
||||
"got invalid direction: %d", dir)) {
|
||||
return NULL;
|
||||
}
|
||||
int lx = container->x + container->width / 2;
|
||||
int ly = container->y + container->height / 2;
|
||||
struct wlr_output_layout *layout =
|
||||
root_container.sway_root->output_layout;
|
||||
struct wlr_output *wlr_adjacent =
|
||||
wlr_output_layout_adjacent_output(layout, wlr_dir,
|
||||
container->sway_output->wlr_output, lx, ly);
|
||||
struct sway_container *adjacent =
|
||||
output_from_wlr_output(wlr_adjacent);
|
||||
int idx = container_sibling_index(current);
|
||||
enum sway_container_layout parent_layout =
|
||||
container_parent_layout(current);
|
||||
list_t *siblings = container_get_siblings(current);
|
||||
|
||||
if (!adjacent || adjacent == container) {
|
||||
if (!wrap_candidate) {
|
||||
return NULL;
|
||||
}
|
||||
return seat_get_focus_inactive_view(seat, wrap_candidate);
|
||||
}
|
||||
struct sway_container *next =
|
||||
get_swayc_in_output_direction(adjacent, dir, seat);
|
||||
if (next == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
struct sway_container *next_workspace = next;
|
||||
if (next_workspace->type != C_WORKSPACE) {
|
||||
next_workspace = container_parent(next_workspace, C_WORKSPACE);
|
||||
}
|
||||
sway_assert(next_workspace, "Next container has no workspace");
|
||||
if (next_workspace->sway_workspace->fullscreen) {
|
||||
return seat_get_focus_inactive(seat,
|
||||
next_workspace->sway_workspace->fullscreen);
|
||||
}
|
||||
if (next->children && next->children->length) {
|
||||
// TODO consider floating children as well
|
||||
return seat_get_focus_inactive_view(seat, next);
|
||||
} else {
|
||||
return next;
|
||||
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
|
||||
if (parent_layout == L_HORIZ || parent_layout == L_TABBED) {
|
||||
can_move = true;
|
||||
desired = idx + (dir == MOVE_LEFT ? -1 : 1);
|
||||
}
|
||||
} else {
|
||||
if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
|
||||
if (parent->layout == L_HORIZ || parent->layout == L_TABBED) {
|
||||
can_move = true;
|
||||
desired = idx + (dir == MOVE_LEFT ? -1 : 1);
|
||||
}
|
||||
} else {
|
||||
if (parent->layout == L_VERT || parent->layout == L_STACKED) {
|
||||
can_move = true;
|
||||
desired = idx + (dir == MOVE_UP ? -1 : 1);
|
||||
}
|
||||
if (parent_layout == L_VERT || parent_layout == L_STACKED) {
|
||||
can_move = true;
|
||||
desired = idx + (dir == MOVE_UP ? -1 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (can_move) {
|
||||
// TODO handle floating
|
||||
if (desired < 0 || desired >= parent->children->length) {
|
||||
if (desired < 0 || desired >= siblings->length) {
|
||||
can_move = false;
|
||||
int len = parent->children->length;
|
||||
int len = siblings->length;
|
||||
if (config->focus_wrapping != WRAP_NO && !wrap_candidate
|
||||
&& len > 1) {
|
||||
if (desired < 0) {
|
||||
wrap_candidate = parent->children->items[len-1];
|
||||
wrap_candidate = siblings->items[len-1];
|
||||
} else {
|
||||
wrap_candidate = parent->children->items[0];
|
||||
wrap_candidate = siblings->items[0];
|
||||
}
|
||||
if (config->focus_wrapping == WRAP_FORCE) {
|
||||
return seat_get_focus_inactive_view(seat,
|
||||
wrap_candidate);
|
||||
struct sway_container *c = seat_get_focus_inactive_view(
|
||||
seat, &wrap_candidate->node);
|
||||
return &c->node;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct sway_container *desired_con =
|
||||
parent->children->items[desired];
|
||||
wlr_log(WLR_DEBUG,
|
||||
"cont %d-%p dir %i sibling %d: %p", idx,
|
||||
container, dir, desired, desired_con);
|
||||
return seat_get_focus_inactive_view(seat, desired_con);
|
||||
struct sway_container *desired_con = siblings->items[desired];
|
||||
struct sway_container *c = seat_get_focus_inactive_view(
|
||||
seat, &desired_con->node);
|
||||
return &c->node;
|
||||
}
|
||||
}
|
||||
|
||||
if (!can_move) {
|
||||
container = parent;
|
||||
parent = parent->parent;
|
||||
if (!parent) {
|
||||
// wrapping is the last chance
|
||||
if (!wrap_candidate) {
|
||||
return NULL;
|
||||
}
|
||||
return seat_get_focus_inactive_view(seat, wrap_candidate);
|
||||
}
|
||||
}
|
||||
current = current->parent;
|
||||
}
|
||||
|
||||
// Check a different output
|
||||
struct sway_output *output = container->workspace->output;
|
||||
struct sway_output *new_output = output_get_in_direction(output, dir);
|
||||
if (new_output) {
|
||||
return get_node_in_output_direction(new_output, dir);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct cmd_results *focus_mode(struct sway_container *con,
|
||||
static struct cmd_results *focus_mode(struct sway_workspace *ws,
|
||||
struct sway_seat *seat, bool floating) {
|
||||
struct sway_container *ws = con->type == C_WORKSPACE ?
|
||||
con : container_parent(con, C_WORKSPACE);
|
||||
|
||||
// If the container is in a floating split container,
|
||||
// operate on the split container instead of the child.
|
||||
if (container_is_floating_or_child(con)) {
|
||||
while (con->parent->type != C_WORKSPACE) {
|
||||
con = con->parent;
|
||||
}
|
||||
}
|
||||
|
||||
struct sway_container *new_focus = NULL;
|
||||
if (floating) {
|
||||
new_focus = seat_get_focus_inactive_floating(seat, ws);
|
||||
|
|
@ -246,7 +174,7 @@ static struct cmd_results *focus_mode(struct sway_container *con,
|
|||
new_focus = seat_get_focus_inactive_tiling(seat, ws);
|
||||
}
|
||||
if (new_focus) {
|
||||
seat_set_focus(seat, new_focus);
|
||||
seat_set_focus(seat, &new_focus->node);
|
||||
} else {
|
||||
return cmd_results_new(CMD_FAILURE, "focus",
|
||||
"Failed to find a %s container in workspace",
|
||||
|
|
@ -255,14 +183,14 @@ static struct cmd_results *focus_mode(struct sway_container *con,
|
|||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
static struct cmd_results *focus_output(struct sway_container *con,
|
||||
struct sway_seat *seat, int argc, char **argv) {
|
||||
static struct cmd_results *focus_output(struct sway_seat *seat,
|
||||
int argc, char **argv) {
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID, "focus",
|
||||
"Expected 'focus output <direction|name>'");
|
||||
}
|
||||
char *identifier = join_args(argv, argc);
|
||||
struct sway_container *output = output_by_name(identifier);
|
||||
struct sway_output *output = output_by_name(identifier);
|
||||
|
||||
if (!output) {
|
||||
enum movement_direction direction;
|
||||
|
|
@ -272,14 +200,13 @@ static struct cmd_results *focus_output(struct sway_container *con,
|
|||
return cmd_results_new(CMD_INVALID, "focus",
|
||||
"There is no output with that name");
|
||||
}
|
||||
struct sway_container *focus = seat_get_focus(seat);
|
||||
focus = container_parent(focus, C_OUTPUT);
|
||||
output = container_get_in_direction(focus, seat, direction);
|
||||
struct sway_workspace *ws = seat_get_focused_workspace(seat);
|
||||
output = output_get_in_direction(ws->output, direction);
|
||||
}
|
||||
|
||||
free(identifier);
|
||||
if (output) {
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, output));
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, &output->node));
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
@ -289,29 +216,32 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
|
|||
if (config->reading || !config->active) {
|
||||
return cmd_results_new(CMD_DEFER, NULL, NULL);
|
||||
}
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_node *node = config->handler_context.node;
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
struct sway_workspace *workspace = config->handler_context.workspace;
|
||||
struct sway_seat *seat = config->handler_context.seat;
|
||||
if (con->type < C_WORKSPACE) {
|
||||
if (node->type < N_WORKSPACE) {
|
||||
return cmd_results_new(CMD_FAILURE, "focus",
|
||||
"Command 'focus' cannot be used above the workspace level");
|
||||
}
|
||||
|
||||
if (argc == 0) {
|
||||
seat_set_focus(seat, con);
|
||||
seat_set_focus(seat, node);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
if (strcmp(argv[0], "floating") == 0) {
|
||||
return focus_mode(con, seat, true);
|
||||
return focus_mode(workspace, seat, true);
|
||||
} else if (strcmp(argv[0], "tiling") == 0) {
|
||||
return focus_mode(con, seat, false);
|
||||
return focus_mode(workspace, seat, false);
|
||||
} else if (strcmp(argv[0], "mode_toggle") == 0) {
|
||||
return focus_mode(con, seat, !container_is_floating_or_child(con));
|
||||
bool floating = container && container_is_floating_or_child(container);
|
||||
return focus_mode(workspace, seat, !floating);
|
||||
}
|
||||
|
||||
if (strcmp(argv[0], "output") == 0) {
|
||||
argc--; argv++;
|
||||
return focus_output(con, seat, argc, argv);
|
||||
return focus_output(seat, argc, argv);
|
||||
}
|
||||
|
||||
enum movement_direction direction = 0;
|
||||
|
|
@ -321,8 +251,18 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
|
|||
"or 'focus output <direction|name>'");
|
||||
}
|
||||
|
||||
struct sway_container *next_focus = container_get_in_direction(
|
||||
con, seat, direction);
|
||||
if (node->type == N_WORKSPACE) {
|
||||
// A workspace is focused, so just jump to the next output
|
||||
struct sway_output *new_output =
|
||||
output_get_in_direction(workspace->output, direction);
|
||||
struct sway_node *node =
|
||||
get_node_in_output_direction(new_output, direction);
|
||||
seat_set_focus(seat, node);
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
||||
struct sway_node *next_focus =
|
||||
node_get_in_direction(container, seat, direction);
|
||||
if (next_focus) {
|
||||
seat_set_focus(seat, next_focus);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,18 +12,18 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "fullscreen", EXPECTED_LESS_THAN, 2))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type == C_WORKSPACE && container->children->length == 0) {
|
||||
struct sway_node *node = config->handler_context.node;
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
struct sway_workspace *workspace = config->handler_context.workspace;
|
||||
if (node->type == N_WORKSPACE && workspace->tiling->length == 0) {
|
||||
return cmd_results_new(CMD_INVALID, "fullscreen",
|
||||
"Can't fullscreen an empty workspace");
|
||||
}
|
||||
if (container->type == C_WORKSPACE) {
|
||||
if (node->type == N_WORKSPACE) {
|
||||
// Wrap the workspace's children in a container so we can fullscreen it
|
||||
struct sway_container *workspace = container;
|
||||
container = workspace_wrap_children(container);
|
||||
container = workspace_wrap_children(workspace);
|
||||
workspace->layout = L_HORIZ;
|
||||
seat_set_focus(config->handler_context.seat, container);
|
||||
seat_set_focus(config->handler_context.seat, &container->node);
|
||||
}
|
||||
bool enable = !container->is_fullscreen;
|
||||
|
||||
|
|
@ -32,9 +32,7 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
|
|||
}
|
||||
|
||||
container_set_fullscreen(container, enable);
|
||||
|
||||
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
||||
arrange_windows(workspace->parent);
|
||||
arrange_workspace(workspace);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "log.h"
|
||||
#include "stringop.h"
|
||||
#include <math.h>
|
||||
|
|
@ -43,7 +44,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "gaps",
|
||||
"gaps edge_gaps on|off|toggle");
|
||||
}
|
||||
arrange_windows(&root_container);
|
||||
arrange_root();
|
||||
} else {
|
||||
int amount_idx = 0; // the current index in argv
|
||||
enum gaps_op op = GAPS_OP_SET;
|
||||
|
|
@ -124,7 +125,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
if (amount_idx == 0) { // gaps <amount>
|
||||
config->gaps_inner = val;
|
||||
config->gaps_outer = val;
|
||||
arrange_windows(&root_container);
|
||||
arrange_root();
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
// Other variants. The middle-length variant (gaps inner|outer <amount>)
|
||||
|
|
@ -155,21 +156,27 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
|
|||
} else {
|
||||
config->gaps_outer = total;
|
||||
}
|
||||
arrange_windows(&root_container);
|
||||
arrange_root();
|
||||
} else {
|
||||
struct sway_container *c =
|
||||
config->handler_context.current_container;
|
||||
if (scope == GAPS_SCOPE_WORKSPACE && c->type != C_WORKSPACE) {
|
||||
c = container_parent(c, C_WORKSPACE);
|
||||
}
|
||||
c->has_gaps = true;
|
||||
if (inner) {
|
||||
c->gaps_inner = total;
|
||||
if (scope == GAPS_SCOPE_WORKSPACE) {
|
||||
struct sway_workspace *ws = config->handler_context.workspace;
|
||||
ws->has_gaps = true;
|
||||
if (inner) {
|
||||
ws->gaps_inner = total;
|
||||
} else {
|
||||
ws->gaps_outer = total;
|
||||
}
|
||||
arrange_workspace(ws);
|
||||
} else {
|
||||
c->gaps_outer = total;
|
||||
struct sway_container *c = config->handler_context.container;
|
||||
c->has_gaps = true;
|
||||
if (inner) {
|
||||
c->gaps_inner = total;
|
||||
} else {
|
||||
c->gaps_outer = total;
|
||||
}
|
||||
arrange_workspace(c->workspace);
|
||||
}
|
||||
|
||||
arrange_windows(c->parent ? c->parent : &root_container);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
#include "sway/tree/view.h"
|
||||
|
||||
static void _configure_view(struct sway_container *con, void *data) {
|
||||
if (con->type == C_VIEW) {
|
||||
view_autoconfigure(con->sway_view);
|
||||
if (con->view) {
|
||||
view_autoconfigure(con->view);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,27 @@
|
|||
#include "log.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "sway/commands.h"
|
||||
|
||||
struct cmd_results *cmd_kill(int argc, char **argv) {
|
||||
struct sway_container *con =
|
||||
config->handler_context.current_container;
|
||||
static void close_container_iterator(struct sway_container *con, void *data) {
|
||||
if (con->view) {
|
||||
view_close(con->view);
|
||||
}
|
||||
}
|
||||
|
||||
container_close(con);
|
||||
struct cmd_results *cmd_kill(int argc, char **argv) {
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
struct sway_workspace *ws = config->handler_context.workspace;
|
||||
|
||||
if (con) {
|
||||
close_container_iterator(con, NULL);
|
||||
container_for_each_child(con, close_container_iterator, NULL);
|
||||
} else {
|
||||
workspace_for_each_container(ws, close_container_iterator, NULL);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,21 +4,20 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "log.h"
|
||||
|
||||
static bool parse_layout_string(char *s, enum sway_container_layout *ptr) {
|
||||
static enum sway_container_layout parse_layout_string(char *s) {
|
||||
if (strcasecmp(s, "splith") == 0) {
|
||||
*ptr = L_HORIZ;
|
||||
return L_HORIZ;
|
||||
} else if (strcasecmp(s, "splitv") == 0) {
|
||||
*ptr = L_VERT;
|
||||
return L_VERT;
|
||||
} else if (strcasecmp(s, "tabbed") == 0) {
|
||||
*ptr = L_TABBED;
|
||||
return L_TABBED;
|
||||
} else if (strcasecmp(s, "stacking") == 0) {
|
||||
*ptr = L_STACKED;
|
||||
} else {
|
||||
return false;
|
||||
return L_STACKED;
|
||||
}
|
||||
return true;
|
||||
return L_NONE;
|
||||
}
|
||||
|
||||
static const char* expected_syntax =
|
||||
|
|
@ -26,85 +25,130 @@ static const char* expected_syntax =
|
|||
"'layout toggle [split|all]' or "
|
||||
"'layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]...'";
|
||||
|
||||
static enum sway_container_layout get_layout_toggle(int argc, char **argv,
|
||||
enum sway_container_layout layout,
|
||||
enum sway_container_layout prev_split_layout) {
|
||||
// "layout toggle"
|
||||
if (argc == 0) {
|
||||
return layout == L_HORIZ ? L_VERT : L_HORIZ;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
// "layout toggle split" (same as "layout toggle")
|
||||
if (strcasecmp(argv[1], "split") == 0) {
|
||||
return layout == L_HORIZ ? L_VERT : L_HORIZ;
|
||||
}
|
||||
// "layout toggle all"
|
||||
if (strcasecmp(argv[1], "all") == 0) {
|
||||
return layout == L_HORIZ ? L_VERT :
|
||||
layout == L_VERT ? L_STACKED :
|
||||
layout == L_STACKED ? L_TABBED : L_HORIZ;
|
||||
}
|
||||
return L_NONE;
|
||||
}
|
||||
|
||||
enum sway_container_layout parsed;
|
||||
int curr = 1;
|
||||
for (; curr < argc; curr++) {
|
||||
parsed = parse_layout_string(argv[curr]);
|
||||
if (parsed == layout || (strcmp(argv[curr], "split") == 0 &&
|
||||
(layout == L_VERT || layout == L_HORIZ))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = curr + 1; i != curr; ++i) {
|
||||
// cycle round to find next valid layout
|
||||
if (i >= argc) {
|
||||
i = 1;
|
||||
}
|
||||
parsed = parse_layout_string(argv[i]);
|
||||
if (parsed != L_NONE) {
|
||||
return parsed;
|
||||
}
|
||||
if (strcmp(argv[i], "split") == 0) {
|
||||
return layout == L_HORIZ ? L_VERT :
|
||||
layout == L_VERT ? L_HORIZ : prev_split_layout;
|
||||
}
|
||||
// invalid layout strings are silently ignored
|
||||
}
|
||||
return L_NONE;
|
||||
}
|
||||
|
||||
static enum sway_container_layout get_layout(int argc, char **argv,
|
||||
enum sway_container_layout layout,
|
||||
enum sway_container_layout prev_split_layout) {
|
||||
// Check if assigned directly
|
||||
enum sway_container_layout parsed = parse_layout_string(argv[0]);
|
||||
if (parsed != L_NONE) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
if (strcasecmp(argv[0], "default") == 0) {
|
||||
return prev_split_layout;
|
||||
}
|
||||
|
||||
if (strcasecmp(argv[0], "toggle") == 0) {
|
||||
argc--; argv++;
|
||||
return get_layout_toggle(argc, argv, layout, prev_split_layout);
|
||||
}
|
||||
|
||||
return L_NONE;
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_layout(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *parent = config->handler_context.current_container;
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
struct sway_workspace *workspace = config->handler_context.workspace;
|
||||
|
||||
if (container_is_floating(parent)) {
|
||||
if (container && container_is_floating(container)) {
|
||||
return cmd_results_new(CMD_FAILURE, "layout",
|
||||
"Unable to change layout of floating windows");
|
||||
}
|
||||
|
||||
while (parent->type == C_VIEW) {
|
||||
parent = parent->parent;
|
||||
// Typically we change the layout of the current container, but if the
|
||||
// current container is a view (it usually is) then we'll change the layout
|
||||
// of the parent instead, as it doesn't make sense for views to have layout.
|
||||
if (container && container->view) {
|
||||
container = container->parent;
|
||||
}
|
||||
|
||||
enum sway_container_layout prev = parent->layout;
|
||||
bool assigned_directly = parse_layout_string(argv[0], &parent->layout);
|
||||
if (!assigned_directly) {
|
||||
if (strcasecmp(argv[0], "default") == 0) {
|
||||
parent->layout = parent->prev_split_layout;
|
||||
} else if (strcasecmp(argv[0], "toggle") == 0) {
|
||||
if (argc == 1) {
|
||||
parent->layout =
|
||||
parent->layout == L_STACKED ? L_TABBED :
|
||||
parent->layout == L_TABBED ? parent->prev_split_layout : L_STACKED;
|
||||
} else if (argc == 2) {
|
||||
if (strcasecmp(argv[1], "all") == 0) {
|
||||
parent->layout =
|
||||
parent->layout == L_HORIZ ? L_VERT :
|
||||
parent->layout == L_VERT ? L_STACKED :
|
||||
parent->layout == L_STACKED ? L_TABBED : L_HORIZ;
|
||||
} else if (strcasecmp(argv[1], "split") == 0) {
|
||||
parent->layout =
|
||||
parent->layout == L_HORIZ ? L_VERT :
|
||||
parent->layout == L_VERT ? L_HORIZ : parent->prev_split_layout;
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
|
||||
}
|
||||
} else {
|
||||
enum sway_container_layout parsed_layout;
|
||||
int curr = 1;
|
||||
for (; curr < argc; curr++) {
|
||||
bool valid = parse_layout_string(argv[curr], &parsed_layout);
|
||||
if ((valid && parsed_layout == parent->layout) ||
|
||||
(strcmp(argv[curr], "split") == 0 &&
|
||||
(parent->layout == L_VERT || parent->layout == L_HORIZ))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = curr + 1; i != curr; ++i) {
|
||||
// cycle round to find next valid layout
|
||||
if (i >= argc) {
|
||||
i = 1;
|
||||
}
|
||||
if (parse_layout_string(argv[i], &parent->layout)) {
|
||||
break;
|
||||
} else if (strcmp(argv[i], "split") == 0) {
|
||||
parent->layout =
|
||||
parent->layout == L_HORIZ ? L_VERT :
|
||||
parent->layout == L_VERT ? L_HORIZ : parent->prev_split_layout;
|
||||
break;
|
||||
} // invalid layout strings are silently ignored
|
||||
}
|
||||
// We could be working with a container OR a workspace. These are different
|
||||
// structures, so we set up pointers to they layouts so we can refer them in
|
||||
// an abstract way.
|
||||
enum sway_container_layout new_layout = L_NONE;
|
||||
enum sway_container_layout old_layout = L_NONE;
|
||||
if (container) {
|
||||
old_layout = container->layout;
|
||||
new_layout = get_layout(argc, argv,
|
||||
container->layout, container->prev_split_layout);
|
||||
} else {
|
||||
old_layout = workspace->layout;
|
||||
new_layout = get_layout(argc, argv,
|
||||
workspace->layout, workspace->prev_split_layout);
|
||||
}
|
||||
if (new_layout == L_NONE) {
|
||||
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
|
||||
}
|
||||
if (new_layout != old_layout) {
|
||||
if (container) {
|
||||
if (old_layout != L_TABBED && old_layout != L_STACKED) {
|
||||
container->prev_split_layout = old_layout;
|
||||
}
|
||||
container->layout = new_layout;
|
||||
container_update_representation(container);
|
||||
arrange_container(container);
|
||||
} else {
|
||||
return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
|
||||
if (old_layout != L_TABBED && old_layout != L_STACKED) {
|
||||
workspace->prev_split_layout = old_layout;
|
||||
}
|
||||
workspace->layout = new_layout;
|
||||
workspace_update_representation(workspace);
|
||||
arrange_workspace(workspace);
|
||||
}
|
||||
}
|
||||
if (parent->layout == L_NONE) {
|
||||
parent->layout = container_get_default_layout(parent);
|
||||
}
|
||||
if (prev != parent->layout) {
|
||||
if (prev != L_TABBED && prev != L_STACKED) {
|
||||
parent->prev_split_layout = prev;
|
||||
}
|
||||
container_notify_subtree_changed(parent);
|
||||
arrange_windows(parent->parent);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,13 +18,12 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "mark", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type != C_VIEW) {
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
if (!container->view) {
|
||||
return cmd_results_new(CMD_INVALID, "mark",
|
||||
"Only views can have marks");
|
||||
}
|
||||
struct sway_view *view = container->sway_view;
|
||||
struct sway_view *view = container->view;
|
||||
|
||||
bool add = false, toggle = false;
|
||||
while (argc > 0 && strncmp(*argv, "--", 2) == 0) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,8 +19,7 @@ struct cmd_results *cmd_opacity(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
struct sway_container *con =
|
||||
config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
|
||||
float opacity = 0.0f;
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
|
|||
}
|
||||
list_free(bar_ids);
|
||||
|
||||
arrange_windows(&root_container);
|
||||
arrange_root();
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,14 +25,11 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
|||
}
|
||||
|
||||
int argn = 1;
|
||||
struct sway_container *workspace;
|
||||
struct sway_workspace *workspace = NULL;
|
||||
|
||||
if (strcasecmp(argv[1], "to") == 0) {
|
||||
// 'rename workspace to new_name'
|
||||
workspace = config->handler_context.current_container;
|
||||
if (workspace->type != C_WORKSPACE) {
|
||||
workspace = container_parent(workspace, C_WORKSPACE);
|
||||
}
|
||||
workspace = config->handler_context.workspace;
|
||||
} else if (strcasecmp(argv[1], "number") == 0) {
|
||||
// 'rename workspace number x to new_name'
|
||||
if (!isdigit(argv[2][0])) {
|
||||
|
|
@ -78,7 +75,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "rename",
|
||||
"Cannot use special workspace name '%s'", argv[argn]);
|
||||
}
|
||||
struct sway_container *tmp_workspace = workspace_by_name(new_name);
|
||||
struct sway_workspace *tmp_workspace = workspace_by_name(new_name);
|
||||
if (tmp_workspace) {
|
||||
free(new_name);
|
||||
return cmd_results_new(CMD_INVALID, "rename",
|
||||
|
|
@ -89,7 +86,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
|
|||
free(workspace->name);
|
||||
workspace->name = new_name;
|
||||
|
||||
output_sort_workspaces(workspace->parent);
|
||||
output_sort_workspaces(workspace->output);
|
||||
ipc_event_workspace(NULL, workspace, "rename");
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "sway/commands.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "log.h"
|
||||
|
||||
static const int MIN_SANE_W = 100, MIN_SANE_H = 60;
|
||||
|
|
@ -75,7 +76,7 @@ static int parse_resize_amount(int argc, char **argv,
|
|||
|
||||
static void calculate_constraints(int *min_width, int *max_width,
|
||||
int *min_height, int *max_height) {
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
|
||||
if (config->floating_minimum_width == -1) { // no minimum
|
||||
*min_width = 0;
|
||||
|
|
@ -96,8 +97,7 @@ static void calculate_constraints(int *min_width, int *max_width,
|
|||
if (config->floating_maximum_width == -1) { // no maximum
|
||||
*max_width = INT_MAX;
|
||||
} else if (config->floating_maximum_width == 0) { // automatic
|
||||
struct sway_container *ws = container_parent(con, C_WORKSPACE);
|
||||
*max_width = ws->width;
|
||||
*max_width = con->workspace->width;
|
||||
} else {
|
||||
*max_width = config->floating_maximum_width;
|
||||
}
|
||||
|
|
@ -105,8 +105,7 @@ static void calculate_constraints(int *min_width, int *max_width,
|
|||
if (config->floating_maximum_height == -1) { // no maximum
|
||||
*max_height = INT_MAX;
|
||||
} else if (config->floating_maximum_height == 0) { // automatic
|
||||
struct sway_container *ws = container_parent(con, C_WORKSPACE);
|
||||
*max_height = ws->height;
|
||||
*max_height = con->workspace->height;
|
||||
} else {
|
||||
*max_height = config->floating_maximum_height;
|
||||
}
|
||||
|
|
@ -191,11 +190,11 @@ static void resize_tiled(struct sway_container *parent, int amount,
|
|||
normalize_axis(axis) == RESIZE_AXIS_HORIZONTAL ? L_HORIZ : L_VERT;
|
||||
int minor_weight = 0;
|
||||
int major_weight = 0;
|
||||
while (parent->parent) {
|
||||
struct sway_container *next = parent->parent;
|
||||
if (next->layout == parallel_layout) {
|
||||
for (int i = 0; i < next->children->length; i++) {
|
||||
struct sway_container *sibling = next->children->items[i];
|
||||
while (parent) {
|
||||
list_t *siblings = container_get_siblings(parent);
|
||||
if (container_parent_layout(parent) == parallel_layout) {
|
||||
for (int i = 0; i < siblings->length; i++) {
|
||||
struct sway_container *sibling = siblings->items[i];
|
||||
|
||||
int sibling_pos = parallel_coord(sibling, axis);
|
||||
int focused_pos = parallel_coord(focused, axis);
|
||||
|
|
@ -213,17 +212,13 @@ static void resize_tiled(struct sway_container *parent, int amount,
|
|||
break;
|
||||
}
|
||||
}
|
||||
parent = next;
|
||||
parent = parent->parent;
|
||||
}
|
||||
|
||||
if (parent->type == C_ROOT) {
|
||||
if (!parent) {
|
||||
// Can't resize in this direction
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG,
|
||||
"Found the proper parent: %p. It has %d l conts, and %d r conts",
|
||||
parent->parent, minor_weight, major_weight);
|
||||
|
||||
// Implement up/down/left/right direction by zeroing one of the weights,
|
||||
// then setting the axis to be horizontal or vertical
|
||||
if (axis == RESIZE_AXIS_UP || axis == RESIZE_AXIS_LEFT) {
|
||||
|
|
@ -237,9 +232,10 @@ static void resize_tiled(struct sway_container *parent, int amount,
|
|||
|
||||
//TODO: Ensure rounding is done in such a way that there are NO pixel leaks
|
||||
// ^ ?????
|
||||
list_t *siblings = container_get_siblings(parent);
|
||||
|
||||
for (int i = 0; i < parent->parent->children->length; i++) {
|
||||
struct sway_container *sibling = parent->parent->children->items[i];
|
||||
for (int i = 0; i < siblings->length; i++) {
|
||||
struct sway_container *sibling = siblings->items[i];
|
||||
|
||||
int sibling_pos = parallel_coord(sibling, axis);
|
||||
int focused_pos = parallel_coord(focused, axis);
|
||||
|
|
@ -277,8 +273,8 @@ static void resize_tiled(struct sway_container *parent, int amount,
|
|||
enum wlr_edges major_edge = axis == RESIZE_AXIS_HORIZONTAL ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_BOTTOM;
|
||||
|
||||
for (int i = 0; i < parent->parent->children->length; i++) {
|
||||
struct sway_container *sibling = parent->parent->children->items[i];
|
||||
for (int i = 0; i < siblings->length; i++) {
|
||||
struct sway_container *sibling = siblings->items[i];
|
||||
|
||||
int sibling_pos = parallel_coord(sibling, axis);
|
||||
int focused_pos = parallel_coord(focused, axis);
|
||||
|
|
@ -316,7 +312,11 @@ static void resize_tiled(struct sway_container *parent, int amount,
|
|||
}
|
||||
}
|
||||
|
||||
arrange_windows(parent->parent);
|
||||
if (parent->parent) {
|
||||
arrange_container(parent->parent);
|
||||
} else {
|
||||
arrange_workspace(parent->workspace);
|
||||
}
|
||||
}
|
||||
|
||||
void container_resize_tiled(struct sway_container *parent,
|
||||
|
|
@ -346,7 +346,7 @@ void container_resize_tiled(struct sway_container *parent,
|
|||
*/
|
||||
static struct cmd_results *resize_adjust_floating(enum resize_axis axis,
|
||||
struct resize_amount *amount) {
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
int grow_width = 0, grow_height = 0;
|
||||
switch (axis) {
|
||||
case RESIZE_AXIS_HORIZONTAL:
|
||||
|
|
@ -400,15 +400,15 @@ static struct cmd_results *resize_adjust_floating(enum resize_axis axis,
|
|||
con->width += grow_width;
|
||||
con->height += grow_height;
|
||||
|
||||
if (con->type == C_VIEW) {
|
||||
struct sway_view *view = con->sway_view;
|
||||
if (con->view) {
|
||||
struct sway_view *view = con->view;
|
||||
view->x += grow_x;
|
||||
view->y += grow_y;
|
||||
view->width += grow_width;
|
||||
view->height += grow_height;
|
||||
}
|
||||
|
||||
arrange_windows(con);
|
||||
arrange_container(con);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
@ -418,7 +418,7 @@ static struct cmd_results *resize_adjust_floating(enum resize_axis axis,
|
|||
*/
|
||||
static struct cmd_results *resize_adjust_tiled(enum resize_axis axis,
|
||||
struct resize_amount *amount) {
|
||||
struct sway_container *current = config->handler_context.current_container;
|
||||
struct sway_container *current = config->handler_context.container;
|
||||
|
||||
if (amount->unit == RESIZE_UNIT_DEFAULT) {
|
||||
amount->unit = RESIZE_UNIT_PPT;
|
||||
|
|
@ -456,13 +456,15 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
|||
width->unit == RESIZE_UNIT_DEFAULT) {
|
||||
// Convert to px
|
||||
struct sway_container *parent = con->parent;
|
||||
while (parent->type >= C_WORKSPACE && parent->layout != L_HORIZ) {
|
||||
while (parent && parent->layout != L_HORIZ) {
|
||||
parent = parent->parent;
|
||||
}
|
||||
if (parent->type >= C_WORKSPACE) {
|
||||
if (parent) {
|
||||
width->amount = parent->width * width->amount / 100;
|
||||
width->unit = RESIZE_UNIT_PX;
|
||||
} else {
|
||||
width->amount = con->workspace->width * width->amount / 100;
|
||||
}
|
||||
width->unit = RESIZE_UNIT_PX;
|
||||
}
|
||||
if (width->unit == RESIZE_UNIT_PX) {
|
||||
resize_tiled(con, width->amount - con->width,
|
||||
|
|
@ -475,13 +477,15 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
|
|||
height->unit == RESIZE_UNIT_DEFAULT) {
|
||||
// Convert to px
|
||||
struct sway_container *parent = con->parent;
|
||||
while (parent->type >= C_WORKSPACE && parent->layout != L_VERT) {
|
||||
while (parent && parent->layout != L_VERT) {
|
||||
parent = parent->parent;
|
||||
}
|
||||
if (parent->type >= C_WORKSPACE) {
|
||||
if (parent) {
|
||||
height->amount = parent->height * height->amount / 100;
|
||||
height->unit = RESIZE_UNIT_PX;
|
||||
} else {
|
||||
height->amount = con->workspace->height * height->amount / 100;
|
||||
}
|
||||
height->unit = RESIZE_UNIT_PX;
|
||||
}
|
||||
if (height->unit == RESIZE_UNIT_PX) {
|
||||
resize_tiled(con, height->amount - con->height,
|
||||
|
|
@ -508,15 +512,15 @@ static struct cmd_results *resize_set_floating(struct sway_container *con,
|
|||
con->width = width->amount;
|
||||
con->height = height->amount;
|
||||
|
||||
if (con->type == C_VIEW) {
|
||||
struct sway_view *view = con->sway_view;
|
||||
if (con->view) {
|
||||
struct sway_view *view = con->view;
|
||||
view->x -= grow_width / 2;
|
||||
view->y -= grow_height / 2;
|
||||
view->width += grow_width;
|
||||
view->height += grow_height;
|
||||
}
|
||||
|
||||
arrange_windows(con);
|
||||
arrange_container(con);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
@ -555,7 +559,7 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// If 0, don't resize that dimension
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
if (width.amount <= 0) {
|
||||
width.amount = con->width;
|
||||
}
|
||||
|
|
@ -624,7 +628,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
|||
first_amount.amount *= multiplier;
|
||||
second_amount.amount *= multiplier;
|
||||
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
if (container_is_floating(con)) {
|
||||
// Floating containers can only resize in px. Choose an amount which
|
||||
// uses px, with fallback to an amount that specified no unit.
|
||||
|
|
@ -657,14 +661,10 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
|
|||
}
|
||||
|
||||
struct cmd_results *cmd_resize(int argc, char **argv) {
|
||||
struct sway_container *current = config->handler_context.current_container;
|
||||
struct sway_container *current = config->handler_context.container;
|
||||
if (!current) {
|
||||
return cmd_results_new(CMD_INVALID, "resize", "Cannot resize nothing");
|
||||
}
|
||||
if (current->type != C_VIEW && current->type != C_CONTAINER) {
|
||||
return cmd_results_new(CMD_INVALID, "resize",
|
||||
"Can only resize views/containers");
|
||||
}
|
||||
|
||||
struct cmd_results *error;
|
||||
if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) {
|
||||
|
|
|
|||
|
|
@ -9,36 +9,34 @@
|
|||
|
||||
static void scratchpad_toggle_auto(void) {
|
||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||
struct sway_container *focus = seat_get_focus(seat);
|
||||
struct sway_container *ws = focus->type == C_WORKSPACE ?
|
||||
focus : container_parent(focus, C_WORKSPACE);
|
||||
struct sway_container *focus = seat_get_focused_container(seat);
|
||||
struct sway_workspace *ws = seat_get_focused_workspace(seat);
|
||||
|
||||
// If the focus is in a floating split container,
|
||||
// operate on the split container instead of the child.
|
||||
if (container_is_floating_or_child(focus)) {
|
||||
while (focus->parent->type != C_WORKSPACE) {
|
||||
if (focus && container_is_floating_or_child(focus)) {
|
||||
while (focus->parent) {
|
||||
focus = focus->parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the currently focused window is a scratchpad window and should
|
||||
// be hidden again.
|
||||
if (focus->scratchpad) {
|
||||
if (focus && focus->scratchpad) {
|
||||
wlr_log(WLR_DEBUG, "Focus is a scratchpad window - hiding %s",
|
||||
focus->name);
|
||||
focus->title);
|
||||
root_scratchpad_hide(focus);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there is an unfocused scratchpad window on the current workspace
|
||||
// and focus it.
|
||||
for (int i = 0; i < ws->sway_workspace->floating->length; ++i) {
|
||||
struct sway_container *floater = ws->sway_workspace->floating->items[i];
|
||||
for (int i = 0; i < ws->floating->length; ++i) {
|
||||
struct sway_container *floater = ws->floating->items[i];
|
||||
if (floater->scratchpad && focus != floater) {
|
||||
wlr_log(WLR_DEBUG,
|
||||
"Focusing other scratchpad window (%s) in this workspace",
|
||||
floater->name);
|
||||
floater->title);
|
||||
root_scratchpad_show(floater);
|
||||
return;
|
||||
}
|
||||
|
|
@ -46,25 +44,23 @@ static void scratchpad_toggle_auto(void) {
|
|||
|
||||
// Check if there is a visible scratchpad window on another workspace.
|
||||
// In this case we move it to the current workspace.
|
||||
for (int i = 0; i < root_container.sway_root->scratchpad->length; ++i) {
|
||||
struct sway_container *con =
|
||||
root_container.sway_root->scratchpad->items[i];
|
||||
for (int i = 0; i < root->scratchpad->length; ++i) {
|
||||
struct sway_container *con = root->scratchpad->items[i];
|
||||
if (con->parent) {
|
||||
wlr_log(WLR_DEBUG,
|
||||
"Moving a visible scratchpad window (%s) to this workspace",
|
||||
con->name);
|
||||
con->title);
|
||||
root_scratchpad_show(con);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Take the container at the bottom of the scratchpad list
|
||||
if (!sway_assert(root_container.sway_root->scratchpad->length,
|
||||
"Scratchpad is empty")) {
|
||||
if (!sway_assert(root->scratchpad->length, "Scratchpad is empty")) {
|
||||
return;
|
||||
}
|
||||
struct sway_container *con = root_container.sway_root->scratchpad->items[0];
|
||||
wlr_log(WLR_DEBUG, "Showing %s from list", con->name);
|
||||
struct sway_container *con = root->scratchpad->items[0];
|
||||
wlr_log(WLR_DEBUG, "Showing %s from list", con->title);
|
||||
root_scratchpad_show(con);
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +70,7 @@ static void scratchpad_toggle_container(struct sway_container *con) {
|
|||
}
|
||||
|
||||
// Check if it matches a currently visible scratchpad window and hide it.
|
||||
if (con->parent) {
|
||||
if (con->workspace) {
|
||||
root_scratchpad_hide(con);
|
||||
return;
|
||||
}
|
||||
|
|
@ -91,18 +87,18 @@ struct cmd_results *cmd_scratchpad(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "scratchpad",
|
||||
"Expected 'scratchpad show'");
|
||||
}
|
||||
if (!root_container.sway_root->scratchpad->length) {
|
||||
if (!root->scratchpad->length) {
|
||||
return cmd_results_new(CMD_INVALID, "scratchpad",
|
||||
"Scratchpad is empty");
|
||||
}
|
||||
|
||||
if (config->handler_context.using_criteria) {
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
|
||||
// If the container is in a floating split container,
|
||||
// operate on the split container instead of the child.
|
||||
if (container_is_floating_or_child(con)) {
|
||||
while (con->parent->type != C_WORKSPACE) {
|
||||
while (con->parent) {
|
||||
con = con->parent;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "cursor", expected_syntax);
|
||||
}
|
||||
// map absolute coords (0..1,0..1) to root container coords
|
||||
float x = strtof(argv[1], NULL) / root_container.width;
|
||||
float y = strtof(argv[2], NULL) / root_container.height;
|
||||
float x = strtof(argv[1], NULL) / root->width;
|
||||
float y = strtof(argv[2], NULL) / root->height;
|
||||
wlr_cursor_warp_absolute(cursor->cursor, NULL, x, y);
|
||||
cursor_send_pointer_motion(cursor, 0, true);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
#include "util.h"
|
||||
|
||||
static void rebuild_marks_iterator(struct sway_container *con, void *data) {
|
||||
if (con->type == C_VIEW) {
|
||||
view_update_marks_textures(con->sway_view);
|
||||
if (con->view) {
|
||||
view_update_marks_textures(con->view);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -28,9 +28,9 @@ struct cmd_results *cmd_show_marks(int argc, char **argv) {
|
|||
root_for_each_container(rebuild_marks_iterator, NULL);
|
||||
}
|
||||
|
||||
for (int i = 0; i < root_container.children->length; ++i) {
|
||||
struct sway_container *con = root_container.children->items[i];
|
||||
output_damage_whole(con->sway_output);
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
output_damage_whole(output);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ struct cmd_results *cmd_smart_gaps(int argc, char **argv) {
|
|||
"Expected 'smart_gaps <on|off>' ");
|
||||
}
|
||||
|
||||
arrange_windows(&root_container);
|
||||
arrange_root();
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,21 @@
|
|||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "log.h"
|
||||
|
||||
static struct cmd_results *do_split(int layout) {
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *parent = container_split(con, layout);
|
||||
container_create_notify(parent);
|
||||
arrange_windows(parent->parent);
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
struct sway_workspace *ws = config->handler_context.workspace;
|
||||
if (con) {
|
||||
container_split(con, layout);
|
||||
} else {
|
||||
workspace_split(ws, layout);
|
||||
}
|
||||
|
||||
arrange_workspace(ws);
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
@ -29,10 +35,9 @@ struct cmd_results *cmd_split(int argc, char **argv) {
|
|||
return do_split(L_HORIZ);
|
||||
} else if (strcasecmp(argv[0], "t") == 0 ||
|
||||
strcasecmp(argv[0], "toggle") == 0) {
|
||||
struct sway_container *focused =
|
||||
config->handler_context.current_container;
|
||||
struct sway_container *focused = config->handler_context.container;
|
||||
|
||||
if (focused->parent->layout == L_VERT) {
|
||||
if (focused && container_parent_layout(focused) == L_VERT) {
|
||||
return do_split(L_HORIZ);
|
||||
} else {
|
||||
return do_split(L_VERT);
|
||||
|
|
@ -66,9 +71,9 @@ struct cmd_results *cmd_splitt(int argc, char **argv) {
|
|||
return error;
|
||||
}
|
||||
|
||||
struct sway_container *con = config->handler_context.current_container;
|
||||
struct sway_container *con = config->handler_context.container;
|
||||
|
||||
if (con->parent->layout == L_VERT) {
|
||||
if (con && container_parent_layout(con) == L_VERT) {
|
||||
return do_split(L_HORIZ);
|
||||
} else {
|
||||
return do_split(L_VERT);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ struct cmd_results *cmd_sticky(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "sticky", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
if (!container_is_floating(container)) {
|
||||
return cmd_results_new(CMD_FAILURE, "sticky",
|
||||
"Can't set sticky on a tiled container");
|
||||
|
|
@ -37,20 +36,16 @@ struct cmd_results *cmd_sticky(int argc, char **argv) {
|
|||
container->is_sticky = wants_sticky;
|
||||
|
||||
if (wants_sticky) {
|
||||
// move container to focused workspace
|
||||
struct sway_container *output = container_parent(container, C_OUTPUT);
|
||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||
struct sway_container *focus = seat_get_focus_inactive(seat, output);
|
||||
struct sway_container *focused_workspace = container_parent(focus, C_WORKSPACE);
|
||||
struct sway_container *current_workspace = container_parent(container, C_WORKSPACE);
|
||||
if (current_workspace != focused_workspace) {
|
||||
container_remove_child(container);
|
||||
workspace_add_floating(focused_workspace, container);
|
||||
container_handle_fullscreen_reparent(container, current_workspace);
|
||||
arrange_windows(focused_workspace);
|
||||
if (!container_reap_empty(current_workspace)) {
|
||||
arrange_windows(current_workspace);
|
||||
}
|
||||
// move container to active workspace
|
||||
struct sway_workspace *active_workspace =
|
||||
output_get_active_workspace(container->workspace->output);
|
||||
if (container->workspace != active_workspace) {
|
||||
struct sway_workspace *old_workspace = container->workspace;
|
||||
container_detach(container);
|
||||
workspace_add_floating(active_workspace, container);
|
||||
container_handle_fullscreen_reparent(container);
|
||||
arrange_workspace(active_workspace);
|
||||
workspace_consider_destroy(old_workspace);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
|
@ -43,27 +44,28 @@ static void swap_focus(struct sway_container *con1,
|
|||
struct sway_container *con2, struct sway_seat *seat,
|
||||
struct sway_container *focus) {
|
||||
if (focus == con1 || focus == con2) {
|
||||
struct sway_container *ws1 = container_parent(con1, C_WORKSPACE);
|
||||
struct sway_container *ws2 = container_parent(con2, C_WORKSPACE);
|
||||
if (focus == con1 && (con2->parent->layout == L_TABBED
|
||||
|| con2->parent->layout == L_STACKED)) {
|
||||
struct sway_workspace *ws1 = con1->workspace;
|
||||
struct sway_workspace *ws2 = con2->workspace;
|
||||
enum sway_container_layout layout1 = container_parent_layout(con1);
|
||||
enum sway_container_layout layout2 = container_parent_layout(con2);
|
||||
if (focus == con1 && (layout2 == L_TABBED || layout2 == L_STACKED)) {
|
||||
if (workspace_is_visible(ws2)) {
|
||||
seat_set_focus_warp(seat, con2, false, true);
|
||||
seat_set_focus_warp(seat, &con2->node, false, true);
|
||||
}
|
||||
seat_set_focus(seat, ws1 != ws2 ? con2 : con1);
|
||||
} else if (focus == con2 && (con1->parent->layout == L_TABBED
|
||||
|| con1->parent->layout == L_STACKED)) {
|
||||
seat_set_focus(seat, ws1 != ws2 ? &con2->node : &con1->node);
|
||||
} else if (focus == con2 && (layout1 == L_TABBED
|
||||
|| layout1 == L_STACKED)) {
|
||||
if (workspace_is_visible(ws1)) {
|
||||
seat_set_focus_warp(seat, con1, false, true);
|
||||
seat_set_focus_warp(seat, &con1->node, false, true);
|
||||
}
|
||||
seat_set_focus(seat, ws1 != ws2 ? con1 : con2);
|
||||
seat_set_focus(seat, ws1 != ws2 ? &con1->node : &con2->node);
|
||||
} else if (ws1 != ws2) {
|
||||
seat_set_focus(seat, focus == con1 ? con2 : con1);
|
||||
seat_set_focus(seat, focus == con1 ? &con2->node : &con1->node);
|
||||
} else {
|
||||
seat_set_focus(seat, focus);
|
||||
seat_set_focus(seat, &focus->node);
|
||||
}
|
||||
} else {
|
||||
seat_set_focus(seat, focus);
|
||||
seat_set_focus(seat, &focus->node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,10 +74,6 @@ static void container_swap(struct sway_container *con1,
|
|||
if (!sway_assert(con1 && con2, "Cannot swap with nothing")) {
|
||||
return;
|
||||
}
|
||||
if (!sway_assert(con1->type >= C_CONTAINER && con2->type >= C_CONTAINER,
|
||||
"Can only swap containers and views")) {
|
||||
return;
|
||||
}
|
||||
if (!sway_assert(!container_has_ancestor(con1, con2)
|
||||
&& !container_has_ancestor(con2, con1),
|
||||
"Cannot swap ancestor and descendant")) {
|
||||
|
|
@ -87,10 +85,11 @@ static void container_swap(struct sway_container *con1,
|
|||
return;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
|
||||
wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu",
|
||||
con1->node.id, con2->node.id);
|
||||
|
||||
int fs1 = con1->is_fullscreen;
|
||||
int fs2 = con2->is_fullscreen;
|
||||
bool fs1 = con1->is_fullscreen;
|
||||
bool fs2 = con2->is_fullscreen;
|
||||
if (fs1) {
|
||||
container_set_fullscreen(con1, false);
|
||||
}
|
||||
|
|
@ -99,13 +98,11 @@ static void container_swap(struct sway_container *con1,
|
|||
}
|
||||
|
||||
struct sway_seat *seat = input_manager_get_default_seat(input_manager);
|
||||
struct sway_container *focus = seat_get_focus(seat);
|
||||
struct sway_container *vis1 = container_parent(
|
||||
seat_get_focus_inactive(seat, container_parent(con1, C_OUTPUT)),
|
||||
C_WORKSPACE);
|
||||
struct sway_container *vis2 = container_parent(
|
||||
seat_get_focus_inactive(seat, container_parent(con2, C_OUTPUT)),
|
||||
C_WORKSPACE);
|
||||
struct sway_container *focus = seat_get_focused_container(seat);
|
||||
struct sway_workspace *vis1 =
|
||||
output_get_active_workspace(con1->workspace->output);
|
||||
struct sway_workspace *vis2 =
|
||||
output_get_active_workspace(con2->workspace->output);
|
||||
|
||||
char *stored_prev_name = NULL;
|
||||
if (prev_workspace_name) {
|
||||
|
|
@ -115,10 +112,10 @@ static void container_swap(struct sway_container *con1,
|
|||
swap_places(con1, con2);
|
||||
|
||||
if (!workspace_is_visible(vis1)) {
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, vis1));
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, &vis1->node));
|
||||
}
|
||||
if (!workspace_is_visible(vis2)) {
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, vis2));
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, &vis2->node));
|
||||
}
|
||||
|
||||
swap_focus(con1, con2, seat, focus);
|
||||
|
|
@ -137,23 +134,22 @@ static void container_swap(struct sway_container *con1,
|
|||
}
|
||||
|
||||
static bool test_con_id(struct sway_container *container, void *con_id) {
|
||||
return container->id == (size_t)con_id;
|
||||
return container->node.id == (size_t)con_id;
|
||||
}
|
||||
|
||||
static bool test_id(struct sway_container *container, void *id) {
|
||||
#ifdef HAVE_XWAYLAND
|
||||
xcb_window_t *wid = id;
|
||||
return (container->type == C_VIEW
|
||||
&& container->sway_view->type == SWAY_VIEW_XWAYLAND
|
||||
&& container->sway_view->wlr_xwayland_surface->window_id == *wid);
|
||||
return (container->view && container->view->type == SWAY_VIEW_XWAYLAND
|
||||
&& container->view->wlr_xwayland_surface->window_id == *wid);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool test_mark(struct sway_container *container, void *mark) {
|
||||
if (container->type == C_VIEW && container->sway_view->marks->length) {
|
||||
return !list_seq_find(container->sway_view->marks,
|
||||
if (container->view && container->view->marks->length) {
|
||||
return !list_seq_find(container->view->marks,
|
||||
(int (*)(const void *, const void *))strcmp, mark);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -169,7 +165,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|
|||
return cmd_results_new(CMD_INVALID, "swap", EXPECTED_SYNTAX);
|
||||
}
|
||||
|
||||
struct sway_container *current = config->handler_context.current_container;
|
||||
struct sway_container *current = config->handler_context.container;
|
||||
struct sway_container *other;
|
||||
|
||||
char *value = join_args(argv + 3, argc - 3);
|
||||
|
|
@ -191,7 +187,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|
|||
if (!other) {
|
||||
error = cmd_results_new(CMD_FAILURE, "swap",
|
||||
"Failed to find %s '%s'", argv[2], value);
|
||||
} else if (current->type < C_CONTAINER || other->type < C_CONTAINER) {
|
||||
} else if (!current) {
|
||||
error = cmd_results_new(CMD_FAILURE, "swap",
|
||||
"Can only swap with containers and views");
|
||||
} else if (container_has_ancestor(current, other)
|
||||
|
|
@ -211,9 +207,9 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
|
|||
|
||||
container_swap(current, other);
|
||||
|
||||
arrange_windows(current->parent);
|
||||
if (other->parent != current->parent) {
|
||||
arrange_windows(other->parent);
|
||||
arrange_node(node_get_parent(¤t->node));
|
||||
if (node_get_parent(&other->node) != node_get_parent(¤t->node)) {
|
||||
arrange_node(node_get_parent(&other->node));
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -11,13 +11,12 @@ struct cmd_results *cmd_title_format(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "title_format", EXPECTED_AT_LEAST, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type != C_VIEW) {
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
if (!container->view) {
|
||||
return cmd_results_new(CMD_INVALID, "title_format",
|
||||
"Only views can have a title_format");
|
||||
}
|
||||
struct sway_view *view = container->sway_view;
|
||||
struct sway_view *view = container->view;
|
||||
char *format = join_args(argv, argc);
|
||||
if (view->title_format) {
|
||||
free(view->title_format);
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
#include "stringop.h"
|
||||
|
||||
static void remove_all_marks_iterator(struct sway_container *con, void *data) {
|
||||
if (con->type == C_VIEW) {
|
||||
view_clear_marks(con->sway_view);
|
||||
view_update_marks_textures(con->sway_view);
|
||||
if (con->view) {
|
||||
view_clear_marks(con->view);
|
||||
view_update_marks_textures(con->view);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -24,13 +24,12 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
|
|||
// Determine the view
|
||||
struct sway_view *view = NULL;
|
||||
if (config->handler_context.using_criteria) {
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type != C_VIEW) {
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
if (!container->view) {
|
||||
return cmd_results_new(CMD_INVALID, "unmark",
|
||||
"Only views can have marks");
|
||||
}
|
||||
view = container->sway_view;
|
||||
view = container->view;
|
||||
}
|
||||
|
||||
// Determine the mark
|
||||
|
|
|
|||
|
|
@ -11,13 +11,12 @@ struct cmd_results *cmd_urgent(int argc, char **argv) {
|
|||
if ((error = checkarg(argc, "urgent", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
struct sway_container *container =
|
||||
config->handler_context.current_container;
|
||||
if (container->type != C_VIEW) {
|
||||
struct sway_container *container = config->handler_context.container;
|
||||
if (!container->view) {
|
||||
return cmd_results_new(CMD_INVALID, "urgent",
|
||||
"Only views can be urgent");
|
||||
}
|
||||
struct sway_view *view = container->sway_view;
|
||||
struct sway_view *view = container->view;
|
||||
|
||||
if (strcmp(argv[0], "allow") == 0) {
|
||||
view->allow_request_urgent = true;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
|
|||
}
|
||||
|
||||
|
||||
struct sway_container *ws = NULL;
|
||||
struct sway_workspace *ws = NULL;
|
||||
if (strcasecmp(argv[0], "number") == 0) {
|
||||
if (argc < 2) {
|
||||
return cmd_results_new(CMD_INVALID, "workspace",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue