From eb1d6f4c8673b8f9c34748c8764d92e5da31971c Mon Sep 17 00:00:00 2001
From: Johan Klokkhammer Helsing <johan.helsing@qt.io>
Date: Mon, 10 Oct 2016 17:52:15 +0200
Subject: [PATCH] Client: Remove windows from keyboard focus list when
 destroyed

This fixes the undefined behavior in tst_WaylandClient::touchDrag and mouseDrag

Note: The test still fails if run twice in a row, but it appears to be
deterministic.

Task-number: QTBUG-56187
Change-Id: Ib45d82224f004d1324f2ce4d6b7df05ee36c04f5
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
(cherry picked from commit 0049240a2b7d8691f09224e1542919ddbbb0d864)
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
---
 src/client/qwaylanddisplay.cpp | 6 ++++++
 src/client/qwaylanddisplay_p.h | 3 ++-
 src/client/qwaylandwindow.cpp  | 2 ++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index ae28eb77..f9a556f4 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -411,6 +411,12 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
     mLastKeyboardFocus = keyboardFocus;
 }
 
+void QWaylandDisplay::handleWindowDestroyed(QWaylandWindow *window)
+{
+    if (mActiveWindows.contains(window))
+        handleWindowDeactivated(window);
+}
+
 void QWaylandDisplay::handleWaylandSync()
 {
     // This callback is used to set the window activation because we may get an activate/deactivate
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index ea127d2f..a6591648 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -170,6 +170,7 @@ public:
     void handleWindowActivated(QWaylandWindow *window);
     void handleWindowDeactivated(QWaylandWindow *window);
     void handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice);
+    void handleWindowDestroyed(QWaylandWindow *window);
 
 public slots:
     void blockingReadEvents();
@@ -211,7 +212,7 @@ private:
     uint32_t mLastInputSerial;
     QWaylandInputDevice *mLastInputDevice;
     QPointer<QWaylandWindow> mLastInputWindow;
-    QWaylandWindow *mLastKeyboardFocus;
+    QPointer<QWaylandWindow> mLastKeyboardFocus;
     QVector<QWaylandWindow *> mActiveWindows;
     struct wl_callback *mSyncCallback;
     static const wl_callback_listener syncCallbackListener;
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index a1daa07f..e504de37 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -93,6 +93,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
 
 QWaylandWindow::~QWaylandWindow()
 {
+    mDisplay->handleWindowDestroyed(this);
+
     delete mWindowDecoration;
 
     if (isInitialized())
-- 
GitLab