From 8533c35a9f15288bb9bade57d972cf0ad0724ec4 Mon Sep 17 00:00:00 2001
From: Ryan Dwyer <ryandwyer1@gmail.com>
Date: Thu, 19 Jul 2018 19:49:50 +1000
Subject: Fix crash and render issues involving cursor_send_pointer_motion

Fixes #2303, as well as a crash.

To replicate the crash:

* Have multiple outputs
* In config: for_window [<criteria>] workspace foo
* Also in config: workspace foo output <left-output-name>
* Focus the right output, and ensure workspace foo doesn't exist
* Launch the app that triggers the criteria

When the view maps, it calls workspace_switch which calls
send_set_focus which calls cursor_send_pointer_motion which calls
transaction_commit_dirty. This call to transaction_commit_dirty is not
meant to happen at this time because the tree isn't guaranteed to be in
a consistent state, but I'm not sure how exactly this leads to the crash
or render issues.

In this case the transaction is already committed by the view
implementation's handle_map function. So the solution is to remove it
from cursor_send_pointer_motion and add it to the other functions in
cursor.c which call cursor_send_pointer_motion.
---
 sway/input/cursor.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'sway')

diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 7a9f3ed7..c76c20b3 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -220,7 +220,6 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
 		struct sway_drag_icon *drag_icon = wlr_drag_icon->data;
 		drag_icon_update_position(drag_icon);
 	}
-	transaction_commit_dirty();
 }
 
 static void handle_cursor_motion(struct wl_listener *listener, void *data) {
@@ -230,6 +229,7 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) {
 	wlr_cursor_move(cursor->cursor, event->device,
 		event->delta_x, event->delta_y);
 	cursor_send_pointer_motion(cursor, event->time_msec, true);
+	transaction_commit_dirty();
 }
 
 static void handle_cursor_motion_absolute(
@@ -240,6 +240,7 @@ static void handle_cursor_motion_absolute(
 	struct wlr_event_pointer_motion_absolute *event = data;
 	wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
 	cursor_send_pointer_motion(cursor, event->time_msec, true);
+	transaction_commit_dirty();
 }
 
 void dispatch_cursor_button(struct sway_cursor *cursor,
@@ -426,6 +427,7 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) {
 
 	wlr_cursor_warp_absolute(cursor->cursor, event->device, x, y);
 	cursor_send_pointer_motion(cursor, event->time_msec, true);
+	transaction_commit_dirty();
 }
 
 static void handle_tool_tip(struct wl_listener *listener, void *data) {
-- 
cgit v1.2.3