diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-10-17 15:57:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-17 15:57:13 +0200 |
commit | 765c80e5f7c36df77e9475a662648a0d87b93606 (patch) | |
tree | 21f28277ff5109d9f8ec196a12fc74bbb5dfd994 | |
parent | Merge pull request #2862 from SpeedJack/fix-stringop-overflow (diff) | |
parent | view: rewarp cursor during view_unmap (diff) | |
download | sway-765c80e5f7c36df77e9475a662648a0d87b93606.tar.gz sway-765c80e5f7c36df77e9475a662648a0d87b93606.tar.zst sway-765c80e5f7c36df77e9475a662648a0d87b93606.zip |
Merge pull request #2820 from Emantor/fix-mouse-warping-container
Fix mouse warping container
-rw-r--r-- | include/sway/input/cursor.h | 7 | ||||
-rw-r--r-- | include/sway/tree/view.h | 3 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 20 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 23 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 12 | ||||
-rw-r--r-- | sway/input/cursor.c | 41 | ||||
-rw-r--r-- | sway/input/seat.c | 27 | ||||
-rw-r--r-- | sway/tree/view.c | 37 |
8 files changed, 102 insertions, 68 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 4d47ab42..5556ea11 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -46,6 +46,11 @@ void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, | |||
46 | uint32_t button, enum wlr_button_state state); | 46 | uint32_t button, enum wlr_button_state state); |
47 | 47 | ||
48 | void cursor_set_image(struct sway_cursor *cursor, const char *image, | 48 | void cursor_set_image(struct sway_cursor *cursor, const char *image, |
49 | struct wl_client *client); | 49 | struct wl_client *client); |
50 | 50 | ||
51 | void cursor_warp_to_container(struct sway_cursor *cursor, | ||
52 | struct sway_container *container); | ||
53 | |||
54 | void cursor_warp_to_workspace(struct sway_cursor *cursor, | ||
55 | struct sway_workspace *workspace); | ||
51 | #endif | 56 | #endif |
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 870ef2e0..dc1f0b02 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -329,7 +329,8 @@ void view_destroy(struct sway_view *view); | |||
329 | 329 | ||
330 | void view_begin_destroy(struct sway_view *view); | 330 | void view_begin_destroy(struct sway_view *view); |
331 | 331 | ||
332 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface); | 332 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, |
333 | bool fullscreen, bool decoration); | ||
333 | 334 | ||
334 | void view_unmap(struct sway_view *view); | 335 | void view_unmap(struct sway_view *view); |
335 | 336 | ||
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 46582204..1ed45a6b 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c | |||
@@ -406,27 +406,19 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
406 | view->natural_height = view->wlr_xdg_surface->surface->current.height; | 406 | view->natural_height = view->wlr_xdg_surface->surface->current.height; |
407 | } | 407 | } |
408 | 408 | ||
409 | view_map(view, view->wlr_xdg_surface->surface); | 409 | bool csd = false; |
410 | 410 | ||
411 | if (!view->xdg_decoration) { | 411 | if (!view->xdg_decoration) { |
412 | struct sway_server_decoration *deco = | 412 | struct sway_server_decoration *deco = |
413 | decoration_from_surface(xdg_surface->surface); | 413 | decoration_from_surface(xdg_surface->surface); |
414 | bool csd = !deco || deco->wlr_server_decoration->mode == | 414 | csd = !deco || deco->wlr_server_decoration->mode == |
415 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | 415 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; |
416 | view_update_csd_from_client(view, csd); | ||
417 | } | ||
418 | 416 | ||
419 | if (xdg_surface->toplevel->client_pending.fullscreen) { | ||
420 | container_set_fullscreen(view->container, true); | ||
421 | arrange_workspace(view->container->workspace); | ||
422 | } else { | ||
423 | if (view->container->parent) { | ||
424 | arrange_container(view->container->parent); | ||
425 | } else if (view->container->workspace) { | ||
426 | arrange_workspace(view->container->workspace); | ||
427 | } | ||
428 | } | 417 | } |
429 | 418 | ||
419 | view_map(view, view->wlr_xdg_surface->surface, | ||
420 | xdg_surface->toplevel->client_pending.fullscreen, csd); | ||
421 | |||
430 | transaction_commit_dirty(); | 422 | transaction_commit_dirty(); |
431 | 423 | ||
432 | xdg_shell_view->commit.notify = handle_commit; | 424 | xdg_shell_view->commit.notify = handle_commit; |
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 165cc7eb..eb8ba853 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -402,25 +402,14 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
402 | view->natural_width = view->wlr_xdg_surface_v6->surface->current.width; | 402 | view->natural_width = view->wlr_xdg_surface_v6->surface->current.width; |
403 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; | 403 | view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; |
404 | } | 404 | } |
405 | struct sway_server_decoration *deco = | ||
406 | decoration_from_surface(xdg_surface->surface); | ||
407 | bool csd = !deco || deco->wlr_server_decoration->mode | ||
408 | == WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | ||
405 | 409 | ||
406 | view_map(view, view->wlr_xdg_surface_v6->surface); | 410 | view_map(view, view->wlr_xdg_surface_v6->surface, |
411 | xdg_surface->toplevel->client_pending.fullscreen, csd); | ||
407 | 412 | ||
408 | struct sway_server_decoration *deco = | ||
409 | decoration_from_surface(xdg_surface->surface); | ||
410 | bool csd = !deco || deco->wlr_server_decoration->mode == | ||
411 | WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT; | ||
412 | view_update_csd_from_client(view, csd); | ||
413 | |||
414 | if (xdg_surface->toplevel->client_pending.fullscreen) { | ||
415 | container_set_fullscreen(view->container, true); | ||
416 | arrange_workspace(view->container->workspace); | ||
417 | } else { | ||
418 | if (view->container->parent) { | ||
419 | arrange_container(view->container->parent); | ||
420 | } else if (view->container->workspace) { | ||
421 | arrange_workspace(view->container->workspace); | ||
422 | } | ||
423 | } | ||
424 | transaction_commit_dirty(); | 413 | transaction_commit_dirty(); |
425 | 414 | ||
426 | xdg_shell_v6_view->commit.notify = handle_commit; | 415 | xdg_shell_v6_view->commit.notify = handle_commit; |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index ebf2131e..066556b8 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -405,18 +405,8 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
405 | xwayland_view->commit.notify = handle_commit; | 405 | xwayland_view->commit.notify = handle_commit; |
406 | 406 | ||
407 | // Put it back into the tree | 407 | // Put it back into the tree |
408 | view_map(view, xsurface->surface); | 408 | view_map(view, xsurface->surface, xsurface->fullscreen, false); |
409 | 409 | ||
410 | if (xsurface->fullscreen) { | ||
411 | container_set_fullscreen(view->container, true); | ||
412 | arrange_workspace(view->container->workspace); | ||
413 | } else { | ||
414 | if (view->container->parent) { | ||
415 | arrange_container(view->container->parent); | ||
416 | } else if (view->container->workspace) { | ||
417 | arrange_workspace(view->container->workspace); | ||
418 | } | ||
419 | } | ||
420 | transaction_commit_dirty(); | 410 | transaction_commit_dirty(); |
421 | } | 411 | } |
422 | 412 | ||
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index bbe6b890..925190d6 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <wlr/types/wlr_cursor.h> | 9 | #include <wlr/types/wlr_cursor.h> |
10 | #include <wlr/types/wlr_xcursor_manager.h> | 10 | #include <wlr/types/wlr_xcursor_manager.h> |
11 | #include <wlr/types/wlr_idle.h> | 11 | #include <wlr/types/wlr_idle.h> |
12 | #include <wlr/types/wlr_box.h> | ||
12 | #include "list.h" | 13 | #include "list.h" |
13 | #include "log.h" | 14 | #include "log.h" |
14 | #include "config.h" | 15 | #include "config.h" |
@@ -1271,4 +1272,44 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) { | |||
1271 | cursor->cursor = wlr_cursor; | 1272 | cursor->cursor = wlr_cursor; |
1272 | 1273 | ||
1273 | return cursor; | 1274 | return cursor; |
1275 | |||
1276 | } | ||
1277 | |||
1278 | /** | ||
1279 | * Warps the cursor to the middle of the container argument. | ||
1280 | * Does nothing if the cursor is already inside the container. | ||
1281 | * If container is NULL, returns without doing anything. | ||
1282 | */ | ||
1283 | void cursor_warp_to_container(struct sway_cursor *cursor, | ||
1284 | struct sway_container *container) { | ||
1285 | if (!container) { | ||
1286 | return; | ||
1287 | } | ||
1288 | |||
1289 | struct wlr_box box; | ||
1290 | container_get_box(container, &box); | ||
1291 | if (wlr_box_contains_point(&box, cursor->cursor->x, cursor->cursor->y)) { | ||
1292 | return; | ||
1293 | } | ||
1294 | |||
1295 | double x = container->x + container->width / 2.0; | ||
1296 | double y = container->y + container->height / 2.0; | ||
1297 | |||
1298 | wlr_cursor_warp(cursor->cursor, NULL, x, y); | ||
1299 | } | ||
1300 | |||
1301 | /** | ||
1302 | * Warps the cursor to the middle of the workspace argument. | ||
1303 | * If workspace is NULL, returns without doing anything. | ||
1304 | */ | ||
1305 | void cursor_warp_to_workspace(struct sway_cursor *cursor, | ||
1306 | struct sway_workspace *workspace) { | ||
1307 | if (!workspace) { | ||
1308 | return; | ||
1309 | } | ||
1310 | |||
1311 | double x = workspace->x + workspace->width / 2.0; | ||
1312 | double y = workspace->y + workspace->height / 2.0; | ||
1313 | |||
1314 | wlr_cursor_warp(cursor->cursor, NULL, x, y); | ||
1274 | } | 1315 | } |
diff --git a/sway/input/seat.c b/sway/input/seat.c index c7deabed..d8d2f3a4 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -774,27 +774,18 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node, | |||
774 | workspace_consider_destroy(last_workspace); | 774 | workspace_consider_destroy(last_workspace); |
775 | } | 775 | } |
776 | 776 | ||
777 | if (last_focus) { | 777 | if (last_focus && warp) { |
778 | if (config->mouse_warping && warp && | 778 | if (container && config->mouse_warping == WARP_CONTAINER) { |
779 | (new_output != last_output || | 779 | cursor_warp_to_container(seat->cursor, container); |
780 | config->mouse_warping == WARP_CONTAINER)) { | 780 | cursor_send_pointer_motion(seat->cursor, 0, true); |
781 | double x = 0; | 781 | } else if (new_output != last_output && |
782 | double y = 0; | 782 | config->mouse_warping >= WARP_OUTPUT) { |
783 | if (container) { | 783 | if (container) { |
784 | x = container->x + container->width / 2.0; | 784 | cursor_warp_to_container(seat->cursor, container); |
785 | y = container->y + container->height / 2.0; | ||
786 | } else { | 785 | } else { |
787 | x = new_workspace->x + new_workspace->width / 2.0; | 786 | cursor_warp_to_workspace(seat->cursor, new_workspace); |
788 | y = new_workspace->y + new_workspace->height / 2.0; | ||
789 | } | ||
790 | |||
791 | if (!wlr_output_layout_contains_point(root->output_layout, | ||
792 | new_output->wlr_output, seat->cursor->cursor->x, | ||
793 | seat->cursor->cursor->y) | ||
794 | || config->mouse_warping == WARP_CONTAINER) { | ||
795 | wlr_cursor_warp(seat->cursor->cursor, NULL, x, y); | ||
796 | cursor_send_pointer_motion(seat->cursor, 0, true); | ||
797 | } | 787 | } |
788 | cursor_send_pointer_motion(seat->cursor, 0, true); | ||
798 | } | 789 | } |
799 | } | 790 | } |
800 | 791 | ||
diff --git a/sway/tree/view.c b/sway/tree/view.c index 1104af36..85998547 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -544,7 +544,8 @@ static bool should_focus(struct sway_view *view) { | |||
544 | return len == 0; | 544 | return len == 0; |
545 | } | 545 | } |
546 | 546 | ||
547 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | 547 | void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, |
548 | bool fullscreen, bool decoration) { | ||
548 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { | 549 | if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { |
549 | return; | 550 | return; |
550 | } | 551 | } |
@@ -595,13 +596,28 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { | |||
595 | } | 596 | } |
596 | } | 597 | } |
597 | 598 | ||
598 | if (should_focus(view)) { | ||
599 | input_manager_set_focus(input_manager, &view->container->node); | ||
600 | } | ||
601 | |||
602 | view_update_title(view, false); | 599 | view_update_title(view, false); |
603 | container_update_representation(view->container); | 600 | container_update_representation(view->container); |
604 | view_execute_criteria(view); | 601 | view_execute_criteria(view); |
602 | |||
603 | if (decoration) { | ||
604 | view_update_csd_from_client(view, decoration); | ||
605 | } | ||
606 | |||
607 | if (fullscreen) { | ||
608 | container_set_fullscreen(view->container, true); | ||
609 | arrange_workspace(view->container->workspace); | ||
610 | } else { | ||
611 | if (view->container->parent) { | ||
612 | arrange_container(view->container->parent); | ||
613 | } else if (view->container->workspace) { | ||
614 | arrange_workspace(view->container->workspace); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | if (should_focus(view)) { | ||
619 | input_manager_set_focus(input_manager, &view->container->node); | ||
620 | } | ||
605 | } | 621 | } |
606 | 622 | ||
607 | void view_unmap(struct sway_view *view) { | 623 | void view_unmap(struct sway_view *view) { |
@@ -630,7 +646,16 @@ void view_unmap(struct sway_view *view) { | |||
630 | 646 | ||
631 | struct sway_seat *seat; | 647 | struct sway_seat *seat; |
632 | wl_list_for_each(seat, &input_manager->seats, link) { | 648 | wl_list_for_each(seat, &input_manager->seats, link) { |
633 | cursor_send_pointer_motion(seat->cursor, 0, true); | 649 | if (config->mouse_warping == WARP_CONTAINER) { |
650 | struct sway_node *node = seat_get_focus(seat); | ||
651 | if (node && node->type == N_CONTAINER) { | ||
652 | cursor_warp_to_container(seat->cursor, node->sway_container); | ||
653 | } else if (node && node->type == N_WORKSPACE) { | ||
654 | cursor_warp_to_workspace(seat->cursor, node->sway_workspace); | ||
655 | } | ||
656 | } else { | ||
657 | cursor_send_pointer_motion(seat->cursor, 0, true); | ||
658 | } | ||
634 | } | 659 | } |
635 | 660 | ||
636 | transaction_commit_dirty(); | 661 | transaction_commit_dirty(); |