diff options
-rw-r--r-- | include/input_state.h | 46 | ||||
-rw-r--r-- | include/layout.h | 2 | ||||
-rw-r--r-- | sway/handlers.c | 190 | ||||
-rw-r--r-- | sway/input_state.c | 219 | ||||
-rw-r--r-- | sway/layout.c | 109 | ||||
-rw-r--r-- | sway/resize.c | 24 |
6 files changed, 454 insertions, 136 deletions
diff --git a/include/input_state.h b/include/input_state.h index 04fde42d..3a246e0c 100644 --- a/include/input_state.h +++ b/include/input_state.h | |||
@@ -17,6 +17,7 @@ void press_key(keycode key); | |||
17 | // unsets a key as pressed | 17 | // unsets a key as pressed |
18 | void release_key(keycode key); | 18 | void release_key(keycode key); |
19 | 19 | ||
20 | |||
20 | /* Pointer state */ | 21 | /* Pointer state */ |
21 | 22 | ||
22 | enum pointer_values { | 23 | enum pointer_values { |
@@ -27,9 +28,40 @@ enum pointer_values { | |||
27 | M_SCROLL_DOWN = 276, | 28 | M_SCROLL_DOWN = 276, |
28 | }; | 29 | }; |
29 | 30 | ||
31 | enum pointer_mode { | ||
32 | // Target | ||
33 | M_FLOATING = 1 << 0, | ||
34 | M_TILING = 1 << 1, | ||
35 | // Action | ||
36 | M_DRAGGING = 1 << 2, | ||
37 | M_RESIZING = 1 << 3, | ||
38 | }; | ||
39 | |||
30 | extern struct pointer_state { | 40 | extern struct pointer_state { |
31 | bool l_held; | 41 | // mouse clicks |
32 | bool r_held; | 42 | bool l_held : 1; |
43 | bool r_held : 1; | ||
44 | |||
45 | // scroll wheel | ||
46 | bool s_held : 1; | ||
47 | bool s_up : 1; | ||
48 | bool s_down :1; | ||
49 | |||
50 | // pointer position | ||
51 | struct mouse_origin{ | ||
52 | int x, y; | ||
53 | } origin; | ||
54 | struct { | ||
55 | int x, y; | ||
56 | } delta; | ||
57 | |||
58 | // view pointer is over | ||
59 | swayc_t *view; | ||
60 | |||
61 | // Pointer mode | ||
62 | int mode; | ||
63 | |||
64 | // OLD | ||
33 | struct pointer_floating { | 65 | struct pointer_floating { |
34 | bool drag; | 66 | bool drag; |
35 | bool resize; | 67 | bool resize; |
@@ -53,6 +85,16 @@ extern struct pointer_state { | |||
53 | } lock; | 85 | } lock; |
54 | } pointer_state; | 86 | } pointer_state; |
55 | 87 | ||
88 | // on button release unset mode depending on the button. | ||
89 | // on button press set mode conditionally depending on the button | ||
90 | void pointer_mode_set(uint32_t button, bool condition); | ||
91 | |||
92 | // Update mode in mouse motion | ||
93 | void pointer_mode_update(void); | ||
94 | |||
95 | // Reset mode on any keypress; | ||
96 | void pointer_mode_reset(void); | ||
97 | |||
56 | void start_floating(swayc_t *view); | 98 | void start_floating(swayc_t *view); |
57 | void reset_floating(swayc_t *view); | 99 | void reset_floating(swayc_t *view); |
58 | void input_init(void); | 100 | void input_init(void); |
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/sway/handlers.c b/sway/handlers.c index cb42196f..7d1e4cde 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -17,10 +17,8 @@ | |||
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; | ||
21 | |||
22 | static bool pointer_test(swayc_t *view, void *_origin) { | 20 | static bool pointer_test(swayc_t *view, void *_origin) { |
23 | const struct wlc_origin *origin = _origin; | 21 | const struct mouse_origin *origin = _origin; |
24 | // Determine the output that the view is under | 22 | // Determine the output that the view is under |
25 | swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); | 23 | swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT); |
26 | if (origin->x >= view->x && origin->y >= view->y | 24 | if (origin->x >= view->x && origin->y >= view->y |
@@ -55,7 +53,7 @@ swayc_t *container_under_pointer(void) { | |||
55 | i = len = lookup->floating->length; | 53 | i = len = lookup->floating->length; |
56 | bool got_floating = false; | 54 | bool got_floating = false; |
57 | while (--i > -1) { | 55 | while (--i > -1) { |
58 | if (pointer_test(lookup->floating->items[i], &mouse_origin)) { | 56 | if (pointer_test(lookup->floating->items[i], &pointer_state.origin)) { |
59 | lookup = lookup->floating->items[i]; | 57 | lookup = lookup->floating->items[i]; |
60 | got_floating = true; | 58 | got_floating = true; |
61 | break; | 59 | break; |
@@ -68,7 +66,7 @@ swayc_t *container_under_pointer(void) { | |||
68 | // search children | 66 | // search children |
69 | len = lookup->children->length; | 67 | len = lookup->children->length; |
70 | for (i = 0; i < len; ++i) { | 68 | for (i = 0; i < len; ++i) { |
71 | if (pointer_test(lookup->children->items[i], &mouse_origin)) { | 69 | if (pointer_test(lookup->children->items[i], &pointer_state.origin)) { |
72 | lookup = lookup->children->items[i]; | 70 | lookup = lookup->children->items[i]; |
73 | break; | 71 | break; |
74 | } | 72 | } |
@@ -281,10 +279,9 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
281 | return false; | 279 | return false; |
282 | } | 280 | } |
283 | 281 | ||
284 | // Revert floating container back to original position on keypress | 282 | // reset pointer mode on keypress |
285 | if (state == WLC_KEY_STATE_PRESSED && | 283 | if (state == WLC_KEY_STATE_PRESSED && pointer_state.mode) { |
286 | (pointer_state.floating.drag || pointer_state.floating.resize)) { | 284 | pointer_mode_reset(); |
287 | reset_floating(get_focused_view(&root_container)); | ||
288 | } | 285 | } |
289 | 286 | ||
290 | struct sway_mode *mode = config->current_mode; | 287 | struct sway_mode *mode = config->current_mode; |
@@ -334,83 +331,25 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
334 | } | 331 | } |
335 | 332 | ||
336 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { | 333 | static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct wlc_origin *origin) { |
337 | static struct wlc_origin prev_pos; | 334 | // Update pointer origin |
338 | static wlc_handle prev_handle = 0; | 335 | pointer_state.delta.x = origin->x - pointer_state.origin.x; |
339 | mouse_origin = *origin; | 336 | pointer_state.delta.y = origin->y - pointer_state.origin.y; |
340 | bool changed_floating = false; | 337 | pointer_state.origin.x = origin->x; |
341 | bool changed_tiling = false; | 338 | pointer_state.origin.y = origin->y; |
342 | if (!swayc_active_workspace()) { | 339 | |
343 | return false; | 340 | // Update view under pointer |
341 | swayc_t *prev_view = pointer_state.view; | ||
342 | pointer_state.view = container_under_pointer(); | ||
343 | |||
344 | // If pointer is in a mode, update it | ||
345 | if (pointer_state.mode) { | ||
346 | pointer_mode_update(); | ||
344 | } | 347 | } |
345 | // Do checks to determine if proper keys are being held | 348 | // Otherwise change focus if config is set an |
346 | swayc_t *view = container_under_pointer(); | 349 | else if (prev_view != pointer_state.view && config->focus_follows_mouse) { |
347 | if (pointer_state.floating.drag && view) { | 350 | if (pointer_state.view && pointer_state.view->type == C_VIEW) { |
348 | if (view->is_floating) { | 351 | set_focused_container(pointer_state.view); |
349 | int dx = mouse_origin.x - prev_pos.x; | ||
350 | int dy = mouse_origin.y - prev_pos.y; | ||
351 | view->x += dx; | ||
352 | view->y += dy; | ||
353 | struct wlc_geometry geometry = { | ||
354 | .origin = { | ||
355 | .x = view->x, | ||
356 | .y = view->y | ||
357 | }, | ||
358 | .size = { | ||
359 | .w = view->width, | ||
360 | .h = view->height | ||
361 | } | ||
362 | }; | ||
363 | wlc_view_set_geometry(view->handle, 0, &geometry); | ||
364 | changed_floating = true; | ||
365 | } else { | ||
366 | swayc_t *init_view = pointer_state.tiling.init_view; | ||
367 | if (view != init_view && view->type == C_VIEW) { | ||
368 | changed_tiling = true; | ||
369 | int i, j; | ||
370 | for (i = 0; i < view->parent->children->length; i++) { | ||
371 | if (view->parent->children->items[i] == view) { | ||
372 | for (j = 0; j < init_view->parent->children->length; j++) { | ||
373 | if (init_view->parent->children->items[j] == init_view) { | ||
374 | double temp_w = view->width; | ||
375 | double temp_h = view->height; | ||
376 | view->width = init_view->width; | ||
377 | view->height = init_view->height; | ||
378 | init_view->width = temp_w; | ||
379 | init_view->height = temp_h; | ||
380 | |||
381 | init_view->parent->children->items[j] = view; | ||
382 | view->parent->children->items[i] = init_view; | ||
383 | |||
384 | swayc_t *temp = view->parent; | ||
385 | view->parent = init_view->parent; | ||
386 | init_view->parent = temp; | ||
387 | |||
388 | arrange_windows(&root_container, -1, -1); | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | break; | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | } | 352 | } |
397 | } else if (pointer_state.floating.resize && view) { | ||
398 | changed_floating = resize_floating(prev_pos); | ||
399 | } else if (pointer_state.tiling.resize && view) { | ||
400 | changed_tiling = mouse_resize_tiled(prev_pos); | ||
401 | } | ||
402 | if (config->focus_follows_mouse && prev_handle != handle) { | ||
403 | // Dont change focus if fullscreen | ||
404 | swayc_t *focused = get_focused_view(view); | ||
405 | if (!swayc_is_fullscreen(focused) | ||
406 | && !(pointer_state.l_held || pointer_state.r_held)) { | ||
407 | set_focused_container(container_under_pointer()); | ||
408 | } | ||
409 | } | ||
410 | prev_handle = handle; | ||
411 | prev_pos = mouse_origin; | ||
412 | if (changed_tiling || changed_floating) { | ||
413 | return true; | ||
414 | } | 353 | } |
415 | return false; | 354 | return false; |
416 | } | 355 | } |
@@ -418,11 +357,82 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
418 | 357 | ||
419 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, | 358 | static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers, |
420 | 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 }; | ||
361 | |||
362 | // Update pointer_state | ||
363 | switch (button) { | ||
364 | case M_LEFT_CLICK: | ||
365 | pointer_state.l_held = state == WLC_BUTTON_STATE_PRESSED; | ||
366 | break; | ||
367 | |||
368 | case M_RIGHT_CLICK: | ||
369 | pointer_state.r_held = state == WLC_BUTTON_STATE_PRESSED; | ||
370 | break; | ||
371 | |||
372 | case M_SCROLL_CLICK: | ||
373 | pointer_state.s_held = state == WLC_BUTTON_STATE_PRESSED; | ||
374 | break; | ||
375 | |||
376 | case M_SCROLL_UP: | ||
377 | pointer_state.s_up = state == WLC_BUTTON_STATE_PRESSED; | ||
378 | break; | ||
379 | |||
380 | case M_SCROLL_DOWN: | ||
381 | pointer_state.s_down = state == WLC_BUTTON_STATE_PRESSED; | ||
382 | break; | ||
383 | } | ||
384 | |||
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 | ||
393 | pointer_mode_set(button, | ||
394 | (modifiers->mods & config->floating_mod) == config->floating_mod); | ||
395 | |||
396 | // Return if mode has been set | ||
397 | if (pointer_state.mode) { | ||
398 | return DONT_SEND_CLICK; | ||
399 | } | ||
400 | |||
401 | // Always send mouse release | ||
402 | if (state == WLC_BUTTON_STATE_RELEASED) { | ||
403 | return SEND_CLICK; | ||
404 | } | ||
405 | |||
406 | // get focused window and check if to change focus on mouse click | ||
421 | swayc_t *focused = get_focused_container(&root_container); | 407 | swayc_t *focused = get_focused_container(&root_container); |
408 | |||
409 | // Check whether to change focus | ||
410 | swayc_t *pointer = pointer_state.view; | ||
411 | if (pointer && focused != pointer) { | ||
412 | set_focused_container(pointer_state.view); | ||
413 | // Send to front if floating | ||
414 | if (pointer->is_floating) { | ||
415 | int i; | ||
416 | for (i = 0; i < pointer->parent->floating->length; i++) { | ||
417 | if (pointer->parent->floating->items[i] == pointer) { | ||
418 | list_del(pointer->parent->floating, i); | ||
419 | list_add(pointer->parent->floating, pointer); | ||
420 | break; | ||
421 | } | ||
422 | } | ||
423 | wlc_view_bring_to_front(view); | ||
424 | } | ||
425 | } | ||
426 | |||
422 | // dont change focus if fullscreen | 427 | // dont change focus if fullscreen |
423 | if (swayc_is_fullscreen(focused)) { | 428 | if (swayc_is_fullscreen(focused)) { |
424 | return false; | 429 | return SEND_CLICK; |
425 | } | 430 | } |
431 | |||
432 | // Finally send click | ||
433 | return SEND_CLICK; | ||
434 | |||
435 | /* OLD */ | ||
426 | if (state == WLC_BUTTON_STATE_PRESSED) { | 436 | if (state == WLC_BUTTON_STATE_PRESSED) { |
427 | sway_log(L_DEBUG, "Mouse button %u pressed", button); | 437 | sway_log(L_DEBUG, "Mouse button %u pressed", button); |
428 | if (button == M_LEFT_CLICK) { | 438 | if (button == M_LEFT_CLICK) { |
@@ -443,15 +453,6 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
443 | } | 453 | } |
444 | 454 | ||
445 | if (pointer->is_floating) { | 455 | if (pointer->is_floating) { |
446 | int i; | ||
447 | for (i = 0; i < pointer->parent->floating->length; i++) { | ||
448 | if (pointer->parent->floating->items[i] == pointer) { | ||
449 | list_del(pointer->parent->floating, i); | ||
450 | list_add(pointer->parent->floating, pointer); | ||
451 | break; | ||
452 | } | ||
453 | } | ||
454 | arrange_windows(pointer->parent, -1, -1); | ||
455 | if (modifiers->mods & config->floating_mod) { | 456 | if (modifiers->mods & config->floating_mod) { |
456 | pointer_state.floating.drag = pointer_state.l_held; | 457 | pointer_state.floating.drag = pointer_state.l_held; |
457 | pointer_state.floating.resize = pointer_state.r_held; | 458 | pointer_state.floating.resize = pointer_state.r_held; |
@@ -484,6 +485,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
484 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false}; | 485 | pointer_state.lock = (struct pointer_lock){false ,false ,false ,false, false, false, false, false}; |
485 | } | 486 | } |
486 | } | 487 | } |
488 | /* OLD */ | ||
487 | return false; | 489 | return false; |
488 | } | 490 | } |
489 | 491 | ||
diff --git a/sway/input_state.c b/sway/input_state.c index e2f3c754..3db78167 100644 --- a/sway/input_state.c +++ b/sway/input_state.c | |||
@@ -50,6 +50,224 @@ void release_key(keycode key) { | |||
50 | 50 | ||
51 | struct pointer_state pointer_state; | 51 | struct pointer_state pointer_state; |
52 | 52 | ||
53 | // Pointer mode values | ||
54 | static struct mode_state { | ||
55 | // Initial view state | ||
56 | struct { | ||
57 | double x, y, w, h; | ||
58 | swayc_t *ptr; | ||
59 | } view; | ||
60 | // Initial pointer state | ||
61 | struct { | ||
62 | int x, y; | ||
63 | } coor; | ||
64 | } initial; | ||
65 | |||
66 | static struct { | ||
67 | enum { LEFT=1, RIGHT=0 } lr; | ||
68 | enum { TOP=1, BOTTOM=0 } tb; | ||
69 | } lock; | ||
70 | |||
71 | // Floating set/unset | ||
72 | |||
73 | static void pointer_mode_set_floating(void) { | ||
74 | initial.view.x = initial.view.ptr->x; | ||
75 | initial.view.y = initial.view.ptr->y; | ||
76 | initial.view.w = initial.view.ptr->width; | ||
77 | initial.view.h = initial.view.ptr->height; | ||
78 | // setup initial cooridinates | ||
79 | initial.coor.x = pointer_state.origin.x; | ||
80 | initial.coor.y = pointer_state.origin.y; | ||
81 | } | ||
82 | |||
83 | static void pointer_mode_reset_floating(void) { | ||
84 | initial.view.ptr->x = initial.view.x; | ||
85 | initial.view.ptr->y = initial.view.y; | ||
86 | initial.view.ptr->width = initial.view.w; | ||
87 | initial.view.ptr->height = initial.view.h; | ||
88 | arrange_windows(initial.view.ptr, -1, -1); | ||
89 | pointer_state.mode = 0; | ||
90 | } | ||
91 | |||
92 | // Mode set left/right click | ||
93 | |||
94 | static void pointer_mode_set_left(void) { | ||
95 | swayc_t *view = pointer_state.view; | ||
96 | initial.view.ptr = view; | ||
97 | if (view->is_floating) { | ||
98 | pointer_state.mode = M_DRAGGING | M_FLOATING; | ||
99 | pointer_mode_set_floating(); | ||
100 | } else { | ||
101 | pointer_state.mode = M_DRAGGING | M_TILING; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static void pointer_mode_set_right(void) { | ||
106 | swayc_t *view = pointer_state.view; | ||
107 | initial.view.ptr = view; | ||
108 | // Setup locking information | ||
109 | int midway_x = view->x + view->width/2; | ||
110 | int midway_y = view->y + view->height/2; | ||
111 | |||
112 | lock.lr = pointer_state.origin.x > midway_x; | ||
113 | lock.tb = pointer_state.origin.y > midway_y; | ||
114 | |||
115 | if (view->is_floating) { | ||
116 | pointer_state.mode = M_RESIZING | M_FLOATING; | ||
117 | pointer_mode_set_floating(); | ||
118 | } else { | ||
119 | pointer_state.mode = M_RESIZING | M_TILING; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | // Mode set/update/reset | ||
124 | |||
125 | void pointer_mode_set(uint32_t button, bool condition) { | ||
126 | // switch on drag/resize mode | ||
127 | switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { | ||
128 | case M_DRAGGING: | ||
129 | // end drag mode when left click is unpressed | ||
130 | if (!pointer_state.l_held) { | ||
131 | pointer_state.mode = 0; | ||
132 | } | ||
133 | break; | ||
134 | |||
135 | case M_RESIZING: | ||
136 | // end resize mode when right click is unpressed | ||
137 | if (!pointer_state.r_held) { | ||
138 | pointer_state.mode = 0; | ||
139 | } | ||
140 | break; | ||
141 | |||
142 | // No mode case | ||
143 | default: | ||
144 | // return if failed condition, or no view | ||
145 | if (!condition || !pointer_state.view) { | ||
146 | break; | ||
147 | } | ||
148 | // Set mode depending on current button press | ||
149 | switch (button) { | ||
150 | // Start dragging mode | ||
151 | case M_LEFT_CLICK: | ||
152 | // if button release dont do anything | ||
153 | if (pointer_state.l_held) { | ||
154 | pointer_mode_set_left(); | ||
155 | } | ||
156 | break; | ||
157 | |||
158 | // Start resize mode | ||
159 | case M_RIGHT_CLICK: | ||
160 | // if button release dont do anyhting | ||
161 | if (pointer_state.r_held) { | ||
162 | pointer_mode_set_right(); | ||
163 | } | ||
164 | break; | ||
165 | |||
166 | case M_SCROLL_UP: | ||
167 | case M_SCROLL_DOWN: | ||
168 | //TODO add scrolling behavior here | ||
169 | ; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | void pointer_mode_update(void) { | ||
175 | swayc_t *view = initial.view.ptr; | ||
176 | if (view->type != C_VIEW) { | ||
177 | pointer_state.mode = 0; | ||
178 | return; | ||
179 | } | ||
180 | int dx = pointer_state.origin.x - initial.coor.x; | ||
181 | int dy = pointer_state.origin.y - initial.coor.y; | ||
182 | bool changed = false; | ||
183 | |||
184 | switch (pointer_state.mode) { | ||
185 | case M_FLOATING | M_DRAGGING: | ||
186 | // Update position | ||
187 | if (initial.view.x + dx != view->x) { | ||
188 | view->x = initial.view.x + dx; | ||
189 | changed = true; | ||
190 | } | ||
191 | if (initial.view.y + dy != view->y) { | ||
192 | view->y = initial.view.y + dy; | ||
193 | changed = true; | ||
194 | } | ||
195 | break; | ||
196 | |||
197 | case M_FLOATING | M_RESIZING: | ||
198 | if (lock.lr) { | ||
199 | if (initial.view.w + dx > min_sane_w) { | ||
200 | if (initial.view.w + dx != view->width) { | ||
201 | view->width = initial.view.w + dx; | ||
202 | changed = true; | ||
203 | } | ||
204 | } | ||
205 | } else { //lock.right | ||
206 | if (initial.view.w - dx > min_sane_w) { | ||
207 | if (initial.view.w - dx != view->width) { | ||
208 | view->width = initial.view.w - dx; | ||
209 | view->x = initial.view.x + dx; | ||
210 | changed = true; | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | if (lock.tb) { | ||
215 | if (initial.view.h + dy > min_sane_h) { | ||
216 | if (initial.view.y - dy != view->height) { | ||
217 | view->height = initial.view.h + dy; | ||
218 | changed = true; | ||
219 | } | ||
220 | } | ||
221 | } else { //lock.bottom | ||
222 | if (initial.view.h - dy > min_sane_h) { | ||
223 | if (initial.view.h - dy != view->height) { | ||
224 | view->height = initial.view.h - dy; | ||
225 | view->y = initial.view.y + dy; | ||
226 | changed = true; | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | break; | ||
231 | |||
232 | case M_TILING | M_DRAGGING: | ||
233 | // swap current view under pointer with dragged view | ||
234 | if (pointer_state.view && pointer_state.view != initial.view.ptr) { | ||
235 | // Swap them around | ||
236 | swap_container(pointer_state.view, initial.view.ptr); | ||
237 | update_geometry(pointer_state.view); | ||
238 | update_geometry(initial.view.ptr); | ||
239 | // Set focus back to initial view | ||
240 | set_focused_container(initial.view.ptr); | ||
241 | } | ||
242 | break; | ||
243 | |||
244 | case M_TILING | M_RESIZING: | ||
245 | |||
246 | |||
247 | |||
248 | default: | ||
249 | return; | ||
250 | } | ||
251 | if (changed) { | ||
252 | update_geometry(view); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | void pointer_mode_reset(void) { | ||
257 | switch (pointer_state.mode) { | ||
258 | case M_FLOATING | M_DRAGGING: | ||
259 | case M_FLOATING | M_RESIZING: | ||
260 | pointer_mode_reset_floating(); | ||
261 | break; | ||
262 | |||
263 | case M_TILING | M_DRAGGING: | ||
264 | case M_TILING | M_RESIZING: | ||
265 | default: | ||
266 | return; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | |||
53 | static struct wlc_geometry saved_floating; | 271 | static struct wlc_geometry saved_floating; |
54 | 272 | ||
55 | void start_floating(swayc_t *view) { | 273 | void start_floating(swayc_t *view) { |
@@ -72,3 +290,4 @@ void reset_floating(swayc_t *view) { | |||
72 | pointer_state.floating = (struct pointer_floating){0, 0}; | 290 | pointer_state.floating = (struct pointer_floating){0, 0}; |
73 | pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0}; | 291 | pointer_state.lock = (struct pointer_lock){0, 0, 0, 0, 0, 0, 0, 0}; |
74 | } | 292 | } |
293 | |||
diff --git a/sway/layout.c b/sway/layout.c index 18ecb1e7..fd2e80fe 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->gaps / 2, | ||
213 | .y = container->y + container->gaps / 2 | ||
214 | }, | ||
215 | .size = { | ||
216 | .w = container->width - container->gaps, | ||
217 | .h = container->height - 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; |
@@ -196,31 +269,11 @@ void arrange_windows(swayc_t *container, double width, double height) { | |||
196 | return; | 269 | return; |
197 | case C_VIEW: | 270 | case C_VIEW: |
198 | { | 271 | { |
199 | struct wlc_geometry geometry = { | 272 | container->width = width; |
200 | .origin = { | 273 | container->height = height; |
201 | .x = container->x + container->gaps / 2, | 274 | update_geometry(container); |
202 | .y = container->y + container->gaps / 2 | 275 | sway_log(L_DEBUG, "Set view to %.f x %.f @ %.f, %.f", container->width, |
203 | }, | 276 | container->height, container->x, container->y); |
204 | .size = { | ||
205 | .w = width - container->gaps, | ||
206 | .h = height - container->gaps | ||
207 | } | ||
208 | }; | ||
209 | if (swayc_is_fullscreen(container)) { | ||
210 | swayc_t *parent = swayc_parent_by_type(container, C_OUTPUT); | ||
211 | geometry.origin.x = 0; | ||
212 | geometry.origin.y = 0; | ||
213 | geometry.size.w = parent->width; | ||
214 | geometry.size.h = parent->height; | ||
215 | wlc_view_set_geometry(container->handle, 0, &geometry); | ||
216 | wlc_view_bring_to_front(container->handle); | ||
217 | } else { | ||
218 | wlc_view_set_geometry(container->handle, 0, &geometry); | ||
219 | container->width = width; | ||
220 | container->height = height; | ||
221 | } | ||
222 | sway_log(L_DEBUG, "Set view to %d x %d @ %d, %d", geometry.size.w, geometry.size.h, | ||
223 | geometry.origin.x, geometry.origin.y); | ||
224 | } | 277 | } |
225 | return; | 278 | return; |
226 | default: | 279 | default: |
diff --git a/sway/resize.c b/sway/resize.c index a08ef4a1..31cd66e8 100644 --- a/sway/resize.c +++ b/sway/resize.c | |||
@@ -10,8 +10,8 @@ bool mouse_resize_tiled(struct wlc_origin prev_pos) { | |||
10 | swayc_t *view = container_under_pointer(); | 10 | swayc_t *view = container_under_pointer(); |
11 | bool valid = true; | 11 | bool valid = true; |
12 | bool changed_tiling = false; | 12 | bool changed_tiling = false; |
13 | double dx = mouse_origin.x - prev_pos.x; | 13 | double dx = pointer_state.origin.x - prev_pos.x; |
14 | double dy = mouse_origin.y - prev_pos.y; | 14 | double dy = pointer_state.origin.y - prev_pos.y; |
15 | if (view != pointer_state.tiling.init_view) { | 15 | if (view != pointer_state.tiling.init_view) { |
16 | changed_tiling = true; | 16 | changed_tiling = true; |
17 | valid = false; | 17 | valid = false; |
@@ -32,7 +32,7 @@ bool mouse_resize_tiled(struct wlc_origin prev_pos) { | |||
32 | } | 32 | } |
33 | } | 33 | } |
34 | 34 | ||
35 | if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) { | 35 | if ((dx < 0 || pointer_state.origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) { |
36 | changed_tiling = true; | 36 | changed_tiling = true; |
37 | valid = false; | 37 | valid = false; |
38 | } else if (dx > 0 && pointer_state.lock.temp_left) { | 38 | } else if (dx > 0 && pointer_state.lock.temp_left) { |
@@ -40,7 +40,7 @@ bool mouse_resize_tiled(struct wlc_origin prev_pos) { | |||
40 | pointer_state.tiling.lock_pos.x = 0; | 40 | pointer_state.tiling.lock_pos.x = 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) { | 43 | if ((dx > 0 || pointer_state.origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) { |
44 | changed_tiling = true; | 44 | changed_tiling = true; |
45 | valid = false; | 45 | valid = false; |
46 | } else if (dx < 0 && pointer_state.lock.temp_right) { | 46 | } else if (dx < 0 && pointer_state.lock.temp_right) { |
@@ -48,7 +48,7 @@ bool mouse_resize_tiled(struct wlc_origin prev_pos) { | |||
48 | pointer_state.tiling.lock_pos.x = 0; | 48 | pointer_state.tiling.lock_pos.x = 0; |
49 | } | 49 | } |
50 | 50 | ||
51 | if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) { | 51 | if ((dy < 0 || pointer_state.origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) { |
52 | changed_tiling = true; | 52 | changed_tiling = true; |
53 | valid = false; | 53 | valid = false; |
54 | } else if (dy > 0 && pointer_state.lock.temp_up) { | 54 | } else if (dy > 0 && pointer_state.lock.temp_up) { |
@@ -56,7 +56,7 @@ bool mouse_resize_tiled(struct wlc_origin prev_pos) { | |||
56 | pointer_state.tiling.lock_pos.y = 0; | 56 | pointer_state.tiling.lock_pos.y = 0; |
57 | } | 57 | } |
58 | 58 | ||
59 | if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) { | 59 | if ((dy > 0 || pointer_state.origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) { |
60 | changed_tiling = true; | 60 | changed_tiling = true; |
61 | valid = false; | 61 | valid = false; |
62 | } else if (dy < 0 && pointer_state.lock.temp_down) { | 62 | } else if (dy < 0 && pointer_state.lock.temp_down) { |
@@ -190,8 +190,8 @@ bool resize_floating(struct wlc_origin prev_pos) { | |||
190 | bool changed = false; | 190 | bool changed = false; |
191 | swayc_t *view = container_under_pointer(); | 191 | swayc_t *view = container_under_pointer(); |
192 | uint32_t edge = 0; | 192 | uint32_t edge = 0; |
193 | int dx = mouse_origin.x - prev_pos.x; | 193 | int dx = pointer_state.origin.x - prev_pos.x; |
194 | int dy = mouse_origin.y - prev_pos.y; | 194 | int dy = pointer_state.origin.y - prev_pos.y; |
195 | 195 | ||
196 | // Move and resize the view based on the dx/dy and mouse position | 196 | // Move and resize the view based on the dx/dy and mouse position |
197 | int midway_x = view->x + view->width/2; | 197 | int midway_x = view->x + view->width/2; |
@@ -203,14 +203,14 @@ bool resize_floating(struct wlc_origin prev_pos) { | |||
203 | view->width += dx; | 203 | view->width += dx; |
204 | edge += WLC_RESIZE_EDGE_RIGHT; | 204 | edge += WLC_RESIZE_EDGE_RIGHT; |
205 | } | 205 | } |
206 | } else if (mouse_origin.x < midway_x && !pointer_state.lock.left) { | 206 | } else if (pointer_state.origin.x < midway_x && !pointer_state.lock.left) { |
207 | changed = true; | 207 | changed = true; |
208 | view->x += dx; | 208 | view->x += dx; |
209 | view->width -= dx; | 209 | view->width -= dx; |
210 | edge += WLC_RESIZE_EDGE_LEFT; | 210 | edge += WLC_RESIZE_EDGE_LEFT; |
211 | } | 211 | } |
212 | } else if (dx > 0) { | 212 | } else if (dx > 0) { |
213 | if (mouse_origin.x > midway_x && !pointer_state.lock.right) { | 213 | if (pointer_state.origin.x > midway_x && !pointer_state.lock.right) { |
214 | changed = true; | 214 | changed = true; |
215 | view->width += dx; | 215 | view->width += dx; |
216 | edge += WLC_RESIZE_EDGE_RIGHT; | 216 | edge += WLC_RESIZE_EDGE_RIGHT; |
@@ -231,14 +231,14 @@ bool resize_floating(struct wlc_origin prev_pos) { | |||
231 | view->height += dy; | 231 | view->height += dy; |
232 | edge += WLC_RESIZE_EDGE_BOTTOM; | 232 | edge += WLC_RESIZE_EDGE_BOTTOM; |
233 | } | 233 | } |
234 | } else if (mouse_origin.y < midway_y && !pointer_state.lock.top) { | 234 | } else if (pointer_state.origin.y < midway_y && !pointer_state.lock.top) { |
235 | changed = true; | 235 | changed = true; |
236 | view->y += dy; | 236 | view->y += dy; |
237 | view->height -= dy; | 237 | view->height -= dy; |
238 | edge += WLC_RESIZE_EDGE_TOP; | 238 | edge += WLC_RESIZE_EDGE_TOP; |
239 | } | 239 | } |
240 | } else if (dy > 0) { | 240 | } else if (dy > 0) { |
241 | if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) { | 241 | if (pointer_state.origin.y > midway_y && !pointer_state.lock.bottom) { |
242 | changed = true; | 242 | changed = true; |
243 | view->height += dy; | 243 | view->height += dy; |
244 | edge += WLC_RESIZE_EDGE_BOTTOM; | 244 | edge += WLC_RESIZE_EDGE_BOTTOM; |