1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-03-09 00:58:15 +03:00

refactor:move qml handling from globalshortcuts

--all the qml handling code from globalshortcuts is
now moved to Latte::View::ContaimentInterface. This
way the code is cleaner and can be expanded easier.
This commit is contained in:
Michail Vourlakos 2019-12-21 18:53:02 +02:00
parent 5fff947091
commit 111254e509
7 changed files with 469 additions and 348 deletions

View File

@ -28,6 +28,7 @@
#include "../layouts/manager.h"
#include "../layouts/synchronizer.h"
#include "../settings/universalsettings.h"
#include "../view/containmentinterface.h"
#include "../view/view.h"
// C++
@ -221,154 +222,71 @@ void GlobalShortcuts::activateLauncherMenu()
}
for (const auto view : sortedViews) {
const auto applets = view->containment()->applets();
for (auto applet : applets) {
const auto provides = applet->kPackage().metadata().value(QStringLiteral("X-Plasma-Provides"));
if (provides.contains(QLatin1String("org.kde.plasma.launchermenu"))) {
if (view->visibility()->isHidden()) {
if (!m_hideViews.contains(view)) {
m_hideViews.append(view);
}
m_lastInvokedAction = m_singleMetaAction;
view->visibility()->setBlockHiding(true);
//! delay the execution in order to show first the view
QTimer::singleShot(APPLETEXECUTIONDELAY, [this, view, applet]() {
view->toggleAppletExpanded(applet->id());
});
m_hideViewsTimer.start();
} else {
view->toggleAppletExpanded(applet->id());
if (view->interface()->containsApplicationLauncher()) {
if (view->visibility()->isHidden()) {
if (!m_hideViews.contains(view)) {
m_hideViews.append(view);
}
return;
m_lastInvokedAction = m_singleMetaAction;
view->visibility()->setBlockHiding(true);
//! delay the execution in order to show first the view
QTimer::singleShot(APPLETEXECUTIONDELAY, [this, view]() {
view->toggleAppletExpanded(view->interface()->applicationLauncherId());
});
m_hideViewsTimer.start();
} else {
view->toggleAppletExpanded(view->interface()->applicationLauncherId());
}
return;
}
}
}
bool GlobalShortcuts::activatePlasmaTaskManagerEntryAtContainment(const Plasma::Containment *c, int index, Qt::Key modifier)
bool GlobalShortcuts::activatePlasmaTaskManager(const Latte::View *view, int index, Qt::Key modifier)
{
const auto &applets = c->applets();
bool activation{modifier == static_cast<Qt::Key>(Qt::META)};
bool newInstance{!activation};
for (auto *applet : applets) {
const auto &provides = KPluginMetaData::readStringList(applet->pluginMetaData().rawData(), QStringLiteral("X-Plasma-Provides"));
if (provides.contains(QLatin1String("org.kde.plasma.multitasking"))) {
if (QQuickItem *appletInterface = applet->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = appletInterface->childItems();
if (childItems.isEmpty()) {
continue;
}
KPluginMetaData meta = applet->kPackage().metadata();
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = modifier == static_cast<Qt::Key>(Qt::META) ?
metaObject->indexOfMethod("activateTaskAtIndex(QVariant)") :
metaObject->indexOfMethod("newInstanceForTaskAtIndex(QVariant)");
int methodIndex2 = metaObject->indexOfMethod("setShowTaskShortcutBadges(QVariant)");
if (methodIndex == -1 || (methodIndex2 == -1 && meta.pluginId() == "org.kde.latte.plasmoid")) {
continue;
}
int showMethodIndex = -1;
if (!m_viewItemsCalled.contains(item)) {
m_viewItemsCalled.append(item);
m_showShortcutBadgesMethods.append(metaObject->method(methodIndex));
showMethodIndex = m_showShortcutBadgesMethods.count() - 1;
} else {
showMethodIndex = m_showShortcutBadgesMethods.indexOf(metaObject->method(methodIndex));
}
QMetaMethod method = metaObject->method(methodIndex);
if (method.invoke(item, Q_ARG(QVariant, index - 1))) {
if (methodIndex2 != -1) {
m_showShortcutBadgesMethods[showMethodIndex].invoke(item, Q_ARG(QVariant, true));
}
return true;
}
}
}
if (view->visibility()->isHidden()) {
//! delay the execution in order to show first the view
QTimer::singleShot(APPLETEXECUTIONDELAY, [this, view, index, activation]() {
if (activation) {
view->interface()->activatePlasmaTask(index);
} else {
view->interface()->newInstanceForPlasmaTask(index);
}
}
}
});
return false;
return true;
} else {
return (activation ? view->interface()->activatePlasmaTask(index) : view->interface()->newInstanceForPlasmaTask(index));
}
}
bool GlobalShortcuts::activateLatteEntryAtContainment(const Latte::View *view, int index, Qt::Key modifier)
bool GlobalShortcuts::activateLatteEntry(const Latte::View *view, int index, Qt::Key modifier)
{
if (QQuickItem *containmentInterface = view->containment()->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = containmentInterface->childItems();
bool activation{modifier == static_cast<Qt::Key>(Qt::META)};
bool newInstance{!activation};
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = modifier == static_cast<Qt::Key>(Qt::META) ?
metaObject->indexOfMethod("activateEntryAtIndex(QVariant)") :
metaObject->indexOfMethod("newInstanceForEntryAtIndex(QVariant)");
int methodIndex2 = metaObject->indexOfMethod("setShowAppletShortcutBadges(QVariant,QVariant,QVariant,QVariant)");
if (methodIndex == -1 || (methodIndex2 == -1)) {
continue;
}
int appLauncher = m_corona->universalSettings()->kwin_metaForwardedToLatte() ?
applicationLauncherId(view->containment()) : -1;
int showMethodIndex = -1;
if (!m_viewItemsCalled.contains(item)) {
m_viewItemsCalled.append(item);
m_showShortcutBadgesMethods.append(metaObject->method(methodIndex2));
showMethodIndex = m_showShortcutBadgesMethods.count() - 1;
} else {
showMethodIndex = m_showShortcutBadgesMethods.indexOf(metaObject->method(methodIndex2));
}
QMetaMethod method = metaObject->method(methodIndex);
if (view->visibility()->isHidden()) {
//! delay the execution in order to show first the view
QTimer::singleShot(APPLETEXECUTIONDELAY, [this, item, method, index]() {
method.invoke(item, Q_ARG(QVariant, index));
});
return true;
} else {
if (method.invoke(item, Q_ARG(QVariant, index))) {
return true;
}
}
if (view->visibility()->isHidden()) {
//! delay the execution in order to show first the view
QTimer::singleShot(APPLETEXECUTIONDELAY, [this, view, index, activation]() {
if (activation) {
view->interface()->activateEntry(index);
} else {
view->interface()->newInstanceForEntry(index);
}
}
}
});
return false;
return true;
} else {
return (activation ? view->interface()->activateEntry(index) : view->interface()->newInstanceForEntry(index));
}
}
@ -390,8 +308,8 @@ void GlobalShortcuts::activateEntry(int index, Qt::Key modifier)
}
if ((!view->latteTasksArePresent() && view->tasksPresent() &&
activatePlasmaTaskManagerEntryAtContainment(view->containment(), index, modifier))
|| activateLatteEntryAtContainment(view, index, modifier)) {
activatePlasmaTaskManager(view, index, modifier))
|| activateLatteEntry(view, index, modifier)) {
if (!m_hideViews.contains(view)) {
m_hideViews.append(view);
@ -408,49 +326,6 @@ void GlobalShortcuts::activateEntry(int index, Qt::Key modifier)
//! update badge for specific view item
void GlobalShortcuts::updateViewItemBadge(QString identifier, QString value)
{
//qDebug() << "DBUS CALL ::: " << identifier << " - " << value;
auto updateBadgeForTaskInContainment = [this](const Plasma::Containment * c, QString identifier, QString value) {
const auto &applets = c->applets();
for (auto *applet : applets) {
KPluginMetaData meta = applet->kPackage().metadata();
if (meta.pluginId() == "org.kde.latte.plasmoid") {
if (QQuickItem *appletInterface = applet->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = appletInterface->childItems();
if (childItems.isEmpty()) {
continue;
}
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject->indexOfMethod("updateBadge(QVariant,QVariant)");
if (methodIndex == -1) {
continue;
}
QMetaMethod method = metaObject->method(methodIndex);
if (method.invoke(item, Q_ARG(QVariant, identifier), Q_ARG(QVariant, value))) {
return true;
}
}
}
}
}
}
return false;
};
CentralLayout *currentLayout = m_corona->layoutsManager()->currentLayout();
QList<Latte::View *> views;
@ -460,57 +335,10 @@ void GlobalShortcuts::updateViewItemBadge(QString identifier, QString value)
// update badges in all Latte Tasks plasmoids
for (const auto &view : views) {
updateBadgeForTaskInContainment(view->containment(), identifier, value);
view->interface()->updateBadgeForLatteTask(identifier, value);
}
}
bool GlobalShortcuts::isCapableToShowShortcutBadges(Latte::View *view)
{
if (!view->latteTasksArePresent() && view->tasksPresent()) {
return false;
}
const Plasma::Containment *c = view->containment();
if (QQuickItem *containmentInterface = c->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = containmentInterface->childItems();
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject->indexOfMethod("setShowAppletShortcutBadges(QVariant,QVariant,QVariant,QVariant)");
if (methodIndex == -1) {
continue;
}
return true;
}
}
}
return false;
}
int GlobalShortcuts::applicationLauncherId(const Plasma::Containment *c)
{
const auto applets = c->applets();
for (auto applet : applets) {
const auto provides = applet->kPackage().metadata().value(QStringLiteral("X-Plasma-Provides"));
if (provides.contains(QLatin1String("org.kde.plasma.launchermenu"))) {
return applet->id();
}
}
return -1;
}
void GlobalShortcuts::showViews()
{
m_lastInvokedAction = dynamic_cast<QAction *>(sender());
@ -519,95 +347,6 @@ void GlobalShortcuts::showViews()
m_lastInvokedAction = m_singleMetaAction;
}
auto invokeShowShortcuts = [this](const Plasma::Containment * c, const bool showLatteShortcuts, const bool showMeta) {
if (QQuickItem *containmentInterface = c->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = containmentInterface->childItems();
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject->indexOfMethod("setShowAppletShortcutBadges(QVariant,QVariant,QVariant,QVariant)");
if (methodIndex == -1) {
continue;
}
int appLauncher = m_corona->universalSettings()->kwin_metaForwardedToLatte() && showMeta ?
applicationLauncherId(c) : -1;
int showMethodIndex = -1;
if (!m_viewItemsCalled.contains(item)) {
m_viewItemsCalled.append(item);
m_showShortcutBadgesMethods.append(metaObject->method(methodIndex));
showMethodIndex = m_showShortcutBadgesMethods.count() - 1;
} else {
showMethodIndex = m_showShortcutBadgesMethods.indexOf(metaObject->method(methodIndex));
}
if (m_showShortcutBadgesMethods[showMethodIndex].invoke(item,
Q_ARG(QVariant, showLatteShortcuts),
Q_ARG(QVariant, true),
Q_ARG(QVariant, showMeta),
Q_ARG(QVariant, appLauncher))) {
return true;
}
}
}
}
return false;
};
auto invokeShowOnlyMeta = [this](const Plasma::Containment * c, const bool showLatteShortcuts) {
if (QQuickItem *containmentInterface = c->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = containmentInterface->childItems();
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject->indexOfMethod("setShowAppletShortcutBadges(QVariant,QVariant,QVariant,QVariant)");
if (methodIndex == -1) {
continue;
}
int appLauncher = m_corona->universalSettings()->kwin_metaForwardedToLatte() ?
applicationLauncherId(c) : -1;
int showMethodIndex = -1;
if (!m_viewItemsCalled.contains(item)) {
m_viewItemsCalled.append(item);
m_showShortcutBadgesMethods.append(metaObject->method(methodIndex));
showMethodIndex = m_showShortcutBadgesMethods.count() - 1;
} else {
showMethodIndex = m_showShortcutBadgesMethods.indexOf(metaObject->method(methodIndex));
}
if (m_showShortcutBadgesMethods[showMethodIndex].invoke(item,
Q_ARG(QVariant, showLatteShortcuts),
Q_ARG(QVariant, true),
Q_ARG(QVariant, true),
Q_ARG(QVariant, appLauncher))) {
return true;
}
}
}
}
return false;
};
QList<Latte::View *> sortedViews;
CentralLayout *currentLayout = m_corona->layoutsManager()->currentLayout();
@ -619,16 +358,18 @@ void GlobalShortcuts::showViews()
Latte::View *viewWithMeta{nullptr};
for(const auto view : sortedViews) {
if (!viewWithTasks && (!view->layout()->preferredForShortcutsTouched() || view->isPreferredForShortcuts()) && isCapableToShowShortcutBadges(view)) {
if (!viewWithTasks
&& view->interface()->isCapableToShowShortcutBadges()
&& (!view->layout()->preferredForShortcutsTouched() || view->isPreferredForShortcuts())) {
viewWithTasks = view;
break;
}
}
//! show Meta if it is not already shown for Tasks Latte View
if (!viewWithTasks || applicationLauncherId(viewWithTasks->containment()) == -1) {
if (!viewWithTasks || !viewWithTasks->interface()->containsApplicationLauncher()) {
for(const auto view : sortedViews) {
if (!viewWithMeta && m_corona->universalSettings()->kwin_metaForwardedToLatte() && applicationLauncherId(view->containment()) > -1) {
if (!viewWithMeta && m_corona->universalSettings()->kwin_metaForwardedToLatte() && view->interface()->containsApplicationLauncher()) {
viewWithMeta = view;
break;
}
@ -639,15 +380,10 @@ void GlobalShortcuts::showViews()
if (!m_hideViewsTimer.isActive()) {
m_hideViews.clear();
if (viewWithTasks || viewWithMeta) {
m_viewItemsCalled.clear();
m_showShortcutBadgesMethods.clear();
}
}
//! show view that contains tasks plasmoid
if (viewWithTasks && invokeShowShortcuts(viewWithTasks->containment(), true, true)) {
if (viewWithTasks && viewWithTasks->interface()->showShortcutBadges(true, true)) {
viewFound = true;
if (!m_hideViewsTimer.isActive()) {
@ -657,7 +393,7 @@ void GlobalShortcuts::showViews()
}
//! show view that contains only meta
if (viewWithMeta && viewWithMeta != viewWithTasks && invokeShowOnlyMeta(viewWithMeta->containment(), false)) {
if (viewWithMeta && viewWithMeta != viewWithTasks && viewWithMeta->interface()->showOnlyMeta()) {
viewFound = true;
if (!m_hideViewsTimer.isActive()) {
@ -679,7 +415,7 @@ void GlobalShortcuts::showViews()
if (!m_hideViewsTimer.isActive()) {
for(const auto view : viewsWithShortcuts) {
if (view != viewWithTasks && view != viewWithMeta) {
if (invokeShowShortcuts(view->containment(), false, false)) {
if (view->interface()->showShortcutBadges(false, false)) {
m_hideViews.append(view);
view->visibility()->setBlockHiding(true);
}
@ -757,22 +493,11 @@ void GlobalShortcuts::hideViewsTimerSlot()
if (viewsToHideAreValid()) {
for(const auto latteView : m_hideViews) {
latteView->visibility()->setBlockHiding(false);
}
if (m_viewItemsCalled.count() > 0) {
for (int i = 0; i < m_viewItemsCalled.count(); ++i) {
m_showShortcutBadgesMethods[i].invoke(m_viewItemsCalled[i],
Q_ARG(QVariant, false),
Q_ARG(QVariant, false),
Q_ARG(QVariant, false),
Q_ARG(QVariant, -1));
}
}
latteView->interface()->hideShortcutBadges();
}
}
m_hideViews.clear();
m_viewItemsCalled.clear();
m_showShortcutBadgesMethods.clear();
m_metaShowedViews = false;
};

View File

@ -25,8 +25,7 @@
#include "../liblatte2/types.h"
// Qt
#include <QMetaMethod>
#include <QQuickItem>
#include <QAction>
#include <QPointer>
#include <QTimer>
@ -74,14 +73,12 @@ private:
void showViews();
void showSettings();
bool activateLatteEntryAtContainment(const Latte::View *view, int index, Qt::Key modifier);
bool activatePlasmaTaskManagerEntryAtContainment(const Plasma::Containment *c, int index, Qt::Key modifier);
bool activateLatteEntry(const Latte::View *view, int index, Qt::Key modifier);
bool activatePlasmaTaskManager(const Latte::View *view, int index, Qt::Key modifier);
bool viewAtLowerEdgePriority(Latte::View *test, Latte::View *base);
bool viewAtLowerScreenPriority(Latte::View *test, Latte::View *base);
bool viewsToHideAreValid();
bool isCapableToShowShortcutBadges(Latte::View *view);
int applicationLauncherId(const Plasma::Containment *c);
QList<Latte::View *> sortedViewsList(QHash<const Plasma::Containment *, Latte::View *> *views);
private:
@ -96,9 +93,6 @@ private:
QTimer m_hideViewsTimer;
QList<Latte::View *> m_hideViews;
QList<QQuickItem *> m_viewItemsCalled;
QList<QMetaMethod> m_showShortcutBadgesMethods;
QPointer<ShortcutsPart::ModifierTracker> m_modifierTracker;
QPointer<ShortcutsPart::ShortcutsTracker> m_shortcutsTracker;
QPointer<Latte::Corona> m_corona;

View File

@ -1,5 +1,6 @@
set(lattedock-app_SRCS
${lattedock-app_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/containmentinterface.cpp
${CMAKE_CURRENT_SOURCE_DIR}/contextmenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/effects.cpp
${CMAKE_CURRENT_SOURCE_DIR}/panelshadows.cpp

View File

@ -0,0 +1,308 @@
/*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "containmentinterface.h"
// local
#include "view.h"
#include "../lattecorona.h"
#include "../settings/universalsettings.h"
// Qt
#include <QDebug>
// Plasma
#include <Plasma/Applet>
#include <Plasma/Containment>
// KDE
#include <KLocalizedString>
#include <KPluginMetaData>
namespace Latte {
namespace ViewPart {
ContainmentInterface::ContainmentInterface(Latte::View *parent)
: QObject(parent),
m_view(parent)
{
m_corona = qobject_cast<Latte::Corona *>(m_view->corona());
}
ContainmentInterface::~ContainmentInterface()
{
}
void ContainmentInterface::identifyMainItem()
{
if (m_mainItem) {
return;
}
if (QQuickItem *graphicItem = m_view->containment()->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = graphicItem->childItems();
for (QQuickItem *item : childItems) {
if (item->objectName() == "containmentViewLayout" ) {
m_mainItem = item;
identifyMethods();
return;
}
}
}
}
void ContainmentInterface::identifyMethods()
{
int aeIndex = m_mainItem->metaObject()->indexOfMethod("activateEntryAtIndex(QVariant)");
int niIndex = m_mainItem->metaObject()->indexOfMethod("newInstanceForEntryAtIndex(QVariant)");
int sbIndex = m_mainItem->metaObject()->indexOfMethod("setShowAppletShortcutBadges(QVariant,QVariant,QVariant,QVariant)");
m_activateEntryMethod = m_mainItem->metaObject()->method(aeIndex);
m_newInstanceMethod = m_mainItem->metaObject()->method(niIndex);
m_showShortcutsMethod = m_mainItem->metaObject()->method(sbIndex);
}
bool ContainmentInterface::containsApplicationLauncher() const
{
return applicationLauncherId() == -1 ? false : true;
}
bool ContainmentInterface::isCapableToShowShortcutBadges() const
{
if (!m_view->latteTasksArePresent() && m_view->tasksPresent()) {
return false;
}
return m_showShortcutsMethod.isValid();
}
int ContainmentInterface::applicationLauncherId() const
{
const auto applets = m_view->containment()->applets();
for (auto applet : applets) {
const auto provides = applet->kPackage().metadata().value(QStringLiteral("X-Plasma-Provides"));
if (provides.contains(QLatin1String("org.kde.plasma.launchermenu"))) {
return applet->id();
}
}
return -1;
}
bool ContainmentInterface::updateBadgeForLatteTask(const QString identifier, const QString value)
{
if (!m_view->latteTasksArePresent()) {
return false;
}
const auto &applets = m_view->containment()->applets();
for (auto *applet : applets) {
KPluginMetaData meta = applet->kPackage().metadata();
if (meta.pluginId() == "org.kde.latte.plasmoid") {
if (QQuickItem *appletInterface = applet->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = appletInterface->childItems();
if (childItems.isEmpty()) {
continue;
}
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject->indexOfMethod("updateBadge(QVariant,QVariant)");
if (methodIndex == -1) {
continue;
}
QMetaMethod method = metaObject->method(methodIndex);
if (method.invoke(item, Q_ARG(QVariant, identifier), Q_ARG(QVariant, value))) {
return true;
}
}
}
}
}
}
return false;
}
bool ContainmentInterface::activatePlasmaTask(const int index)
{
bool containsPlasmaTaskManager{m_view->tasksPresent() && !m_view->latteTasksArePresent()};
if (!containsPlasmaTaskManager) {
return false;
}
const auto &applets = m_view->containment()->applets();
for (auto *applet : applets) {
const auto &provides = KPluginMetaData::readStringList(applet->pluginMetaData().rawData(), QStringLiteral("X-Plasma-Provides"));
if (provides.contains(QLatin1String("org.kde.plasma.multitasking"))) {
if (QQuickItem *appletInterface = applet->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = appletInterface->childItems();
if (childItems.isEmpty()) {
continue;
}
KPluginMetaData meta = applet->kPackage().metadata();
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
int methodIndex{metaObject->indexOfMethod("activateTaskAtIndex(QVariant)")};
if (methodIndex == -1) {
continue;
}
QMetaMethod method = metaObject->method(methodIndex);
if (method.invoke(item, Q_ARG(QVariant, index - 1))) {
showShortcutBadges(false, true);
return true;
}
}
}
}
}
}
return false;
}
bool ContainmentInterface::newInstanceForPlasmaTask(const int index)
{
bool containsPlasmaTaskManager{m_view->tasksPresent() && !m_view->latteTasksArePresent()};
if (!containsPlasmaTaskManager) {
return false;
}
const auto &applets = m_view->containment()->applets();
for (auto *applet : applets) {
const auto &provides = KPluginMetaData::readStringList(applet->pluginMetaData().rawData(), QStringLiteral("X-Plasma-Provides"));
if (provides.contains(QLatin1String("org.kde.plasma.multitasking"))) {
if (QQuickItem *appletInterface = applet->property("_plasma_graphicObject").value<QQuickItem *>()) {
const auto &childItems = appletInterface->childItems();
if (childItems.isEmpty()) {
continue;
}
KPluginMetaData meta = applet->kPackage().metadata();
for (QQuickItem *item : childItems) {
if (auto *metaObject = item->metaObject()) {
int methodIndex{metaObject->indexOfMethod("ewInstanceForTaskAtIndex(QVariant)")};
if (methodIndex == -1) {
continue;
}
QMetaMethod method = metaObject->method(methodIndex);
if (method.invoke(item, Q_ARG(QVariant, index - 1))) {
showShortcutBadges(false, true);
return true;
}
}
}
}
}
}
return false;
}
bool ContainmentInterface::activateEntry(const int index)
{
identifyMainItem();
if (!m_activateEntryMethod.isValid()) {
return false;
}
return m_activateEntryMethod.invoke(m_mainItem, Q_ARG(QVariant, index));
}
bool ContainmentInterface::newInstanceForEntry(const int index)
{
identifyMainItem();
if (!m_newInstanceMethod.isValid()) {
return false;
}
return m_newInstanceMethod.invoke(m_mainItem, Q_ARG(QVariant, index));
}
bool ContainmentInterface::hideShortcutBadges()
{
identifyMainItem();
if (!m_showShortcutsMethod.isValid()) {
return false;
}
return m_showShortcutsMethod.invoke(m_mainItem, Q_ARG(QVariant, false), Q_ARG(QVariant, false), Q_ARG(QVariant, false), Q_ARG(QVariant, -1));
}
bool ContainmentInterface::showOnlyMeta()
{
if (!m_corona->universalSettings()->kwin_metaForwardedToLatte()) {
return false;
}
return showShortcutBadges(false, true);
}
bool ContainmentInterface::showShortcutBadges(const bool showLatteShortcuts, const bool showMeta)
{
identifyMainItem();
if (!m_showShortcutsMethod.isValid()) {
return false;
}
int appLauncherId = m_corona->universalSettings()->kwin_metaForwardedToLatte() && showMeta ? applicationLauncherId() : -1;
return m_showShortcutsMethod.invoke(m_mainItem, Q_ARG(QVariant, showLatteShortcuts), Q_ARG(QVariant, true), Q_ARG(QVariant, showMeta), Q_ARG(QVariant, appLauncherId));
}
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
*
* This file is part of Latte-Dock
*
* Latte-Dock is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* Latte-Dock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VIEWCONTAINMENTINTERFACE_H
#define VIEWCONTAINMENTINTERFACE_H
// Qt
#include <QMetaMethod>
#include <QObject>
#include <QPointer>
#include <QQuickItem>
namespace Latte {
class Corona;
class View;
}
namespace Latte {
namespace ViewPart {
class ContainmentInterface: public QObject
{
Q_OBJECT
public:
ContainmentInterface(Latte::View *parent);
virtual ~ContainmentInterface();
bool containsApplicationLauncher() const;
bool isCapableToShowShortcutBadges() const;
bool activateEntry(const int index);
bool newInstanceForEntry(const int index);
bool activatePlasmaTask(const int index);
bool newInstanceForPlasmaTask(const int index);
bool hideShortcutBadges();
bool showOnlyMeta();
bool showShortcutBadges(const bool showLatteShortcuts, const bool showMeta);
//! this is updated from external apps e.g. a thunderbird plugin
bool updateBadgeForLatteTask(const QString identifier, const QString value);
int applicationLauncherId() const;
private slots:
void identifyMainItem();
void identifyMethods();
private:
QMetaMethod m_activateEntryMethod;
QMetaMethod m_newInstanceMethod;
QMetaMethod m_showShortcutsMethod;
QPointer<Latte::Corona> m_corona;
QPointer<Latte::View> m_view;
QPointer<QQuickItem> m_mainItem;
};
}
}
#endif

View File

@ -67,7 +67,8 @@ namespace Latte {
View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
: PlasmaQuick::ContainmentView(corona),
m_contextMenu(new ViewPart::ContextMenu(this)),
m_effects(new ViewPart::Effects(this))
m_effects(new ViewPart::Effects(this)),
m_interface(new ViewPart::ContainmentInterface(this))
{
//! needs to be created after Effects because it catches some of its signals
//! and avoid a crash from View::winId() at the same time
@ -205,6 +206,10 @@ View::~View()
delete m_indicator;
}
if (m_interface) {
delete m_interface;
}
if (m_visibility) {
delete m_visibility;
}
@ -1112,6 +1117,11 @@ ViewPart::Indicator *View::indicator() const
return m_indicator;
}
ViewPart::ContainmentInterface *View::interface() const
{
return m_interface;
}
ViewPart::Positioner *View::positioner() const
{
return m_positioner;

View File

@ -22,6 +22,7 @@
#define VIEW_H
// local
#include "containmentinterface.h"
#include "effects.h"
#include "positioner.h"
#include "visibilitymanager.h"
@ -195,8 +196,9 @@ public:
PlasmaQuick::ConfigView *configView();
ViewPart::Effects *effects() const;
ViewPart::Effects *effects() const;
ViewPart::Indicator *indicator() const;
ViewPart::ContainmentInterface *interface() const;
ViewPart::Positioner *positioner() const;
ViewPart::VisibilityManager *visibility() const;
ViewPart::WindowsTracker *windowsTracker() const;
@ -356,6 +358,7 @@ private:
QPointer<ViewPart::ContextMenu> m_contextMenu;
QPointer<ViewPart::Effects> m_effects;
QPointer<ViewPart::Indicator> m_indicator;
QPointer<ViewPart::ContainmentInterface> m_interface;
QPointer<ViewPart::Positioner> m_positioner;
QPointer<ViewPart::VisibilityManager> m_visibility;
QPointer<ViewPart::WindowsTracker> m_windowsTracker;