Merge pull request #94 from taiyu-len/master

input_state.ch, and command conflicts resolved
This commit is contained in:
Drew DeVault 2015-08-20 07:38:04 -04:00
commit 14947c92aa
9 changed files with 243 additions and 172 deletions

View file

@ -1,7 +1,5 @@
#ifndef _SWAY_FOCUS_H #ifndef _SWAY_FOCUS_H
#define _SWAY_FOCUS_H #define _SWAY_FOCUS_H
#include "container.h"
enum movement_direction { enum movement_direction {
MOVE_LEFT, MOVE_LEFT,
MOVE_RIGHT, MOVE_RIGHT,
@ -10,6 +8,8 @@ enum movement_direction {
MOVE_PARENT MOVE_PARENT
}; };
#include "container.h"
// focused_container - the container found by following the `focused` pointer // focused_container - the container found by following the `focused` pointer
// from a given container to a container with `is_focused` boolean set // from a given container to a container with `is_focused` boolean set
// --- // ---

49
include/input_state.h Normal file
View file

@ -0,0 +1,49 @@
#ifndef _SWAY_KEY_STATE_H
#define _SWAY_KEY_STATE_H
#include <stdbool.h>
#include <stdint.h>
#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

View file

@ -4,6 +4,7 @@
#include <wlc/wlc.h> #include <wlc/wlc.h>
#include "list.h" #include "list.h"
#include "container.h" #include "container.h"
#include "focus.h"
extern swayc_t root_container; 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_focused_container(swayc_t *parent);
swayc_t *get_swayc_for_handle(wlc_handle handle, 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 #endif

View file

@ -22,11 +22,11 @@ Commands
-------- --------
**bindsym** <key combo> <command>:: **bindsym** <key combo> <command>::
Binds _key combo_ to execute _command_ when pressed. You may use XKB key names Binds _key combo_ to execute _command_ when pressed. You may use XKB key
here (**xev**(1) is a good tool for discovering them). An example bindsym names here (**xev**(1) is a good tool for discovering them). An example
command would be _bindsym Mod1+Shift+f exec firefox_, which would execute bindsym command would be _bindsym Mod1+Shift+f exec firefox_, which would
Firefox if the alt, shift, and F keys are pressed together. Any valid sway execute Firefox if the alt, shift, and F keys are pressed together. Any
command is eligible to be bound to a key combo. valid sway command is eligible to be bound to a key combo.
**exec** <shell command>:: **exec** <shell command>::
Executes _shell command_ with sh. Executes _shell command_ with sh.
@ -41,9 +41,6 @@ Commands
**floating** toggle:: **floating** toggle::
Toggles the "floating" status of the focused view. Toggles the "floating" status of the focused view.
**floating** mode_toggle::
Toggles focus between floating view and tiled view.
**focus** <direction>:: **focus** <direction>::
Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The Direction may be one of _up_, _down_, _left_, _right_, or _parent_. The
directional focus commands will move the focus in that direction. The parent directional focus commands will move the focus in that direction. The parent
@ -51,6 +48,9 @@ Commands
container, which is useful, for example, to open a sibling of the parent container, which is useful, for example, to open a sibling of the parent
container, or to move the entire container around. container, or to move the entire container around.
**focus** mode_toggle::
Toggles focus between floating view and tiled view.
**focus_follows_mouse** <yes|no>:: **focus_follows_mouse** <yes|no>::
If set to _yes_, the currently focused view will change as you move your If set to _yes_, the currently focused view will change as you move your
mouse around the screen to the view that ends up underneath your mouse. mouse around the screen to the view that ends up underneath your mouse.
@ -86,10 +86,10 @@ Commands
**fullscreen**:: **fullscreen**::
Toggles fullscreen status for the focused view. Toggles fullscreen status for the focused view.
**gaps** <amount>**:: **gaps** <amount>::
Adds _amount_ pixels between each view, and around each output. Adds _amount_ pixels between each view, and around each output.
**gaps** <inner|outer> <amount>**:: **gaps** <inner|outer> <amount>::
Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects Adds _amount_ pixels as an _inner_ or _outer_ gap, where the former affects
spacing between views and the latter affects the space around each output. spacing between views and the latter affects the space around each output.

View file

@ -76,6 +76,18 @@ static bool checkarg(int argc, char *name, enum expected_args type, int val) {
return false; return false;
} }
static int bindsym_sort(const void *_lbind, const void *_rbind) {
const struct sway_binding *lbind = *(void **)_lbind;
const struct sway_binding *rbind = *(void **)_rbind;
unsigned int lmod = 0, rmod = 0, i;
//Count how any modifiers are pressed
for (i = 0; i < 8 * sizeof(lbind->modifiers); ++i) {
lmod += lbind->modifiers & 1 << i;
rmod += rbind->modifiers & 1 << i;
}
return (rbind->keys->length + rmod) - (lbind->keys->length + lmod);
}
static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) { if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) {
@ -118,7 +130,10 @@ static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
list_free(split); list_free(split);
// TODO: Check if there are other commands with this key binding // TODO: Check if there are other commands with this key binding
list_add(config->current_mode->bindings, binding); struct sway_mode *mode = config->current_mode;
list_add(mode->bindings, binding);
qsort(mode->bindings->items, mode->bindings->length,
sizeof(mode->bindings->items[0]), bindsym_sort);
sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command); sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command);
return true; return true;
@ -228,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 // Refocus on the view once its been put back into the layout
arrange_windows(active_workspace, -1, -1); arrange_windows(active_workspace, -1, -1);
return true;
} }
set_focused_container(view); set_focused_container(view);
} }

View file

@ -3,6 +3,7 @@
#include "focus.h" #include "focus.h"
#include "log.h" #include "log.h"
#include "workspace.h" #include "workspace.h"
#include "layout.h"
bool locked_container_focus = false; bool locked_container_focus = false;
bool locked_view_focus = false; bool locked_view_focus = false;
@ -53,74 +54,17 @@ static void update_focus(swayc_t *c) {
} }
bool move_focus(enum movement_direction direction) { bool move_focus(enum movement_direction direction) {
if (locked_container_focus) { swayc_t *view = get_swayc_in_direction(
return false; get_focused_container(&root_container), direction);
} if (view) {
swayc_t *current = get_focused_container(&root_container); if (direction == MOVE_PARENT) {
if (current->type == C_VIEW set_focused_container(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 { } else {
sway_log(L_DEBUG, "Moving focus from %p:%ld to %p:%ld", set_focused_container(get_focused_view(view));
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;
}
} }
return true;
} }
return false;
} }
swayc_t *get_focused_container(swayc_t *parent) { swayc_t *get_focused_container(swayc_t *parent) {

View file

@ -13,18 +13,10 @@
#include "workspace.h" #include "workspace.h"
#include "container.h" #include "container.h"
#include "focus.h" #include "focus.h"
#include "input_state.h"
#define KEY_CACHE_SIZE 32
uint32_t keys_pressed[KEY_CACHE_SIZE];
static struct wlc_origin mouse_origin; 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) { static bool pointer_test(swayc_t *view, void *_origin) {
const struct wlc_origin *origin = _origin; const struct wlc_origin *origin = _origin;
// Determine the output that the view is under // Determine the output that the view is under
@ -90,29 +82,6 @@ swayc_t *container_under_pointer(void) {
return lookup; 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 */ /* Handles */
static bool handle_output_created(wlc_handle output) { static bool handle_output_created(wlc_handle output) {
@ -327,10 +296,10 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) {
return false; return false;
} }
bool cmd_success = false;
// Revert floating container back to original position on keypress // 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)); reset_floating(get_focused_view(&root_container));
} }
@ -356,16 +325,10 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
} }
} }
int total = 0; if (state == WLC_KEY_STATE_PRESSED) {
for (i = 0; i < KEY_CACHE_SIZE && !mod; ++i) { press_key(sym);
total += keys_pressed[i] != 0; } else { // WLC_KEY_STATE_RELEASED
if (state == WLC_KEY_STATE_PRESSED && keys_pressed[i] == 0) { release_key(sym);
keys_pressed[i] = sym;
break;
} else if (state == WLC_KEY_STATE_RELEASED && keys_pressed[i] == sym) {
keys_pressed[i] = 0;
break;
}
} }
// TODO: reminder to check conflicts with mod+q+a versus mod+q // TODO: reminder to check conflicts with mod+q+a versus mod+q
@ -376,32 +339,22 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
bool match; bool match;
int j; int j;
for (j = 0; j < binding->keys->length; ++j) { for (j = 0; j < binding->keys->length; ++j) {
match = false;
xkb_keysym_t *key = binding->keys->items[j]; xkb_keysym_t *key = binding->keys->items[j];
int k; if ((match = check_key(*key)) == false) {
for (k = 0; k < KEY_CACHE_SIZE; ++k) {
if (keys_pressed[k] == *key) {
match = true;
break;
}
}
if (match == false) {
break; break;
} }
} }
if (match) { if (match) {
// Remove matched keys from keys_pressed
if (state == WLC_KEY_STATE_PRESSED) { if (state == WLC_KEY_STATE_PRESSED) {
handle_command(config, binding->command); handle_command(config, binding->command);
cmd_success = true; return true;
} else if (state == WLC_KEY_STATE_RELEASED) { } else if (state == WLC_KEY_STATE_RELEASED) {
// TODO: --released // TODO: --released
} }
} }
} }
} }
return cmd_success; return false;
} }
static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) {
@ -415,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 // Do checks to determine if proper keys are being held
swayc_t *view = get_focused_view(active_workspace); swayc_t *view = get_focused_view(active_workspace);
uint32_t edge = 0; uint32_t edge = 0;
if (dragging && view) { if (pointer_state.floating.drag && view) {
if (view->is_floating) { if (view->is_floating) {
int dx = mouse_origin.x - prev_pos.x; int dx = mouse_origin.x - prev_pos.x;
int dy = mouse_origin.y - prev_pos.y; int dy = mouse_origin.y - prev_pos.y;
@ -423,7 +376,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
view->y += dy; view->y += dy;
changed_floating = true; changed_floating = true;
} }
} else if (resizing && view) { } else if (pointer_state.floating.resize && view) {
if (view->is_floating) { if (view->is_floating) {
int dx = mouse_origin.x - prev_pos.x; int dx = mouse_origin.x - prev_pos.x;
int dy = mouse_origin.y - prev_pos.y; int dy = mouse_origin.y - prev_pos.y;
@ -434,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_x = view->x + view->width/2;
int midway_y = view->y + view->height/2; int midway_y = view->y + view->height/2;
if (dx < 0) { if (dx < 0) {
if (!lock_right) { if (!pointer_state.lock.right) {
if (view->width > min_sane_w) { if (view->width > min_sane_w) {
changed_floating = true; changed_floating = true;
view->width += dx; view->width += dx;
edge += WLC_RESIZE_EDGE_RIGHT; 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; changed_floating = true;
view->x += dx; view->x += dx;
view->width -= dx; view->width -= dx;
edge += WLC_RESIZE_EDGE_LEFT; edge += WLC_RESIZE_EDGE_LEFT;
} }
} else if (dx > 0) { } 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; changed_floating = true;
view->width += dx; view->width += dx;
edge += WLC_RESIZE_EDGE_RIGHT; edge += WLC_RESIZE_EDGE_RIGHT;
} else if (!lock_left) { } else if (!pointer_state.lock.left) {
if (view->width > min_sane_w) { if (view->width > min_sane_w) {
changed_floating = true; changed_floating = true;
view->x += dx; view->x += dx;
@ -462,24 +415,24 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
} }
if (dy < 0) { if (dy < 0) {
if (!lock_bottom) { if (!pointer_state.lock.bottom) {
if (view->height > min_sane_h) { if (view->height > min_sane_h) {
changed_floating = true; changed_floating = true;
view->height += dy; view->height += dy;
edge += WLC_RESIZE_EDGE_BOTTOM; 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; changed_floating = true;
view->y += dy; view->y += dy;
view->height -= dy; view->height -= dy;
edge += WLC_RESIZE_EDGE_TOP; edge += WLC_RESIZE_EDGE_TOP;
} }
} else if (dy > 0) { } 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; changed_floating = true;
view->height += dy; view->height += dy;
edge += WLC_RESIZE_EDGE_BOTTOM; edge += WLC_RESIZE_EDGE_BOTTOM;
} else if (!lock_top) { } else if (!pointer_state.lock.top) {
if (view->height > min_sane_h) { if (view->height > min_sane_h) {
changed_floating = true; changed_floating = true;
view->y += dy; view->y += dy;
@ -493,7 +446,8 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
if (config->focus_follows_mouse && prev_handle != handle) { if (config->focus_follows_mouse && prev_handle != handle) {
//Dont change focus if fullscreen //Dont change focus if fullscreen
swayc_t *focused = get_focused_view(view); 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()); set_focused_container(container_under_pointer());
} }
} }
@ -516,13 +470,6 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct
return false; 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, 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) { uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) {
@ -534,10 +481,10 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
if (state == WLC_BUTTON_STATE_PRESSED) { if (state == WLC_BUTTON_STATE_PRESSED) {
sway_log(L_DEBUG, "Mouse button %u pressed", button); sway_log(L_DEBUG, "Mouse button %u pressed", button);
if (button == M_LEFT_CLICK) { if (button == M_LEFT_CLICK) {
m1_held = true; pointer_state.l_held = true;
} }
if (button == M_RIGHT_CLICK) { if (button == M_RIGHT_CLICK) {
m2_held = true; pointer_state.r_held = true;
} }
swayc_t *pointer = container_under_pointer(); swayc_t *pointer = container_under_pointer();
set_focused_container(pointer); set_focused_container(pointer);
@ -552,30 +499,31 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
} }
arrange_windows(pointer->parent, -1, -1); arrange_windows(pointer->parent, -1, -1);
if (modifiers->mods & config->floating_mod) { if (modifiers->mods & config->floating_mod) {
dragging = m1_held;
resizing = m2_held;
int midway_x = pointer->x + pointer->width/2; int midway_x = pointer->x + pointer->width/2;
int midway_y = pointer->y + pointer->height/2; int midway_y = pointer->y + pointer->height/2;
lock_bottom = origin->y < midway_y;
lock_top = !lock_bottom; pointer_state.floating.drag = pointer_state.l_held;
lock_right = origin->x < midway_x; pointer_state.floating.resize = pointer_state.r_held;
lock_left = !lock_right; 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); start_floating(pointer);
} }
//Dont want pointer sent to window while dragging or resizing //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); return (pointer && pointer != focused);
} else { } else {
sway_log(L_DEBUG, "Mouse button %u released", button); sway_log(L_DEBUG, "Mouse button %u released", button);
if (button == M_LEFT_CLICK) { if (button == M_LEFT_CLICK) {
m1_held = false; pointer_state.l_held = false;
dragging = false; pointer_state.floating.drag = false;
} }
if (button == M_RIGHT_CLICK) { if (button == M_RIGHT_CLICK) {
m2_held = false; pointer_state.r_held = false;
resizing = false; pointer_state.floating.resize = false;
lock_top = lock_bottom = lock_left = lock_right = false; pointer_state.lock = (struct pointer_lock){false ,false ,false ,false};
} }
} }
return false; return false;
@ -590,10 +538,6 @@ static void handle_wlc_ready(void) {
} }
free_flat_list(config->cmd_queue); free_flat_list(config->cmd_queue);
config->active = true; config->active = true;
for (i = 0; i < KEY_CACHE_SIZE; ++i) {
keys_pressed[i] = 0;
}
} }

68
sway/input_state.c Normal file
View file

@ -0,0 +1,68 @@
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include "input_state.h"
#define KEY_STATE_MAX_LENGTH 64
static keycode key_state_array[KEY_STATE_MAX_LENGTH];
static uint8_t find_key(keycode key) {
int i;
for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
if (key_state_array[i] == key) {
break;
}
}
return i;
}
bool check_key(keycode key) {
return find_key(key) < KEY_STATE_MAX_LENGTH;
}
void press_key(keycode key) {
// Check if key exists
if (!check_key(key)) {
// Check that we dont exceed buffer length
int insert = find_key(0);
if (insert < KEY_STATE_MAX_LENGTH) {
key_state_array[insert] = key;
}
}
}
void release_key(keycode key) {
uint8_t index = find_key(key);
if (index < KEY_STATE_MAX_LENGTH) {
//shift it over and remove key
key_state_array[index] = 0;
}
}
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};
}

View file

@ -298,3 +298,53 @@ swayc_t *get_swayc_for_handle(wlc_handle handle, swayc_t *parent) {
return NULL; 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) {
container = parent;
parent = parent->parent;
if (!parent) {
// Nothing we can do
return NULL;
}
}
}
}