aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-24 19:38:52 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-10-24 19:38:52 +1000
commitbdae625cb344209424841a7c5f0c0967773c8c10 (patch)
tree754adb52ec2e2eb9d336d1c826bab62ea96e6c52
parentMerge pull request #2933 from Snaipe/xwayland-window-properties (diff)
downloadsway-bdae625cb344209424841a7c5f0c0967773c8c10.tar.gz
sway-bdae625cb344209424841a7c5f0c0967773c8c10.tar.zst
sway-bdae625cb344209424841a7c5f0c0967773c8c10.zip
Rebase the cursor after mapping a view
I originally put the rebase at the end of view_map, but at this point the view is still at its native size and will ignore the motion event if it falls outside of its native size. The only way to do this properly is to rebase the cursor later - either after sending the configure, after the view commits with the new size, or after applying the transaction. I chose to do it after applying the transaction for simplicity. I then attempted to just call cursor_rebase after applying every transaction, but this causes crashes when exiting sway (and possibly other places) because cursor_rebase assumes the tree is in a valid state. So my chosen solution introduces transaction_commit_dirty_with_callback which allows handle_map to register a callback which will run when the transaction is applied.
-rw-r--r--include/sway/desktop/transaction.h7
-rw-r--r--sway/desktop/transaction.c40
-rw-r--r--sway/desktop/xdg_shell.c9
-rw-r--r--sway/desktop/xdg_shell_v6.c9
-rw-r--r--sway/desktop/xwayland.c9
5 files changed, 63 insertions, 11 deletions
diff --git a/include/sway/desktop/transaction.h b/include/sway/desktop/transaction.h
index 66e8c9a2..f38f033c 100644
--- a/include/sway/desktop/transaction.h
+++ b/include/sway/desktop/transaction.h
@@ -29,6 +29,13 @@ struct sway_view;
29void transaction_commit_dirty(void); 29void transaction_commit_dirty(void);
30 30
31/** 31/**
32 * Same as above, but runs the specific callback when the transaction is
33 * applied.
34 */
35void transaction_commit_dirty_with_callback(
36 void (*callback)(void *data), void *data);
37
38/**
32 * Notify the transaction system that a view is ready for the new layout. 39 * Notify the transaction system that a view is ready for the new layout.
33 * 40 *
34 * When all views in the transaction are ready, the layout will be applied. 41 * When all views in the transaction are ready, the layout will be applied.
diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 5dec279d..b2f7f922 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -25,6 +25,8 @@ struct sway_transaction {
25 size_t num_waiting; 25 size_t num_waiting;
26 size_t num_configures; 26 size_t num_configures;
27 struct timespec commit_time; 27 struct timespec commit_time;
28 void (*callback)(void *data);
29 void *callback_data;
28}; 30};
29 31
30struct sway_transaction_instruction { 32struct sway_transaction_instruction {
@@ -295,6 +297,10 @@ static void transaction_apply(struct sway_transaction *transaction) {
295 297
296 node->instruction = NULL; 298 node->instruction = NULL;
297 } 299 }
300
301 if (transaction->callback) {
302 transaction->callback(transaction->callback_data);
303 }
298} 304}
299 305
300static void transaction_commit(struct sway_transaction *transaction); 306static void transaction_commit(struct sway_transaction *transaction);
@@ -499,14 +505,7 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
499 } 505 }
500} 506}
501 507
502void transaction_commit_dirty(void) { 508static void do_commit_dirty(struct sway_transaction *transaction) {
503 if (!server.dirty_nodes->length) {
504 return;
505 }
506 struct sway_transaction *transaction = transaction_create();
507 if (!transaction) {
508 return;
509 }
510 for (int i = 0; i < server.dirty_nodes->length; ++i) { 509 for (int i = 0; i < server.dirty_nodes->length; ++i) {
511 struct sway_node *node = server.dirty_nodes->items[i]; 510 struct sway_node *node = server.dirty_nodes->items[i];
512 transaction_add_node(transaction, node); 511 transaction_add_node(transaction, node);
@@ -525,3 +524,28 @@ void transaction_commit_dirty(void) {
525 transaction_progress_queue(); 524 transaction_progress_queue();
526 } 525 }
527} 526}
527
528void transaction_commit_dirty(void) {
529 if (!server.dirty_nodes->length) {
530 return;
531 }
532 struct sway_transaction *transaction = transaction_create();
533 if (!transaction) {
534 return;
535 }
536 do_commit_dirty(transaction);
537}
538
539void transaction_commit_dirty_with_callback(
540 void (*callback)(void *data), void *data) {
541 if (!server.dirty_nodes->length) {
542 return;
543 }
544 struct sway_transaction *transaction = transaction_create();
545 if (!transaction) {
546 return;
547 }
548 transaction->callback = callback;
549 transaction->callback_data = data;
550 do_commit_dirty(transaction);
551}
diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c
index fda1bdef..064e2707 100644
--- a/sway/desktop/xdg_shell.c
+++ b/sway/desktop/xdg_shell.c
@@ -9,6 +9,7 @@
9#include "sway/decoration.h" 9#include "sway/decoration.h"
10#include "sway/desktop.h" 10#include "sway/desktop.h"
11#include "sway/desktop/transaction.h" 11#include "sway/desktop/transaction.h"
12#include "sway/input/cursor.h"
12#include "sway/input/input-manager.h" 13#include "sway/input/input-manager.h"
13#include "sway/input/seat.h" 14#include "sway/input/seat.h"
14#include "sway/output.h" 15#include "sway/output.h"
@@ -396,6 +397,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
396 wl_list_remove(&xdg_shell_view->set_app_id.link); 397 wl_list_remove(&xdg_shell_view->set_app_id.link);
397} 398}
398 399
400static void do_rebase(void *data) {
401 struct sway_cursor *cursor = data;
402 cursor_rebase(cursor);
403}
404
399static void handle_map(struct wl_listener *listener, void *data) { 405static void handle_map(struct wl_listener *listener, void *data) {
400 struct sway_xdg_shell_view *xdg_shell_view = 406 struct sway_xdg_shell_view *xdg_shell_view =
401 wl_container_of(listener, xdg_shell_view, map); 407 wl_container_of(listener, xdg_shell_view, map);
@@ -422,7 +428,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
422 view_map(view, view->wlr_xdg_surface->surface, 428 view_map(view, view->wlr_xdg_surface->surface,
423 xdg_surface->toplevel->client_pending.fullscreen, csd); 429 xdg_surface->toplevel->client_pending.fullscreen, csd);
424 430
425 transaction_commit_dirty(); 431 struct sway_seat *seat = input_manager_current_seat();
432 transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
426 433
427 xdg_shell_view->commit.notify = handle_commit; 434 xdg_shell_view->commit.notify = handle_commit;
428 wl_signal_add(&xdg_surface->surface->events.commit, 435 wl_signal_add(&xdg_surface->surface->events.commit,
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index 7159f1ed..90bf55b2 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -8,6 +8,7 @@
8#include "sway/decoration.h" 8#include "sway/decoration.h"
9#include "sway/desktop.h" 9#include "sway/desktop.h"
10#include "sway/desktop/transaction.h" 10#include "sway/desktop/transaction.h"
11#include "sway/input/cursor.h"
11#include "sway/input/input-manager.h" 12#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 13#include "sway/input/seat.h"
13#include "sway/output.h" 14#include "sway/output.h"
@@ -393,6 +394,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
393 wl_list_remove(&xdg_shell_v6_view->set_app_id.link); 394 wl_list_remove(&xdg_shell_v6_view->set_app_id.link);
394} 395}
395 396
397static void do_rebase(void *data) {
398 struct sway_cursor *cursor = data;
399 cursor_rebase(cursor);
400}
401
396static void handle_map(struct wl_listener *listener, void *data) { 402static void handle_map(struct wl_listener *listener, void *data) {
397 struct sway_xdg_shell_v6_view *xdg_shell_v6_view = 403 struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
398 wl_container_of(listener, xdg_shell_v6_view, map); 404 wl_container_of(listener, xdg_shell_v6_view, map);
@@ -413,7 +419,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
413 view_map(view, view->wlr_xdg_surface_v6->surface, 419 view_map(view, view->wlr_xdg_surface_v6->surface,
414 xdg_surface->toplevel->client_pending.fullscreen, csd); 420 xdg_surface->toplevel->client_pending.fullscreen, csd);
415 421
416 transaction_commit_dirty(); 422 struct sway_seat *seat = input_manager_current_seat();
423 transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
417 424
418 xdg_shell_v6_view->commit.notify = handle_commit; 425 xdg_shell_v6_view->commit.notify = handle_commit;
419 wl_signal_add(&xdg_surface->surface->events.commit, 426 wl_signal_add(&xdg_surface->surface->events.commit,
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index d1aec084..95275937 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -8,6 +8,7 @@
8#include "log.h" 8#include "log.h"
9#include "sway/desktop.h" 9#include "sway/desktop.h"
10#include "sway/desktop/transaction.h" 10#include "sway/desktop/transaction.h"
11#include "sway/input/cursor.h"
11#include "sway/input/input-manager.h" 12#include "sway/input/input-manager.h"
12#include "sway/input/seat.h" 13#include "sway/input/seat.h"
13#include "sway/output.h" 14#include "sway/output.h"
@@ -390,6 +391,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
390 wl_list_remove(&xwayland_view->commit.link); 391 wl_list_remove(&xwayland_view->commit.link);
391} 392}
392 393
394static void do_rebase(void *data) {
395 struct sway_cursor *cursor = data;
396 cursor_rebase(cursor);
397}
398
393static void handle_map(struct wl_listener *listener, void *data) { 399static void handle_map(struct wl_listener *listener, void *data) {
394 struct sway_xwayland_view *xwayland_view = 400 struct sway_xwayland_view *xwayland_view =
395 wl_container_of(listener, xwayland_view, map); 401 wl_container_of(listener, xwayland_view, map);
@@ -416,7 +422,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
416 // Put it back into the tree 422 // Put it back into the tree
417 view_map(view, xsurface->surface, xsurface->fullscreen, false); 423 view_map(view, xsurface->surface, xsurface->fullscreen, false);
418 424
419 transaction_commit_dirty(); 425 struct sway_seat *seat = input_manager_current_seat();
426 transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
420} 427}
421 428
422static void handle_request_configure(struct wl_listener *listener, void *data) { 429static void handle_request_configure(struct wl_listener *listener, void *data) {