mouse tile resize mode done

This commit is contained in:
taiyu 2015-08-22 21:03:45 -07:00
parent e139de0857
commit 42d5d9a177
5 changed files with 175 additions and 486 deletions

View file

@ -37,52 +37,34 @@ enum pointer_mode {
M_RESIZING = 1 << 3, M_RESIZING = 1 << 3,
}; };
struct pointer_button_state {
bool held;
// state at the point it was pressed
int x, y;
swayc_t *view;
};
extern struct pointer_state { extern struct pointer_state {
// mouse clicks // mouse clicks
bool l_held : 1; struct pointer_button_state left;
bool r_held : 1; struct pointer_button_state right;
struct pointer_button_state scroll;
// scroll wheel
bool s_held : 1;
bool s_up : 1;
bool s_down :1;
// pointer position // pointer position
struct mouse_origin{ struct mouse_origin{
int x, y; int x, y;
} origin; } origin;
// change in pointer position
struct { struct {
int x, y; int x, y;
} delta; } delta;
// view pointer is over // view pointer is currently over
swayc_t *view; swayc_t *view;
// Pointer mode // Pointer mode
int mode; int mode;
// OLD
struct pointer_floating {
bool drag;
bool resize;
} floating;
struct pointer_tiling {
bool resize;
swayc_t *init_view;
struct wlc_origin lock_pos;
} tiling;
struct pointer_lock {
// Lock movement for certain edges
bool left;
bool right;
bool top;
bool bottom;
// Lock movement in certain directions
bool temp_left;
bool temp_right;
bool temp_up;
bool temp_down;
} lock;
} pointer_state; } pointer_state;
// on button release unset mode depending on the button. // on button release unset mode depending on the button.
@ -95,8 +77,6 @@ void pointer_mode_update(void);
// Reset mode on any keypress; // Reset mode on any keypress;
void pointer_mode_reset(void); void pointer_mode_reset(void);
void start_floating(swayc_t *view);
void reset_floating(swayc_t *view);
void input_init(void); void input_init(void);
#endif #endif

View file

@ -1,8 +1,8 @@
#ifndef _SWAY_RESIZE_H #ifndef _SWAY_RESIZE_H
#define _SWAY_RESIZE_H #define _SWAY_RESIZE_H
#include <stdbool.h>
bool mouse_resize_tiled(struct wlc_origin prev_pos); bool mouse_resize_tiled(struct wlc_origin prev_pos);
bool resize_floating(struct wlc_origin prev_pos);
bool resize_tiled(int amount, bool use_width); bool resize_tiled(int amount, bool use_width);
#endif #endif

View file

@ -359,35 +359,53 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
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) {
enum { DONT_SEND_CLICK = true, SEND_CLICK = false }; enum { DONT_SEND_CLICK = true, SEND_CLICK = false };
// Update pointer_state // Update view pointer is on
switch (button) { pointer_state.view = container_under_pointer();
case M_LEFT_CLICK:
pointer_state.l_held = state == WLC_BUTTON_STATE_PRESSED;
break;
case M_RIGHT_CLICK:
pointer_state.r_held = state == WLC_BUTTON_STATE_PRESSED;
break;
case M_SCROLL_CLICK:
pointer_state.s_held = state == WLC_BUTTON_STATE_PRESSED;
break;
case M_SCROLL_UP:
pointer_state.s_up = state == WLC_BUTTON_STATE_PRESSED;
break;
case M_SCROLL_DOWN:
pointer_state.s_down = state == WLC_BUTTON_STATE_PRESSED;
break;
}
// Update pointer origin // Update pointer origin
pointer_state.origin.x = origin->x; pointer_state.origin.x = origin->x;
pointer_state.origin.y = origin->y; pointer_state.origin.y = origin->y;
// Update view pointer is on // Update pointer_state
pointer_state.view = container_under_pointer(); switch (button) {
case M_LEFT_CLICK:
if (state == WLC_BUTTON_STATE_PRESSED) {
pointer_state.left.held = true;
pointer_state.left.x = origin->x;
pointer_state.left.y = origin->y;
pointer_state.left.view = pointer_state.view;
} else {
pointer_state.left.held = false;
}
break;
case M_RIGHT_CLICK:
if (state == WLC_BUTTON_STATE_PRESSED) {
pointer_state.right.held = true;
pointer_state.right.x = origin->x;
pointer_state.right.y = origin->y;
pointer_state.right.view = pointer_state.view;
} else {
pointer_state.right.held = false;
}
break;
case M_SCROLL_CLICK:
if (state == WLC_BUTTON_STATE_PRESSED) {
pointer_state.scroll.held = true;
pointer_state.scroll.x = origin->x;
pointer_state.scroll.y = origin->y;
pointer_state.scroll.view = pointer_state.view;
} else {
pointer_state.scroll.held = false;
}
break;
//TODO scrolling behavior
case M_SCROLL_UP:
case M_SCROLL_DOWN:
break;
}
// set pointer mode // set pointer mode
pointer_mode_set(button, pointer_mode_set(button,
@ -431,62 +449,6 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
// Finally send click // Finally send click
return SEND_CLICK; return SEND_CLICK;
/* OLD */
if (state == WLC_BUTTON_STATE_PRESSED) {
sway_log(L_DEBUG, "Mouse button %u pressed", button);
if (button == M_LEFT_CLICK) {
pointer_state.l_held = true;
}
if (button == M_RIGHT_CLICK) {
pointer_state.r_held = true;
}
swayc_t *pointer = container_under_pointer();
if (pointer) {
set_focused_container(pointer);
int midway_x = pointer->x + pointer->width/2;
int midway_y = pointer->y + pointer->height/2;
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;
}
if (pointer->is_floating) {
if (modifiers->mods & config->floating_mod) {
pointer_state.floating.drag = pointer_state.l_held;
pointer_state.floating.resize = pointer_state.r_held;
start_floating(pointer);
}
// Dont want pointer sent to window while dragging or resizing
return (pointer_state.floating.drag || pointer_state.floating.resize);
} else {
if (modifiers->mods & config->floating_mod) {
pointer_state.floating.drag = pointer_state.l_held;
pointer_state.tiling.resize = pointer_state.r_held;
pointer_state.tiling.init_view = pointer;
// Dont want pointer sent when resizing
return (pointer_state.tiling.resize);
}
}
return (pointer && pointer != focused);
} else {
sway_log(L_DEBUG, "Mouse button %u released", button);
if (button == M_LEFT_CLICK) {
pointer_state.l_held = false;
pointer_state.floating.drag = false;
pointer_state.tiling.init_view = NULL;
}
if (button == M_RIGHT_CLICK) {
pointer_state.r_held = false;
pointer_state.floating.resize = false;
pointer_state.tiling.resize = false;
pointer_state.tiling.init_view = NULL;
pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false};
}
}
/* OLD */
return false;
} }
static void handle_wlc_ready(void) { static void handle_wlc_ready(void) {

View file

@ -48,75 +48,81 @@ void release_key(keycode key) {
} }
} }
// Pointer state and mode
struct pointer_state pointer_state; struct pointer_state pointer_state;
// Pointer mode values
static struct mode_state { static struct mode_state {
// Initial view state // initial view state
struct {
double x, y, w, h; double x, y, w, h;
swayc_t *ptr; swayc_t *ptr;
} view; // containers resized with tiling resize
// Initial pointer state
struct { struct {
int x, y; double x, w;
} coor; swayc_t *ptr;
} lr;
struct {
double y, h;
swayc_t *ptr;
} tb;
} initial; } initial;
static struct { static struct {
enum { LEFT=1, RIGHT=0 } lr; bool left;
enum { TOP=1, BOTTOM=0 } tb; bool top;
} lock; } lock;
// Floating set/unset // Floating set/unset
static void pointer_mode_set_floating(void) { static void set_initial_view(swayc_t *view) {
initial.view.x = initial.view.ptr->x; initial.ptr = view;
initial.view.y = initial.view.ptr->y; initial.x = view->x;
initial.view.w = initial.view.ptr->width; initial.y = view->y;
initial.view.h = initial.view.ptr->height; initial.w = view->width;
// setup initial cooridinates initial.h = view->height;
initial.coor.x = pointer_state.origin.x;
initial.coor.y = pointer_state.origin.y;
} }
static void pointer_mode_reset_floating(void) { static void reset_initial_view(void) {
initial.view.ptr->x = initial.view.x; initial.ptr->x = initial.x;
initial.view.ptr->y = initial.view.y; initial.ptr->y = initial.y;
initial.view.ptr->width = initial.view.w; initial.ptr->width = initial.w;
initial.view.ptr->height = initial.view.h; initial.ptr->height = initial.h;
arrange_windows(initial.view.ptr, -1, -1); arrange_windows(initial.ptr, -1, -1);
pointer_state.mode = 0; pointer_state.mode = 0;
} }
// Mode set left/right click // Mode set left/right click
static void pointer_mode_set_left(void) { static void pointer_mode_set_left(void) {
swayc_t *view = pointer_state.view; set_initial_view(pointer_state.left.view);
initial.view.ptr = view; if (initial.ptr->is_floating) {
if (view->is_floating) {
pointer_state.mode = M_DRAGGING | M_FLOATING; pointer_state.mode = M_DRAGGING | M_FLOATING;
pointer_mode_set_floating();
} else { } else {
pointer_state.mode = M_DRAGGING | M_TILING; pointer_state.mode = M_DRAGGING | M_TILING;
} }
} }
static void pointer_mode_set_right(void) { static void pointer_mode_set_right(void) {
swayc_t *view = pointer_state.view; set_initial_view(pointer_state.right.view);
initial.view.ptr = view;
// Setup locking information // Setup locking information
int midway_x = view->x + view->width/2; int midway_x = initial.ptr->x + initial.ptr->width/2;
int midway_y = view->y + view->height/2; int midway_y = initial.ptr->y + initial.ptr->height/2;
lock.lr = pointer_state.origin.x > midway_x; lock.left = pointer_state.origin.x > midway_x;
lock.tb = pointer_state.origin.y > midway_y; lock.top = pointer_state.origin.y > midway_y;
if (view->is_floating) { if (initial.ptr->is_floating) {
pointer_state.mode = M_RESIZING | M_FLOATING; pointer_state.mode = M_RESIZING | M_FLOATING;
pointer_mode_set_floating();
} else { } else {
pointer_state.mode = M_RESIZING | M_TILING; pointer_state.mode = M_RESIZING | M_TILING;
if ((initial.lr.ptr = get_swayc_in_direction(initial.ptr, lock.left ? MOVE_RIGHT: MOVE_LEFT))) {
initial.lr.x = initial.lr.ptr->x;
initial.lr.w = initial.lr.ptr->width;
}
if ((initial.tb.ptr = get_swayc_in_direction(initial.ptr, lock.top ? MOVE_DOWN: MOVE_UP))) {
initial.tb.y = initial.tb.ptr->y;
initial.tb.h = initial.tb.ptr->height;
}
} }
} }
@ -127,14 +133,14 @@ void pointer_mode_set(uint32_t button, bool condition) {
switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) {
case M_DRAGGING: case M_DRAGGING:
// end drag mode when left click is unpressed // end drag mode when left click is unpressed
if (!pointer_state.l_held) { if (!pointer_state.left.held) {
pointer_state.mode = 0; pointer_state.mode = 0;
} }
break; break;
case M_RESIZING: case M_RESIZING:
// end resize mode when right click is unpressed // end resize mode when right click is unpressed
if (!pointer_state.r_held) { if (!pointer_state.right.held) {
pointer_state.mode = 0; pointer_state.mode = 0;
} }
break; break;
@ -145,12 +151,13 @@ void pointer_mode_set(uint32_t button, bool condition) {
if (!condition || !pointer_state.view) { if (!condition || !pointer_state.view) {
break; break;
} }
// Set mode depending on current button press // Set mode depending on current button press
switch (button) { switch (button) {
// Start dragging mode // Start dragging mode
case M_LEFT_CLICK: case M_LEFT_CLICK:
// if button release dont do anything // if button release dont do anything
if (pointer_state.l_held) { if (pointer_state.left.held) {
pointer_mode_set_left(); pointer_mode_set_left();
} }
break; break;
@ -158,98 +165,123 @@ void pointer_mode_set(uint32_t button, bool condition) {
// Start resize mode // Start resize mode
case M_RIGHT_CLICK: case M_RIGHT_CLICK:
// if button release dont do anyhting // if button release dont do anyhting
if (pointer_state.r_held) { if (pointer_state.right.held) {
pointer_mode_set_right(); pointer_mode_set_right();
} }
break; break;
case M_SCROLL_UP:
case M_SCROLL_DOWN:
//TODO add scrolling behavior here
;
} }
} }
} }
void pointer_mode_update(void) { void pointer_mode_update(void) {
swayc_t *view = initial.view.ptr; if (initial.ptr->type != C_VIEW) {
if (view->type != C_VIEW) {
pointer_state.mode = 0; pointer_state.mode = 0;
return; return;
} }
int dx = pointer_state.origin.x - initial.coor.x; int dx = pointer_state.origin.x;
int dy = pointer_state.origin.y - initial.coor.y; int dy = pointer_state.origin.y;
bool changed = false; bool changed = false;
switch (pointer_state.mode) { switch (pointer_state.mode) {
case M_FLOATING | M_DRAGGING: case M_FLOATING | M_DRAGGING:
// Update position // Update position
if (initial.view.x + dx != view->x) { dx -= pointer_state.left.x;
view->x = initial.view.x + dx; dy -= pointer_state.left.y;
if (initial.x + dx != initial.ptr->x) {
initial.ptr->x = initial.x + dx;
changed = true; changed = true;
} }
if (initial.view.y + dy != view->y) { if (initial.y + dy != initial.ptr->y) {
view->y = initial.view.y + dy; initial.ptr->y = initial.y + dy;
changed = true; changed = true;
} }
update_geometry(initial.ptr);
break; break;
case M_FLOATING | M_RESIZING: case M_FLOATING | M_RESIZING:
if (lock.lr) { dx -= pointer_state.right.x;
if (initial.view.w + dx > min_sane_w) { dy -= pointer_state.right.y;
if (initial.view.w + dx != view->width) { initial.ptr = pointer_state.right.view;
view->width = initial.view.w + dx; if (lock.left) {
changed = true; if (initial.w + dx > min_sane_w) {
} initial.ptr->width = initial.w + dx;
} }
} else { //lock.right } else { //lock.right
if (initial.view.w - dx > min_sane_w) { if (initial.w - dx > min_sane_w) {
if (initial.view.w - dx != view->width) { initial.ptr->width = initial.w - dx;
view->width = initial.view.w - dx; initial.ptr->x = initial.x + dx;
view->x = initial.view.x + dx;
changed = true;
} }
} }
} if (lock.top) {
if (lock.tb) { if (initial.h + dy > min_sane_h) {
if (initial.view.h + dy > min_sane_h) { initial.ptr->height = initial.h + dy;
if (initial.view.y - dy != view->height) {
view->height = initial.view.h + dy;
changed = true;
}
} }
} else { //lock.bottom } else { //lock.bottom
if (initial.view.h - dy > min_sane_h) { if (initial.h - dy > min_sane_h) {
if (initial.view.h - dy != view->height) { initial.ptr->height = initial.h - dy;
view->height = initial.view.h - dy; initial.ptr->y = initial.y + dy;
view->y = initial.view.y + dy;
changed = true;
}
} }
} }
update_geometry(initial.ptr);
break; break;
case M_TILING | M_DRAGGING: case M_TILING | M_DRAGGING:
// swap current view under pointer with dragged view // swap current view under pointer with dragged view
if (pointer_state.view && pointer_state.view != initial.view.ptr) { if (pointer_state.view && pointer_state.view != initial.ptr) {
// Swap them around // Swap them around
swap_container(pointer_state.view, initial.view.ptr); swap_container(pointer_state.view, initial.ptr);
update_geometry(pointer_state.view); update_geometry(pointer_state.view);
update_geometry(initial.view.ptr); update_geometry(initial.ptr);
// Set focus back to initial view // Set focus back to initial view
set_focused_container(initial.view.ptr); set_focused_container(initial.ptr);
} }
break; break;
case M_TILING | M_RESIZING: case M_TILING | M_RESIZING:
dx -= pointer_state.right.x;
dy -= pointer_state.right.y;
// resize if we can
default: if (initial.lr.ptr) {
return; if (lock.left) {
// Check whether its fine to resize
if (initial.w + dx > min_sane_w && initial.lr.w - dx > min_sane_w) {
initial.ptr->width = initial.w + dx;
initial.lr.ptr->width = initial.lr.w - dx;
initial.lr.ptr->x = initial.lr.x + dx;
}
} else { //lock.right
if (initial.w - dx > min_sane_w && initial.lr.w + dx > min_sane_w) {
initial.ptr->width = initial.w - dx;
initial.ptr->x = initial.x + dx;
initial.lr.ptr->width = initial.lr.w + dx;
}
changed = true;
}
arrange_windows(initial.lr.ptr->parent, -1, -1);
}
if (initial.tb.ptr) {
if (lock.top) {
if (initial.h + dy > min_sane_h && initial.tb.h - dy > min_sane_h) {
initial.ptr->height = initial.h + dy;
initial.tb.ptr->height = initial.tb.h - dy;
initial.tb.ptr->y = initial.tb.y + dy;
}
} else { //lock.bottom
if (initial.h - dy > min_sane_h && initial.tb.h + dy > min_sane_h) {
initial.ptr->height = initial.h - dy;
initial.ptr->y = initial.y + dy;
initial.tb.ptr->height = initial.tb.h + dy;
}
changed = true;
}
arrange_windows(initial.tb.ptr->parent, -1, -1);
} }
if (changed) { if (changed) {
update_geometry(view); arrange_windows(initial.ptr->parent, -1, -1);
}
changed = false;
default:
return;
} }
} }
@ -257,7 +289,7 @@ void pointer_mode_reset(void) {
switch (pointer_state.mode) { switch (pointer_state.mode) {
case M_FLOATING | M_DRAGGING: case M_FLOATING | M_DRAGGING:
case M_FLOATING | M_RESIZING: case M_FLOATING | M_RESIZING:
pointer_mode_reset_floating(); reset_initial_view();
break; break;
case M_TILING | M_DRAGGING: case M_TILING | M_DRAGGING:
@ -267,27 +299,3 @@ void pointer_mode_reset(void) {
} }
} }
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, 0, 0, 0, 0};
}

View file

@ -6,267 +6,6 @@
#include "input_state.h" #include "input_state.h"
#include "handlers.h" #include "handlers.h"
bool mouse_resize_tiled(struct wlc_origin prev_pos) {
swayc_t *view = container_under_pointer();
bool valid = true;
bool changed_tiling = false;
double dx = pointer_state.origin.x - prev_pos.x;
double dy = pointer_state.origin.y - prev_pos.y;
if (view != pointer_state.tiling.init_view) {
changed_tiling = true;
valid = false;
if (view->type != C_WORKSPACE) {
if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) {
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
pointer_state.lock.temp_left = true;
} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) {
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
pointer_state.lock.temp_right = true;
} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) {
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
pointer_state.lock.temp_up = true;
} else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) {
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
pointer_state.lock.temp_down = true;
}
}
}
if ((dx < 0 || pointer_state.origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) {
changed_tiling = true;
valid = false;
} else if (dx > 0 && pointer_state.lock.temp_left) {
pointer_state.lock.temp_left = false;
pointer_state.tiling.lock_pos.x = 0;
}
if ((dx > 0 || pointer_state.origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) {
changed_tiling = true;
valid = false;
} else if (dx < 0 && pointer_state.lock.temp_right) {
pointer_state.lock.temp_right = false;
pointer_state.tiling.lock_pos.x = 0;
}
if ((dy < 0 || pointer_state.origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) {
changed_tiling = true;
valid = false;
} else if (dy > 0 && pointer_state.lock.temp_up) {
pointer_state.lock.temp_up = false;
pointer_state.tiling.lock_pos.y = 0;
}
if ((dy > 0 || pointer_state.origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) {
changed_tiling = true;
valid = false;
} else if (dy < 0 && pointer_state.lock.temp_down) {
pointer_state.lock.temp_down = false;
pointer_state.tiling.lock_pos.y = 0;
}
if (!view->is_floating && valid) {
// Handle layout resizes -- Find the biggest parent container then apply resizes to that
// and its bordering siblings
swayc_t *parent = view;
if (!pointer_state.lock.bottom) {
while (parent->type != C_WORKSPACE) {
// TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
// way of doing this.
if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
parent = parent->parent;
} else {
break;
}
}
if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
if (sibling) {
if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
changed_tiling = true;
} else {
if (parent->height < min_sane_h) {
//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
pointer_state.lock.temp_up = true;
} else if (sibling->height < min_sane_h) {
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
pointer_state.lock.temp_down = true;
}
}
}
}
} else if (!pointer_state.lock.top) {
while (parent->type != C_WORKSPACE) {
if (fabs(parent->parent->y - view->y) <= 1) {
parent = parent->parent;
} else {
break;
}
}
if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
if (sibling) {
if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
changed_tiling = true;
} else {
if (parent->height < min_sane_h) {
//pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
pointer_state.lock.temp_down = true;
} else if (sibling->height < min_sane_h) {
pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
pointer_state.lock.temp_up = true;
}
}
}
}
}
parent = view;
if (!pointer_state.lock.right) {
while (parent->type != C_WORKSPACE) {
if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
parent = parent->parent;
} else {
sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
break;
}
}
if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
if (sibling) {
if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
changed_tiling = true;
} else {
if (parent->width < min_sane_w) {
pointer_state.lock.temp_left = true;
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
} else if (sibling->width < min_sane_w) {
pointer_state.lock.temp_right = true;
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
}
}
}
}
} else if (!pointer_state.lock.left) {
while (parent->type != C_WORKSPACE) {
if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
parent = parent->parent;
} else {
break;
}
}
if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
if (sibling) {
if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
changed_tiling = true;
} else {
if (parent->width < min_sane_w) {
pointer_state.lock.temp_right = true;
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
} else if (sibling->width < min_sane_w) {
pointer_state.lock.temp_left = true;
pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
}
}
}
}
}
arrange_windows(swayc_active_workspace(), -1, -1);
}
return changed_tiling;
}
bool resize_floating(struct wlc_origin prev_pos) {
bool changed = false;
swayc_t *view = container_under_pointer();
uint32_t edge = 0;
int dx = pointer_state.origin.x - prev_pos.x;
int dy = pointer_state.origin.y - prev_pos.y;
// Move and resize the view based on the dx/dy and mouse position
int midway_x = view->x + view->width/2;
int midway_y = view->y + view->height/2;
if (dx < 0) {
if (!pointer_state.lock.right) {
if (view->width > min_sane_w) {
changed = true;
view->width += dx;
edge += WLC_RESIZE_EDGE_RIGHT;
}
} else if (pointer_state.origin.x < midway_x && !pointer_state.lock.left) {
changed = true;
view->x += dx;
view->width -= dx;
edge += WLC_RESIZE_EDGE_LEFT;
}
} else if (dx > 0) {
if (pointer_state.origin.x > midway_x && !pointer_state.lock.right) {
changed = true;
view->width += dx;
edge += WLC_RESIZE_EDGE_RIGHT;
} else if (!pointer_state.lock.left) {
if (view->width > min_sane_w) {
changed = true;
view->x += dx;
view->width -= dx;
edge += WLC_RESIZE_EDGE_LEFT;
}
}
}
if (dy < 0) {
if (!pointer_state.lock.bottom) {
if (view->height > min_sane_h) {
changed = true;
view->height += dy;
edge += WLC_RESIZE_EDGE_BOTTOM;
}
} else if (pointer_state.origin.y < midway_y && !pointer_state.lock.top) {
changed = true;
view->y += dy;
view->height -= dy;
edge += WLC_RESIZE_EDGE_TOP;
}
} else if (dy > 0) {
if (pointer_state.origin.y > midway_y && !pointer_state.lock.bottom) {
changed = true;
view->height += dy;
edge += WLC_RESIZE_EDGE_BOTTOM;
} else if (!pointer_state.lock.top) {
if (view->height > min_sane_h) {
changed = true;
view->y += dy;
view->height -= dy;
edge += WLC_RESIZE_EDGE_TOP;
}
}
}
if (changed) {
struct wlc_geometry geometry = {
.origin = {
.x = view->x,
.y = view->y
},
.size = {
.w = view->width,
.h = view->height
}
};
wlc_view_set_geometry(view->handle, edge, &geometry);
}
return changed;
}
bool resize_tiled(int amount, bool use_width) { bool resize_tiled(int amount, bool use_width) {
swayc_t *parent = get_focused_view(swayc_active_workspace()); swayc_t *parent = get_focused_view(swayc_active_workspace());
swayc_t *focused = parent; swayc_t *focused = parent;