diff options
author | Drew DeVault <sir@cmpwn.com> | 2015-08-23 15:38:51 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2015-08-23 15:38:51 -0400 |
commit | 9a7f48f87272dea8cb1e678673b2fe95dc993d68 (patch) | |
tree | 1a9e633ead0ff50f55987310621dab39531d2305 | |
parent | Refactor keyboard to consider modified keysyms (diff) | |
parent | merge (diff) | |
download | sway-9a7f48f87272dea8cb1e678673b2fe95dc993d68.tar.gz sway-9a7f48f87272dea8cb1e678673b2fe95dc993d68.tar.zst sway-9a7f48f87272dea8cb1e678673b2fe95dc993d68.zip |
Merge pull request #121 from taiyu-len/pointer_mod
Pointer mode clean and fix.
-rw-r--r-- | include/input_state.h | 72 | ||||
-rw-r--r-- | include/layout.h | 2 | ||||
-rw-r--r-- | include/resize.h | 3 | ||||
-rw-r--r-- | sway/handlers.c | 247 | ||||
-rw-r--r-- | sway/input_state.c | 281 | ||||
-rw-r--r-- | sway/layout.c | 140 | ||||
-rw-r--r-- | sway/resize.c | 261 |
7 files changed, 508 insertions, 498 deletions
diff --git a/include/input_state.h b/include/input_state.h index 29064fd0..d87ae18c 100644 --- a/include/input_state.h +++ b/include/input_state.h | |||
@@ -15,6 +15,7 @@ void press_key(uint32_t key_sym, uint32_t key_code); | |||
15 | // unsets a key as pressed | 15 | // unsets a key as pressed |
16 | void release_key(uint32_t key_sym, uint32_t key_code); | 16 | void release_key(uint32_t key_sym, uint32_t key_code); |
17 | 17 | ||
18 | |||
18 | /* Pointer state */ | 19 | /* Pointer state */ |
19 | 20 | ||
20 | enum pointer_values { | 21 | enum pointer_values { |
@@ -25,34 +26,55 @@ enum pointer_values { | |||
25 | M_SCROLL_DOWN = 276, | 26 | M_SCROLL_DOWN = 276, |
26 | }; | 27 | }; |
27 | 28 | ||
29 | enum pointer_mode { | ||
30 | // Target | ||
31 | M_FLOATING = 1, | ||
32 | M_TILING = 2, | ||
33 | // Action | ||
34 | M_DRAGGING = 4, | ||
35 | M_RESIZING = 8, | ||
36 | }; | ||
37 | |||
38 | struct pointer_button_state { | ||
39 | bool held; | ||
40 | // state at the point it was pressed | ||
41 | int x, y; | ||
42 | swayc_t *view; | ||
43 | }; | ||
44 | |||
28 | extern struct pointer_state { | 45 | extern struct pointer_state { |
29 | bool l_held; | 46 | // mouse clicks |
30 | bool r_held; | 47 | struct pointer_button_state left; |
31 | struct pointer_floating { | 48 | struct pointer_button_state right; |
32 | bool drag; | 49 | struct pointer_button_state scroll; |
33 | bool resize; | 50 | |
34 | } floating; | 51 | // pointer position |
35 | struct pointer_tiling { | 52 | struct mouse_origin{ |
36 | bool resize; | 53 | int x, y; |
37 | swayc_t *init_view; | 54 | } origin; |
38 | struct wlc_origin lock_pos; | 55 | |
39 | } tiling; | 56 | // change in pointer position |
40 | struct pointer_lock { | 57 | struct { |
41 | // Lock movement for certain edges | 58 | int x, y; |
42 | bool left; | 59 | } delta; |
43 | bool right; | 60 | |
44 | bool top; | 61 | // view pointer is currently over |
45 | bool bottom; | 62 | swayc_t *view; |
46 | // Lock movement in certain directions | 63 | |
47 | bool temp_left; | 64 | // Pointer mode |
48 | bool temp_right; | 65 | int mode; |
49 | bool temp_up; | ||
50 | bool temp_down; | ||
51 | } lock; | ||
52 | } pointer_state; | 66 | } pointer_state; |
53 | 67 | ||
54 | void start_floating(swayc_t *view); | 68 | // on button release unset mode depending on the button. |
55 | void reset_floating(swayc_t *view); | 69 | // on button press set mode conditionally depending on the button |
70 | void pointer_mode_set(uint32_t button, bool condition); | ||
71 | |||
72 | // Update mode in mouse motion | ||
73 | void pointer_mode_update(void); | ||
74 | |||
75 | // Reset mode on any keypress; | ||
76 | void pointer_mode_reset(void); | ||
77 | |||
56 | void input_init(void); | 78 | void input_init(void); |
57 | 79 | ||
58 | #endif | 80 | #endif |
diff --git a/include/layout.h b/include/layout.h index f8aebe0a..8f269607 100644 --- a/include/layout.h +++ b/include/layout.h | |||
@@ -19,10 +19,12 @@ void add_floating(swayc_t *ws, swayc_t *child); | |||
19 | swayc_t *add_sibling(swayc_t *sibling, swayc_t *child); | 19 | swayc_t *add_sibling(swayc_t *sibling, swayc_t *child); |
20 | swayc_t *replace_child(swayc_t *child, swayc_t *new_child); | 20 | swayc_t *replace_child(swayc_t *child, swayc_t *new_child); |
21 | swayc_t *remove_child(swayc_t *child); | 21 | swayc_t *remove_child(swayc_t *child); |
22 | void swap_container(swayc_t *a, swayc_t *b); | ||
22 | 23 | ||
23 | void move_container(swayc_t* container,swayc_t* root,enum movement_direction direction); | 24 | void move_container(swayc_t* container,swayc_t* root,enum movement_direction direction); |
24 | 25 | ||
25 | // Layout | 26 | // Layout |
27 | void update_geometry(swayc_t *view); | ||
26 | void arrange_windows(swayc_t *container, double width, double height); | 28 | void arrange_windows(swayc_t *container, double width, double height); |
27 | 29 | ||
28 | swayc_t *get_focused_container(swayc_t *parent); | 30 | swayc_t *get_focused_container(swayc_t *parent); |
diff --git a/include/resize.h b/include/resize.h index 4ace1815..8d205d3b 100644 --- a/include/resize.h +++ b/include/resize.h | |||
@@ -1,8 +1,7 @@ | |||
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 | ||
4 | bool mouse_resize_tiled(struct wlc_origin prev_pos); | ||
5 | bool resize_floating(struct wlc_origin prev_pos); | ||
6 | bool resize_tiled(int amount, bool use_width); | 5 | bool resize_tiled(int amount, bool use_width); |
7 | 6 | ||
8 | #endif | 7 | #endif |
diff --git a/sway/handlers.c b/sway/handlers.c index acf3e6a4..27f6d294 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -17,10 +17,14 @@ | |||
17 | #include "input_state.h" | 17 | #include "input_state.h" |
18 | #include "resize.h" | 18 | #include "resize.h" |
19 | 19 | ||
20 | struct wlc_origin mouse_origin; | 20 | // Event should be sent to client |
21 | #define EVENT_PASSTHROUGH false | ||
22 | |||
23 | // Event handled by sway and should not be sent to client | ||
24 | #define EVENT_HANDLED true | ||
21 | 25 | ||
22 | static bool pointer_test(swayc_t *view, void *_origin) { | 26 | static bool pointer_test(swayc_t *view, void *_origin) { |
23 | const struct wlc_origin *origin = _origin; | 27 | const struct mouse_origin *origin = _origin; |
24 | // Determine the output that the view is under | 28 | // Determine the output that the view is under |
25 | swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); | 29 | swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); |
26 | if (origin->x >= view->x && origin->y >= view->y | 30 | if (origin->x >= view->x && origin->y >= view->y |
@@ -55,7 +59,7 @@ swayc_t *container_under_pointer(void) { | |||
55 | i = len = lookup->floating->length; | 59 | i = len = lookup->floating->length; |
56 | bool got_floating = false; | 60 | bool got_floating = false; |
57 | while (--i > -1) { | 61 | while (--i > -1) { |
58 | if (pointer_test(lookup->floating->items[i], &mouse_origin)) { | 62 | if (pointer_test(lookup->floating->items[i], &pointer_state.origin)) { |
59 | lookup = lookup->floating->items[i]; | 63 | lookup = lookup->floating->items[i]; |
60 | got_floating = true; | 64 | got_floating = true; |
61 | break; | 65 | break; |
@@ -68,7 +72,7 @@ swayc_t *container_under_pointer(void) { | |||
68 | // search children | 72 | // search children |
69 | len = lookup->children->length; | 73 | len = lookup->children->length; |
70 | for (i = 0; i < len; ++i) { | 74 | for (i = 0; i < len; ++i) { |
71 | if (pointer_test(lookup->children->items[i], &mouse_origin)) { | 75 | if (pointer_test(lookup->children->items[i], &pointer_state.origin)) { |
72 | lookup = lookup->children->items[i]; | 76 | lookup = lookup->children->items[i]; |
73 | break; | 77 | break; |
74 | } | 78 | } |
@@ -284,13 +288,12 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
284 | uint32_t key, uint32_t sym, enum wlc_key_state state) { | 288 | uint32_t key, uint32_t sym, enum wlc_key_state state) { |
285 | 289 | ||
286 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { | 290 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { |
287 | return false; | 291 | return EVENT_PASSTHROUGH; |
288 | } | 292 | } |
289 | 293 | ||
290 | // Revert floating container back to original position on keypress | 294 | // reset pointer mode on keypress |
291 | if (state == WLC_KEY_STATE_PRESSED && | 295 | if (state == WLC_KEY_STATE_PRESSED && pointer_state.mode) { |
292 | (pointer_state.floating.drag || pointer_state.floating.resize)) { | 296 | pointer_mode_reset(); |
293 | reset_floating(get_focused_view(&root_container)); | ||
294 | } | 297 | } |
295 | 298 | ||
296 | struct sway_mode *mode = config->current_mode; | 299 | struct sway_mode *mode = config->current_mode; |
@@ -319,125 +322,119 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
319 | if (match) { | 322 | if (match) { |
320 | if (state == WLC_KEY_STATE_PRESSED) { | 323 | if (state == WLC_KEY_STATE_PRESSED) { |
321 | handle_command(config, binding->command); | 324 | handle_command(config, binding->command); |
322 | return true; | 325 | return EVENT_HANDLED; |
323 | } else if (state == WLC_KEY_STATE_RELEASED) { | 326 | } else if (state == WLC_KEY_STATE_RELEASED) { |
324 | // TODO: --released | 327 | // TODO: --released |
325 | } | 328 | } |
326 | } | 329 | } |
327 | } | 330 | } |
328 | } | 331 | } |
329 | return false; | 332 | return EVENT_PASSTHROUGH; |
330 | } | 333 | } |
331 | 334 | ||
332 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { | 335 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { |
333 | static struct wlc_origin prev_pos; | 336 | // Update pointer origin |
334 | static wlc_handle prev_handle = 0; | 337 | pointer_state.delta.x = origin->x - pointer_state.origin.x; |
335 | mouse_origin = *origin; | 338 | pointer_state.delta.y = origin->y - pointer_state.origin.y; |
336 | bool changed_floating = false; | 339 | pointer_state.origin.x = origin->x; |
337 | bool changed_tiling = false; | 340 | pointer_state.origin.y = origin->y; |
338 | if (!swayc_active_workspace()) { | 341 | |
339 | return false; | 342 | // Update view under pointer |
340 | } | 343 | swayc_t *prev_view = pointer_state.view; |
341 | // Do checks to determine if proper keys are being held | 344 | pointer_state.view = container_under_pointer(); |
342 | swayc_t *view = container_under_pointer(); | 345 | |
343 | if (pointer_state.floating.drag && view) { | 346 | // If pointer is in a mode, update it |
344 | if (view->is_floating) { | 347 | if (pointer_state.mode) { |
345 | int dx = mouse_origin.x - prev_pos.x; | 348 | pointer_mode_update(); |
346 | int dy = mouse_origin.y - prev_pos.y; | ||
347 | view->x += dx; | ||
348 | view->y += dy; | ||
349 | struct wlc_geometry geometry = { | ||
350 | .origin = { | ||
351 | .x = view->x, | ||
352 | .y = view->y | ||
353 | }, | ||
354 | .size = { | ||
355 | .w = view->width, | ||
356 | .h = view->height | ||
357 | } | ||
358 | }; | ||
359 | wlc_view_set_geometry(view->handle, 0, &geometry); | ||
360 | changed_floating = true; | ||
361 | } else { | ||
362 | swayc_t *init_view = pointer_state.tiling.init_view; | ||
363 | if (view != init_view && view->type == C_VIEW) { | ||
364 | changed_tiling = true; | ||
365 | int i, j; | ||
366 | for (i = 0; i < view->parent->children->length; i++) { | ||
367 | if (view->parent->children->items[i] == view) { | ||
368 | for (j = 0; j < init_view->parent->children->length; j++) { | ||
369 | if (init_view->parent->children->items[j] == init_view) { | ||
370 | double temp_w = view->width; | ||
371 | double temp_h = view->height; | ||
372 | view->width = init_view->width; | ||
373 | view->height = init_view->height; | ||
374 | init_view->width = temp_w; | ||
375 | init_view->height = temp_h; | ||
376 | |||
377 | init_view->parent->children->items[j] = view; | ||
378 | view->parent->children->items[i] = init_view; | ||
379 | |||
380 | swayc_t *temp = view->parent; | ||
381 | view->parent = init_view->parent; | ||
382 | init_view->parent = temp; | ||
383 | |||
384 | arrange_windows(&root_container, -1, -1); | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | break; | ||
389 | } | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | } else if (pointer_state.floating.resize && view) { | ||
394 | changed_floating = resize_floating(prev_pos); | ||
395 | } else if (pointer_state.tiling.resize && view) { | ||
396 | changed_tiling = mouse_resize_tiled(prev_pos); | ||
397 | } | 349 | } |
398 | if (config->focus_follows_mouse && prev_handle != handle) { | 350 | // Otherwise change focus if config is set an |
399 | // Dont change focus if fullscreen | 351 | else if (prev_view != pointer_state.view && config->focus_follows_mouse) { |
400 | swayc_t *focused = get_focused_view(view); | 352 | if (pointer_state.view && pointer_state.view->type == C_VIEW) { |
401 | if (!swayc_is_fullscreen(focused) | 353 | set_focused_container(pointer_state.view); |
402 | && !(pointer_state.l_held || pointer_state.r_held)) { | ||
403 | set_focused_container(container_under_pointer()); | ||
404 | } | 354 | } |
405 | } | 355 | } |
406 | prev_handle = handle; | 356 | return EVENT_PASSTHROUGH; |
407 | prev_pos = mouse_origin; | ||
408 | if (changed_tiling || changed_floating) { | ||
409 | return true; | ||
410 | } | ||
411 | return false; | ||
412 | } | 357 | } |
413 | 358 | ||
414 | 359 | ||
415 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, | 360 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, |
416 | uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { | 361 | uint32_t button, enum wlc_button_state state, const struct wlc_origin *origin) { |
417 | swayc_t *focused = get_focused_container(&root_container); | 362 | |
418 | // dont change focus if fullscreen | 363 | // Update view pointer is on |
419 | if (swayc_is_fullscreen(focused)) { | 364 | pointer_state.view = container_under_pointer(); |
420 | return false; | 365 | |
421 | } | 366 | // Update pointer origin |
422 | if (state == WLC_BUTTON_STATE_PRESSED) { | 367 | pointer_state.origin.x = origin->x; |
423 | sway_log(L_DEBUG, "Mouse button %u pressed", button); | 368 | pointer_state.origin.y = origin->y; |
424 | if (button == M_LEFT_CLICK) { | 369 | |
425 | pointer_state.l_held = true; | 370 | // Update pointer_state |
371 | switch (button) { | ||
372 | case M_LEFT_CLICK: | ||
373 | if (state == WLC_BUTTON_STATE_PRESSED) { | ||
374 | pointer_state.left.held = true; | ||
375 | pointer_state.left.x = origin->x; | ||
376 | pointer_state.left.y = origin->y; | ||
377 | pointer_state.left.view = pointer_state.view; | ||
378 | } else { | ||
379 | pointer_state.left.held = false; | ||
426 | } | 380 | } |
427 | if (button == M_RIGHT_CLICK) { | 381 | break; |
428 | pointer_state.r_held = true; | 382 | |
383 | case M_RIGHT_CLICK: | ||
384 | if (state == WLC_BUTTON_STATE_PRESSED) { | ||
385 | pointer_state.right.held = true; | ||
386 | pointer_state.right.x = origin->x; | ||
387 | pointer_state.right.y = origin->y; | ||
388 | pointer_state.right.view = pointer_state.view; | ||
389 | } else { | ||
390 | pointer_state.right.held = false; | ||
429 | } | 391 | } |
430 | swayc_t *pointer = container_under_pointer(); | 392 | break; |
431 | if (pointer) { | 393 | |
432 | set_focused_container(pointer); | 394 | case M_SCROLL_CLICK: |
433 | int midway_x = pointer->x + pointer->width/2; | 395 | if (state == WLC_BUTTON_STATE_PRESSED) { |
434 | int midway_y = pointer->y + pointer->height/2; | 396 | pointer_state.scroll.held = true; |
435 | pointer_state.lock.bottom = origin->y < midway_y; | 397 | pointer_state.scroll.x = origin->x; |
436 | pointer_state.lock.top = !pointer_state.lock.bottom; | 398 | pointer_state.scroll.y = origin->y; |
437 | pointer_state.lock.right = origin->x < midway_x; | 399 | pointer_state.scroll.view = pointer_state.view; |
438 | pointer_state.lock.left = !pointer_state.lock.right; | 400 | } else { |
401 | pointer_state.scroll.held = false; | ||
439 | } | 402 | } |
403 | break; | ||
404 | |||
405 | //TODO scrolling behavior | ||
406 | case M_SCROLL_UP: | ||
407 | case M_SCROLL_DOWN: | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | // get focused window and check if to change focus on mouse click | ||
412 | swayc_t *focused = get_focused_container(&root_container); | ||
413 | |||
414 | // dont change focus or mode if fullscreen | ||
415 | if (swayc_is_fullscreen(focused)) { | ||
416 | return EVENT_PASSTHROUGH; | ||
417 | } | ||
418 | |||
419 | // set pointer mode | ||
420 | pointer_mode_set(button, | ||
421 | (modifiers->mods & config->floating_mod) == config->floating_mod); | ||
440 | 422 | ||
423 | // Return if mode has been set | ||
424 | if (pointer_state.mode) { | ||
425 | return EVENT_HANDLED; | ||
426 | } | ||
427 | |||
428 | // Always send mouse release | ||
429 | if (state == WLC_BUTTON_STATE_RELEASED) { | ||
430 | return EVENT_PASSTHROUGH; | ||
431 | } | ||
432 | |||
433 | // Check whether to change focus | ||
434 | swayc_t *pointer = pointer_state.view; | ||
435 | if (pointer && focused != pointer) { | ||
436 | set_focused_container(pointer_state.view); | ||
437 | // Send to front if floating | ||
441 | if (pointer->is_floating) { | 438 | if (pointer->is_floating) { |
442 | int i; | 439 | int i; |
443 | for (i = 0; i < pointer->parent->floating->length; i++) { | 440 | for (i = 0; i < pointer->parent->floating->length; i++) { |
@@ -447,40 +444,12 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
447 | break; | 444 | break; |
448 | } | 445 | } |
449 | } | 446 | } |
450 | arrange_windows(pointer->parent, -1, -1); | 447 | wlc_view_bring_to_front(view); |
451 | if (modifiers->mods & config->floating_mod) { | ||
452 | pointer_state.floating.drag = pointer_state.l_held; | ||
453 | pointer_state.floating.resize = pointer_state.r_held; | ||
454 | start_floating(pointer); | ||
455 | } | ||
456 | // Dont want pointer sent to window while dragging or resizing | ||
457 | return (pointer_state.floating.drag || pointer_state.floating.resize); | ||
458 | } else { | ||
459 | if (modifiers->mods & config->floating_mod) { | ||
460 | pointer_state.floating.drag = pointer_state.l_held; | ||
461 | pointer_state.tiling.resize = pointer_state.r_held; | ||
462 | pointer_state.tiling.init_view = pointer; | ||
463 | // Dont want pointer sent when resizing | ||
464 | return (pointer_state.tiling.resize); | ||
465 | } | ||
466 | } | ||
467 | return (pointer && pointer != focused); | ||
468 | } else { | ||
469 | sway_log(L_DEBUG, "Mouse button %u released", button); | ||
470 | if (button == M_LEFT_CLICK) { | ||
471 | pointer_state.l_held = false; | ||
472 | pointer_state.floating.drag = false; | ||
473 | pointer_state.tiling.init_view = NULL; | ||
474 | } | ||
475 | if (button == M_RIGHT_CLICK) { | ||
476 | pointer_state.r_held = false; | ||
477 | pointer_state.floating.resize = false; | ||
478 | pointer_state.tiling.resize = false; | ||
479 | pointer_state.tiling.init_view = NULL; | ||
480 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false}; | ||
481 | } | 448 | } |
482 | } | 449 | } |
483 | return false; | 450 | |
451 | // Finally send click | ||
452 | return EVENT_PASSTHROUGH; | ||
484 | } | 453 | } |
485 | 454 | ||
486 | static void handle_wlc_ready(void) { | 455 | static void handle_wlc_ready(void) { |
diff --git a/sway/input_state.c b/sway/input_state.c index 9e065e60..e911d9cf 100644 --- a/sway/input_state.c +++ b/sway/input_state.c | |||
@@ -74,27 +74,276 @@ void release_key(uint32_t key_sym, uint32_t key_code) { | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | // Pointer state and mode | ||
78 | |||
77 | struct pointer_state pointer_state; | 79 | struct pointer_state pointer_state; |
78 | 80 | ||
79 | static struct wlc_geometry saved_floating; | 81 | static struct mode_state { |
82 | // initial view state | ||
83 | double x, y, w, h; | ||
84 | swayc_t *ptr; | ||
85 | // Containers used for resizing horizontally | ||
86 | struct { | ||
87 | double w; | ||
88 | swayc_t *ptr; | ||
89 | struct { | ||
90 | double w; | ||
91 | swayc_t *ptr; | ||
92 | } parent; | ||
93 | } horiz; | ||
94 | // Containers used for resizing vertically | ||
95 | struct { | ||
96 | double h; | ||
97 | swayc_t *ptr; | ||
98 | struct { | ||
99 | double h; | ||
100 | swayc_t *ptr; | ||
101 | } parent; | ||
102 | } vert; | ||
103 | } initial; | ||
104 | |||
105 | static struct { | ||
106 | bool left; | ||
107 | bool top; | ||
108 | } lock; | ||
109 | |||
110 | // initial set/unset | ||
111 | |||
112 | static void set_initial_view(swayc_t *view) { | ||
113 | initial.ptr = view; | ||
114 | initial.x = view->x; | ||
115 | initial.y = view->y; | ||
116 | initial.w = view->width; | ||
117 | initial.h = view->height; | ||
118 | } | ||
119 | |||
120 | static void set_initial_sibling(void) { | ||
121 | bool reset = true; | ||
122 | if ((initial.horiz.ptr = get_swayc_in_direction(initial.ptr, lock.left ? MOVE_RIGHT: MOVE_LEFT))) { | ||
123 | initial.horiz.w = initial.horiz.ptr->width; | ||
124 | initial.horiz.parent.ptr = get_swayc_in_direction(initial.horiz.ptr, lock.left ? MOVE_LEFT : MOVE_RIGHT); | ||
125 | initial.horiz.parent.w = initial.horiz.parent.ptr->width; | ||
126 | reset = false; | ||
127 | } | ||
128 | if ((initial.vert.ptr = get_swayc_in_direction(initial.ptr, lock.top ? MOVE_DOWN: MOVE_UP))) { | ||
129 | initial.vert.h = initial.vert.ptr->height; | ||
130 | initial.vert.parent.ptr = get_swayc_in_direction(initial.vert.ptr, lock.top ? MOVE_UP : MOVE_DOWN); | ||
131 | initial.vert.parent.h = initial.vert.parent.ptr->height; | ||
132 | reset = false; | ||
133 | } | ||
134 | // If nothing will change just undo the mode | ||
135 | if (reset) { | ||
136 | pointer_state.mode = 0; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | static void reset_initial_view(void) { | ||
141 | initial.ptr->x = initial.x; | ||
142 | initial.ptr->y = initial.y; | ||
143 | initial.ptr->width = initial.w; | ||
144 | initial.ptr->height = initial.h; | ||
145 | arrange_windows(initial.ptr, -1, -1); | ||
146 | pointer_state.mode = 0; | ||
147 | } | ||
148 | |||
149 | static void reset_initial_sibling(void) { | ||
150 | initial.horiz.ptr->width = initial.horiz.w; | ||
151 | initial.horiz.parent.ptr->width = initial.horiz.parent.w; | ||
152 | initial.vert.ptr->height = initial.vert.h; | ||
153 | initial.vert.parent.ptr->height = initial.vert.parent.h; | ||
154 | arrange_windows(initial.horiz.ptr->parent, -1, -1); | ||
155 | arrange_windows(initial.vert.ptr->parent, -1, -1); | ||
156 | pointer_state.mode = 0; | ||
157 | } | ||
158 | |||
159 | // Mode set left/right click | ||
160 | |||
161 | static void pointer_mode_set_left(void) { | ||
162 | set_initial_view(pointer_state.left.view); | ||
163 | if (initial.ptr->is_floating) { | ||
164 | pointer_state.mode = M_DRAGGING | M_FLOATING; | ||
165 | } else { | ||
166 | pointer_state.mode = M_DRAGGING | M_TILING; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void pointer_mode_set_right(void) { | ||
171 | set_initial_view(pointer_state.right.view); | ||
172 | // Setup locking information | ||
173 | int midway_x = initial.ptr->x + initial.ptr->width/2; | ||
174 | int midway_y = initial.ptr->y + initial.ptr->height/2; | ||
175 | |||
176 | lock.left = pointer_state.origin.x > midway_x; | ||
177 | lock.top = pointer_state.origin.y > midway_y; | ||
178 | |||
179 | if (initial.ptr->is_floating) { | ||
180 | pointer_state.mode = M_RESIZING | M_FLOATING; | ||
181 | } else { | ||
182 | pointer_state.mode = M_RESIZING | M_TILING; | ||
183 | set_initial_sibling(); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | // Mode set/update/reset | ||
188 | |||
189 | void pointer_mode_set(uint32_t button, bool condition) { | ||
190 | // switch on drag/resize mode | ||
191 | switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { | ||
192 | case M_DRAGGING: | ||
193 | // end drag mode when left click is unpressed | ||
194 | if (!pointer_state.left.held) { | ||
195 | pointer_state.mode = 0; | ||
196 | } | ||
197 | break; | ||
198 | |||
199 | case M_RESIZING: | ||
200 | // end resize mode when right click is unpressed | ||
201 | if (!pointer_state.right.held) { | ||
202 | pointer_state.mode = 0; | ||
203 | } | ||
204 | break; | ||
205 | |||
206 | // No mode case | ||
207 | default: | ||
208 | // return if failed condition, or no view | ||
209 | if (!condition || !pointer_state.view) { | ||
210 | break; | ||
211 | } | ||
80 | 212 | ||
81 | void start_floating(swayc_t *view) { | 213 | // Set mode depending on current button press |
82 | if (view->is_floating) { | 214 | switch (button) { |
83 | saved_floating.origin.x = view->x; | 215 | // Start dragging mode |
84 | saved_floating.origin.y = view->y; | 216 | case M_LEFT_CLICK: |
85 | saved_floating.size.w = view->width; | 217 | // if button release dont do anything |
86 | saved_floating.size.h = view->height; | 218 | if (pointer_state.left.held) { |
219 | pointer_mode_set_left(); | ||
220 | } | ||
221 | break; | ||
222 | |||
223 | // Start resize mode | ||
224 | case M_RIGHT_CLICK: | ||
225 | // if button release dont do anyhting | ||
226 | if (pointer_state.right.held) { | ||
227 | pointer_mode_set_right(); | ||
228 | } | ||
229 | break; | ||
230 | } | ||
87 | } | 231 | } |
88 | } | 232 | } |
89 | 233 | ||
90 | void reset_floating(swayc_t *view) { | 234 | void pointer_mode_update(void) { |
91 | if (view->is_floating) { | 235 | if (initial.ptr->type != C_VIEW) { |
92 | view->x = saved_floating.origin.x; | 236 | pointer_state.mode = 0; |
93 | view->y = saved_floating.origin.y; | 237 | return; |
94 | view->width = saved_floating.size.w; | 238 | } |
95 | view->height = saved_floating.size.h; | 239 | int dx = pointer_state.origin.x; |
96 | arrange_windows(view->parent, -1, -1); | 240 | int dy = pointer_state.origin.y; |
241 | |||
242 | switch (pointer_state.mode) { | ||
243 | case M_FLOATING | M_DRAGGING: | ||
244 | // Update position | ||
245 | dx -= pointer_state.left.x; | ||
246 | dy -= pointer_state.left.y; | ||
247 | if (initial.x + dx != initial.ptr->x) { | ||
248 | initial.ptr->x = initial.x + dx; | ||
249 | } | ||
250 | if (initial.y + dy != initial.ptr->y) { | ||
251 | initial.ptr->y = initial.y + dy; | ||
252 | } | ||
253 | update_geometry(initial.ptr); | ||
254 | break; | ||
255 | |||
256 | case M_FLOATING | M_RESIZING: | ||
257 | dx -= pointer_state.right.x; | ||
258 | dy -= pointer_state.right.y; | ||
259 | initial.ptr = pointer_state.right.view; | ||
260 | if (lock.left) { | ||
261 | if (initial.w + dx > min_sane_w) { | ||
262 | initial.ptr->width = initial.w + dx; | ||
263 | } | ||
264 | } else { // lock.right | ||
265 | if (initial.w - dx > min_sane_w) { | ||
266 | initial.ptr->width = initial.w - dx; | ||
267 | initial.ptr->x = initial.x + dx; | ||
268 | } | ||
269 | } | ||
270 | if (lock.top) { | ||
271 | if (initial.h + dy > min_sane_h) { | ||
272 | initial.ptr->height = initial.h + dy; | ||
273 | } | ||
274 | } else { // lock.bottom | ||
275 | if (initial.h - dy > min_sane_h) { | ||
276 | initial.ptr->height = initial.h - dy; | ||
277 | initial.ptr->y = initial.y + dy; | ||
278 | } | ||
279 | } | ||
280 | update_geometry(initial.ptr); | ||
281 | break; | ||
282 | |||
283 | case M_TILING | M_DRAGGING: | ||
284 | // swap current view under pointer with dragged view | ||
285 | if (pointer_state.view && pointer_state.view->type == C_VIEW | ||
286 | && pointer_state.view != initial.ptr) { | ||
287 | // Swap them around | ||
288 | swap_container(pointer_state.view, initial.ptr); | ||
289 | update_geometry(pointer_state.view); | ||
290 | update_geometry(initial.ptr); | ||
291 | // Set focus back to initial view | ||
292 | set_focused_container(initial.ptr); | ||
293 | } | ||
294 | break; | ||
295 | |||
296 | case M_TILING | M_RESIZING: | ||
297 | dx -= pointer_state.right.x; | ||
298 | dy -= pointer_state.right.y; | ||
299 | // resize if we can | ||
300 | if (initial.horiz.ptr) { | ||
301 | if (lock.left) { | ||
302 | // Check whether its fine to resize | ||
303 | if (initial.w + dx > min_sane_w && initial.horiz.w - dx > min_sane_w) { | ||
304 | initial.horiz.ptr->width = initial.horiz.w - dx; | ||
305 | initial.horiz.parent.ptr->width = initial.horiz.parent.w + dx; | ||
306 | } | ||
307 | } else { // lock.right | ||
308 | if (initial.w - dx > min_sane_w && initial.horiz.w + dx > min_sane_w) { | ||
309 | initial.horiz.ptr->width = initial.horiz.w + dx; | ||
310 | initial.horiz.parent.ptr->width = initial.horiz.parent.w - dx; | ||
311 | } | ||
312 | } | ||
313 | arrange_windows(initial.horiz.ptr->parent, -1, -1); | ||
314 | } | ||
315 | if (initial.vert.ptr) { | ||
316 | if (lock.top) { | ||
317 | if (initial.h + dy > min_sane_h && initial.vert.h - dy > min_sane_h) { | ||
318 | initial.vert.ptr->height = initial.vert.h - dy; | ||
319 | initial.vert.parent.ptr->height = initial.vert.parent.h + dy; | ||
320 | } | ||
321 | } else { // lock.bottom | ||
322 | if (initial.h - dy > min_sane_h && initial.vert.h + dy > min_sane_h) { | ||
323 | initial.vert.ptr->height = initial.vert.h + dy; | ||
324 | initial.vert.parent.ptr->height = initial.vert.parent.h - dy; | ||
325 | } | ||
326 | } | ||
327 | arrange_windows(initial.vert.ptr->parent, -1, -1); | ||
328 | } | ||
329 | default: | ||
330 | return; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | void pointer_mode_reset(void) { | ||
335 | switch (pointer_state.mode) { | ||
336 | case M_FLOATING | M_RESIZING: | ||
337 | case M_FLOATING | M_DRAGGING: | ||
338 | reset_initial_view(); | ||
339 | break; | ||
340 | |||
341 | case M_TILING | M_RESIZING: | ||
342 | (void) reset_initial_sibling; | ||
343 | break; | ||
344 | |||
345 | case M_TILING | M_DRAGGING: | ||
346 | default: | ||
347 | break; | ||
97 | } | 348 | } |
98 | pointer_state.floating = (struct pointer_floating){0, 0}; | ||
99 | pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0}; | ||
100 | } | 349 | } |
diff --git a/sway/layout.c b/sway/layout.c index 035fea34..bc12b9b1 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -20,7 +20,8 @@ void init_layout(void) { | |||
20 | root_container.handle = -1; | 20 | root_container.handle = -1; |
21 | } | 21 | } |
22 | 22 | ||
23 | static int index_child(swayc_t *parent, swayc_t *child) { | 23 | static int index_child(swayc_t *child) { |
24 | swayc_t *parent = child->parent; | ||
24 | int i; | 25 | int i; |
25 | for (i = 0; i < parent->children->length; ++i) { | 26 | for (i = 0; i < parent->children->length; ++i) { |
26 | if (parent->children->items[i] == child) { | 27 | if (parent->children->items[i] == child) { |
@@ -54,7 +55,7 @@ void add_floating(swayc_t *ws, swayc_t *child) { | |||
54 | 55 | ||
55 | swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) { | 56 | swayc_t *add_sibling(swayc_t *sibling, swayc_t *child) { |
56 | swayc_t *parent = sibling->parent; | 57 | swayc_t *parent = sibling->parent; |
57 | int i = index_child(parent, sibling); | 58 | int i = index_child(sibling); |
58 | if (i == parent->children->length) { | 59 | if (i == parent->children->length) { |
59 | --i; | 60 | --i; |
60 | } | 61 | } |
@@ -68,17 +69,65 @@ swayc_t *replace_child(swayc_t *child, swayc_t *new_child) { | |||
68 | if (parent == NULL) { | 69 | if (parent == NULL) { |
69 | return NULL; | 70 | return NULL; |
70 | } | 71 | } |
71 | int i = index_child(parent, child); | 72 | int i = index_child(child); |
72 | parent->children->items[i] = new_child; | 73 | parent->children->items[i] = new_child; |
73 | new_child->parent = child->parent; | 74 | new_child->parent = child->parent; |
74 | 75 | ||
76 | // Set parent for new child | ||
75 | if (child->parent->focused == child) { | 77 | if (child->parent->focused == child) { |
76 | child->parent->focused = new_child; | 78 | child->parent->focused = new_child; |
77 | } | 79 | } |
78 | child->parent = NULL; | 80 | child->parent = NULL; |
81 | // Set geometry for new child | ||
82 | new_child->x = child->x; | ||
83 | new_child->y = child->y; | ||
84 | new_child->width = child->width; | ||
85 | new_child->height = child->height; | ||
86 | // set child geometry to 0 | ||
87 | child->x = 0; | ||
88 | child->y = 0; | ||
89 | child->width = 0; | ||
90 | child->height = 0; | ||
79 | return parent; | 91 | return parent; |
80 | } | 92 | } |
81 | 93 | ||
94 | void swap_container(swayc_t *a, swayc_t *b) { | ||
95 | //TODO doesnt handle floating <-> tiling swap | ||
96 | if (!sway_assert(a&&b, "%s: parameters must be non null",__func__) || | ||
97 | !sway_assert(a->parent && b->parent, "%s: containers must have parents",__func__)) { | ||
98 | return; | ||
99 | } | ||
100 | size_t a_index = index_child(a); | ||
101 | size_t b_index = index_child(b); | ||
102 | swayc_t *a_parent = a->parent; | ||
103 | swayc_t *b_parent = b->parent; | ||
104 | // Swap the pointers | ||
105 | a_parent->children->items[a_index] = b; | ||
106 | b_parent->children->items[b_index] = a; | ||
107 | a->parent = b_parent; | ||
108 | b->parent = a_parent; | ||
109 | if (a_parent->focused == a) { | ||
110 | a_parent->focused = b; | ||
111 | } | ||
112 | // dont want to double switch | ||
113 | if (b_parent->focused == b && a_parent != b_parent) { | ||
114 | b_parent->focused = a; | ||
115 | } | ||
116 | // and their geometry | ||
117 | double x = a->x; | ||
118 | double y = a->y; | ||
119 | double w = a->width; | ||
120 | double h = a->height; | ||
121 | a->x = b->x; | ||
122 | a->y = b->y; | ||
123 | a->width = b->width; | ||
124 | a->height = b->height; | ||
125 | b->x = x; | ||
126 | b->y = y; | ||
127 | b->width = w; | ||
128 | b->height = h; | ||
129 | } | ||
130 | |||
82 | swayc_t *remove_child(swayc_t *child) { | 131 | swayc_t *remove_child(swayc_t *child) { |
83 | int i; | 132 | int i; |
84 | swayc_t *parent = child->parent; | 133 | swayc_t *parent = child->parent; |
@@ -154,6 +203,30 @@ void move_container(swayc_t *container,swayc_t* root,enum movement_direction dir | |||
154 | 203 | ||
155 | } | 204 | } |
156 | 205 | ||
206 | void update_geometry(swayc_t *container) { | ||
207 | if (container->type != C_VIEW) { | ||
208 | return; | ||
209 | } | ||
210 | struct wlc_geometry geometry = { | ||
211 | .origin = { | ||
212 | .x = container->x + (container->is_floating ? 0 : container->gaps / 2), | ||
213 | .y = container->y + (container->is_floating ? 0 : container->gaps / 2) | ||
214 | }, | ||
215 | .size = { | ||
216 | .w = container->width - (container->is_floating ? 0 : container->gaps), | ||
217 | .h = container->height - (container->is_floating ? 0 : container->gaps) | ||
218 | } | ||
219 | }; | ||
220 | if (swayc_is_fullscreen(container)) { | ||
221 | swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); | ||
222 | geometry.origin.x = 0; | ||
223 | geometry.origin.y = 0; | ||
224 | geometry.size.w = parent->width; | ||
225 | geometry.size.h = parent->height; | ||
226 | } | ||
227 | wlc_view_set_geometry(container->handle, 0, &geometry); | ||
228 | return; | ||
229 | } | ||
157 | 230 | ||
158 | void arrange_windows(swayc_t *container, double width, double height) { | 231 | void arrange_windows(swayc_t *container, double width, double height) { |
159 | int i; | 232 | int i; |
@@ -189,31 +262,11 @@ void arrange_windows(swayc_t *container, double width, double height) { | |||
189 | return; | 262 | return; |
190 | case C_VIEW: | 263 | case C_VIEW: |
191 | { | 264 | { |
192 | struct wlc_geometry geometry = { | 265 | container->width = width; |
193 | .origin = { | 266 | container->height = height; |
194 | .x = container->x + container->gaps / 2, | 267 | update_geometry(container); |
195 | .y = container->y + container->gaps / 2 | 268 | sway_log(L_DEBUG, "Set view to %.f x %.f @ %.f, %.f", container->width, |
196 | }, | 269 | container->height, container->x, container->y); |
197 | .size = { | ||
198 | .w = width - container->gaps, | ||
199 | .h = height - container->gaps | ||
200 | } | ||
201 | }; | ||
202 | if (swayc_is_fullscreen(container)) { | ||
203 | swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); | ||
204 | geometry.origin.x = 0; | ||
205 | geometry.origin.y = 0; | ||
206 | geometry.size.w = parent->width; | ||
207 | geometry.size.h = parent->height; | ||
208 | wlc_view_set_geometry(container->handle, 0, &geometry); | ||
209 | wlc_view_bring_to_front(container->handle); | ||
210 | } else { | ||
211 | wlc_view_set_geometry(container->handle, 0, &geometry); | ||
212 | container->width = width; | ||
213 | container->height = height; | ||
214 | } | ||
215 | sway_log(L_DEBUG, "Set view to %d x %d @ %d, %d", geometry.size.w, geometry.size.h, | ||
216 | geometry.origin.x, geometry.origin.y); | ||
217 | } | 270 | } |
218 | return; | 271 | return; |
219 | default: | 272 | default: |
@@ -287,35 +340,12 @@ void arrange_windows(swayc_t *container, double width, double height) { | |||
287 | for (i = 0; i < container->floating->length; ++i) { | 340 | for (i = 0; i < container->floating->length; ++i) { |
288 | swayc_t *view = container->floating->items[i]; | 341 | swayc_t *view = container->floating->items[i]; |
289 | if (view->type == C_VIEW) { | 342 | if (view->type == C_VIEW) { |
290 | // Set the geometry | 343 | update_geometry(view); |
291 | struct wlc_geometry geometry = { | ||
292 | .origin = { | ||
293 | .x = view->x, | ||
294 | .y = view->y | ||
295 | }, | ||
296 | .size = { | ||
297 | .w = view->width, | ||
298 | .h = view->height | ||
299 | } | ||
300 | }; | ||
301 | if (swayc_is_fullscreen(view)) { | 344 | if (swayc_is_fullscreen(view)) { |
302 | swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); | ||
303 | geometry.origin.x = 0; | ||
304 | geometry.origin.y = 0; | ||
305 | geometry.size.w = parent->width; | ||
306 | geometry.size.h = parent->height; | ||
307 | wlc_view_set_geometry(view->handle, 0, &geometry); | ||
308 | wlc_view_bring_to_front(view->handle); | 345 | wlc_view_bring_to_front(view->handle); |
309 | } else { | 346 | } else if (!container->focused |
310 | wlc_view_set_geometry(view->handle, 0, &geometry); | 347 | || !swayc_is_fullscreen(container->focused)) { |
311 | // Bring the views to the front in order of the list, the list | 348 | wlc_view_bring_to_front(view->handle); |
312 | // will be kept up to date so that more recently focused views | ||
313 | // have higher indexes | ||
314 | // This is conditional on there not being a fullscreen view in the workspace | ||
315 | if (!container->focused | ||
316 | || !swayc_is_fullscreen(container->focused)) { | ||
317 | wlc_view_bring_to_front(view->handle); | ||
318 | } | ||
319 | } | 349 | } |
320 | } | 350 | } |
321 | } | 351 | } |
diff --git a/sway/resize.c b/sway/resize.c index a08ef4a1..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 | ||
9 | bool 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 = mouse_origin.x - prev_pos.x; | ||
14 | double dy = mouse_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 || mouse_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 || mouse_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 || mouse_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 || mouse_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 | |||
189 | bool 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 = mouse_origin.x - prev_pos.x; | ||
194 | int dy = mouse_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 (mouse_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 (mouse_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 (mouse_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 (mouse_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 | |||
270 | bool resize_tiled(int amount, bool use_width) { | 9 | bool 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; |