From 259e373bfc93d713b875987de0e1559e8f2beb13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 12 Apr 2017 18:14:37 +0200 Subject: [PATCH] [tabbox] Expose noModifierGrab to QtQuick Summary: There is a special mode in TabBox which is the noModifierGrab mode. This is Alt+Tab active without a modifier being hold. This mode is entered when being activated through screen edges (either pointer or touch). So far this was not exposed to QtQuick and thus one could not end the mode using pointer or touch. It is possible to select another window, but not to activate it. That required the press of a keyboard key. This setup is rather unfortunate. By exposing the mode to QtQuick we can react from QtQuick side to it and invoke already exposed functionality to select and item and directly activate it - existing left-over from the Plasma Active window switcher. Test Plan: Tested on X11 and Wayland with an adjusted lnf package. It kind of works, but there are additional issues on both X11 and Wayland. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D5414 --- autotests/tabbox/mock_tabboxhandler.h | 4 ++++ tabbox/switcheritem.cpp | 9 +++++++++ tabbox/switcheritem.h | 7 +++++++ tabbox/tabbox.cpp | 5 +++++ tabbox/tabbox.h | 5 +++++ tabbox/tabboxhandler.cpp | 1 + tabbox/tabboxhandler.h | 6 ++++++ 7 files changed, 37 insertions(+) diff --git a/autotests/tabbox/mock_tabboxhandler.h b/autotests/tabbox/mock_tabboxhandler.h index b76a9f86b5..4820a3d6af 100644 --- a/autotests/tabbox/mock_tabboxhandler.h +++ b/autotests/tabbox/mock_tabboxhandler.h @@ -98,6 +98,10 @@ public: Q_UNUSED(controller) } + bool noModifierGrab() const override { + return false; + } + // mock methods QWeakPointer createMockWindow(const QString &caption, WId id); void closeWindow(TabBox::TabBoxClient *client); diff --git a/tabbox/switcheritem.cpp b/tabbox/switcheritem.cpp index 47a33e5cfb..cce4336722 100644 --- a/tabbox/switcheritem.cpp +++ b/tabbox/switcheritem.cpp @@ -102,5 +102,14 @@ void SwitcherItem::setAllDesktops(bool all) emit allDesktopsChanged(); } +void SwitcherItem::setNoModifierGrab(bool set) +{ + if (m_noModifierGrab == set) { + return; + } + m_noModifierGrab = set; + emit noModifierGrabChanged(); +} + } } diff --git a/tabbox/switcheritem.h b/tabbox/switcheritem.h index a04cb1bdc7..4464a7f979 100644 --- a/tabbox/switcheritem.h +++ b/tabbox/switcheritem.h @@ -38,6 +38,7 @@ class SwitcherItem : public QObject Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged) Q_PROPERTY(bool allDesktops READ isAllDesktops NOTIFY allDesktopsChanged) Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged) + Q_PROPERTY(bool noModifierGrab READ noModifierGrab NOTIFY noModifierGrabChanged) /** * The main QML item that will be displayed in the Dialog @@ -57,11 +58,15 @@ public: void setCurrentIndex(int index); QObject *item() const; void setItem(QObject *item); + bool noModifierGrab() const { + return m_noModifierGrab; + } // for usage from outside void setModel(QAbstractItemModel *model); void setAllDesktops(bool all); void setVisible(bool visible); + void setNoModifierGrab(bool set); Q_SIGNALS: void visibleChanged(); @@ -70,6 +75,7 @@ Q_SIGNALS: void allDesktopsChanged(); void screenGeometryChanged(); void itemChanged(); + void noModifierGrabChanged(); private: QAbstractItemModel *m_model; @@ -78,6 +84,7 @@ private: bool m_allDesktops; int m_currentIndex; QMetaObject::Connection m_selectedIndexConnection; + bool m_noModifierGrab = false; }; inline QAbstractItemModel *SwitcherItem::model() const diff --git a/tabbox/tabbox.cpp b/tabbox/tabbox.cpp index 014c09b7b1..4dc2a599a3 100644 --- a/tabbox/tabbox.cpp +++ b/tabbox/tabbox.cpp @@ -359,6 +359,11 @@ void TabBoxHandlerImpl::highlightWindows(TabBoxClient *window, QWindow *controll static_cast(effects)->highlightWindows(windows); } +bool TabBoxHandlerImpl::noModifierGrab() const +{ + return m_tabBox->noModifierGrab(); +} + /********************************************************* * TabBoxClientImpl *********************************************************/ diff --git a/tabbox/tabbox.h b/tabbox/tabbox.h index bdc02a6fcc..012cd815da 100644 --- a/tabbox/tabbox.h +++ b/tabbox/tabbox.h @@ -75,6 +75,7 @@ public: virtual QWeakPointer< TabBoxClient > desktopClient() const; virtual void activateAndClose(); void highlightWindows(TabBoxClient *window = nullptr, QWindow *controller = nullptr) override; + bool noModifierGrab() const override; private: bool checkDesktop(TabBoxClient* client, int desktop) const; @@ -187,6 +188,10 @@ public: return m_forcedGlobalMouseGrab; } + bool noModifierGrab() const { + return m_noModifierGrab; + } + static TabBox *self(); static TabBox *create(QObject *parent); diff --git a/tabbox/tabboxhandler.cpp b/tabbox/tabboxhandler.cpp index afaf5a12f2..9edfca2e54 100644 --- a/tabbox/tabboxhandler.cpp +++ b/tabbox/tabboxhandler.cpp @@ -337,6 +337,7 @@ void TabBoxHandlerPrivate::show() } item->setAllDesktops(config.clientDesktopMode() == TabBoxConfig::AllDesktopsClients); item->setCurrentIndex(indexRow); + item->setNoModifierGrab(q->noModifierGrab()); // everything is prepared, so let's make the whole thing visible item->setVisible(true); } diff --git a/tabbox/tabboxhandler.h b/tabbox/tabboxhandler.h index 3400af4217..040a2f294b 100644 --- a/tabbox/tabboxhandler.h +++ b/tabbox/tabboxhandler.h @@ -336,6 +336,12 @@ public: bool eventFilter(QObject *watcher, QEvent *event) override; + /** + * @returns whether the TabBox operates in a no modifier grab mode. + * In this mode a click on an item should directly accept and close the tabbox. + **/ + virtual bool noModifierGrab() const = 0; + Q_SIGNALS: /** * This signal is fired when the TabBoxConfig changes