diff --git a/input.h b/input.h --- a/input.h +++ b/input.h @@ -381,7 +381,7 @@ * @return Toplevel* at device position. **/ QPointer at() const { - return m_at; + return m_at.at; } /** * @brief Toplevel currently having pointer input focus (this might @@ -451,7 +451,11 @@ QWindow* findInternalWindow(const QPoint &pos) const; - QPointer m_at; + struct { + QPointer at; + QMetaObject::Connection surfaceCreatedConnection; + } m_at; + struct { QPointer focus; QPointer decoration; diff --git a/input.cpp b/input.cpp --- a/input.cpp +++ b/input.cpp @@ -2229,11 +2229,14 @@ bool InputDeviceHandler::setAt(Toplevel *toplevel) { - if (m_at == toplevel) { + if (m_at.at == toplevel) { return false; } - auto old = m_at; - m_at = toplevel; + auto old = m_at.at; + disconnect(m_at.surfaceCreatedConnection); + m_at.surfaceCreatedConnection = QMetaObject::Connection(); + + m_at.at = toplevel; emit atChanged(old, toplevel); return true; } @@ -2261,16 +2264,26 @@ void InputDeviceHandler::updateFocus() { auto oldFocus = m_focus.focus; - m_focus.focus = m_at; + + if (m_at.at && !m_at.at->surface()) { + if (!m_at.surfaceCreatedConnection) { + m_at.surfaceCreatedConnection = connect(m_at.at, &Toplevel::surfaceChanged, + this, &InputDeviceHandler::update); + } + m_focus.focus = nullptr; + } else { + m_focus.focus = m_at.at; + } + focusUpdate(oldFocus, m_focus.focus); } bool InputDeviceHandler::updateDecoration() { const auto oldDeco = m_focus.decoration; m_focus.decoration = nullptr; - auto *ac = qobject_cast(m_at); + auto *ac = qobject_cast(m_at.at); if (ac && ac->decoratedClient()) { const QRect clientRect = QRect(ac->clientPos(), ac->clientSize()).translated(ac->pos()); if (!clientRect.contains(position().toPoint())) { @@ -2338,7 +2351,7 @@ } updateInternalWindow(nullptr); - if (m_focus.focus != m_at) { + if (m_focus.focus != m_at.at) { // focus change updateDecoration(); updateFocus();