diff --git a/include/focus.h b/include/focus.h index 410ed134..383993fa 100644 --- a/include/focus.h +++ b/include/focus.h @@ -1,7 +1,5 @@ #ifndef _SWAY_FOCUS_H #define _SWAY_FOCUS_H -#include "container.h" - enum movement_direction { MOVE_LEFT, MOVE_RIGHT, @@ -10,6 +8,8 @@ enum movement_direction { MOVE_PARENT }; +#include "container.h" + // focused_container - the container found by following the `focused` pointer // from a given container to a container with `is_focused` boolean set // --- diff --git a/include/input_state.h b/include/input_state.h new file mode 100644 index 00000000..782b4b19 --- /dev/null +++ b/include/input_state.h @@ -0,0 +1,49 @@ +#ifndef _SWAY_KEY_STATE_H +#define _SWAY_KEY_STATE_H +#include +#include +#include "container.h" + +/* Keyboard state */ + +typedef uint32_t keycode; + +// returns true if key has been pressed, otherwise false +bool check_key(keycode key); + +// sets a key as pressed +void press_key(keycode key); + +// unsets a key as pressed +void release_key(keycode key); + +/* Pointer state */ + +enum pointer_values { + M_LEFT_CLICK = 272, + M_RIGHT_CLICK = 273, + M_SCROLL_CLICK = 274, + M_SCROLL_UP = 275, + M_SCROLL_DOWN = 276, +}; + +extern struct pointer_state { + bool l_held; + bool r_held; + struct pointer_floating { + bool drag; + bool resize; + } floating; + struct pointer_lock { + bool left; + bool right; + bool top; + bool bottom; + } lock; +} pointer_state; + +void start_floating(swayc_t *view); +void reset_floating(swayc_t *view); + +#endif + diff --git a/include/key_state.h b/include/key_state.h deleted file mode 100644 index a8fa8d5e..00000000 --- a/include/key_state.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _SWAY_KEY_STATE_H -#define _SWAY_KEY_STATE_H -#include -#include - -typedef uint32_t keycode; - -// returns true if key has been pressed, otherwise false -bool check_key(keycode key); - -// sets a key as pressed -void press_key(keycode key); - -// unsets a key as pressed -void release_key(keycode key); - -#endif - diff --git a/include/layout.h b/include/layout.h index 98fdb531..75e72d2f 100644 --- a/include/layout.h +++ b/include/layout.h @@ -4,6 +4,7 @@ #include #include "list.h" #include "container.h" +#include "focus.h" extern swayc_t root_container; @@ -26,5 +27,6 @@ void focus_view_for(swayc_t *ancestor, swayc_t *container); swayc_t *get_focused_container(swayc_t *parent); swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent); +swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir); #endif diff --git a/sway/commands.c b/sway/commands.c index 66c05a0c..c4cf96a2 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -243,7 +243,6 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) { } // Refocus on the view once its been put back into the layout arrange_windows(active_workspace, -1, -1); - return true; } set_focused_container(view); } diff --git a/sway/focus.c b/sway/focus.c index f76b2d9a..1dbac003 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -3,6 +3,7 @@ #include "focus.h" #include "log.h" #include "workspace.h" +#include "layout.h" bool locked_container_focus = false; bool locked_view_focus = false; @@ -53,74 +54,13 @@ static void update_focus(swayc_t *c) { } bool move_focus(enum movement_direction direction) { - if (locked_container_focus) { - return false; - } - swayc_t *current = get_focused_container(&root_container); - if (current->type == C_VIEW - && wlc_view_get_state(current->handle) & WLC_BIT_FULLSCREEN) { - return false; - } - swayc_t *parent = current->parent; - - if (direction == MOVE_PARENT) { - if (parent->type == C_OUTPUT) { - sway_log(L_DEBUG, "Focus cannot move to parent"); - return false; - } else { - sway_log(L_DEBUG, "Moving focus from %p:%ld to %p:%ld", - current, current->handle, parent, parent->handle); - set_focused_container(parent); - return true; - } - } - - while (true) { - sway_log(L_DEBUG, "Moving focus away from %p", current); - - // Test if we can even make a difference here - bool can_move = false; - int diff = 0; - if (direction == MOVE_LEFT || direction == MOVE_RIGHT) { - if (parent->layout == L_HORIZ || parent->type == C_ROOT) { - can_move = true; - diff = direction == MOVE_LEFT ? -1 : 1; - } - } else { - if (parent->layout == L_VERT) { - can_move = true; - diff = direction == MOVE_UP ? -1 : 1; - } - } - sway_log(L_DEBUG, "Can move? %s", can_move ? "yes" : "no"); - if (can_move) { - int i; - for (i = 0; i < parent->children->length; ++i) { - swayc_t *child = parent->children->items[i]; - if (child == current) { - break; - } - } - int desired = i + diff; - sway_log(L_DEBUG, "Moving from %d to %d", i, desired); - if (desired < 0 || desired >= parent->children->length) { - can_move = false; - } else { - swayc_t *newview = parent->children->items[desired]; - set_focused_container(get_focused_view(newview)); - return true; - } - } - if (!can_move) { - sway_log(L_DEBUG, "Can't move at current level, moving up tree"); - current = parent; - parent = parent->parent; - if (!parent) { - // Nothing we can do - return false; - } - } + swayc_t *view = get_swayc_in_direction( + get_focused_container(&root_container), direction); + if (view) { + set_focused_container(view); + return true; } + return false; } swayc_t *get_focused_container(swayc_t *parent) { diff --git a/sway/handlers.c b/sway/handlers.c index c9d7c7ac..03a32835 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -13,16 +13,10 @@ #include "workspace.h" #include "container.h" #include "focus.h" -#include "key_state.h" +#include "input_state.h" static struct wlc_origin mouse_origin; -static bool m1_held = false; -static bool dragging = false; -static bool m2_held = false; -static bool resizing = false; -static bool lock_left, lock_right, lock_top, lock_bottom = false; - static bool pointer_test(swayc_t *view, void *_origin) { const struct wlc_origin *origin = _origin; // Determine the output that the view is under @@ -88,29 +82,6 @@ swayc_t *container_under_pointer(void) { return lookup; } -static struct wlc_geometry saved_floating; - -static void start_floating(swayc_t *view) { - if (view->is_floating) { - saved_floating.origin.x = view->x; - saved_floating.origin.y = view->y; - saved_floating.size.w = view->width; - saved_floating.size.h = view->height; - } -} - -static void reset_floating(swayc_t *view) { - if (view->is_floating) { - view->x = saved_floating.origin.x; - view->y = saved_floating.origin.y; - view->width = saved_floating.size.w; - view->height = saved_floating.size.h; - arrange_windows(view->parent, -1, -1); - } - dragging = resizing = false; - lock_left = lock_right = lock_top = lock_bottom = false; -} - /* Handles */ static bool handle_output_created(wlc_handle output) { @@ -327,7 +298,8 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier } // Revert floating container back to original position on keypress - if (state == WLC_KEY_STATE_PRESSED && (dragging || resizing)) { + if (state == WLC_KEY_STATE_PRESSED && + (pointer_state.floating.drag || pointer_state.floating.resize)) { reset_floating(get_focused_view(&root_container)); } @@ -396,7 +368,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct // Do checks to determine if proper keys are being held swayc_t *view = get_focused_view(active_workspace); uint32_t edge = 0; - if (dragging && view) { + if (pointer_state.floating.drag && view) { if (view->is_floating) { int dx = mouse_origin.x - prev_pos.x; int dy = mouse_origin.y - prev_pos.y; @@ -404,7 +376,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct view->y += dy; changed_floating = true; } - } else if (resizing && view) { + } else if (pointer_state.floating.resize && view) { if (view->is_floating) { int dx = mouse_origin.x - prev_pos.x; int dy = mouse_origin.y - prev_pos.y; @@ -415,24 +387,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct int midway_x = view->x + view->width/2; int midway_y = view->y + view->height/2; if (dx < 0) { - if (!lock_right) { + if (!pointer_state.lock.right) { if (view->width > min_sane_w) { changed_floating = true; view->width += dx; edge += WLC_RESIZE_EDGE_RIGHT; } - } else if (mouse_origin.x < midway_x && !lock_left) { + } else if (mouse_origin.x < midway_x && !pointer_state.lock.left) { changed_floating = true; view->x += dx; view->width -= dx; edge += WLC_RESIZE_EDGE_LEFT; } } else if (dx > 0) { - if (mouse_origin.x > midway_x && !lock_right) { + if (mouse_origin.x > midway_x && !pointer_state.lock.right) { changed_floating = true; view->width += dx; edge += WLC_RESIZE_EDGE_RIGHT; - } else if (!lock_left) { + } else if (!pointer_state.lock.left) { if (view->width > min_sane_w) { changed_floating = true; view->x += dx; @@ -443,24 +415,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct } if (dy < 0) { - if (!lock_bottom) { + if (!pointer_state.lock.bottom) { if (view->height > min_sane_h) { changed_floating = true; view->height += dy; edge += WLC_RESIZE_EDGE_BOTTOM; } - } else if (mouse_origin.y < midway_y && !lock_top) { + } else if (mouse_origin.y < midway_y && !pointer_state.lock.top) { changed_floating = true; view->y += dy; view->height -= dy; edge += WLC_RESIZE_EDGE_TOP; } } else if (dy > 0) { - if (mouse_origin.y > midway_y && !lock_bottom) { + if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) { changed_floating = true; view->height += dy; edge += WLC_RESIZE_EDGE_BOTTOM; - } else if (!lock_top) { + } else if (!pointer_state.lock.top) { if (view->height > min_sane_h) { changed_floating = true; view->y += dy; @@ -474,7 +446,8 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct if (config->focus_follows_mouse && prev_handle != handle) { //Dont change focus if fullscreen swayc_t *focused = get_focused_view(view); - if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) && !(m1_held || m2_held)) { + if (!(focused->type == C_VIEW && wlc_view_get_state(focused->handle) & WLC_BIT_FULLSCREEN) + && !(pointer_state.l_held || pointer_state.r_held)) { set_focused_container(container_under_pointer()); } } @@ -497,13 +470,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct return false; } -enum pointer_values { - M_LEFT_CLICK = 272, - M_RIGHT_CLICK = 273, - M_SCROLL_CLICK = 274, - M_SCROLL_UP = 275, - M_SCROLL_DOWN = 276, -}; static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { @@ -515,10 +481,10 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w if (state == WLC_BUTTON_STATE_PRESSED) { sway_log(L_DEBUG, "Mouse button %u pressed", button); if (button == M_LEFT_CLICK) { - m1_held = true; + pointer_state.l_held = true; } if (button == M_RIGHT_CLICK) { - m2_held = true; + pointer_state.r_held = true; } swayc_t *pointer = container_under_pointer(); set_focused_container(pointer); @@ -533,30 +499,31 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w } arrange_windows(pointer->parent, -1, -1); if (modifiers->mods & config->floating_mod) { - dragging = m1_held; - resizing = m2_held; int midway_x = pointer->x + pointer->width/2; int midway_y = pointer->y + pointer->height/2; - lock_bottom = origin->y < midway_y; - lock_top = !lock_bottom; - lock_right = origin->x < midway_x; - lock_left = !lock_right; + + pointer_state.floating.drag = pointer_state.l_held; + pointer_state.floating.resize = pointer_state.r_held; + pointer_state.lock.bottom = origin->y < midway_y; + pointer_state.lock.top = !pointer_state.lock.bottom; + pointer_state.lock.right = origin->x < midway_x; + pointer_state.lock.left = !pointer_state.lock.right; start_floating(pointer); } //Dont want pointer sent to window while dragging or resizing - return (dragging || resizing); + return (pointer_state.floating.drag || pointer_state.floating.resize); } return (pointer && pointer != focused); } else { sway_log(L_DEBUG, "Mouse button %u released", button); if (button == M_LEFT_CLICK) { - m1_held = false; - dragging = false; + pointer_state.l_held = false; + pointer_state.floating.drag = false; } if (button == M_RIGHT_CLICK) { - m2_held = false; - resizing = false; - lock_top = lock_bottom = lock_left = lock_right = false; + pointer_state.r_held = false; + pointer_state.floating.resize = false; + pointer_state.lock = (struct pointer_lock){false ,false ,false ,false}; } } return false; diff --git a/sway/input_state.c b/sway/input_state.c new file mode 100644 index 00000000..0769c30f --- /dev/null +++ b/sway/input_state.c @@ -0,0 +1,70 @@ +#include +#include +#include + +#include "input_state.h" + +enum { KEY_STATE_MAX_LENGTH = 64 }; + +static keycode key_state_array[KEY_STATE_MAX_LENGTH]; +static uint8_t key_state_length = 0; + +static uint8_t find_key(keycode key) { + int i; + for (i = 0; i < key_state_length; ++i) { + if (key_state_array[i] == key) { + break; + } + } + return i; +} + +bool check_key(keycode key) { + return find_key(key) < key_state_length; +} + +void press_key(keycode key) { + // Check if key exists + if (!check_key(key)) { + // Check that we dont exceed buffer length + if (key_state_length < KEY_STATE_MAX_LENGTH) { + key_state_array[key_state_length++] = key; + } + } +} + +void release_key(keycode key) { + uint8_t index = find_key(key); + if (index < key_state_length) { + //shift it over and remove key + memmove(&key_state_array[index], + &key_state_array[index + 1], + sizeof(*key_state_array) * (--key_state_length - index)); + } +} + +struct pointer_state pointer_state = {0, 0, {0, 0}, {0, 0, 0, 0}}; + +static struct wlc_geometry saved_floating; + +void start_floating(swayc_t *view) { + if (view->is_floating) { + saved_floating.origin.x = view->x; + saved_floating.origin.y = view->y; + saved_floating.size.w = view->width; + saved_floating.size.h = view->height; + } +} + +void reset_floating(swayc_t *view) { + if (view->is_floating) { + view->x = saved_floating.origin.x; + view->y = saved_floating.origin.y; + view->width = saved_floating.size.w; + view->height = saved_floating.size.h; + arrange_windows(view->parent, -1, -1); + } + pointer_state.floating = (struct pointer_floating){0,0}; + pointer_state.lock = (struct pointer_lock){0,0,0,0}; +} + diff --git a/sway/key_state.c b/sway/key_state.c deleted file mode 100644 index 76561dbc..00000000 --- a/sway/key_state.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include - -#include "key_state.h" - -enum { KEY_STATE_MAX_LENGTH = 64 }; - -static keycode key_state_array[KEY_STATE_MAX_LENGTH]; -static uint8_t key_state_length = 0; - -static uint8_t find_key(keycode key) -{ - int i; - for (i = 0; i < key_state_length; ++i) - { - if (key_state_array[i] == key) - { - break; - } - } - return i; -} - -bool check_key(keycode key) -{ - return find_key(key) < key_state_length; -} - -void press_key(keycode key) -{ - // Check if key exists - if (!check_key(key)) - { - // Check that we dont exceed buffer length - if (key_state_length < KEY_STATE_MAX_LENGTH) { - key_state_array[key_state_length++] = key; - } - } -} - -void release_key(keycode key) -{ - uint8_t index = find_key(key); - if (index < key_state_length) - { - //shift it over and remove key - memmove(&key_state_array[index], - &key_state_array[index + 1], - sizeof(*key_state_array) * (--key_state_length - index)); - } -} diff --git a/sway/layout.c b/sway/layout.c index eb8391ce..2a43671b 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -298,3 +298,54 @@ swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) { return NULL; } +swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) { + swayc_t *parent = container->parent; + + if (dir == MOVE_PARENT) { + if (parent->type == C_OUTPUT) { + return NULL; + } else { + return parent; + } + } + while (true) { + // Test if we can even make a difference here + bool can_move = false; + int diff = 0; + if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { + if (parent->layout == L_HORIZ || parent->type == C_ROOT) { + can_move = true; + diff = dir == MOVE_LEFT ? -1 : 1; + } + } else { + if (parent->layout == L_VERT) { + can_move = true; + diff = dir == MOVE_UP ? -1 : 1; + } + } + if (can_move) { + int i; + for (i = 0; i < parent->children->length; ++i) { + swayc_t *child = parent->children->items[i]; + if (child == container) { + break; + } + } + int desired = i + diff; + if (desired < 0 || desired >= parent->children->length) { + can_move = false; + } else { + return parent->children->items[desired]; + } + } + if (!can_move) { + sway_log(L_DEBUG, "Can't move at current level, moving up tree"); + container = parent; + parent = parent->parent; + if (!parent) { + // Nothing we can do + return NULL; + } + } + } +}