diff options
Diffstat (limited to 'sway/handlers.c')
-rw-r--r-- | sway/handlers.c | 202 |
1 files changed, 110 insertions, 92 deletions
diff --git a/sway/handlers.c b/sway/handlers.c index e785e9c5..3ae33294 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "focus.h" | 15 | #include "focus.h" |
16 | 16 | ||
17 | uint32_t keys_pressed[32]; | 17 | uint32_t keys_pressed[32]; |
18 | int keys_pressed_length = 0; | ||
18 | 19 | ||
19 | static struct wlc_origin mouse_origin; | 20 | static struct wlc_origin mouse_origin; |
20 | 21 | ||
@@ -23,6 +24,15 @@ static bool dragging = false; | |||
23 | static bool m2_held = false; | 24 | static bool m2_held = false; |
24 | static bool resizing = false; | 25 | static bool resizing = false; |
25 | 26 | ||
27 | static bool floating_mod_pressed(void) { | ||
28 | int i = 0; | ||
29 | while (i < keys_pressed_length) { | ||
30 | if (keys_pressed[i++] == config->floating_mod) | ||
31 | return true; | ||
32 | } | ||
33 | return false; | ||
34 | } | ||
35 | |||
26 | static bool pointer_test(swayc_t *view, void *_origin) { | 36 | static bool pointer_test(swayc_t *view, void *_origin) { |
27 | const struct wlc_origin *origin = _origin; | 37 | const struct wlc_origin *origin = _origin; |
28 | // Determine the output that the view is under | 38 | // Determine the output that the view is under |
@@ -139,35 +149,54 @@ static void handle_output_focused(wlc_handle output, bool focus) { | |||
139 | } | 149 | } |
140 | 150 | ||
141 | static bool handle_view_created(wlc_handle handle) { | 151 | static bool handle_view_created(wlc_handle handle) { |
142 | swayc_t *focused = get_focused_container(&root_container); | 152 | // if view is child of another view, the use that as focused container |
153 | wlc_handle parent = wlc_view_get_parent(handle); | ||
154 | swayc_t *focused = NULL; | ||
143 | swayc_t *newview = NULL; | 155 | swayc_t *newview = NULL; |
156 | |||
157 | // Get parent container, to add view in | ||
158 | if (parent) { | ||
159 | focused = get_swayc_for_handle(parent, &root_container); | ||
160 | } | ||
161 | if (!focused || focused->type == C_OUTPUT) { | ||
162 | focused = get_focused_container(&root_container); | ||
163 | } | ||
164 | sway_log(L_DEBUG, "creating view %ld with type %x, state %x, with parent %ld", | ||
165 | handle, wlc_view_get_type(handle), wlc_view_get_state(handle), parent); | ||
166 | |||
167 | // TODO properly figure out how each window should be handled. | ||
144 | switch (wlc_view_get_type(handle)) { | 168 | switch (wlc_view_get_type(handle)) { |
145 | // regular view created regularly | 169 | // regular view created regularly |
146 | case 0: | 170 | case 0: |
147 | newview = new_view(focused, handle); | 171 | newview = new_view(focused, handle); |
148 | wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true); | 172 | wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true); |
149 | break; | 173 | break; |
150 | // takes keyboard focus | 174 | |
175 | // Dmenu keeps viewfocus, but others with this flag dont, for now simulate | ||
176 | // dmenu | ||
151 | case WLC_BIT_OVERRIDE_REDIRECT: | 177 | case WLC_BIT_OVERRIDE_REDIRECT: |
152 | sway_log(L_DEBUG, "view %ld with OVERRIDE_REDIRECT", handle); | 178 | // locked_view_focus = true; |
153 | locked_view_focus = true; | ||
154 | wlc_view_focus(handle); | 179 | wlc_view_focus(handle); |
155 | wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true); | 180 | wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true); |
156 | wlc_view_bring_to_front(handle); | 181 | wlc_view_bring_to_front(handle); |
157 | break; | 182 | break; |
158 | // Takes container focus | 183 | |
184 | // Firefox popups have this flag set. | ||
159 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: | 185 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: |
160 | sway_log(L_DEBUG, "view %ld with OVERRIDE_REDIRECT|WLC_BIT_MANAGED", handle); | ||
161 | wlc_view_bring_to_front(handle); | 186 | wlc_view_bring_to_front(handle); |
162 | locked_container_focus = true; | 187 | locked_container_focus = true; |
163 | break; | 188 | break; |
164 | // set modals as floating containers | 189 | |
190 | // Modals, get focus, popups do not | ||
165 | case WLC_BIT_MODAL: | 191 | case WLC_BIT_MODAL: |
192 | wlc_view_focus(handle); | ||
166 | wlc_view_bring_to_front(handle); | 193 | wlc_view_bring_to_front(handle); |
167 | newview = new_floating_view(handle); | 194 | newview = new_floating_view(handle); |
168 | case WLC_BIT_POPUP: | 195 | case WLC_BIT_POPUP: |
196 | wlc_view_bring_to_front(handle); | ||
169 | break; | 197 | break; |
170 | } | 198 | } |
199 | |||
171 | if (newview) { | 200 | if (newview) { |
172 | set_focused_container(newview); | 201 | set_focused_container(newview); |
173 | swayc_t *output = newview->parent; | 202 | swayc_t *output = newview->parent; |
@@ -187,19 +216,19 @@ static void handle_view_destroyed(wlc_handle handle) { | |||
187 | // regular view created regularly | 216 | // regular view created regularly |
188 | case 0: | 217 | case 0: |
189 | case WLC_BIT_MODAL: | 218 | case WLC_BIT_MODAL: |
219 | case WLC_BIT_POPUP: | ||
190 | if (view) { | 220 | if (view) { |
191 | swayc_t *parent = destroy_view(view); | 221 | swayc_t *parent = destroy_view(view); |
192 | arrange_windows(parent, -1, -1); | 222 | arrange_windows(parent, -1, -1); |
193 | } | 223 | } |
194 | break; | 224 | break; |
195 | // takes keyboard focus | 225 | // DMENU has this flag, and takes view_focus, but other things with this |
226 | // flag dont | ||
196 | case WLC_BIT_OVERRIDE_REDIRECT: | 227 | case WLC_BIT_OVERRIDE_REDIRECT: |
197 | locked_view_focus = false; | 228 | // locked_view_focus = false; |
198 | break; | 229 | break; |
199 | // Takes container focus | ||
200 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: | 230 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: |
201 | locked_container_focus = false; | 231 | locked_container_focus = false; |
202 | case WLC_BIT_POPUP: | ||
203 | break; | 232 | break; |
204 | } | 233 | } |
205 | set_focused_container(get_focused_view(&root_container)); | 234 | set_focused_container(get_focused_view(&root_container)); |
@@ -267,7 +296,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
267 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { | 296 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { |
268 | return false; | 297 | return false; |
269 | } | 298 | } |
270 | static uint8_t head = 0; | ||
271 | bool cmd_success = false; | 299 | bool cmd_success = false; |
272 | 300 | ||
273 | struct sway_mode *mode = config->current_mode; | 301 | struct sway_mode *mode = config->current_mode; |
@@ -276,13 +304,15 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
276 | 304 | ||
277 | // Find key, if it has been pressed | 305 | // Find key, if it has been pressed |
278 | int mid = 0; | 306 | int mid = 0; |
279 | while (mid < head && keys_pressed[mid] != sym) { | 307 | while (mid < keys_pressed_length && keys_pressed[mid] != sym) { |
280 | ++mid; | 308 | ++mid; |
281 | } | 309 | } |
282 | if (state == WLC_KEY_STATE_PRESSED && mid == head && head + 1 < QSIZE) { | 310 | //Add or remove key depending on state |
283 | keys_pressed[head++] = sym; | 311 | if (state == WLC_KEY_STATE_PRESSED && mid == keys_pressed_length && keys_pressed_length + 1 < QSIZE) { |
284 | } else if (state == WLC_KEY_STATE_RELEASED && mid < head) { | 312 | keys_pressed[keys_pressed_length++] = sym; |
285 | memmove(keys_pressed + mid, keys_pressed + mid + 1, sizeof*keys_pressed * (--head - mid)); | 313 | } else if (state == WLC_KEY_STATE_RELEASED && mid < keys_pressed_length) { |
314 | memmove(keys_pressed + mid, keys_pressed + mid + 1, sizeof*keys_pressed * (--keys_pressed_length - mid)); | ||
315 | keys_pressed[keys_pressed_length] = 0; | ||
286 | } | 316 | } |
287 | // TODO: reminder to check conflicts with mod+q+a versus mod+q | 317 | // TODO: reminder to check conflicts with mod+q+a versus mod+q |
288 | int i; | 318 | int i; |
@@ -296,7 +326,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
296 | match = false; | 326 | match = false; |
297 | xkb_keysym_t *key = binding->keys->items[j]; | 327 | xkb_keysym_t *key = binding->keys->items[j]; |
298 | uint8_t k; | 328 | uint8_t k; |
299 | for (k = 0; k < head; ++k) { | 329 | for (k = 0; k < keys_pressed_length; ++k) { |
300 | if (keys_pressed[k] == *key) { | 330 | if (keys_pressed[k] == *key) { |
301 | match = true; | 331 | match = true; |
302 | break; | 332 | break; |
@@ -312,8 +342,9 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
312 | int j; | 342 | int j; |
313 | for (j = 0; j < binding->keys->length; ++j) { | 343 | for (j = 0; j < binding->keys->length; ++j) { |
314 | uint8_t k; | 344 | uint8_t k; |
315 | for (k = 0; k < head; ++k) { | 345 | for (k = 0; k < keys_pressed_length; ++k) { |
316 | memmove(keys_pressed + k, keys_pressed + k + 1, sizeof*keys_pressed * (--head - k)); | 346 | memmove(keys_pressed + k, keys_pressed + k + 1, sizeof*keys_pressed * (--keys_pressed_length - k)); |
347 | keys_pressed[keys_pressed_length] = 0; | ||
317 | break; | 348 | break; |
318 | } | 349 | } |
319 | } | 350 | } |
@@ -333,84 +364,67 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
333 | static wlc_handle prev_handle = 0; | 364 | static wlc_handle prev_handle = 0; |
334 | mouse_origin = *origin; | 365 | mouse_origin = *origin; |
335 | bool changed_floating = false; | 366 | bool changed_floating = false; |
336 | int i = 0; | ||
337 | if (!active_workspace) { | 367 | if (!active_workspace) { |
338 | return false; | 368 | return false; |
339 | } | 369 | } |
340 | // Do checks to determine if proper keys are being held | 370 | // Do checks to determine if proper keys are being held |
341 | swayc_t *view = active_workspace->focused; | 371 | swayc_t *view = get_focused_view(active_workspace); |
342 | uint32_t edge = 0; | 372 | uint32_t edge = 0; |
343 | if (dragging && view) { | 373 | if (dragging && view && view->is_floating) { |
344 | if (view->is_floating) { | 374 | int dx = mouse_origin.x - prev_pos.x; |
345 | while (keys_pressed[i++]) { | 375 | int dy = mouse_origin.y - prev_pos.y; |
346 | if (keys_pressed[i] == config->floating_mod) { | 376 | view->x += dx; |
347 | int dx = mouse_origin.x - prev_pos.x; | 377 | view->y += dy; |
348 | int dy = mouse_origin.y - prev_pos.y; | 378 | changed_floating = true; |
349 | view->x += dx; | 379 | } else if (resizing && view && view->is_floating) { |
350 | view->y += dy; | 380 | int dx = mouse_origin.x - prev_pos.x; |
351 | changed_floating = true; | 381 | int dy = mouse_origin.y - prev_pos.y; |
352 | break; | 382 | |
353 | } | 383 | // Move and resize the view based on the dx/dy and mouse position |
384 | int midway_x = view->x + view->width/2; | ||
385 | int midway_y = view->y + view->height/2; | ||
386 | if (dx < 0) { | ||
387 | changed_floating = true; | ||
388 | if (mouse_origin.x > midway_x) { | ||
389 | view->width += dx; | ||
390 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
391 | } else { | ||
392 | view->x += dx; | ||
393 | view->width -= dx; | ||
394 | edge += WLC_RESIZE_EDGE_LEFT; | ||
395 | } | ||
396 | } else if (dx > 0){ | ||
397 | changed_floating = true; | ||
398 | if (mouse_origin.x > midway_x) { | ||
399 | view->width += dx; | ||
400 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
401 | } else { | ||
402 | view->x += dx; | ||
403 | view->width -= dx; | ||
404 | edge += WLC_RESIZE_EDGE_LEFT; | ||
354 | } | 405 | } |
355 | } | 406 | } |
356 | } else if (resizing && view) { | ||
357 | if (view->is_floating) { | ||
358 | while (keys_pressed[i++]) { | ||
359 | if (keys_pressed[i] == config->floating_mod) { | ||
360 | int dx = mouse_origin.x - prev_pos.x; | ||
361 | int dy = mouse_origin.y - prev_pos.y; | ||
362 | |||
363 | // Move and resize the view based on the dx/dy and mouse position | ||
364 | int midway_x = view->x + view->width/2; | ||
365 | int midway_y = view->y + view->height/2; | ||
366 | |||
367 | |||
368 | if (dx < 0) { | ||
369 | changed_floating = true; | ||
370 | if (mouse_origin.x > midway_x) { | ||
371 | view->width += dx; | ||
372 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
373 | } else { | ||
374 | view->x += dx; | ||
375 | view->width -= dx; | ||
376 | edge += WLC_RESIZE_EDGE_LEFT; | ||
377 | } | ||
378 | } else if (dx > 0){ | ||
379 | changed_floating = true; | ||
380 | if (mouse_origin.x > midway_x) { | ||
381 | view->width += dx; | ||
382 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
383 | } else { | ||
384 | view->x += dx; | ||
385 | view->width -= dx; | ||
386 | edge += WLC_RESIZE_EDGE_LEFT; | ||
387 | } | ||
388 | } | ||
389 | 407 | ||
390 | if (dy < 0) { | 408 | if (dy < 0) { |
391 | changed_floating = true; | 409 | changed_floating = true; |
392 | if (mouse_origin.y > midway_y) { | 410 | if (mouse_origin.y > midway_y) { |
393 | view->height += dy; | 411 | view->height += dy; |
394 | edge += WLC_RESIZE_EDGE_BOTTOM; | 412 | edge += WLC_RESIZE_EDGE_BOTTOM; |
395 | } else { | 413 | } else { |
396 | view->y += dy; | 414 | view->y += dy; |
397 | view->height -= dy; | 415 | view->height -= dy; |
398 | edge += WLC_RESIZE_EDGE_TOP; | 416 | edge += WLC_RESIZE_EDGE_TOP; |
399 | } | 417 | } |
400 | } else if (dy > 0) { | 418 | } else if (dy > 0) { |
401 | changed_floating = true; | 419 | changed_floating = true; |
402 | if (mouse_origin.y > midway_y) { | 420 | if (mouse_origin.y > midway_y) { |
403 | view->height += dy; | 421 | view->height += dy; |
404 | edge += WLC_RESIZE_EDGE_BOTTOM; | 422 | edge += WLC_RESIZE_EDGE_BOTTOM; |
405 | } else { | 423 | } else { |
406 | edge = WLC_RESIZE_EDGE_BOTTOM; | 424 | edge = WLC_RESIZE_EDGE_BOTTOM; |
407 | view->y += dy; | 425 | view->y += dy; |
408 | view->height -= dy; | 426 | view->height -= dy; |
409 | edge += WLC_RESIZE_EDGE_TOP; | 427 | edge += WLC_RESIZE_EDGE_TOP; |
410 | } | ||
411 | } | ||
412 | break; | ||
413 | } | ||
414 | } | 428 | } |
415 | } | 429 | } |
416 | } | 430 | } |
@@ -467,8 +481,12 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
467 | } | 481 | } |
468 | } | 482 | } |
469 | arrange_windows(pointer->parent, -1, -1); | 483 | arrange_windows(pointer->parent, -1, -1); |
470 | dragging = m1_held; | 484 | if (floating_mod_pressed()) { |
471 | resizing = m2_held; | 485 | dragging = m1_held; |
486 | resizing = m2_held; | ||
487 | } | ||
488 | //Dont want pointer sent to window while dragging or resizing | ||
489 | return (dragging || resizing); | ||
472 | } | 490 | } |
473 | return (pointer && pointer != focused); | 491 | return (pointer && pointer != focused); |
474 | } else { | 492 | } else { |