summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/input_state.h46
-rw-r--r--include/resize.h2
-rw-r--r--sway/handlers.c102
-rw-r--r--sway/input_state.c230
-rw-r--r--sway/resize.c261
5 files changed, 165 insertions, 476 deletions
diff --git a/include/input_state.h b/include/input_state.h
index 3a246e0c..747a3563 100644
--- a/include/input_state.h
+++ b/include/input_state.h
@@ -37,52 +37,34 @@ enum pointer_mode {
37 M_RESIZING = 1 << 3, 37 M_RESIZING = 1 << 3,
38}; 38};
39 39
40struct pointer_button_state {
41 bool held;
42 // state at the point it was pressed
43 int x, y;
44 swayc_t *view;
45};
46
40extern struct pointer_state { 47extern struct pointer_state {
41 // mouse clicks 48 // mouse clicks
42 bool l_held : 1; 49 struct pointer_button_state left;
43 bool r_held : 1; 50 struct pointer_button_state right;
44 51 struct pointer_button_state scroll;
45 // scroll wheel
46 bool s_held : 1;
47 bool s_up : 1;
48 bool s_down :1;
49 52
50 // pointer position 53 // pointer position
51 struct mouse_origin{ 54 struct mouse_origin{
52 int x, y; 55 int x, y;
53 } origin; 56 } origin;
57
58 // change in pointer position
54 struct { 59 struct {
55 int x, y; 60 int x, y;
56 } delta; 61 } delta;
57 62
58 // view pointer is over 63 // view pointer is currently over
59 swayc_t *view; 64 swayc_t *view;
60 65
61 // Pointer mode 66 // Pointer mode
62 int mode; 67 int mode;
63
64 // OLD
65 struct pointer_floating {
66 bool drag;
67 bool resize;
68 } floating;
69 struct pointer_tiling {
70 bool resize;
71 swayc_t *init_view;
72 struct wlc_origin lock_pos;
73 } tiling;
74 struct pointer_lock {
75 // Lock movement for certain edges
76 bool left;
77 bool right;
78 bool top;
79 bool bottom;
80 // Lock movement in certain directions
81 bool temp_left;
82 bool temp_right;
83 bool temp_up;
84 bool temp_down;
85 } lock;
86} pointer_state; 68} pointer_state;
87 69
88// on button release unset mode depending on the button. 70// on button release unset mode depending on the button.
@@ -95,8 +77,6 @@ void pointer_mode_update(void);
95// Reset mode on any keypress; 77// Reset mode on any keypress;
96void pointer_mode_reset(void); 78void pointer_mode_reset(void);
97 79
98void start_floating(swayc_t *view);
99void reset_floating(swayc_t *view);
100void input_init(void); 80void input_init(void);
101 81
102#endif 82#endif
diff --git a/include/resize.h b/include/resize.h
index 4ace1815..04209983 100644
--- a/include/resize.h
+++ b/include/resize.h
@@ -1,8 +1,8 @@
1#ifndef _SWAY_RESIZE_H 1#ifndef _SWAY_RESIZE_H
2#define _SWAY_RESIZE_H 2#define _SWAY_RESIZE_H
3#include <stdbool.h>
3 4
4bool mouse_resize_tiled(struct wlc_origin prev_pos); 5bool mouse_resize_tiled(struct wlc_origin prev_pos);
5bool resize_floating(struct wlc_origin prev_pos);
6bool resize_tiled(int amount, bool use_width); 6bool resize_tiled(int amount, bool use_width);
7 7
8#endif 8#endif
diff --git a/sway/handlers.c b/sway/handlers.c
index 7d1e4cde..896caa10 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -359,36 +359,54 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
359 uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { 359 uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) {
360 enum { DONT_SEND_CLICK = true, SEND_CLICK = false }; 360 enum { DONT_SEND_CLICK = true, SEND_CLICK = false };
361 361
362 // Update view pointer is on
363 pointer_state.view = container_under_pointer();
364
365 // Update pointer origin
366 pointer_state.origin.x = origin->x;
367 pointer_state.origin.y = origin->y;
368
362 // Update pointer_state 369 // Update pointer_state
363 switch (button) { 370 switch (button) {
364 case M_LEFT_CLICK: 371 case M_LEFT_CLICK:
365 pointer_state.l_held = state == WLC_BUTTON_STATE_PRESSED; 372 if (state == WLC_BUTTON_STATE_PRESSED) {
373 pointer_state.left.held = true;
374 pointer_state.left.x = origin->x;
375 pointer_state.left.y = origin->y;
376 pointer_state.left.view = pointer_state.view;
377 } else {
378 pointer_state.left.held = false;
379 }
366 break; 380 break;
367 381
368 case M_RIGHT_CLICK: 382 case M_RIGHT_CLICK:
369 pointer_state.r_held = state == WLC_BUTTON_STATE_PRESSED; 383 if (state == WLC_BUTTON_STATE_PRESSED) {
384 pointer_state.right.held = true;
385 pointer_state.right.x = origin->x;
386 pointer_state.right.y = origin->y;
387 pointer_state.right.view = pointer_state.view;
388 } else {
389 pointer_state.right.held = false;
390 }
370 break; 391 break;
371 392
372 case M_SCROLL_CLICK: 393 case M_SCROLL_CLICK:
373 pointer_state.s_held = state == WLC_BUTTON_STATE_PRESSED; 394 if (state == WLC_BUTTON_STATE_PRESSED) {
395 pointer_state.scroll.held = true;
396 pointer_state.scroll.x = origin->x;
397 pointer_state.scroll.y = origin->y;
398 pointer_state.scroll.view = pointer_state.view;
399 } else {
400 pointer_state.scroll.held = false;
401 }
374 break; 402 break;
375 403
404 //TODO scrolling behavior
376 case M_SCROLL_UP: 405 case M_SCROLL_UP:
377 pointer_state.s_up = state == WLC_BUTTON_STATE_PRESSED;
378 break;
379
380 case M_SCROLL_DOWN: 406 case M_SCROLL_DOWN:
381 pointer_state.s_down = state == WLC_BUTTON_STATE_PRESSED;
382 break; 407 break;
383 } 408 }
384 409
385 // Update pointer origin
386 pointer_state.origin.x = origin->x;
387 pointer_state.origin.y = origin->y;
388
389 // Update view pointer is on
390 pointer_state.view = container_under_pointer();
391
392 // set pointer mode 410 // set pointer mode
393 pointer_mode_set(button, 411 pointer_mode_set(button,
394 (modifiers->mods & config->floating_mod) == config->floating_mod); 412 (modifiers->mods & config->floating_mod) == config->floating_mod);
@@ -431,62 +449,6 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w
431 449
432 // Finally send click 450 // Finally send click
433 return SEND_CLICK; 451 return SEND_CLICK;
434
435 /* OLD */
436 if (state == WLC_BUTTON_STATE_PRESSED) {
437 sway_log(L_DEBUG, "Mouse button %u pressed", button);
438 if (button == M_LEFT_CLICK) {
439 pointer_state.l_held = true;
440 }
441 if (button == M_RIGHT_CLICK) {
442 pointer_state.r_held = true;
443 }
444 swayc_t *pointer = container_under_pointer();
445 if (pointer) {
446 set_focused_container(pointer);
447 int midway_x = pointer->x + pointer->width/2;
448 int midway_y = pointer->y + pointer->height/2;
449 pointer_state.lock.bottom = origin->y < midway_y;
450 pointer_state.lock.top = !pointer_state.lock.bottom;
451 pointer_state.lock.right = origin->x < midway_x;
452 pointer_state.lock.left = !pointer_state.lock.right;
453 }
454
455 if (pointer->is_floating) {
456 if (modifiers->mods & config->floating_mod) {
457 pointer_state.floating.drag = pointer_state.l_held;
458 pointer_state.floating.resize = pointer_state.r_held;
459 start_floating(pointer);
460 }
461 // Dont want pointer sent to window while dragging or resizing
462 return (pointer_state.floating.drag || pointer_state.floating.resize);
463 } else {
464 if (modifiers->mods & config->floating_mod) {
465 pointer_state.floating.drag = pointer_state.l_held;
466 pointer_state.tiling.resize = pointer_state.r_held;
467 pointer_state.tiling.init_view = pointer;
468 // Dont want pointer sent when resizing
469 return (pointer_state.tiling.resize);
470 }
471 }
472 return (pointer && pointer != focused);
473 } else {
474 sway_log(L_DEBUG, "Mouse button %u released", button);
475 if (button == M_LEFT_CLICK) {
476 pointer_state.l_held = false;
477 pointer_state.floating.drag = false;
478 pointer_state.tiling.init_view = NULL;
479 }
480 if (button == M_RIGHT_CLICK) {
481 pointer_state.r_held = false;
482 pointer_state.floating.resize = false;
483 pointer_state.tiling.resize = false;
484 pointer_state.tiling.init_view = NULL;
485 pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false};
486 }
487 }
488 /* OLD */
489 return false;
490} 452}
491 453
492static void handle_wlc_ready(void) { 454static void handle_wlc_ready(void) {
diff --git a/sway/input_state.c b/sway/input_state.c
index 3db78167..a63fc01c 100644
--- a/sway/input_state.c
+++ b/sway/input_state.c
@@ -48,75 +48,81 @@ void release_key(keycode key) {
48 } 48 }
49} 49}
50 50
51// Pointer state and mode
52
51struct pointer_state pointer_state; 53struct pointer_state pointer_state;
52 54
53// Pointer mode values
54static struct mode_state { 55static struct mode_state {
55 // Initial view state 56 // initial view state
57 double x, y, w, h;
58 swayc_t *ptr;
59 // containers resized with tiling resize
56 struct { 60 struct {
57 double x, y, w, h; 61 double x, w;
58 swayc_t *ptr; 62 swayc_t *ptr;
59 } view; 63 } lr;
60 // Initial pointer state
61 struct { 64 struct {
62 int x, y; 65 double y, h;
63 } coor; 66 swayc_t *ptr;
67 } tb;
64} initial; 68} initial;
65 69
66static struct { 70static struct {
67 enum { LEFT=1, RIGHT=0 } lr; 71 bool left;
68 enum { TOP=1, BOTTOM=0 } tb; 72 bool top;
69} lock; 73} lock;
70 74
71// Floating set/unset 75// Floating set/unset
72 76
73static void pointer_mode_set_floating(void) { 77static void set_initial_view(swayc_t *view) {
74 initial.view.x = initial.view.ptr->x; 78 initial.ptr = view;
75 initial.view.y = initial.view.ptr->y; 79 initial.x = view->x;
76 initial.view.w = initial.view.ptr->width; 80 initial.y = view->y;
77 initial.view.h = initial.view.ptr->height; 81 initial.w = view->width;
78 // setup initial cooridinates 82 initial.h = view->height;
79 initial.coor.x = pointer_state.origin.x;
80 initial.coor.y = pointer_state.origin.y;
81} 83}
82 84
83static void pointer_mode_reset_floating(void) { 85static void reset_initial_view(void) {
84 initial.view.ptr->x = initial.view.x; 86 initial.ptr->x = initial.x;
85 initial.view.ptr->y = initial.view.y; 87 initial.ptr->y = initial.y;
86 initial.view.ptr->width = initial.view.w; 88 initial.ptr->width = initial.w;
87 initial.view.ptr->height = initial.view.h; 89 initial.ptr->height = initial.h;
88 arrange_windows(initial.view.ptr, -1, -1); 90 arrange_windows(initial.ptr, -1, -1);
89 pointer_state.mode = 0; 91 pointer_state.mode = 0;
90} 92}
91 93
92// Mode set left/right click 94// Mode set left/right click
93 95
94static void pointer_mode_set_left(void) { 96static void pointer_mode_set_left(void) {
95 swayc_t *view = pointer_state.view; 97 set_initial_view(pointer_state.left.view);
96 initial.view.ptr = view; 98 if (initial.ptr->is_floating) {
97 if (view->is_floating) {
98 pointer_state.mode = M_DRAGGING | M_FLOATING; 99 pointer_state.mode = M_DRAGGING | M_FLOATING;
99 pointer_mode_set_floating();
100 } else { 100 } else {
101 pointer_state.mode = M_DRAGGING | M_TILING; 101 pointer_state.mode = M_DRAGGING | M_TILING;
102 } 102 }
103} 103}
104 104
105static void pointer_mode_set_right(void) { 105static void pointer_mode_set_right(void) {
106 swayc_t *view = pointer_state.view; 106 set_initial_view(pointer_state.right.view);
107 initial.view.ptr = view;
108 // Setup locking information 107 // Setup locking information
109 int midway_x = view->x + view->width/2; 108 int midway_x = initial.ptr->x + initial.ptr->width/2;
110 int midway_y = view->y + view->height/2; 109 int midway_y = initial.ptr->y + initial.ptr->height/2;
111 110
112 lock.lr = pointer_state.origin.x > midway_x; 111 lock.left = pointer_state.origin.x > midway_x;
113 lock.tb = pointer_state.origin.y > midway_y; 112 lock.top = pointer_state.origin.y > midway_y;
114 113
115 if (view->is_floating) { 114 if (initial.ptr->is_floating) {
116 pointer_state.mode = M_RESIZING | M_FLOATING; 115 pointer_state.mode = M_RESIZING | M_FLOATING;
117 pointer_mode_set_floating();
118 } else { 116 } else {
119 pointer_state.mode = M_RESIZING | M_TILING; 117 pointer_state.mode = M_RESIZING | M_TILING;
118 if ((initial.lr.ptr = get_swayc_in_direction(initial.ptr, lock.left ? MOVE_RIGHT: MOVE_LEFT))) {
119 initial.lr.x = initial.lr.ptr->x;
120 initial.lr.w = initial.lr.ptr->width;
121 }
122 if ((initial.tb.ptr = get_swayc_in_direction(initial.ptr, lock.top ? MOVE_DOWN: MOVE_UP))) {
123 initial.tb.y = initial.tb.ptr->y;
124 initial.tb.h = initial.tb.ptr->height;
125 }
120 } 126 }
121} 127}
122 128
@@ -127,14 +133,14 @@ void pointer_mode_set(uint32_t button, bool condition) {
127 switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { 133 switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) {
128 case M_DRAGGING: 134 case M_DRAGGING:
129 // end drag mode when left click is unpressed 135 // end drag mode when left click is unpressed
130 if (!pointer_state.l_held) { 136 if (!pointer_state.left.held) {
131 pointer_state.mode = 0; 137 pointer_state.mode = 0;
132 } 138 }
133 break; 139 break;
134 140
135 case M_RESIZING: 141 case M_RESIZING:
136 // end resize mode when right click is unpressed 142 // end resize mode when right click is unpressed
137 if (!pointer_state.r_held) { 143 if (!pointer_state.right.held) {
138 pointer_state.mode = 0; 144 pointer_state.mode = 0;
139 } 145 }
140 break; 146 break;
@@ -145,12 +151,13 @@ void pointer_mode_set(uint32_t button, bool condition) {
145 if (!condition || !pointer_state.view) { 151 if (!condition || !pointer_state.view) {
146 break; 152 break;
147 } 153 }
154
148 // Set mode depending on current button press 155 // Set mode depending on current button press
149 switch (button) { 156 switch (button) {
150 // Start dragging mode 157 // Start dragging mode
151 case M_LEFT_CLICK: 158 case M_LEFT_CLICK:
152 // if button release dont do anything 159 // if button release dont do anything
153 if (pointer_state.l_held) { 160 if (pointer_state.left.held) {
154 pointer_mode_set_left(); 161 pointer_mode_set_left();
155 } 162 }
156 break; 163 break;
@@ -158,106 +165,131 @@ void pointer_mode_set(uint32_t button, bool condition) {
158 // Start resize mode 165 // Start resize mode
159 case M_RIGHT_CLICK: 166 case M_RIGHT_CLICK:
160 // if button release dont do anyhting 167 // if button release dont do anyhting
161 if (pointer_state.r_held) { 168 if (pointer_state.right.held) {
162 pointer_mode_set_right(); 169 pointer_mode_set_right();
163 } 170 }
164 break; 171 break;
165
166 case M_SCROLL_UP:
167 case M_SCROLL_DOWN:
168 //TODO add scrolling behavior here
169 ;
170 } 172 }
171 } 173 }
172} 174}
173 175
174void pointer_mode_update(void) { 176void pointer_mode_update(void) {
175 swayc_t *view = initial.view.ptr; 177 if (initial.ptr->type != C_VIEW) {
176 if (view->type != C_VIEW) {
177 pointer_state.mode = 0; 178 pointer_state.mode = 0;
178 return; 179 return;
179 } 180 }
180 int dx = pointer_state.origin.x - initial.coor.x; 181 int dx = pointer_state.origin.x;
181 int dy = pointer_state.origin.y - initial.coor.y; 182 int dy = pointer_state.origin.y;
182 bool changed = false; 183 bool changed = false;
183 184
184 switch (pointer_state.mode) { 185 switch (pointer_state.mode) {
185 case M_FLOATING | M_DRAGGING: 186 case M_FLOATING | M_DRAGGING:
186 // Update position 187 // Update position
187 if (initial.view.x + dx != view->x) { 188 dx -= pointer_state.left.x;
188 view->x = initial.view.x + dx; 189 dy -= pointer_state.left.y;
190 if (initial.x + dx != initial.ptr->x) {
191 initial.ptr->x = initial.x + dx;
189 changed = true; 192 changed = true;
190 } 193 }
191 if (initial.view.y + dy != view->y) { 194 if (initial.y + dy != initial.ptr->y) {
192 view->y = initial.view.y + dy; 195 initial.ptr->y = initial.y + dy;
193 changed = true; 196 changed = true;
194 } 197 }
198 update_geometry(initial.ptr);
195 break; 199 break;
196 200
197 case M_FLOATING | M_RESIZING: 201 case M_FLOATING | M_RESIZING:
198 if (lock.lr) { 202 dx -= pointer_state.right.x;
199 if (initial.view.w + dx > min_sane_w) { 203 dy -= pointer_state.right.y;
200 if (initial.view.w + dx != view->width) { 204 initial.ptr = pointer_state.right.view;
201 view->width = initial.view.w + dx; 205 if (lock.left) {
202 changed = true; 206 if (initial.w + dx > min_sane_w) {
203 } 207 initial.ptr->width = initial.w + dx;
204 } 208 }
205 } else { //lock.right 209 } else { //lock.right
206 if (initial.view.w - dx > min_sane_w) { 210 if (initial.w - dx > min_sane_w) {
207 if (initial.view.w - dx != view->width) { 211 initial.ptr->width = initial.w - dx;
208 view->width = initial.view.w - dx; 212 initial.ptr->x = initial.x + dx;
209 view->x = initial.view.x + dx;
210 changed = true;
211 }
212 } 213 }
213 } 214 }
214 if (lock.tb) { 215 if (lock.top) {
215 if (initial.view.h + dy > min_sane_h) { 216 if (initial.h + dy > min_sane_h) {
216 if (initial.view.y - dy != view->height) { 217 initial.ptr->height = initial.h + dy;
217 view->height = initial.view.h + dy;
218 changed = true;
219 }
220 } 218 }
221 } else { //lock.bottom 219 } else { //lock.bottom
222 if (initial.view.h - dy > min_sane_h) { 220 if (initial.h - dy > min_sane_h) {
223 if (initial.view.h - dy != view->height) { 221 initial.ptr->height = initial.h - dy;
224 view->height = initial.view.h - dy; 222 initial.ptr->y = initial.y + dy;
225 view->y = initial.view.y + dy;
226 changed = true;
227 }
228 } 223 }
229 } 224 }
225 update_geometry(initial.ptr);
230 break; 226 break;
231 227
232 case M_TILING | M_DRAGGING: 228 case M_TILING | M_DRAGGING:
233 // swap current view under pointer with dragged view 229 // swap current view under pointer with dragged view
234 if (pointer_state.view && pointer_state.view != initial.view.ptr) { 230 if (pointer_state.view && pointer_state.view != initial.ptr) {
235 // Swap them around 231 // Swap them around
236 swap_container(pointer_state.view, initial.view.ptr); 232 swap_container(pointer_state.view, initial.ptr);
237 update_geometry(pointer_state.view); 233 update_geometry(pointer_state.view);
238 update_geometry(initial.view.ptr); 234 update_geometry(initial.ptr);
239 // Set focus back to initial view 235 // Set focus back to initial view
240 set_focused_container(initial.view.ptr); 236 set_focused_container(initial.ptr);
241 } 237 }
242 break; 238 break;
243 239
244 case M_TILING | M_RESIZING: 240 case M_TILING | M_RESIZING:
245 241 dx -= pointer_state.right.x;
246 242 dy -= pointer_state.right.y;
247 243 // resize if we can
244 if (initial.lr.ptr) {
245 if (lock.left) {
246 // Check whether its fine to resize
247 if (initial.w + dx > min_sane_w && initial.lr.w - dx > min_sane_w) {
248 initial.ptr->width = initial.w + dx;
249 initial.lr.ptr->width = initial.lr.w - dx;
250 initial.lr.ptr->x = initial.lr.x + dx;
251 }
252 } else { //lock.right
253 if (initial.w - dx > min_sane_w && initial.lr.w + dx > min_sane_w) {
254 initial.ptr->width = initial.w - dx;
255 initial.ptr->x = initial.x + dx;
256 initial.lr.ptr->width = initial.lr.w + dx;
257 }
258 changed = true;
259 }
260 arrange_windows(initial.lr.ptr->parent, -1, -1);
261 }
262 if (initial.tb.ptr) {
263 if (lock.top) {
264 if (initial.h + dy > min_sane_h && initial.tb.h - dy > min_sane_h) {
265 initial.ptr->height = initial.h + dy;
266 initial.tb.ptr->height = initial.tb.h - dy;
267 initial.tb.ptr->y = initial.tb.y + dy;
268 }
269 } else { //lock.bottom
270 if (initial.h - dy > min_sane_h && initial.tb.h + dy > min_sane_h) {
271 initial.ptr->height = initial.h - dy;
272 initial.ptr->y = initial.y + dy;
273 initial.tb.ptr->height = initial.tb.h + dy;
274 }
275 changed = true;
276 }
277 arrange_windows(initial.tb.ptr->parent, -1, -1);
278 }
279 if (changed) {
280 arrange_windows(initial.ptr->parent, -1, -1);
281 }
282 changed = false;
248 default: 283 default:
249 return; 284 return;
250 } 285 }
251 if (changed) {
252 update_geometry(view);
253 }
254} 286}
255 287
256void pointer_mode_reset(void) { 288void pointer_mode_reset(void) {
257 switch (pointer_state.mode) { 289 switch (pointer_state.mode) {
258 case M_FLOATING | M_DRAGGING: 290 case M_FLOATING | M_DRAGGING:
259 case M_FLOATING | M_RESIZING: 291 case M_FLOATING | M_RESIZING:
260 pointer_mode_reset_floating(); 292 reset_initial_view();
261 break; 293 break;
262 294
263 case M_TILING | M_DRAGGING: 295 case M_TILING | M_DRAGGING:
@@ -267,27 +299,3 @@ void pointer_mode_reset(void) {
267 } 299 }
268} 300}
269 301
270
271static struct wlc_geometry saved_floating;
272
273void start_floating(swayc_t *view) {
274 if (view->is_floating) {
275 saved_floating.origin.x = view->x;
276 saved_floating.origin.y = view->y;
277 saved_floating.size.w = view->width;
278 saved_floating.size.h = view->height;
279 }
280}
281
282void reset_floating(swayc_t *view) {
283 if (view->is_floating) {
284 view->x = saved_floating.origin.x;
285 view->y = saved_floating.origin.y;
286 view->width = saved_floating.size.w;
287 view->height = saved_floating.size.h;
288 arrange_windows(view->parent, -1, -1);
289 }
290 pointer_state.floating = (struct pointer_floating){0, 0};
291 pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0};
292}
293
diff --git a/sway/resize.c b/sway/resize.c
index 31cd66e8..22d520af 100644
--- a/sway/resize.c
+++ b/sway/resize.c
@@ -6,267 +6,6 @@
6#include "input_state.h" 6#include "input_state.h"
7#include "handlers.h" 7#include "handlers.h"
8 8
9bool mouse_resize_tiled(struct wlc_origin prev_pos) {
10 swayc_t *view = container_under_pointer();
11 bool valid = true;
12 bool changed_tiling = false;
13 double dx = pointer_state.origin.x - prev_pos.x;
14 double dy = pointer_state.origin.y - prev_pos.y;
15 if (view != pointer_state.tiling.init_view) {
16 changed_tiling = true;
17 valid = false;
18 if (view->type != C_WORKSPACE) {
19 if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) {
20 pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
21 pointer_state.lock.temp_left = true;
22 } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) {
23 pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
24 pointer_state.lock.temp_right = true;
25 } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) {
26 pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
27 pointer_state.lock.temp_up = true;
28 } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) {
29 pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
30 pointer_state.lock.temp_down = true;
31 }
32 }
33 }
34
35 if ((dx < 0 || pointer_state.origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) {
36 changed_tiling = true;
37 valid = false;
38 } else if (dx > 0 && pointer_state.lock.temp_left) {
39 pointer_state.lock.temp_left = false;
40 pointer_state.tiling.lock_pos.x = 0;
41 }
42
43 if ((dx > 0 || pointer_state.origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) {
44 changed_tiling = true;
45 valid = false;
46 } else if (dx < 0 && pointer_state.lock.temp_right) {
47 pointer_state.lock.temp_right = false;
48 pointer_state.tiling.lock_pos.x = 0;
49 }
50
51 if ((dy < 0 || pointer_state.origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) {
52 changed_tiling = true;
53 valid = false;
54 } else if (dy > 0 && pointer_state.lock.temp_up) {
55 pointer_state.lock.temp_up = false;
56 pointer_state.tiling.lock_pos.y = 0;
57 }
58
59 if ((dy > 0 || pointer_state.origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) {
60 changed_tiling = true;
61 valid = false;
62 } else if (dy < 0 && pointer_state.lock.temp_down) {
63 pointer_state.lock.temp_down = false;
64 pointer_state.tiling.lock_pos.y = 0;
65 }
66
67 if (!view->is_floating && valid) {
68 // Handle layout resizes -- Find the biggest parent container then apply resizes to that
69 // and its bordering siblings
70 swayc_t *parent = view;
71 if (!pointer_state.lock.bottom) {
72 while (parent->type != C_WORKSPACE) {
73 // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better
74 // way of doing this.
75 if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) {
76 parent = parent->parent;
77 } else {
78 break;
79 }
80 }
81 if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
82 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN);
83 if (sibling) {
84 if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) {
85 recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM);
86 recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP);
87 changed_tiling = true;
88 } else {
89 if (parent->height < min_sane_h) {
90 //pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
91 pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
92 pointer_state.lock.temp_up = true;
93 } else if (sibling->height < min_sane_h) {
94 pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
95 pointer_state.lock.temp_down = true;
96 }
97 }
98 }
99 }
100 } else if (!pointer_state.lock.top) {
101 while (parent->type != C_WORKSPACE) {
102 if (fabs(parent->parent->y - view->y) <= 1) {
103 parent = parent->parent;
104 } else {
105 break;
106 }
107 }
108 if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) {
109 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP);
110 if (sibling) {
111 if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) {
112 recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP);
113 recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM);
114 changed_tiling = true;
115 } else {
116 if (parent->height < min_sane_h) {
117 //pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20;
118 pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
119 pointer_state.lock.temp_down = true;
120 } else if (sibling->height < min_sane_h) {
121 pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20;
122 pointer_state.lock.temp_up = true;
123 }
124 }
125 }
126 }
127 }
128
129 parent = view;
130 if (!pointer_state.lock.right) {
131 while (parent->type != C_WORKSPACE) {
132 if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) {
133 parent = parent->parent;
134 } else {
135 sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width);
136 break;
137 }
138 }
139 if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
140 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT);
141 if (sibling) {
142 if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) {
143 recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT);
144 recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT);
145 changed_tiling = true;
146 } else {
147 if (parent->width < min_sane_w) {
148 pointer_state.lock.temp_left = true;
149 pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
150 } else if (sibling->width < min_sane_w) {
151 pointer_state.lock.temp_right = true;
152 pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20;
153 }
154 }
155 }
156 }
157 } else if (!pointer_state.lock.left) {
158 while (parent->type != C_WORKSPACE) {
159 if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) {
160 parent = parent->parent;
161 } else {
162 break;
163 }
164 }
165 if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) {
166 swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT);
167 if (sibling) {
168 if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) {
169 recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT);
170 recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT);
171 changed_tiling = true;
172 } else {
173 if (parent->width < min_sane_w) {
174 pointer_state.lock.temp_right = true;
175 pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
176 } else if (sibling->width < min_sane_w) {
177 pointer_state.lock.temp_left = true;
178 pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20;
179 }
180 }
181 }
182 }
183 }
184 arrange_windows(swayc_active_workspace(), -1, -1);
185 }
186 return changed_tiling;
187}
188
189bool resize_floating(struct wlc_origin prev_pos) {
190 bool changed = false;
191 swayc_t *view = container_under_pointer();
192 uint32_t edge = 0;
193 int dx = pointer_state.origin.x - prev_pos.x;
194 int dy = pointer_state.origin.y - prev_pos.y;
195
196 // Move and resize the view based on the dx/dy and mouse position
197 int midway_x = view->x + view->width/2;
198 int midway_y = view->y + view->height/2;
199 if (dx < 0) {
200 if (!pointer_state.lock.right) {
201 if (view->width > min_sane_w) {
202 changed = true;
203 view->width += dx;
204 edge += WLC_RESIZE_EDGE_RIGHT;
205 }
206 } else if (pointer_state.origin.x < midway_x && !pointer_state.lock.left) {
207 changed = true;
208 view->x += dx;
209 view->width -= dx;
210 edge += WLC_RESIZE_EDGE_LEFT;
211 }
212 } else if (dx > 0) {
213 if (pointer_state.origin.x > midway_x && !pointer_state.lock.right) {
214 changed = true;
215 view->width += dx;
216 edge += WLC_RESIZE_EDGE_RIGHT;
217 } else if (!pointer_state.lock.left) {
218 if (view->width > min_sane_w) {
219 changed = true;
220 view->x += dx;
221 view->width -= dx;
222 edge += WLC_RESIZE_EDGE_LEFT;
223 }
224 }
225 }
226
227 if (dy < 0) {
228 if (!pointer_state.lock.bottom) {
229 if (view->height > min_sane_h) {
230 changed = true;
231 view->height += dy;
232 edge += WLC_RESIZE_EDGE_BOTTOM;
233 }
234 } else if (pointer_state.origin.y < midway_y && !pointer_state.lock.top) {
235 changed = true;
236 view->y += dy;
237 view->height -= dy;
238 edge += WLC_RESIZE_EDGE_TOP;
239 }
240 } else if (dy > 0) {
241 if (pointer_state.origin.y > midway_y && !pointer_state.lock.bottom) {
242 changed = true;
243 view->height += dy;
244 edge += WLC_RESIZE_EDGE_BOTTOM;
245 } else if (!pointer_state.lock.top) {
246 if (view->height > min_sane_h) {
247 changed = true;
248 view->y += dy;
249 view->height -= dy;
250 edge += WLC_RESIZE_EDGE_TOP;
251 }
252 }
253 }
254 if (changed) {
255 struct wlc_geometry geometry = {
256 .origin = {
257 .x = view->x,
258 .y = view->y
259 },
260 .size = {
261 .w = view->width,
262 .h = view->height
263 }
264 };
265 wlc_view_set_geometry(view->handle, edge, &geometry);
266 }
267 return changed;
268}
269
270bool resize_tiled(int amount, bool use_width) { 9bool resize_tiled(int amount, bool use_width) {
271 swayc_t *parent = get_focused_view(swayc_active_workspace()); 10 swayc_t *parent = get_focused_view(swayc_active_workspace());
272 swayc_t *focused = parent; 11 swayc_t *focused = parent;