summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-10-17 15:57:13 +0200
committerLibravatar GitHub <noreply@github.com>2018-10-17 15:57:13 +0200
commit765c80e5f7c36df77e9475a662648a0d87b93606 (patch)
tree21f28277ff5109d9f8ec196a12fc74bbb5dfd994
parentMerge pull request #2862 from SpeedJack/fix-stringop-overflow (diff)
parentview: rewarp cursor during view_unmap (diff)
downloadsway-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.h7
-rw-r--r--include/sway/tree/view.h3
-rw-r--r--sway/desktop/xdg_shell.c20
-rw-r--r--sway/desktop/xdg_shell_v6.c23
-rw-r--r--sway/desktop/xwayland.c12
-rw-r--r--sway/input/cursor.c41
-rw-r--r--sway/input/seat.c27
-rw-r--r--sway/tree/view.c37
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
48void cursor_set_image(struct sway_cursor *cursor, const char *image, 48void cursor_set_image(struct sway_cursor *cursor, const char *image,
49 struct wl_client *client); 49 struct wl_client *client);
50 50
51void cursor_warp_to_container(struct sway_cursor *cursor,
52 struct sway_container *container);
53
54void 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
330void view_begin_destroy(struct sway_view *view); 330void view_begin_destroy(struct sway_view *view);
331 331
332void view_map(struct sway_view *view, struct wlr_surface *wlr_surface); 332void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
333 bool fullscreen, bool decoration);
333 334
334void view_unmap(struct sway_view *view); 335void 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 */
1283void 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 */
1305void 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
547void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { 547void 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
607void view_unmap(struct sway_view *view) { 623void 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();