mirror of
https://github.com/swaywm/sway.git
synced 2026-06-13 14:33:19 -04:00
Merge 9b81b6273f into 3302f1ce5c
This commit is contained in:
commit
ca4f892e6e
5 changed files with 114 additions and 93 deletions
|
|
@ -110,6 +110,9 @@ struct sway_output *output_by_name_or_id(const char *name_or_id);
|
|||
// this includes all the outputs, including disabled ones
|
||||
struct sway_output *all_output_by_name_or_id(const char *name_or_id);
|
||||
|
||||
struct sway_output *output_by_direction_or_name(const char *spec,
|
||||
const struct sway_output *reference, double ref_lx, double ref_ly);
|
||||
|
||||
void output_sort_workspaces(struct sway_output *output);
|
||||
|
||||
void output_enable(struct sway_output *output);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include <float.h>
|
||||
#include <strings.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include "log.h"
|
||||
#include "sway/commands.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
|
|
@ -12,7 +11,6 @@
|
|||
#include "sway/tree/view.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
#include "stringop.h"
|
||||
#include "util.h"
|
||||
|
||||
static bool get_direction_from_next_prev(struct sway_container *container,
|
||||
struct sway_seat *seat, const char *name, enum wlr_direction *out) {
|
||||
|
|
@ -295,43 +293,31 @@ static struct cmd_results *focus_output(struct sway_seat *seat,
|
|||
int argc, char **argv) {
|
||||
if (!argc) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Expected 'focus output <direction|name>'.");
|
||||
"Expected 'focus output <direction|name|next|prev|current>'.");
|
||||
}
|
||||
char *identifier = join_args(argv, argc);
|
||||
struct sway_output *output = output_by_name_or_id(identifier);
|
||||
|
||||
if (!output) {
|
||||
enum wlr_direction direction;
|
||||
if (!parse_direction(identifier, &direction)) {
|
||||
free(identifier);
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"There is no output with that name.");
|
||||
}
|
||||
struct sway_workspace *ws = seat_get_focused_workspace(seat);
|
||||
if (!ws) {
|
||||
free(identifier);
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
"No focused workspace to base directions off of.");
|
||||
struct sway_output *reference = ws ? ws->output : NULL;
|
||||
double ref_lx = 0, ref_ly = 0;
|
||||
if (reference) {
|
||||
ref_lx = reference->lx + reference->width / 2;
|
||||
ref_ly = reference->ly + reference->height / 2;
|
||||
}
|
||||
output = output_get_in_direction(ws->output, direction);
|
||||
|
||||
struct sway_output *output = output_by_direction_or_name(identifier,
|
||||
reference, ref_lx, ref_ly);
|
||||
|
||||
if (!output) {
|
||||
int center_lx = ws->output->lx + ws->output->width / 2;
|
||||
int center_ly = ws->output->ly + ws->output->height / 2;
|
||||
struct wlr_output *target = wlr_output_layout_farthest_output(
|
||||
root->output_layout, opposite_direction(direction),
|
||||
ws->output->wlr_output, center_lx, center_ly);
|
||||
if (target) {
|
||||
output = output_from_wlr_output(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct cmd_results *err = cmd_results_new(CMD_INVALID,
|
||||
"No output matches '%s'.", identifier);
|
||||
free(identifier);
|
||||
if (output) {
|
||||
return err;
|
||||
}
|
||||
free(identifier);
|
||||
|
||||
seat_set_focus(seat, seat_get_focus_inactive(seat, &output->node));
|
||||
seat_consider_warp_to_focus(seat);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL);
|
||||
}
|
||||
|
|
@ -426,7 +412,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
|
|||
if (!get_direction_from_next_prev(container, seat, argv[0], &direction)) {
|
||||
return cmd_results_new(CMD_INVALID,
|
||||
"Expected 'focus <direction|next|prev|parent|child|mode_toggle|floating|tiling>' "
|
||||
"or 'focus output <direction|name>'");
|
||||
"or 'focus output <direction|name|next|prev|current>'");
|
||||
} else if (argc == 2 && strcasecmp(argv[1], "sibling") == 0) {
|
||||
descend = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,58 +24,9 @@
|
|||
static const char expected_syntax[] =
|
||||
"Expected 'move <left|right|up|down> <[px] px>' or "
|
||||
"'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or "
|
||||
"'move <container|window|workspace> [to] output <name|direction>' or "
|
||||
"'move <container|window|workspace> [to] output <name|direction|next|prev|current>' or "
|
||||
"'move <container|window> [to] mark <mark>'";
|
||||
|
||||
static struct sway_output *output_in_direction(const char *direction_string,
|
||||
struct sway_output *reference, int ref_lx, int ref_ly) {
|
||||
if (strcasecmp(direction_string, "current") == 0) {
|
||||
struct sway_workspace *active_ws =
|
||||
seat_get_focused_workspace(config->handler_context.seat);
|
||||
if (!active_ws) {
|
||||
return NULL;
|
||||
}
|
||||
return active_ws->output;
|
||||
}
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
enum wlr_direction direction;
|
||||
} names[] = {
|
||||
{ "up", WLR_DIRECTION_UP },
|
||||
{ "down", WLR_DIRECTION_DOWN },
|
||||
{ "left", WLR_DIRECTION_LEFT },
|
||||
{ "right", WLR_DIRECTION_RIGHT },
|
||||
};
|
||||
|
||||
enum wlr_direction direction = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); ++i) {
|
||||
if (strcasecmp(names[i].name, direction_string) == 0) {
|
||||
direction = names[i].direction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (reference && direction) {
|
||||
struct wlr_output *target = wlr_output_layout_adjacent_output(
|
||||
root->output_layout, direction, reference->wlr_output,
|
||||
ref_lx, ref_ly);
|
||||
|
||||
if (!target) {
|
||||
target = wlr_output_layout_farthest_output(
|
||||
root->output_layout, opposite_direction(direction),
|
||||
reference->wlr_output, ref_lx, ref_ly);
|
||||
}
|
||||
|
||||
if (target) {
|
||||
return target->data;
|
||||
}
|
||||
}
|
||||
|
||||
return output_by_name_or_id(direction_string);
|
||||
}
|
||||
|
||||
static bool is_parallel(enum sway_container_layout layout,
|
||||
enum wlr_direction dir) {
|
||||
switch (layout) {
|
||||
|
|
@ -516,7 +467,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
|
|||
struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws);
|
||||
destination = dst ? &dst->node : &ws->node;
|
||||
} else if (strcasecmp(argv[0], "output") == 0) {
|
||||
struct sway_output *new_output = output_in_direction(argv[1],
|
||||
struct sway_output *new_output = output_by_direction_or_name(argv[1],
|
||||
old_output, container->pending.x, container->pending.y);
|
||||
if (!new_output) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
|
|
@ -650,7 +601,7 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
|
|||
struct sway_output *old_output = workspace->output;
|
||||
int center_x = workspace->width / 2 + workspace->x,
|
||||
center_y = workspace->height / 2 + workspace->y;
|
||||
struct sway_output *new_output = output_in_direction(argv[0],
|
||||
struct sway_output *new_output = output_by_direction_or_name(argv[0],
|
||||
old_output, center_x, center_y);
|
||||
if (!new_output) {
|
||||
return cmd_results_new(CMD_FAILURE,
|
||||
|
|
|
|||
|
|
@ -7,29 +7,22 @@
|
|||
#include <wlr/backend/headless.h>
|
||||
#include <wlr/render/swapchain.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_buffer.h>
|
||||
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_presentation_time.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <wlr/util/transform.h>
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "sway/config.h"
|
||||
#include "sway/desktop/transaction.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/ipc-server.h"
|
||||
#include "sway/layers.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/scene_descriptor.h"
|
||||
#include "sway/server.h"
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/root.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
|
@ -72,6 +65,75 @@ struct sway_output *all_output_by_name_or_id(const char *name_or_id) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct sway_output *output_cycle(const struct sway_output *reference,
|
||||
bool forward) {
|
||||
if (root->outputs->length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
int ref_idx = -1;
|
||||
if (reference) {
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
if (root->outputs->items[i] == reference) {
|
||||
ref_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int next_idx;
|
||||
if (ref_idx < 0) {
|
||||
next_idx = forward ? 0 : root->outputs->length - 1;
|
||||
} else {
|
||||
next_idx = forward
|
||||
? (ref_idx + 1) % root->outputs->length
|
||||
: (ref_idx - 1 + root->outputs->length) % root->outputs->length;
|
||||
}
|
||||
return root->outputs->items[next_idx];
|
||||
}
|
||||
|
||||
struct sway_output *output_by_direction_or_name(const char *spec,
|
||||
const struct sway_output *reference, double ref_lx, double ref_ly) {
|
||||
if (strcasecmp(spec, "current") == 0) {
|
||||
const struct sway_workspace *active_ws =
|
||||
seat_get_focused_workspace(config->handler_context.seat);
|
||||
return active_ws ? active_ws->output : NULL;
|
||||
}
|
||||
|
||||
if (strcasecmp(spec, "next") == 0) {
|
||||
return output_cycle(reference, true);
|
||||
}
|
||||
if (strcasecmp(spec, "prev") == 0) {
|
||||
return output_cycle(reference, false);
|
||||
}
|
||||
|
||||
enum wlr_direction direction = 0;
|
||||
if (strcasecmp(spec, "up") == 0) {
|
||||
direction = WLR_DIRECTION_UP;
|
||||
} else if (strcasecmp(spec, "down") == 0) {
|
||||
direction = WLR_DIRECTION_DOWN;
|
||||
} else if (strcasecmp(spec, "left") == 0) {
|
||||
direction = WLR_DIRECTION_LEFT;
|
||||
} else if (strcasecmp(spec, "right") == 0) {
|
||||
direction = WLR_DIRECTION_RIGHT;
|
||||
}
|
||||
|
||||
if (reference && direction) {
|
||||
struct wlr_output *target = wlr_output_layout_adjacent_output(
|
||||
root->output_layout, direction, reference->wlr_output,
|
||||
ref_lx, ref_ly);
|
||||
|
||||
if (!target) {
|
||||
target = wlr_output_layout_farthest_output(
|
||||
root->output_layout, opposite_direction(direction),
|
||||
reference->wlr_output, ref_lx, ref_ly);
|
||||
}
|
||||
|
||||
if (target) {
|
||||
return target->data;
|
||||
}
|
||||
}
|
||||
|
||||
return output_by_name_or_id(spec);
|
||||
}
|
||||
|
||||
struct sway_workspace *output_get_active_workspace(struct sway_output *output) {
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
|
|
|
|||
|
|
@ -139,6 +139,13 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
|
|||
*focus* output up|right|down|left
|
||||
Moves focus to the next output in the specified direction.
|
||||
|
||||
*focus* output next|prev
|
||||
Moves focus to the next or previous output, wrapping around.
|
||||
|
||||
*focus* output current
|
||||
Moves focus to the output containing the focused workspace. Mainly useful
|
||||
with criteria to refocus the seat's current output.
|
||||
|
||||
*focus* output <name>
|
||||
Moves focus to the named output.
|
||||
|
||||
|
|
@ -275,6 +282,10 @@ set|plus|minus|toggle <amount>
|
|||
Moves the focused container to next output in the specified
|
||||
direction.
|
||||
|
||||
*move* [container|window] [to] output next|prev
|
||||
Moves the focused container to the next or previous output,
|
||||
wrapping around.
|
||||
|
||||
*move* [container|window] [to] scratchpad
|
||||
Moves the focused container to the scratchpad.
|
||||
|
||||
|
|
@ -290,6 +301,14 @@ set|plus|minus|toggle <amount>
|
|||
*move* workspace to [output] up|right|down|left
|
||||
Moves the focused workspace to next output in the specified direction.
|
||||
|
||||
*move* workspace [to] output next|prev
|
||||
Moves the focused workspace to the next or previous output,
|
||||
wrapping around.
|
||||
|
||||
*move* workspace to [output] next|prev
|
||||
Moves the focused workspace to the next or previous output,
|
||||
wrapping around.
|
||||
|
||||
*nop* <comment>
|
||||
A no operation command that can be used to override default behaviour. The
|
||||
optional comment argument is ignored, but logged for debugging purposes.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue