commands: Learn mouse_warping.

Place mouse at center of focused view when changing to a workspace on a
different output, if option is enabled. (This replicates existing i3
option.)

This can be triggered in multiple ways:
A) via `workspace <name>` which changes output
B) via `focus <direction>` which changes output
C) via `focus output <name>` which (obviously) changes output
This commit is contained in:
S. Christoffer Eliesen 2015-10-26 12:20:32 +01:00
parent 4799d07ac1
commit 78ca619769
6 changed files with 64 additions and 9 deletions

View file

@ -2,6 +2,7 @@
#define _SWAY_COMMANDS_H #define _SWAY_COMMANDS_H
#include <stdbool.h> #include <stdbool.h>
#include <json-c/json.h> #include <json-c/json.h>
#include <wlc/wlc.h>
#include "config.h" #include "config.h"

View file

@ -66,6 +66,7 @@ extern struct pointer_state {
} pointer_state; } pointer_state;
void pointer_position_set(struct wlc_origin *new_origin, bool force_focus); void pointer_position_set(struct wlc_origin *new_origin, bool force_focus);
void center_pointer_on(swayc_t *view);
// on button release unset mode depending on the button. // on button release unset mode depending on the button.
// on button press set mode conditionally depending on the button // on button press set mode conditionally depending on the button

View file

@ -102,6 +102,10 @@ Commands
Moves the focused container to the workspace identified by _name_. Moves the focused container to the workspace identified by _name_.
_name_ may be a special workspace name. See **workspace**. _name_ may be a special workspace name. See **workspace**.
**mouse_warping** <output|none>::
When _output_: place mouse at center of newly focused window when changing
output. When _none_: don't move mouse.
**output** <name> <resolution|res WIDTHxHEIGHT> <position|pos X,Y>:: **output** <name> <resolution|res WIDTHxHEIGHT> <position|pos X,Y>::
Configures the specified output. It will use the given resolution and be Configures the specified output. It will use the given resolution and be
arranged at the given position in the layout tree. You may omit either of arranged at the given position in the layout tree. You may omit either of

View file

@ -21,6 +21,7 @@
#include "handlers.h" #include "handlers.h"
#include "sway.h" #include "sway.h"
#include "resize.h" #include "resize.h"
#include "input_state.h"
typedef struct cmd_results *sway_cmd(int argc, char **argv); typedef struct cmd_results *sway_cmd(int argc, char **argv);
@ -45,6 +46,7 @@ static sway_cmd cmd_kill;
static sway_cmd cmd_layout; static sway_cmd cmd_layout;
static sway_cmd cmd_log_colors; static sway_cmd cmd_log_colors;
static sway_cmd cmd_mode; static sway_cmd cmd_mode;
static sway_cmd cmd_mouse_warping;
static sway_cmd cmd_move; static sway_cmd cmd_move;
static sway_cmd cmd_output; static sway_cmd cmd_output;
static sway_cmd cmd_reload; static sway_cmd cmd_reload;
@ -383,9 +385,13 @@ static struct cmd_results *cmd_focus(int argc, char **argv) {
} else if (!workspace_switch(swayc_active_workspace_for(output))) { } else if (!workspace_switch(swayc_active_workspace_for(output))) {
return cmd_results_new(CMD_FAILURE, "focus output", return cmd_results_new(CMD_FAILURE, "focus output",
"Switching to workspace on output '%s' was blocked", argv[1]); "Switching to workspace on output '%s' was blocked", argv[1]);
} else { } else if (config->mouse_warping) {
return cmd_results_new(CMD_SUCCESS, NULL, NULL); swayc_t *focused = get_focused_view(output);
if (focused && focused->type == C_VIEW) {
center_pointer_on(focused);
}
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} else if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) { } else if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) {
return error; return error;
} }
@ -528,6 +534,20 @@ static struct cmd_results *cmd_mode(int argc, char **argv) {
return cmd_results_new(mode_make ? CMD_BLOCK_MODE : CMD_SUCCESS, NULL, NULL); return cmd_results_new(mode_make ? CMD_BLOCK_MODE : CMD_SUCCESS, NULL, NULL);
} }
static struct cmd_results *cmd_mouse_warping(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "mouse_warping", EXPECTED_EQUAL_TO, 1))) {
return error;
} else if (strcasecmp(argv[0], "output") == 0) {
config->mouse_warping = true;
} else if (strcasecmp(argv[0], "none") == 0) {
config->mouse_warping = false;
} else {
return cmd_results_new(CMD_FAILURE, "mouse_warping", "Expected 'mouse_warping output|none'");
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
static struct cmd_results *cmd_move(int argc, char **argv) { static struct cmd_results *cmd_move(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
if (config->reading) return cmd_results_new(CMD_FAILURE, "move", "Can't be used in config file."); if (config->reading) return cmd_results_new(CMD_FAILURE, "move", "Can't be used in config file.");
@ -1165,7 +1185,16 @@ static struct cmd_results *cmd_workspace(int argc, char **argv) {
ws = workspace_create(argv[0]); ws = workspace_create(argv[0]);
} }
} }
swayc_t *old_output = swayc_active_output();
workspace_switch(ws); workspace_switch(ws);
swayc_t *new_output = swayc_active_output();
if (config->mouse_warping && old_output != new_output) {
swayc_t *focused = get_focused_view(ws);
if (focused && focused->type == C_VIEW) {
center_pointer_on(focused);
}
}
} else { } else {
if (strcasecmp(argv[1], "output") == 0) { if (strcasecmp(argv[1], "output") == 0) {
if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 3))) { if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, 3))) {
@ -1217,6 +1246,7 @@ static struct cmd_handler handlers[] = {
{ "layout", cmd_layout }, { "layout", cmd_layout },
{ "log_colors", cmd_log_colors }, { "log_colors", cmd_log_colors },
{ "mode", cmd_mode }, { "mode", cmd_mode },
{ "mouse_warping", cmd_mouse_warping },
{ "move", cmd_move }, { "move", cmd_move },
{ "output", cmd_output }, { "output", cmd_output },
{ "reload", cmd_reload }, { "reload", cmd_reload },

View file

@ -4,6 +4,8 @@
#include "log.h" #include "log.h"
#include "workspace.h" #include "workspace.h"
#include "layout.h" #include "layout.h"
#include "config.h"
#include "input_state.h"
bool locked_container_focus = false; bool locked_container_focus = false;
bool locked_view_focus = false; bool locked_view_focus = false;
@ -49,14 +51,24 @@ static void update_focus(swayc_t *c) {
} }
bool move_focus(enum movement_direction direction) { bool move_focus(enum movement_direction direction) {
swayc_t *view = get_focused_container(&root_container); swayc_t *old_view = get_focused_container(&root_container);
view = get_swayc_in_direction(view, direction); swayc_t *new_view = get_swayc_in_direction(old_view, direction);
if (view) { if (!new_view) {
if (direction == MOVE_PARENT) { return false;
return set_focused_container(view); } else if (direction == MOVE_PARENT) {
} else { return set_focused_container(new_view);
return set_focused_container(get_focused_view(view)); } else if (config->mouse_warping) {
swayc_t *old_op = old_view->type == C_OUTPUT ?
old_view : swayc_parent_by_type(old_view, C_OUTPUT);
swayc_t *focused = get_focused_view(new_view);
if (set_focused_container(focused)) {
if (old_op != swayc_active_output() && focused && focused->type == C_VIEW) {
center_pointer_on(focused);
}
return true;
} }
} else {
return set_focused_container(get_focused_view(new_view));
} }
return false; return false;
} }

View file

@ -185,6 +185,13 @@ void pointer_position_set(struct wlc_origin *new_origin, bool force_focus) {
wlc_pointer_set_origin(new_origin); wlc_pointer_set_origin(new_origin);
} }
void center_pointer_on(swayc_t *view) {
struct wlc_origin new_origin;
new_origin.x = view->x + view->width/2;
new_origin.y = view->y + view->height/2;
pointer_position_set(&new_origin, true);
}
// Mode set left/right click // Mode set left/right click
static void pointer_mode_set_left(void) { static void pointer_mode_set_left(void) {