From 76549a9f998d79f819cbc82d1f51b788c704f7cc Mon Sep 17 00:00:00 2001 From: Michail Vourlakos Date: Thu, 13 May 2021 20:09:05 +0300 Subject: [PATCH] shortcuts:wait for view to fully shown properly --the new approach is not using timers but actual events from View in order to identify when the view is fully shown and when their popup is actual visible. This way popup showing and view slide-in is always synchronized properly BUG:425078 --- app/shortcuts/globalshortcuts.cpp | 56 +++++++++++-------- app/shortcuts/globalshortcuts.h | 2 + app/view/containmentinterface.cpp | 2 +- app/view/view.cpp | 5 ++ app/view/visibilitymanager.cpp | 5 ++ app/view/visibilitymanager.h | 1 + .../package/contents/ui/abilities/Indexer.qml | 10 ++-- 7 files changed, 52 insertions(+), 29 deletions(-) diff --git a/app/shortcuts/globalshortcuts.cpp b/app/shortcuts/globalshortcuts.cpp index b0d94246d..ed9d383ec 100644 --- a/app/shortcuts/globalshortcuts.cpp +++ b/app/shortcuts/globalshortcuts.cpp @@ -52,12 +52,9 @@ #include #include -#define SHORTCUTBLOCKHIDINGTYPE "globalshortcuts::blockHiding()" namespace Latte { -const int APPLETEXECUTIONDELAY = 400; - GlobalShortcuts::GlobalShortcuts(QObject *parent) : QObject(parent) { @@ -249,16 +246,21 @@ void GlobalShortcuts::activateLauncherMenu() Latte::View *highestPriorityView = highestApplicationLauncherView(sortedViews); if (highestPriorityView) { - if (highestPriorityView->visibility()->isHidden() && highestPriorityView->extendedInterface()->applicationLauncherInPopup()) { + if (!highestPriorityView->visibility()->isShownFully() && highestPriorityView->extendedInterface()->applicationLauncherInPopup()) { m_lastInvokedAction = m_singleMetaAction; + //! wait for view to fully shown + connect(highestPriorityView->visibility(), &Latte::ViewPart::VisibilityManager::isShownFullyChanged, this, [&, highestPriorityView](){ + if (highestPriorityView->visibility()->isShownFully()) { + highestPriorityView->extendedInterface()->toggleAppletExpanded(highestPriorityView->extendedInterface()->applicationLauncherId()); + //!remove that signal tracking + disconnect(highestPriorityView->visibility(), &Latte::ViewPart::VisibilityManager::isShownFullyChanged, this, nullptr); + } + }); + + //! That signal is removed from Latte::View only when the popup is really shown! highestPriorityView->visibility()->addBlockHidingEvent(SHORTCUTBLOCKHIDINGTYPE); - //! delay the execution in order to show first the view - QTimer::singleShot(APPLETEXECUTIONDELAY, [this, highestPriorityView]() { - highestPriorityView->extendedInterface()->toggleAppletExpanded(highestPriorityView->extendedInterface()->applicationLauncherId()); - highestPriorityView->visibility()->removeBlockHidingEvent(SHORTCUTBLOCKHIDINGTYPE); - }); } else { highestPriorityView->extendedInterface()->toggleAppletExpanded(highestPriorityView->extendedInterface()->applicationLauncherId()); } @@ -270,13 +272,17 @@ bool GlobalShortcuts::activatePlasmaTaskManager(const Latte::View *view, int ind bool activation{modifier == static_cast(Qt::META)}; bool newInstance{!activation}; - if (view->visibility()->isHidden()) { - //! delay the execution in order to show first the view - QTimer::singleShot(APPLETEXECUTIONDELAY, [this, view, index, activation]() { - if (activation) { - view->extendedInterface()->activatePlasmaTask(index); - } else { - view->extendedInterface()->newInstanceForPlasmaTask(index); + if (!view->visibility()->isShownFully()) { + //! wait for view to fully shown + connect(view->visibility(), &Latte::ViewPart::VisibilityManager::isShownFullyChanged, this, [&, view, index, activation](){ + if (view->visibility()->isShownFully()) { + if (activation) { + view->extendedInterface()->activatePlasmaTask(index); + } else { + view->extendedInterface()->newInstanceForPlasmaTask(index); + } + //!remove that signal tracking + disconnect(view->visibility(), &Latte::ViewPart::VisibilityManager::isShownFullyChanged, this, nullptr); } }); @@ -298,13 +304,17 @@ bool GlobalShortcuts::activateLatteEntry(Latte::View *view, int index, Qt::Key m int appletId = view->extendedInterface()->appletIdForVisualIndex(index); bool hasPopUp {(appletId>-1 && view->extendedInterface()->appletIsExpandable(appletId))}; - if (view->visibility()->isHidden() && hasPopUp) { - //! delay the execution in order to show first the view - QTimer::singleShot(APPLETEXECUTIONDELAY, [this, view, index, activation]() { - if (activation) { - view->extendedInterface()->activateEntry(index); - } else { - view->extendedInterface()->newInstanceForEntry(index); + if (!view->visibility()->isShownFully() && hasPopUp) { + //! wait for view to fully shown + connect(view->visibility(), &Latte::ViewPart::VisibilityManager::isShownFullyChanged, this, [&, view, index, activation](){ + if (view->visibility()->isShownFully()) { + if (activation) { + view->extendedInterface()->activateEntry(index); + } else { + view->extendedInterface()->newInstanceForEntry(index); + } + //!remove that signal tracking + disconnect(view->visibility(), &Latte::ViewPart::VisibilityManager::isShownFullyChanged, this, nullptr); } }); diff --git a/app/shortcuts/globalshortcuts.h b/app/shortcuts/globalshortcuts.h index 5f643d164..e2ae50e6e 100644 --- a/app/shortcuts/globalshortcuts.h +++ b/app/shortcuts/globalshortcuts.h @@ -53,6 +53,8 @@ class GlobalShortcuts : public QObject Q_OBJECT public: + static constexpr const char* SHORTCUTBLOCKHIDINGTYPE = "globalshortcuts::blockHiding()"; + GlobalShortcuts(QObject *parent = nullptr); ~GlobalShortcuts() override; diff --git a/app/view/containmentinterface.cpp b/app/view/containmentinterface.cpp index db7c7a19f..bd7468d5d 100644 --- a/app/view/containmentinterface.cpp +++ b/app/view/containmentinterface.cpp @@ -402,7 +402,7 @@ int ContainmentInterface::appletIdForVisualIndex(const int index) identifyShortcutsHost(); if (!m_appletIdForIndexMethod.isValid()) { - return false; + return -1; } QVariant appletId{-1}; diff --git a/app/view/view.cpp b/app/view/view.cpp index 028c14baa..ae89d78c8 100644 --- a/app/view/view.cpp +++ b/app/view/view.cpp @@ -695,6 +695,11 @@ void View::addTransientWindow(QWindow *window) QString winPtrStr = "0x" + QString::number((qulonglong)window,16); m_visibility->addBlockHidingEvent(winPtrStr); + + if (m_visibility->hasBlockHidingEvent(Latte::GlobalShortcuts::SHORTCUTBLOCKHIDINGTYPE)) { + m_visibility->removeBlockHidingEvent(Latte::GlobalShortcuts::SHORTCUTBLOCKHIDINGTYPE); + } + connect(window, &QWindow::visibleChanged, this, &View::removeTransientWindow); } } diff --git a/app/view/visibilitymanager.cpp b/app/view/visibilitymanager.cpp index 2e70dc0cd..936e47d20 100644 --- a/app/view/visibilitymanager.cpp +++ b/app/view/visibilitymanager.cpp @@ -530,6 +530,11 @@ void VisibilityManager::setIsFloatingGapWindowEnabled(bool enabled) emit isFloatingGapWindowEnabledChanged(); } +bool VisibilityManager::hasBlockHidingEvent(const QString &type) +{ + return (!type.isEmpty() && m_blockHidingEvents.contains(type)); +} + void VisibilityManager::addBlockHidingEvent(const QString &type) { if (m_blockHidingEvents.contains(type) || type.isEmpty()) { diff --git a/app/view/visibilitymanager.h b/app/view/visibilitymanager.h index 82a2ea448..47ac5f391 100644 --- a/app/view/visibilitymanager.h +++ b/app/view/visibilitymanager.h @@ -115,6 +115,7 @@ public: int timerHide() const; void setTimerHide(int msec); + bool hasBlockHidingEvent(const QString &type); bool isSidebar() const; //! KWin Edges Support functions diff --git a/containment/package/contents/ui/abilities/Indexer.qml b/containment/package/contents/ui/abilities/Indexer.qml index 5accf64c2..0cdca5edc 100644 --- a/containment/package/contents/ui/abilities/Indexer.qml +++ b/containment/package/contents/ui/abilities/Indexer.qml @@ -51,25 +51,25 @@ Ability.IndexerPrivate { var appletItem = sLayout.children[i]; if (visibleIndexBelongsAtApplet(appletItem, itemVisibleIndex)) { - return appletItem.index; + return appletItem.applet ? appletItem.applet.id : -1; } } var mLayout = layouts.mainLayout; for (var i=0; i