From 93c09bcafbc6f2accd11d34433dc475822ba7712 Mon Sep 17 00:00:00 2001
From: Johan Klokkhammer Helsing <johan.helsing@qt.io>
Date: Wed, 24 Aug 2016 16:08:56 +0200
Subject: [PATCH] Client: Fix keyboard focus logic and crash

The previous solution did not check for nullptr before dereferencing, which
caused a crash. Furthermore, it checked the new ShellSurface's
shellManagesActiveState before deciding whether to unfocus the old one.

Task-number: QTBUG-55526
Change-Id: I410b6200a5b7b86806f70970730045a4a25f21db
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
---
 src/client/qwaylanddisplay.cpp | 17 ++++++++++-------
 src/client/qwaylandwindow.cpp  |  5 +++++
 src/client/qwaylandwindow_p.h  |  2 ++
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index 7225d24a..ae28eb77 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -399,13 +399,16 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
 {
     QWaylandWindow *keyboardFocus = inputDevice->keyboardFocus();
 
-    if (!keyboardFocus->shellSurface()->shellManagesActiveState() && mLastKeyboardFocus != keyboardFocus) {
-        if (keyboardFocus)
-            handleWindowActivated(keyboardFocus);
-        if (mLastKeyboardFocus)
-            handleWindowDeactivated(mLastKeyboardFocus);
-    }
-    mLastKeyboardFocus = inputDevice->keyboardFocus();
+    if (mLastKeyboardFocus == keyboardFocus)
+        return;
+
+    if (keyboardFocus && !keyboardFocus->shellManagesActiveState())
+        handleWindowActivated(keyboardFocus);
+
+    if (mLastKeyboardFocus && !mLastKeyboardFocus->shellManagesActiveState())
+        handleWindowDeactivated(mLastKeyboardFocus);
+
+    mLastKeyboardFocus = keyboardFocus;
 }
 
 void QWaylandDisplay::handleWaylandSync()
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index aba67653..8885c0e5 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -500,6 +500,11 @@ QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const
     return mSubSurfaceWindow;
 }
 
+bool QWaylandWindow::shellManagesActiveState() const
+{
+    return mShellSurface && mShellSurface->shellManagesActiveState();
+}
+
 void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
 {
     if (mDisplay->compositorVersion() < 2)
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index c60891d4..d7e79515 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -136,6 +136,8 @@ public:
     QWaylandSubSurface *subSurfaceWindow() const;
     QWaylandScreen *screen() const { return mScreen; }
 
+    bool shellManagesActiveState() const;
+
     void handleContentOrientationChange(Qt::ScreenOrientation orientation) Q_DECL_OVERRIDE;
     void setOrientationMask(Qt::ScreenOrientations mask);
 
-- 
GitLab