aboutsummaryrefslogtreecommitdiff
path: root/sway/input_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input_state.c')
-rw-r--r--sway/input_state.c490
1 files changed, 0 insertions, 490 deletions
diff --git a/sway/input_state.c b/sway/input_state.c
deleted file mode 100644
index 04aafd37..00000000
--- a/sway/input_state.c
+++ /dev/null
@@ -1,490 +0,0 @@
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include "sway/input_state.h"
-#include "sway/config.h"
-#include "log.h"
-
-#define KEY_STATE_MAX_LENGTH 64
-
-struct key_state {
- /*
- * Aims to store state regardless of modifiers.
- * If you press a key, then hold shift, then release the key, we'll
- * get two different key syms, but the same key code. This handles
- * that scenario and makes sure we can use the right bindings.
- */
- uint32_t key_sym;
- uint32_t alt_sym;
- uint32_t key_code;
-};
-
-static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
-
-static struct key_state last_released;
-
-static uint32_t modifiers_state;
-
-void input_init(void) {
- int i;
- for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
- struct key_state none = { 0, 0, 0 };
- key_state_array[i] = none;
- }
-
- struct key_state none = { 0, 0, 0 };
- last_released = none;
-
- modifiers_state = 0;
-}
-
-uint32_t modifier_state_changed(uint32_t new_state, uint32_t mod) {
- if ((new_state & mod) != 0) { // pressed
- if ((modifiers_state & mod) != 0) { // already pressed
- return MOD_STATE_UNCHANGED;
- } else { // pressed
- return MOD_STATE_PRESSED;
- }
- } else { // not pressed
- if ((modifiers_state & mod) != 0) { // released
- return MOD_STATE_RELEASED;
- } else { // already released
- return MOD_STATE_UNCHANGED;
- }
- }
-}
-
-void modifiers_state_update(uint32_t new_state) {
- modifiers_state = new_state;
-}
-
-static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {
- int i;
- for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
- if (0 == key_sym && 0 == key_code && key_state_array[i].key_sym == 0) {
- break;
- }
- if (key_sym != 0 && (key_state_array[i].key_sym == key_sym
- || key_state_array[i].alt_sym == key_sym)) {
- break;
- }
- if (update && key_state_array[i].key_code == key_code) {
- key_state_array[i].alt_sym = key_sym;
- break;
- }
- if (key_sym == 0 && key_code != 0 && key_state_array[i].key_code == key_code) {
- break;
- }
- }
- return i;
-}
-
-bool check_key(uint32_t key_sym, uint32_t key_code) {
- return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
-}
-
-bool check_released_key(uint32_t key_sym) {
- return (key_sym != 0
- && (last_released.key_sym == key_sym
- || last_released.alt_sym == key_sym));
-}
-
-void press_key(uint32_t key_sym, uint32_t key_code) {
- if (key_code == 0) {
- return;
- }
- // Check if key exists
- if (!check_key(key_sym, key_code)) {
- // Check that we don't exceed buffer length
- int insert = find_key(0, 0, true);
- if (insert < KEY_STATE_MAX_LENGTH) {
- key_state_array[insert].key_sym = key_sym;
- key_state_array[insert].key_code = key_code;
- }
- }
-}
-
-void release_key(uint32_t key_sym, uint32_t key_code) {
- uint8_t index = find_key(key_sym, key_code, true);
- if (index < KEY_STATE_MAX_LENGTH) {
- last_released.key_sym = key_state_array[index].key_sym;
- last_released.alt_sym = key_state_array[index].alt_sym;
- last_released.key_code = key_state_array[index].key_code;
- struct key_state none = { 0, 0, 0 };
- key_state_array[index] = none;
- }
-}
-
-// Pointer state and mode
-
-struct pointer_state pointer_state;
-
-static struct mode_state {
- // initial view state
- double x, y, w, h;
- swayc_t *ptr;
- // Containers used for resizing horizontally
- struct {
- double w;
- swayc_t *ptr;
- struct {
- double w;
- swayc_t *ptr;
- } parent;
- } horiz;
- // Containers used for resizing vertically
- struct {
- double h;
- swayc_t *ptr;
- struct {
- double h;
- swayc_t *ptr;
- } parent;
- } vert;
-} initial;
-
-static struct {
- bool left;
- bool top;
-} lock;
-
-// initial set/unset
-
-static void set_initial_view(swayc_t *view) {
- initial.ptr = view;
- initial.x = view->x;
- initial.y = view->y;
- initial.w = view->width;
- initial.h = view->height;
-}
-
-static void set_initial_sibling(void) {
- bool reset = true;
- swayc_t *ws = swayc_active_workspace_for(initial.ptr);
- if ((initial.horiz.ptr = get_swayc_in_direction_under(initial.ptr,
- lock.left ? MOVE_RIGHT: MOVE_LEFT, ws))) {
- initial.horiz.w = initial.horiz.ptr->width;
- initial.horiz.parent.ptr = get_swayc_in_direction_under(initial.horiz.ptr,
- lock.left ? MOVE_LEFT : MOVE_RIGHT, ws);
- initial.horiz.parent.w = initial.horiz.parent.ptr->width;
- reset = false;
- }
- if ((initial.vert.ptr = get_swayc_in_direction_under(initial.ptr,
- lock.top ? MOVE_DOWN: MOVE_UP, ws))) {
- initial.vert.h = initial.vert.ptr->height;
- initial.vert.parent.ptr = get_swayc_in_direction_under(initial.vert.ptr,
- lock.top ? MOVE_UP : MOVE_DOWN, ws);
- initial.vert.parent.h = initial.vert.parent.ptr->height;
- reset = false;
- }
- // If nothing will change just undo the mode
- if (reset) {
- pointer_state.mode = 0;
- }
-}
-
-static void reset_initial_view(void) {
- initial.ptr->x = initial.x;
- initial.ptr->y = initial.y;
- initial.ptr->width = initial.w;
- initial.ptr->height = initial.h;
- arrange_windows(initial.ptr, -1, -1);
- pointer_state.mode = 0;
-}
-
-static void reset_initial_sibling(void) {
- initial.horiz.ptr->width = initial.horiz.w;
- initial.horiz.parent.ptr->width = initial.horiz.parent.w;
- initial.vert.ptr->height = initial.vert.h;
- initial.vert.parent.ptr->height = initial.vert.parent.h;
- arrange_windows(initial.horiz.ptr->parent, -1, -1);
- arrange_windows(initial.vert.ptr->parent, -1, -1);
- pointer_state.mode = 0;
-}
-
-void pointer_position_set(double new_x, double new_y, bool force_focus) {
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- pointer_state.delta.x = new_x - x;
- pointer_state.delta.y = new_y - y;
-
- wlc_pointer_set_position_v2(new_x, new_y);
-
- // Update view under pointer
- swayc_t *prev_view = pointer_state.view;
- pointer_state.view = container_under_pointer();
-
- // If pointer is in a mode, update it
- if (pointer_state.mode) {
- pointer_mode_update();
- // Otherwise change focus if config is set
- } else if (force_focus || (prev_view != pointer_state.view && config->focus_follows_mouse)) {
- if (pointer_state.view && pointer_state.view->type == C_VIEW) {
- set_focused_container(pointer_state.view);
- }
- }
-}
-
-void center_pointer_on(swayc_t *view) {
- pointer_position_set(view->x + view->width/2, view->y + view->height/2, true);
-}
-
-// Mode set left/right click
-
-static void pointer_mode_set_dragging(void) {
- switch (config->dragging_key) {
- case M_LEFT_CLICK:
- set_initial_view(pointer_state.left.view);
- break;
- case M_RIGHT_CLICK:
- set_initial_view(pointer_state.right.view);
- break;
- }
-
- if (initial.ptr->is_floating) {
- pointer_state.mode = M_DRAGGING | M_FLOATING;
- } else {
- pointer_state.mode = M_DRAGGING | M_TILING;
- // unset mode if we can't drag tile
- if (initial.ptr->parent->type == C_WORKSPACE &&
- initial.ptr->parent->children->length == 1) {
- pointer_state.mode = 0;
- }
- }
-}
-
-static void pointer_mode_set_resizing(void) {
- switch (config->resizing_key) {
- case M_LEFT_CLICK:
- set_initial_view(pointer_state.left.view);
- break;
- case M_RIGHT_CLICK:
- set_initial_view(pointer_state.right.view);
- break;
- }
- // Setup locking information
- int midway_x = initial.ptr->x + initial.ptr->width/2;
- int midway_y = initial.ptr->y + initial.ptr->height/2;
-
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- lock.left = x > midway_x;
- lock.top = y > midway_y;
-
- if (initial.ptr->is_floating) {
- pointer_state.mode = M_RESIZING | M_FLOATING;
- } else {
- pointer_state.mode = M_RESIZING | M_TILING;
- set_initial_sibling();
- }
-}
-
-// Mode set/update/reset
-
-void pointer_mode_set(uint32_t button, bool condition) {
- // switch on drag/resize mode
- switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) {
- case M_DRAGGING:
- // end drag mode when 'dragging' click is unpressed
- if (config->dragging_key == M_LEFT_CLICK && !pointer_state.left.held) {
- pointer_state.mode = 0;
- } else if (config->dragging_key == M_RIGHT_CLICK && !pointer_state.right.held) {
- pointer_state.mode = 0;
- }
- break;
-
- case M_RESIZING:
- // end resize mode when 'resizing' click is unpressed
- if (config->resizing_key == M_LEFT_CLICK && !pointer_state.left.held) {
- pointer_state.mode = 0;
- } else if (config->resizing_key == M_RIGHT_CLICK && !pointer_state.right.held) {
- pointer_state.mode = 0;
- }
- break;
-
- // No mode case
- default:
- // return if failed condition, or no view
- if (!condition || !pointer_state.view) {
- break;
- }
-
- // Set mode depending on current button press
- switch (button) {
- // Start left-click mode
- case M_LEFT_CLICK:
- // if button release don't do anything
- if (pointer_state.left.held) {
- if (config->dragging_key == M_LEFT_CLICK) {
- pointer_mode_set_dragging();
- } else if (config->resizing_key == M_LEFT_CLICK) {
- pointer_mode_set_resizing();
- }
- }
- break;
-
- // Start right-click mode
- case M_RIGHT_CLICK:
- // if button release don't do anyhting
- if (pointer_state.right.held) {
- if (config->dragging_key == M_RIGHT_CLICK) {
- pointer_mode_set_dragging();
- } else if (config->resizing_key == M_RIGHT_CLICK) {
- pointer_mode_set_resizing();
- }
- }
- break;
- }
- }
-}
-
-void pointer_mode_update(void) {
- if (initial.ptr->type != C_VIEW) {
- pointer_state.mode = 0;
- return;
- }
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- int dx = x;
- int dy = y;
-
- switch (pointer_state.mode) {
- case M_FLOATING | M_DRAGGING:
- // Update position
- switch (config->dragging_key) {
- case M_LEFT_CLICK:
- dx -= pointer_state.left.x;
- dy -= pointer_state.left.y;
- break;
- case M_RIGHT_CLICK:
- dx -= pointer_state.right.x;
- dy -= pointer_state.right.y;
- break;
- }
-
- if (initial.x + dx != initial.ptr->x) {
- initial.ptr->x = initial.x + dx;
- }
- if (initial.y + dy != initial.ptr->y) {
- initial.ptr->y = initial.y + dy;
- }
- update_geometry(initial.ptr);
- break;
-
- case M_FLOATING | M_RESIZING:
- switch (config->resizing_key) {
- case M_LEFT_CLICK:
- dx -= pointer_state.left.x;
- dy -= pointer_state.left.y;
- initial.ptr = pointer_state.left.view;
- break;
- case M_RIGHT_CLICK:
- dx -= pointer_state.right.x;
- dy -= pointer_state.right.y;
- initial.ptr = pointer_state.right.view;
- break;
- }
-
- if (lock.left) {
- if (initial.w + dx > min_sane_w) {
- initial.ptr->width = initial.w + dx;
- }
- } else { // lock.right
- if (initial.w - dx > min_sane_w) {
- initial.ptr->width = initial.w - dx;
- initial.ptr->x = initial.x + dx;
- }
- }
- if (lock.top) {
- if (initial.h + dy > min_sane_h) {
- initial.ptr->height = initial.h + dy;
- }
- } else { // lock.bottom
- if (initial.h - dy > min_sane_h) {
- initial.ptr->height = initial.h - dy;
- initial.ptr->y = initial.y + dy;
- }
- }
- update_geometry(initial.ptr);
- break;
-
- case M_TILING | M_DRAGGING:
- // swap current view under pointer with dragged view
- if (pointer_state.view && pointer_state.view->type == C_VIEW
- && pointer_state.view != initial.ptr
- && !pointer_state.view->is_floating) {
- // Swap them around
- swap_container(pointer_state.view, initial.ptr);
- swap_geometry(pointer_state.view, initial.ptr);
- update_geometry(pointer_state.view);
- update_geometry(initial.ptr);
- // Set focus back to initial view
- set_focused_container(initial.ptr);
- // Arrange the windows
- arrange_windows(&root_container, -1, -1);
- }
- break;
-
- case M_TILING | M_RESIZING:
- switch (config->resizing_key) {
- case M_LEFT_CLICK:
- dx -= pointer_state.left.x;
- dy -= pointer_state.left.y;
- break;
- case M_RIGHT_CLICK:
- dx -= pointer_state.right.x;
- dy -= pointer_state.right.y;
- break;
- }
-
- // resize if we can
- if (initial.horiz.ptr) {
- if (lock.left) {
- // Check whether its fine to resize
- if (initial.w + dx > min_sane_w && initial.horiz.w - dx > min_sane_w) {
- initial.horiz.ptr->width = initial.horiz.w - dx;
- initial.horiz.parent.ptr->width = initial.horiz.parent.w + dx;
- }
- } else { // lock.right
- if (initial.w - dx > min_sane_w && initial.horiz.w + dx > min_sane_w) {
- initial.horiz.ptr->width = initial.horiz.w + dx;
- initial.horiz.parent.ptr->width = initial.horiz.parent.w - dx;
- }
- }
- arrange_windows(initial.horiz.ptr->parent, -1, -1);
- }
- if (initial.vert.ptr) {
- if (lock.top) {
- if (initial.h + dy > min_sane_h && initial.vert.h - dy > min_sane_h) {
- initial.vert.ptr->height = initial.vert.h - dy;
- initial.vert.parent.ptr->height = initial.vert.parent.h + dy;
- }
- } else { // lock.bottom
- if (initial.h - dy > min_sane_h && initial.vert.h + dy > min_sane_h) {
- initial.vert.ptr->height = initial.vert.h + dy;
- initial.vert.parent.ptr->height = initial.vert.parent.h - dy;
- }
- }
- arrange_windows(initial.vert.ptr->parent, -1, -1);
- }
- default:
- return;
- }
-}
-
-void pointer_mode_reset(void) {
- switch (pointer_state.mode) {
- case M_FLOATING | M_RESIZING:
- case M_FLOATING | M_DRAGGING:
- reset_initial_view();
- break;
-
- case M_TILING | M_RESIZING:
- (void) reset_initial_sibling;
- break;
-
- case M_TILING | M_DRAGGING:
- default:
- break;
- }
-}