Browse Source

Merge pull request #106414 from Riteo/unexpected-frame

Wayland: Fix stuck pointer buttons on window leave
Thaddeus Crews 3 months ago
parent
commit
856d7108e0
1 changed files with 16 additions and 4 deletions
  1. 16 4
      platform/linuxbsd/wayland/wayland_thread.cpp

+ 16 - 4
platform/linuxbsd/wayland/wayland_thread.cpp

@@ -1728,16 +1728,28 @@ void WaylandThread::_wl_pointer_on_frame(void *data, struct wl_pointer *wl_point
 		}
 		}
 	}
 	}
 
 
-	if (pd.pointed_id == DisplayServer::INVALID_WINDOW_ID) {
+	WindowState *ws = nullptr;
+
+	// NOTE: At least on sway, with wl_pointer version 5 or greater,
+	// wl_pointer::leave might be emitted with other events (like
+	// wl_pointer::button) within the same wl_pointer::frame. Because of this, we
+	// need to account for when the currently pointed window might be invalid
+	// (third-party or even none) and fall back to the old one.
+	if (pd.pointed_id != DisplayServer::INVALID_WINDOW_ID) {
+		ws = ss->wayland_thread->window_get_state(pd.pointed_id);
+		ERR_FAIL_NULL(ws);
+	} else if (old_pd.pointed_id != DisplayServer::INVALID_WINDOW_ID) {
+		ws = ss->wayland_thread->window_get_state(old_pd.pointed_id);
+		ERR_FAIL_NULL(ws);
+	}
+
+	if (ws == nullptr) {
 		// We're probably on a decoration or some other third-party thing. Let's
 		// We're probably on a decoration or some other third-party thing. Let's
 		// "commit" the data and call it a day.
 		// "commit" the data and call it a day.
 		old_pd = pd;
 		old_pd = pd;
 		return;
 		return;
 	}
 	}
 
 
-	WindowState *ws = ss->wayland_thread->window_get_state(pd.pointed_id);
-	ERR_FAIL_NULL(ws);
-
 	double scale = window_state_get_scale_factor(ws);
 	double scale = window_state_get_scale_factor(ws);
 
 
 	wayland_thread->_set_current_seat(ss->wl_seat);
 	wayland_thread->_set_current_seat(ss->wl_seat);