aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dwyer <ryandwyer1@gmail.com>2018-10-24 19:38:52 +1000
committerRyan Dwyer <ryandwyer1@gmail.com>2018-10-24 19:38:52 +1000
commitbdae625cb344209424841a7c5f0c0967773c8c10 (patch)
tree754adb52ec2e2eb9d336d1c826bab62ea96e6c52
parentbdb176863c3c45caae70abb909f9eca9f611e78f (diff)
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;
void transaction_commit_dirty(void);
/**
+ * Same as above, but runs the specific callback when the transaction is
+ * applied.
+ */
+void transaction_commit_dirty_with_callback(
+ void (*callback)(void *data), void *data);
+
+/**
* Notify the transaction system that a view is ready for the new layout.
*
* 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 {
size_t num_waiting;
size_t num_configures;
struct timespec commit_time;
+ void (*callback)(void *data);
+ void *callback_data;
};
struct sway_transaction_instruction {
@@ -295,6 +297,10 @@ static void transaction_apply(struct sway_transaction *transaction) {
node->instruction = NULL;
}
+
+ if (transaction->callback) {
+ transaction->callback(transaction->callback_data);
+ }
}
static void transaction_commit(struct sway_transaction *transaction);
@@ -499,14 +505,7 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
}
}
-void transaction_commit_dirty(void) {
- if (!server.dirty_nodes->length) {
- return;
- }
- struct sway_transaction *transaction = transaction_create();
- if (!transaction) {
- return;
- }
+static void do_commit_dirty(struct sway_transaction *transaction) {
for (int i = 0; i < server.dirty_nodes->length; ++i) {
struct sway_node *node = server.dirty_nodes->items[i];
transaction_add_node(transaction, node);
@@ -525,3 +524,28 @@ void transaction_commit_dirty(void) {
transaction_progress_queue();
}
}
+
+void transaction_commit_dirty(void) {
+ if (!server.dirty_nodes->length) {
+ return;
+ }
+ struct sway_transaction *transaction = transaction_create();
+ if (!transaction) {
+ return;
+ }
+ do_commit_dirty(transaction);
+}
+
+void transaction_commit_dirty_with_callback(
+ void (*callback)(void *data), void *data) {
+ if (!server.dirty_nodes->length) {
+ return;
+ }
+ struct sway_transaction *transaction = transaction_create();
+ if (!transaction) {
+ return;
+ }
+ transaction->callback = callback;
+ transaction->callback_data = data;
+ do_commit_dirty(transaction);
+}
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 @@
#include "sway/decoration.h"
#include "sway/desktop.h"
#include "sway/desktop/transaction.h"
+#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/output.h"
@@ -396,6 +397,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
wl_list_remove(&xdg_shell_view->set_app_id.link);
}
+static void do_rebase(void *data) {
+ struct sway_cursor *cursor = data;
+ cursor_rebase(cursor);
+}
+
static void handle_map(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, map);
@@ -422,7 +428,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
view_map(view, view->wlr_xdg_surface->surface,
xdg_surface->toplevel->client_pending.fullscreen, csd);
- transaction_commit_dirty();
+ struct sway_seat *seat = input_manager_current_seat();
+ transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
xdg_shell_view->commit.notify = handle_commit;
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 @@
#include "sway/decoration.h"
#include "sway/desktop.h"
#include "sway/desktop/transaction.h"
+#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/output.h"
@@ -393,6 +394,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
wl_list_remove(&xdg_shell_v6_view->set_app_id.link);
}
+static void do_rebase(void *data) {
+ struct sway_cursor *cursor = data;
+ cursor_rebase(cursor);
+}
+
static void handle_map(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_v6_view *xdg_shell_v6_view =
wl_container_of(listener, xdg_shell_v6_view, map);
@@ -413,7 +419,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
view_map(view, view->wlr_xdg_surface_v6->surface,
xdg_surface->toplevel->client_pending.fullscreen, csd);
- transaction_commit_dirty();
+ struct sway_seat *seat = input_manager_current_seat();
+ transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
xdg_shell_v6_view->commit.notify = handle_commit;
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 @@
#include "log.h"
#include "sway/desktop.h"
#include "sway/desktop/transaction.h"
+#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/output.h"
@@ -390,6 +391,11 @@ static void handle_unmap(struct wl_listener *listener, void *data) {
wl_list_remove(&xwayland_view->commit.link);
}
+static void do_rebase(void *data) {
+ struct sway_cursor *cursor = data;
+ cursor_rebase(cursor);
+}
+
static void handle_map(struct wl_listener *listener, void *data) {
struct sway_xwayland_view *xwayland_view =
wl_container_of(listener, xwayland_view, map);
@@ -416,7 +422,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
// Put it back into the tree
view_map(view, xsurface->surface, xsurface->fullscreen, false);
- transaction_commit_dirty();
+ struct sway_seat *seat = input_manager_current_seat();
+ transaction_commit_dirty_with_callback(do_rebase, seat->cursor);
}
static void handle_request_configure(struct wl_listener *listener, void *data) {