diff options
author | Bernd Weimer <bernd.weimer@qt.io> | 2022-11-15 16:38:43 +0100 |
---|---|---|
committer | Bernd Weimer <bernd.weimer@qt.io> | 2022-12-01 14:35:32 +0100 |
commit | a7d4f5324b3e80f794a73bbb4f2f4674214cf4a5 (patch) | |
tree | d16fd7abe6c5e7e6ebec02cf4841e7645d19f585 /src | |
parent | 68888133e2aa7dd3ed2ef1c4d1095065749d7e7f (diff) | |
download | qtapplicationmanager-a7d4f5324b3e80f794a73bbb4f2f4674214cf4a5.tar.gz |
Forward keyboard focus to applications
Key events were not passed to applications, when the focus moved to
a WindowItem in the System UI, since the item representing the
application window is actually a child of the WindowItem.
A possible solution would be to explicitly send the key events to the
application item, though the approach taken here is to forward the
keyboard focus. This results in key events always reaching the
application first (even when the System UI would actually consume the
events) and in single-process mode, if the application consumes the
event the System UI won't get it any more.
Fixes: QTBUG-108837
Change-Id: I1699556f1a67057e8be2848e37c846c2ee33a646
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/manager-lib/inprocesssurfaceitem.cpp | 4 | ||||
-rw-r--r-- | src/manager-lib/inprocesssurfaceitem.h | 4 | ||||
-rw-r--r-- | src/window-lib/windowitem.cpp | 42 | ||||
-rw-r--r-- | src/window-lib/windowitem.h | 11 |
4 files changed, 50 insertions, 11 deletions
diff --git a/src/manager-lib/inprocesssurfaceitem.cpp b/src/manager-lib/inprocesssurfaceitem.cpp index 4ae43b83..e18f7ec6 100644 --- a/src/manager-lib/inprocesssurfaceitem.cpp +++ b/src/manager-lib/inprocesssurfaceitem.cpp @@ -25,7 +25,7 @@ static bool isName(const QByteArray &key) } InProcessSurfaceItem::InProcessSurfaceItem(QQuickItem *parent) - : QQuickItem(parent) + : QQuickFocusScope(parent) { QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); setClip(true); @@ -83,7 +83,7 @@ bool InProcessSurfaceItem::eventFilter(QObject *o, QEvent *e) } } - return QQuickItem::eventFilter(o, e); + return QQuickFocusScope::eventFilter(o, e); } void InProcessSurfaceItem::setVisibleClientSide(bool value) diff --git a/src/manager-lib/inprocesssurfaceitem.h b/src/manager-lib/inprocesssurfaceitem.h index 2600ddcc..c0e0fa49 100644 --- a/src/manager-lib/inprocesssurfaceitem.h +++ b/src/manager-lib/inprocesssurfaceitem.h @@ -6,8 +6,8 @@ #pragma once #include <QColor> -#include <QQuickItem> #include <QPointer> +#include <private/qquickfocusscope_p.h> #include <QtAppManCommon/global.h> QT_BEGIN_NAMESPACE_AM @@ -15,7 +15,7 @@ QT_BEGIN_NAMESPACE_AM /* * Item exposed to the System UI */ -class InProcessSurfaceItem : public QQuickItem +class InProcessSurfaceItem : public QQuickFocusScope { Q_OBJECT public: diff --git a/src/window-lib/windowitem.cpp b/src/window-lib/windowitem.cpp index c3dbaee1..5d540624 100644 --- a/src/window-lib/windowitem.cpp +++ b/src/window-lib/windowitem.cpp @@ -7,6 +7,7 @@ #include "window.h" #if defined(AM_MULTI_PROCESS) +#include <QWaylandQuickItem> #include "waylandcompositor.h" #include "waylandwindow.h" #endif // AM_MULTI_PROCESS @@ -108,6 +109,11 @@ WindowItem::WindowItem(QQuickItem *parent) m_contentItem->setZ(2); m_contentItem->setWidth(width()); m_contentItem->setHeight(height()); + + connect(this, &QQuickItem::activeFocusChanged, this, [this] () { + if (hasActiveFocus() && m_impl) + m_impl->forwardActiveFocus(); + }); } WindowItem::~WindowItem() @@ -354,12 +360,36 @@ void WindowItem::InProcessImpl::setupSecondaryView() } } +void WindowItem::InProcessImpl::forwardActiveFocus() +{ + m_inProcessWindow->rootItem()->forceActiveFocus(); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // WindowItem::WaylandImpl /////////////////////////////////////////////////////////////////////////////////////////////////// #if defined(AM_MULTI_PROCESS) +class WaylandQuickIgnoreKeyItem : public QWaylandQuickItem +{ +public: + WaylandQuickIgnoreKeyItem(QQuickItem *parent) : QWaylandQuickItem(parent) {} + +protected: + void keyPressEvent(QKeyEvent *event) override + { + QWaylandQuickItem::keyPressEvent(event); + event->ignore(); + } + + void keyReleaseEvent(QKeyEvent *event) override + { + QWaylandQuickItem::keyReleaseEvent(event); + event->ignore(); + } +}; + WindowItem::WaylandImpl::~WaylandImpl() { delete m_waylandItem; @@ -377,18 +407,26 @@ void WindowItem::WaylandImpl::setup(Window *window) m_waylandItem->setBufferLocked(false); m_waylandItem->setSurface(m_waylandWindow->surface()); + + if (q->hasActiveFocus()) + forwardActiveFocus(); } void WindowItem::WaylandImpl::createWaylandItem() { - m_waylandItem = new QWaylandQuickItem(q); + m_waylandItem = new WaylandQuickIgnoreKeyItem(q); - connect(m_waylandItem, &QWaylandQuickItem::surfaceDestroyed, q, [this]() { + connect(m_waylandItem, &WaylandQuickIgnoreKeyItem::surfaceDestroyed, q, [this]() { // keep the buffer there to allow us to animate the window destruction m_waylandItem->setBufferLocked(true); }); } +void WindowItem::WaylandImpl::forwardActiveFocus() +{ + m_waylandItem->forceActiveFocus(); +} + void WindowItem::WaylandImpl::tearDown() { m_waylandItem->setSurface(nullptr); diff --git a/src/window-lib/windowitem.h b/src/window-lib/windowitem.h index 19989542..33f51258 100644 --- a/src/window-lib/windowitem.h +++ b/src/window-lib/windowitem.h @@ -8,16 +8,13 @@ #include <QQuickItem> #include <QtAppManCommon/global.h> -#if defined(AM_MULTI_PROCESS) -#include <QWaylandQuickItem> -#endif // AM_MULTI_PROCESS - QT_BEGIN_NAMESPACE_AM class Window; class InProcessWindow; #if defined(AM_MULTI_PROCESS) class WaylandWindow; +class WaylandQuickIgnoreKeyItem; #endif // AM_MULTI_PROCESS @@ -57,6 +54,7 @@ public: protected: void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; + signals: void windowChanged(); void primaryChanged(); @@ -78,6 +76,7 @@ private: virtual Window *window() const = 0; virtual void setupPrimaryView() = 0; virtual void setupSecondaryView() = 0; + virtual void forwardActiveFocus() = 0; WindowItem *q; }; @@ -90,6 +89,7 @@ private: Window *window() const override; void setupPrimaryView() override; void setupSecondaryView() override; + void forwardActiveFocus() override; InProcessWindow *m_inProcessWindow{nullptr}; QQuickItem *m_shaderEffectSource{nullptr}; @@ -107,9 +107,10 @@ private: void setupPrimaryView() override; void setupSecondaryView() override; void createWaylandItem(); + void forwardActiveFocus() override; WaylandWindow *m_waylandWindow{nullptr}; - QWaylandQuickItem *m_waylandItem{nullptr}; + WaylandQuickIgnoreKeyItem *m_waylandItem{nullptr}; }; #endif // AM_MULTI_PROCESS |