diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index f7010e7f..d690187c 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,86 +1,86 @@ set(lattedock-app_SRCS ../liblattedock/dock.cpp packageplugins/shell/dockpackage.cpp abstractwindowinterface.cpp alternativeshelper.cpp commontools.cpp dockcorona.cpp globalshortcuts.cpp importer.cpp infoview.cpp launcherssignals.cpp layout.cpp layoutmanager.cpp plasmathemeextended.cpp schemecolors.cpp screenpool.cpp settingsdialog.cpp sortedactivitiesmodel.cpp universalsettings.cpp waylandinterface.cpp windowinfowrap.cpp xwindowinterface.cpp + dock/contextmenu.cpp dock/dockconfigview.cpp - dock/dockmenumanager.cpp dock/docksecconfigview.cpp dock/dockview.cpp dock/effects.cpp dock/panelshadows.cpp dock/positioner.cpp dock/screenedgeghostwindow.cpp dock/visibilitymanager.cpp layoutsDelegates/activitycmbboxdelegate.cpp layoutsDelegates/checkboxdelegate.cpp layoutsDelegates/colorcmbboxdelegate.cpp layoutsDelegates/colorcmbboxitemdelegate.cpp layoutsDelegates/layoutnamedelegate.cpp main.cpp ) set(latte_dbusXML dbus/org.kde.LatteDock.xml) qt5_add_dbus_adaptor(lattedock-app_SRCS ${latte_dbusXML} dockcorona.h Latte::DockCorona lattedockadaptor) ki18n_wrap_ui(lattedock-app_SRCS settingsdialog.ui) add_executable(latte-dock ${lattedock-app_SRCS}) include(FakeTarget.cmake) target_link_libraries(latte-dock Qt5::DBus Qt5::Quick Qt5::Qml KF5::I18n KF5::DBusAddons KF5::Declarative KF5::CoreAddons KF5::GlobalAccel KF5::Archive KF5::Crash KF5::XmlGui KF5::Plasma KF5::PlasmaQuick KF5::Activities KF5::Notifications KF5::NewStuff KF5::QuickAddons KF5::WaylandClient ) if(HAVE_X11) target_link_libraries(latte-dock Qt5::X11Extras KF5::WindowSystem ${X11_LIBRARIES} ${XCB_LIBRARIES} ) endif() configure_file(org.kde.latte-dock.desktop.cmake org.kde.latte-dock.desktop) configure_file(org.kde.latte-dock.appdata.xml.cmake org.kde.latte-dock.appdata.xml) install(TARGETS latte-dock ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.latte-dock.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.latte-dock.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES dbus/org.kde.LatteDock.xml DESTINATION ${KDE_INSTALL_DBUSINTERFACEDIR}) install(FILES lattedock.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) install(FILES latte-layouts.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) diff --git a/app/dock/dockmenumanager.cpp b/app/dock/contextmenu.cpp similarity index 95% rename from app/dock/dockmenumanager.cpp rename to app/dock/contextmenu.cpp index c58a24c5..f7b9680c 100644 --- a/app/dock/dockmenumanager.cpp +++ b/app/dock/contextmenu.cpp @@ -1,466 +1,468 @@ /* * Copyright 2018 Michail Vourlakos * * 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 . */ -#include "dockmenumanager.h" +#include "contextmenu.h" #include "dockview.h" #include "visibilitymanager.h" #include "../dockcorona.h" #include "../layoutmanager.h" #include #include #include #include #include #include #include #include #include #include namespace Latte { +namespace View { -DockMenuManager::DockMenuManager(DockView *view) : +ContextMenu::ContextMenu(Latte::DockView *view) : QObject(view), m_dockView(view) { } -DockMenuManager::~DockMenuManager() +ContextMenu::~ContextMenu() { } -QMenu *DockMenuManager::contextMenu() +QMenu *ContextMenu::menu() { return m_contextMenu; } -void DockMenuManager::menuAboutToHide() +void ContextMenu::menuAboutToHide() { if (!m_dockView) { return; } m_contextMenu = 0; if (!m_dockView->containment()->isUserConfiguring()) { m_dockView->visibility()->setBlockHiding(false); } - emit contextMenuChanged(); + emit menuChanged(); } -bool DockMenuManager::mousePressEvent(QMouseEvent *event) +bool ContextMenu::mousePressEvent(QMouseEvent *event) { //qDebug() << "Step -1 ..."; if (!event || !m_dockView->containment()) { return false; } //qDebug() << "Step 0..."; //even if the menu is executed synchronously, other events may be processed //by the qml incubator when plasma is loading, so we need to guard there if (m_contextMenu) { //qDebug() << "Step 0.5 ..."; m_contextMenu->close(); m_contextMenu = 0; - emit contextMenuChanged(); + emit menuChanged(); // PlasmaQuick::ContainmentView::mousePressEvent(event); return false; } //qDebug() << "1 ..."; QString trigger = Plasma::ContainmentActions::eventToString(event); if (trigger == "RightButton;NoModifier") { Plasma::ContainmentActions *plugin = m_dockView->containment()->containmentActions().value(trigger); if (!plugin || plugin->contextualActions().isEmpty()) { event->setAccepted(false); return false; } //qDebug() << "2 ..."; //the plugin can be a single action or a context menu //Don't have an action list? execute as single action //and set the event position as action data /*if (plugin->contextualActions().length() == 1) { QAction *action = plugin->contextualActions().at(0); action->setData(event->pos()); action->trigger(); event->accept(); return; }*/ //FIXME: very inefficient appletAt() implementation Plasma::Applet *applet = 0; bool inSystray = false; //! initialize the appletContainsMethod on the first right click if (!m_appletContainsMethod.isValid()) { updateAppletContainsMethod(); } foreach (Plasma::Applet *appletTemp, m_dockView->containment()->applets()) { PlasmaQuick::AppletQuickItem *ai = appletTemp->property("_plasma_graphicObject").value(); bool appletContainsMouse = false; if (m_appletContainsMethod.isValid()) { QVariant retVal; m_appletContainsMethod.invoke(m_appletContainsMethodItem, Qt::DirectConnection, Q_RETURN_ARG(QVariant, retVal) , Q_ARG(QVariant, appletTemp->id()), Q_ARG(QVariant, event->pos())); appletContainsMouse = retVal.toBool(); } else { appletContainsMouse = ai->contains(ai->mapFromItem(m_dockView->contentItem(), event->pos())); } if (ai && ai->isVisible() && appletContainsMouse) { applet = ai->applet(); KPluginMetaData meta = applet->kPackage().metadata(); //Try to find applets inside a systray if (meta.pluginId() == "org.kde.plasma.systemtray" || meta.pluginId() == "org.nomad.systemtray") { auto systrayId = applet->config().readEntry("SystrayContainmentId"); applet = 0; inSystray = true; Plasma::Containment *cont = containmentById(systrayId.toInt()); if (cont) { foreach (Plasma::Applet *appletCont, cont->applets()) { PlasmaQuick::AppletQuickItem *ai2 = appletCont->property("_plasma_graphicObject").value(); if (ai2 && ai2->isVisible() && ai2->contains(ai2->mapFromItem(m_dockView->contentItem(), event->pos()))) { applet = ai2->applet(); break; } } } break; } else { ai = 0; } } } if (!applet && !inSystray) { applet = m_dockView->containment(); } //qDebug() << "3 ..."; if (applet) { const auto &provides = KPluginMetaData::readStringList(applet->pluginMetaData().rawData(), QStringLiteral("X-Plasma-Provides")); //qDebug() << "3.5 ..."; if (!provides.contains(QLatin1String("org.kde.plasma.multitasking"))) { //qDebug() << "4..."; QMenu *desktopMenu = new QMenu; //this is a workaround where Qt now creates the menu widget //in .exec before oxygen can polish it and set the following attribute desktopMenu->setAttribute(Qt::WA_TranslucentBackground); //end workaround if (desktopMenu->winId()) { desktopMenu->windowHandle()->setTransientParent(m_dockView); } desktopMenu->setAttribute(Qt::WA_DeleteOnClose); m_contextMenu = desktopMenu; //! deprecated old code that can be removed if the following plasma approach doesn't //! create any issues with context menu creation in Latte /*if (m_dockView->mouseGrabberItem()) { //workaround, this fixes for me most of the right click menu behavior m_dockView->mouseGrabberItem()->ungrabMouse(); return; }*/ //!plasma official code //this is a workaround where Qt will fail to realise a mouse has been released // this happens if a window which does not accept focus spawns a new window that takes focus and X grab // whilst the mouse is depressed // https://bugreports.qt.io/browse/QTBUG-59044 // this causes the next click to go missing //by releasing manually we avoid that situation auto ungrabMouseHack = [this]() { if (m_dockView->mouseGrabberItem()) { m_dockView->mouseGrabberItem()->ungrabMouse(); } }; //pre 5.8.0 QQuickWindow code is "item->grabMouse(); sendEvent(item, mouseEvent)" //post 5.8.0 QQuickWindow code is sendEvent(item, mouseEvent); item->grabMouse() if (QVersionNumber::fromString(qVersion()) > QVersionNumber(5, 8, 0)) { QTimer::singleShot(0, this, ungrabMouseHack); } else { ungrabMouseHack(); } //end workaround //!end of plasma official code(workaround) //qDebug() << "5 ..."; if (applet && applet != m_dockView->containment()) { //qDebug() << "5.3 ..."; emit applet->contextualActionsAboutToShow(); addAppletActions(desktopMenu, applet, event); } else { //qDebug() << "5.6 ..."; emit m_dockView->containment()->contextualActionsAboutToShow(); addContainmentActions(desktopMenu, event); } //this is a workaround where Qt now creates the menu widget //in .exec before oxygen can polish it and set the following attribute desktopMenu->setAttribute(Qt::WA_TranslucentBackground); //end workaround QPoint pos = event->globalPos(); if (applet) { //qDebug() << "6 ..."; desktopMenu->adjustSize(); if (m_dockView->screen()) { const QRect scr = m_dockView->screen()->geometry(); int smallStep = 3; int x = event->globalPos().x() + smallStep; int y = event->globalPos().y() + smallStep; //qDebug()<globalPos().x() > scr.center().x()) { x = event->globalPos().x() - desktopMenu->width() - smallStep; } if (event->globalPos().y() > scr.center().y()) { y = event->globalPos().y() - desktopMenu->height() - smallStep; } pos = QPoint(x, y); } } //qDebug() << "7..."; if (desktopMenu->isEmpty()) { //qDebug() << "7.5 ..."; delete desktopMenu; event->accept(); return false; } connect(desktopMenu, SIGNAL(aboutToHide()), this, SLOT(menuAboutToHide())); m_dockView->visibility()->setBlockHiding(true); desktopMenu->popup(pos); event->setAccepted(true); - emit contextMenuChanged(); + emit menuChanged(); return false; } //qDebug() << "8 ..."; } //qDebug() << "9 ..."; } //qDebug() << "10 ..."; - emit contextMenuChanged(); + emit menuChanged(); return true; // PlasmaQuick::ContainmentView::mousePressEvent(event); } //! update the appletContainsPos method from Panel view -void DockMenuManager::updateAppletContainsMethod() +void ContextMenu::updateAppletContainsMethod() { for (QQuickItem *item : m_dockView->contentItem()->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("appletContainsPos(QVariant,QVariant)"); if (methodIndex == -1) { continue; } m_appletContainsMethod = metaObject->method(methodIndex); m_appletContainsMethodItem = item; } } } -void DockMenuManager::addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event) +void ContextMenu::addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event) { if (!m_dockView->containment()) { return; } foreach (QAction *action, applet->contextualActions()) { if (action) { desktopMenu->addAction(action); } } if (!applet->failedToLaunch()) { QAction *runAssociatedApplication = applet->actions()->action(QStringLiteral("run associated application")); if (runAssociatedApplication && runAssociatedApplication->isEnabled()) { desktopMenu->addAction(runAssociatedApplication); } QAction *configureApplet = applet->actions()->action(QStringLiteral("configure")); if (configureApplet && configureApplet->isEnabled()) { desktopMenu->addAction(configureApplet); } QAction *appletAlternatives = applet->actions()->action(QStringLiteral("alternatives")); if (appletAlternatives && appletAlternatives->isEnabled() && m_dockView->containment()->isUserConfiguring()) { desktopMenu->addAction(appletAlternatives); } } QAction *containmentAction = desktopMenu->menuAction(); containmentAction->setText(i18nc("%1 is the name of the containment", "%1 Options", m_dockView->containment()->title())); addContainmentActions(containmentAction->menu(), event); if (!containmentAction->menu()->isEmpty()) { int enabled = 0; //count number of real actions QListIterator actionsIt(containmentAction->menu()->actions()); while (enabled < 3 && actionsIt.hasNext()) { QAction *action = actionsIt.next(); if (action->isVisible() && !action->isSeparator()) { ++enabled; } } desktopMenu->addSeparator(); if (enabled) { //if there is only one, don't create a submenu // if (enabled < 2) { foreach (QAction *action, containmentAction->menu()->actions()) { if (action->isVisible()) { desktopMenu->addAction(action); } } // } else { // desktopMenu->addMenu(containmentMenu); // } } } if (m_dockView->containment()->immutability() == Plasma::Types::Mutable && (m_dockView->containment()->containmentType() != Plasma::Types::PanelContainment || m_dockView->containment()->isUserConfiguring())) { QAction *closeApplet = applet->actions()->action(QStringLiteral("remove")); //qDebug() << "checking for removal" << closeApplet; if (closeApplet) { if (!desktopMenu->isEmpty()) { desktopMenu->addSeparator(); } //qDebug() << "adding close action" << closeApplet->isEnabled() << closeApplet->isVisible(); desktopMenu->addAction(closeApplet); } } } -void DockMenuManager::addContainmentActions(QMenu *desktopMenu, QEvent *event) +void ContextMenu::addContainmentActions(QMenu *desktopMenu, QEvent *event) { if (!m_dockView->containment()) { return; } if (m_dockView->containment()->corona()->immutability() != Plasma::Types::Mutable && !KAuthorized::authorizeAction(QStringLiteral("plasma/containment_actions"))) { //qDebug() << "immutability"; return; } //this is what ContainmentPrivate::prepareContainmentActions was const QString trigger = Plasma::ContainmentActions::eventToString(event); //"RightButton;NoModifier" Plasma::ContainmentActions *plugin = m_dockView->containment()->containmentActions().value(trigger); if (!plugin) { return; } if (plugin->containment() != m_dockView->containment()) { plugin->setContainment(m_dockView->containment()); // now configure it KConfigGroup cfg(m_dockView->containment()->corona()->config(), "ActionPlugins"); cfg = KConfigGroup(&cfg, QString::number(m_dockView->containment()->containmentType())); KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); plugin->restore(pluginConfig); } QList actions = plugin->contextualActions(); foreach (auto act, actions) { if (act->menu()) { //this is a workaround where Qt now creates the menu widget //in .exec before oxygen can polish it and set the following attribute act->menu()->setAttribute(Qt::WA_TranslucentBackground); //end workaround if (act->menu()->winId()) { act->menu()->windowHandle()->setTransientParent(m_dockView); } } } desktopMenu->addActions(actions); return; } -Plasma::Containment *DockMenuManager::containmentById(uint id) +Plasma::Containment *ContextMenu::containmentById(uint id) { foreach (auto containment, m_dockView->corona()->containments()) { if (id == containment->id()) { return containment; } } return 0; } } +} diff --git a/app/dock/dockmenumanager.h b/app/dock/contextmenu.h similarity index 84% rename from app/dock/dockmenumanager.h rename to app/dock/contextmenu.h index 7ae2bc69..00732931 100644 --- a/app/dock/dockmenumanager.h +++ b/app/dock/contextmenu.h @@ -1,79 +1,80 @@ /* * Copyright 2018 Michail Vourlakos * * 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 . */ - -#ifndef DOCKMENUMANAGER_H -#define DOCKMENUMANAGER_H +#ifndef CONTEXTMENU_H +#define CONTEXTMENU_H #include #include #include #include #include #include namespace Plasma { class Applet; class Containment; } namespace Latte { class DockView; } namespace Latte { +namespace View { -class DockMenuManager : public QObject +class ContextMenu : public QObject { Q_OBJECT public: - DockMenuManager(DockView *view); - ~DockMenuManager() override; + ContextMenu(Latte::DockView *view); + ~ContextMenu() override; - QMenu *contextMenu(); + QMenu *menu(); bool mousePressEvent(QMouseEvent *event); signals: - void contextMenuChanged(); + void menuChanged(); private slots: void menuAboutToHide(); private: void addAppletActions(QMenu *desktopMenu, Plasma::Applet *applet, QEvent *event); void addContainmentActions(QMenu *desktopMenu, QEvent *event); void updateAppletContainsMethod(); Plasma::Containment *containmentById(uint id); private: QMenu *m_contextMenu{nullptr}; QMetaMethod m_appletContainsMethod; QQuickItem *m_appletContainsMethodItem{nullptr}; - DockView *m_dockView; + Latte::DockView *m_dockView; - friend class DockView; + friend class Latte::DockView; }; +} } #endif // DOCKMENUMANAGER_H diff --git a/app/dock/dockview.cpp b/app/dock/dockview.cpp index 3e7fa774..cc291ea8 100644 --- a/app/dock/dockview.cpp +++ b/app/dock/dockview.cpp @@ -1,1070 +1,1070 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * 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 . */ #include "dockview.h" +#include "contextmenu.h" #include "dockconfigview.h" -#include "dockmenumanager.h" #include "effects.h" #include "positioner.h" #include "visibilitymanager.h" #include "../dockcorona.h" #include "../layout.h" #include "../layoutmanager.h" #include "../screenpool.h" #include "../plasmathemeextended.h" #include "../universalsettings.h" #include "../../liblattedock/extras.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Latte { //! both alwaysVisible and dockWinBehavior are passed through corona because //! during the dock window creation containment hasn't been set, but these variables //! are needed in order for window flags to be set correctly DockView::DockView(Plasma::Corona *corona, QScreen *targetScreen, bool dockWindowBehavior) : PlasmaQuick::ContainmentView(corona), - m_menuManager(new DockMenuManager(this)), + m_contextMenu(new View::ContextMenu(this)), m_effects(new View::Effects(this)), m_positioner(new View::Positioner(this)) //needs to be created after Effects becuase it catches some of its signals { setTitle(corona->kPackage().metadata().name()); setIcon(qGuiApp->windowIcon()); setResizeMode(QuickViewSharedEngine::SizeRootObjectToView); setColor(QColor(Qt::transparent)); setClearBeforeRendering(true); const auto flags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::NoDropShadowWindowHint | Qt::WindowDoesNotAcceptFocus; if (dockWindowBehavior) { setFlags(flags); } else { setFlags(flags | Qt::BypassWindowManagerHint); } KWindowSystem::setOnAllDesktops(winId(), true); if (targetScreen) m_positioner->setScreenToFollow(targetScreen); else m_positioner->setScreenToFollow(qGuiApp->primaryScreen()); connect(this, &DockView::containmentChanged , this, [ &, dockWindowBehavior]() { qDebug() << "dock view c++ containment changed 1..."; if (!this->containment()) return; qDebug() << "dock view c++ containment changed 2..."; //! First load default values from file restoreConfig(); //! Afterwards override that values in case during creation something different is needed setDockWinBehavior(dockWindowBehavior); //! Check the screen assigned to this dock reconsiderScreen(); if (!m_visibility) { m_visibility = new VisibilityManager(this); connect(m_visibility, &VisibilityManager::isHiddenChanged, this, [&]() { if (m_visibility->isHidden()) { deactivateApplets(); } }); } connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus))); }, Qt::DirectConnection); auto *dockCorona = qobject_cast(this->corona()); if (dockCorona) { connect(dockCorona, &DockCorona::dockLocationChanged, this, &DockView::dockLocationChanged); } } DockView::~DockView() { m_inDelete = true; disconnect(corona(), &Plasma::Corona::availableScreenRectChanged, this, &DockView::availableScreenRectChanged); disconnect(containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), this, SLOT(statusChanged(Plasma::Types::ItemStatus))); qDebug() << "dock view deleting..."; rootContext()->setContextProperty(QStringLiteral("dock"), nullptr); rootContext()->setContextProperty(QStringLiteral("themeExtended"), nullptr); rootContext()->setContextProperty(QStringLiteral("universalSettings"), nullptr); rootContext()->setContextProperty(QStringLiteral("layoutManager"), nullptr); //! this disconnect does not free up connections correctly when //! dockView is deleted. A crash for this example is the following: //! switch to Alternative Session and disable compositing, //! the signal creating the crash was probably from deleted //! windows. //! this->disconnect(); if (m_configView) { m_configView->setVisible(false);//hide(); } - if (m_menuManager) { - delete m_menuManager; + if (m_contextMenu) { + delete m_contextMenu; } //needs to be deleted before Effects becuase it catches some of its signals if (m_positioner) { delete m_positioner; } if (m_effects) { delete m_effects; } if (m_visibility) delete m_visibility; } void DockView::init() { connect(this, &QQuickWindow::xChanged, this, &DockView::xChanged); connect(this, &QQuickWindow::xChanged, this, &DockView::updateAbsDockGeometry); connect(this, &QQuickWindow::yChanged, this, &DockView::yChanged); connect(this, &QQuickWindow::yChanged, this, &DockView::updateAbsDockGeometry); connect(this, &QQuickWindow::widthChanged, this, &DockView::widthChanged); connect(this, &QQuickWindow::widthChanged, this, &DockView::updateAbsDockGeometry); connect(this, &QQuickWindow::heightChanged, this, &DockView::heightChanged); connect(this, &QQuickWindow::heightChanged, this, &DockView::updateAbsDockGeometry); connect(corona(), &Plasma::Corona::availableScreenRectChanged, this, &DockView::availableScreenRectChanged); connect(m_positioner, &View::Positioner::onHideWindowsForSlidingOut, this, &DockView::hideWindowsForSlidingOut); connect(m_positioner, &View::Positioner::screenGeometryChanged, this, &DockView::screenGeometryChanged); connect(this, &DockView::dockWinBehaviorChanged, this, &DockView::saveConfig); connect(this, &DockView::onPrimaryChanged, this, &DockView::saveConfig); connect(this, &DockView::isPreferredForShortcutsChanged, this, &DockView::saveConfig); connect(this, SIGNAL(normalThicknessChanged()), corona(), SIGNAL(availableScreenRectChanged())); - connect(m_menuManager, &DockMenuManager::contextMenuChanged, this, &DockView::contextMenuIsShownChanged); + connect(m_contextMenu, &View::ContextMenu::menuChanged, this, &DockView::contextMenuIsShownChanged); ///!!!!! rootContext()->setContextProperty(QStringLiteral("dock"), this); auto *dockCorona = qobject_cast(this->corona()); if (dockCorona) { rootContext()->setContextProperty(QStringLiteral("universalSettings"), dockCorona->universalSettings()); rootContext()->setContextProperty(QStringLiteral("layoutManager"), dockCorona->layoutManager()); rootContext()->setContextProperty(QStringLiteral("themeExtended"), dockCorona->themeExtended()); } setSource(corona()->kPackage().filePath("lattedockui")); // setVisible(true); m_positioner->syncGeometry(); if (!KWindowSystem::isPlatformWayland()) { setVisible(true); } qDebug() << "SOURCE:" << source(); } bool DockView::inDelete() const { return m_inDelete; } void DockView::disconnectSensitiveSignals() { disconnect(corona(), &Plasma::Corona::availableScreenRectChanged, this, &DockView::availableScreenRectChanged); setManagedLayout(nullptr); if (visibility()) { visibility()->setEnabledDynamicBackground(false); } } void DockView::availableScreenRectChanged() { if (m_inDelete) return; if (formFactor() == Plasma::Types::Vertical) { m_positioner->syncGeometry(); } } void DockView::setupWaylandIntegration() { if (m_shellSurface) return; if (DockCorona *c = qobject_cast(corona())) { using namespace KWayland::Client; PlasmaShell *interface {c->waylandDockCoronaInterface()}; if (!interface) return; Surface *s{Surface::fromWindow(this)}; if (!s) return; m_shellSurface = interface->createSurface(s, this); qDebug() << "WAYLAND dock window surface was created..."; m_shellSurface->setSkipTaskbar(true); m_shellSurface->setRole(PlasmaShellSurface::Role::Panel); m_shellSurface->setPanelBehavior(PlasmaShellSurface::PanelBehavior::WindowsGoBelow); } } KWayland::Client::PlasmaShellSurface *DockView::surface() { return m_shellSurface; } //! the main function which decides if this dock is at the //! correct screen void DockView::reconsiderScreen() { m_positioner->reconsiderScreen(); } void DockView::copyDock() { m_managedLayout->copyDock(containment()); } void DockView::removeDock() { if (m_managedLayout && m_managedLayout->viewsCount() > 1) { QAction *removeAct = this->containment()->actions()->action(QStringLiteral("remove")); if (removeAct) { removeAct->trigger(); } } } bool DockView::settingsWindowIsShown() { auto configView = qobject_cast(m_configView); return (configView != nullptr); } void DockView::showSettingsWindow() { showConfigurationInterface(containment()); applyActivitiesToWindows(); } void DockView::showConfigurationInterface(Plasma::Applet *applet) { if (!applet || !applet->containment()) return; Plasma::Containment *c = qobject_cast(applet); if (m_configView && c && c->isContainment() && c == this->containment()) { if (m_configView->isVisible()) { m_configView->setVisible(false); //m_configView->hide(); } else { m_configView->setVisible(true); //m_configView->show(); } return; } else if (m_configView) { if (m_configView->applet() == applet) { m_configView->setVisible(true); //m_configView->show(); m_configView->requestActivate(); return; } else { m_configView->setVisible(false); //m_configView->hide(); m_configView->deleteLater(); } } bool delayConfigView = false; if (c && containment() && c->isContainment() && c->id() == this->containment()->id()) { m_configView = new DockConfigView(c, this); delayConfigView = true; } else { m_configView = new PlasmaQuick::ConfigView(applet); } m_configView.data()->init(); if (!delayConfigView) { m_configView->setVisible(true); //m_configView.data()->show(); } else { //add a timer for showing the configuration window the first time it is //created in order to give the containmnent's layouts the time to //calculate the window's height if (!KWindowSystem::isPlatformWayland()) { QTimer::singleShot(150, m_configView, SLOT(show())); } else { QTimer::singleShot(150, [this]() { m_configView->setVisible(true); }); } } } QRect DockView::localGeometry() const { return m_localGeometry; } void DockView::setLocalGeometry(const QRect &geometry) { if (m_localGeometry == geometry) { return; } m_localGeometry = geometry; emit localGeometryChanged(); updateAbsDockGeometry(); } void DockView::updateAbsDockGeometry(bool bypassChecks) { //! there was a -1 in height and width here. The reason of this //! if I remember correctly was related to multi-screen but I cant //! remember exactly the reason, something related to rigth edge in //! multi screen environment. BUT this was breaking the entire AlwaysVisible //! experience with struts. Removing them in order to restore correct //! behavior and keeping this comment in order to check for //! multi-screen breakage QRect absGeometry {x() + m_localGeometry.x(), y() + m_localGeometry.y() , m_localGeometry.width(), m_localGeometry.height()}; if (m_absGeometry == absGeometry && !bypassChecks) return; m_absGeometry = absGeometry; emit absGeometryChanged(m_absGeometry); //! this is needed in order to update correctly the screenGeometries if (visibility() && corona() && visibility()->mode() == Dock::AlwaysVisible) { emit corona()->availableScreenRectChanged(); emit corona()->availableScreenRegionChanged(); } } void DockView::statusChanged(Plasma::Types::ItemStatus status) { if (containment()) { if (containment()->status() >= Plasma::Types::NeedsAttentionStatus && containment()->status() != Plasma::Types::HiddenStatus) { setBlockHiding(true); } else { setBlockHiding(false); } } } bool DockView::alternativesIsShown() const { return m_alternativesIsShown; } void DockView::setAlternativesIsShown(bool show) { if (m_alternativesIsShown == show) { return; } m_alternativesIsShown = show; setBlockHiding(show); emit alternativesIsShownChanged(); } bool DockView::contextMenuIsShown() const { - if (!m_menuManager) { + if (!m_contextMenu) { return false; } - return m_menuManager->contextMenu(); + return m_contextMenu->menu(); } int DockView::currentThickness() const { if (formFactor() == Plasma::Types::Vertical) { return m_effects->mask().isNull() ? width() : m_effects->mask().width() - m_effects->innerShadow(); } else { return m_effects->mask().isNull() ? height() : m_effects->mask().height() - m_effects->innerShadow(); } } int DockView::normalThickness() const { return m_normalThickness; } void DockView::setNormalThickness(int thickness) { if (m_normalThickness == thickness) { return; } m_normalThickness = thickness; emit normalThicknessChanged(); } bool DockView::dockWinBehavior() const { return m_dockWinBehavior; } void DockView::setDockWinBehavior(bool dock) { if (m_dockWinBehavior == dock) { return; } m_dockWinBehavior = dock; emit dockWinBehaviorChanged(); } bool DockView::behaveAsPlasmaPanel() const { return m_behaveAsPlasmaPanel; } void DockView::setBehaveAsPlasmaPanel(bool behavior) { if (m_behaveAsPlasmaPanel == behavior) { return; } m_behaveAsPlasmaPanel = behavior; emit behaveAsPlasmaPanelChanged(); } bool DockView::inEditMode() const { return m_inEditMode; } void DockView::setInEditMode(bool edit) { if (m_inEditMode == edit) { return; } m_inEditMode = edit; emit inEditModeChanged(); } bool DockView::isPreferredForShortcuts() const { return m_isPreferredForShortcuts; } void DockView::setIsPreferredForShortcuts(bool preferred) { if (m_isPreferredForShortcuts == preferred) { return; } m_isPreferredForShortcuts = preferred; emit isPreferredForShortcutsChanged(); if (m_isPreferredForShortcuts && m_managedLayout) { emit m_managedLayout->preferredViewForShortcutsChanged(this); } } void DockView::preferredViewForShortcutsChangedSlot(DockView *view) { if (view != this) { setIsPreferredForShortcuts(false); } } bool DockView::onPrimary() const { return m_onPrimary; } void DockView::setOnPrimary(bool flag) { if (m_onPrimary == flag) { return; } m_onPrimary = flag; emit onPrimaryChanged(); } float DockView::maxLength() const { return m_maxLength; } void DockView::setMaxLength(float length) { if (m_maxLength == length) { return; } m_maxLength = length; emit maxLengthChanged(); } int DockView::maxThickness() const { return m_maxThickness; } void DockView::setMaxThickness(int thickness) { if (m_maxThickness == thickness) return; m_maxThickness = thickness; emit maxThicknessChanged(); } int DockView::alignment() const { return m_alignment; } void DockView::setAlignment(int alignment) { Dock::Alignment align = static_cast(alignment); if (m_alignment == alignment) { return; } m_alignment = align; emit alignmentChanged(); } QRect DockView::absGeometry() const { return m_absGeometry; } QRect DockView::screenGeometry() const { if (this->screen()) { QRect geom = this->screen()->geometry(); return geom; } return QRect(); } int DockView::offset() const { return m_offset; } void DockView::setOffset(int offset) { if (m_offset == offset) { return; } m_offset = offset; emit offsetChanged(); } int DockView::fontPixelSize() const { return m_fontPixelSize; } void DockView::setFontPixelSize(int size) { if (m_fontPixelSize == size) { return; } m_fontPixelSize = size; emit fontPixelSizeChanged(); } void DockView::applyActivitiesToWindows() { if (m_visibility) { QStringList activities = m_managedLayout->appliedActivities(); m_visibility->setWindowOnActivities(*this, activities); if (m_configView) { m_visibility->setWindowOnActivities(*m_configView, activities); auto configView = qobject_cast(m_configView); if (configView && configView->secondaryWindow()) { m_visibility->setWindowOnActivities(*configView->secondaryWindow(), activities); } } if (m_visibility->supportsKWinEdges()) { m_visibility->applyActivitiesToHiddenWindows(activities); } } } Layout *DockView::managedLayout() const { return m_managedLayout; } void DockView::setManagedLayout(Layout *layout) { if (m_managedLayout == layout) { return; } // clear mode for (auto &c : connectionsManagedLayout) { disconnect(c); } m_managedLayout = layout; if (m_managedLayout) { //! Sometimes the activity isnt completely ready, by adding a delay //! we try to catch up QTimer::singleShot(100, [this]() { if (m_managedLayout && m_visibility) { qDebug() << "DOCK VIEW FROM LAYOUT ::: " << m_managedLayout->name() << " - activities: " << m_managedLayout->appliedActivities(); applyActivitiesToWindows(); emit activitiesChanged(); } }); connectionsManagedLayout[0] = connect(m_managedLayout, &Layout::preferredViewForShortcutsChanged, this, &DockView::preferredViewForShortcutsChangedSlot); } DockCorona *dockCorona = qobject_cast(this->corona()); if (dockCorona->layoutManager()->memoryUsage() == Dock::MultipleLayouts) { connectionsManagedLayout[1] = connect(dockCorona->activitiesConsumer(), &KActivities::Consumer::runningActivitiesChanged, this, [&]() { if (m_managedLayout && m_visibility) { qDebug() << "DOCK VIEW FROM LAYOUT (runningActivitiesChanged) ::: " << m_managedLayout->name() << " - activities: " << m_managedLayout->appliedActivities(); applyActivitiesToWindows(); emit activitiesChanged(); } }); connectionsManagedLayout[2] = connect(m_managedLayout, &Layout::activitiesChanged, this, [&]() { if (m_managedLayout) { applyActivitiesToWindows(); emit activitiesChanged(); } }); connectionsManagedLayout[3] = connect(dockCorona->layoutManager(), &LayoutManager::layoutsChanged, this, [&]() { if (m_managedLayout) { applyActivitiesToWindows(); emit activitiesChanged(); } }); //!IMPORTANT!!! ::: This fixes a bug when closing an Activity all docks from all Activities are //! disappearing! With this they reappear!!! connectionsManagedLayout[4] = connect(this, &QWindow::visibleChanged, this, [&]() { if (!isVisible() && m_managedLayout) { QTimer::singleShot(100, [this]() { if (m_managedLayout && containment() && !containment()->destroyed()) { setVisible(true); applyActivitiesToWindows(); emit activitiesChanged(); } }); QTimer::singleShot(1500, [this]() { if (m_managedLayout && containment() && !containment()->destroyed()) { setVisible(true); applyActivitiesToWindows(); emit activitiesChanged(); } }); } }); } emit managedLayoutChanged(); } void DockView::moveToLayout(QString layoutName) { if (!m_managedLayout) { return; } QList containments = m_managedLayout->unassignFromLayout(this); DockCorona *dockCorona = qobject_cast(this->corona()); if (dockCorona && containments.size() > 0) { Layout *newLayout = dockCorona->layoutManager()->activeLayout(layoutName); if (newLayout) { newLayout->assignToLayout(this, containments); } } } void DockView::setBlockHiding(bool block) { if (!block) { auto *configView = qobject_cast(m_configView); if (m_alternativesIsShown || (configView && configView->sticker() && configView->isVisible())) { return; } if (m_visibility) { m_visibility->setBlockHiding(false); } } else { if (m_visibility) { m_visibility->setBlockHiding(true); } } } void DockView::hideWindowsForSlidingOut() { setBlockHiding(false); if (m_configView) { auto configDialog = qobject_cast(m_configView); if (configDialog) { configDialog->hideConfigWindow(); } } } //! remove latte tasks plasmoid void DockView::removeTasksPlasmoid() { if (!tasksPresent() || !containment()) { return; } foreach (Plasma::Applet *applet, containment()->applets()) { KPluginMetaData meta = applet->kPackage().metadata(); if (meta.pluginId() == "org.kde.latte.plasmoid") { QAction *closeApplet = applet->actions()->action(QStringLiteral("remove")); if (closeApplet) { closeApplet->trigger(); //! remove only the first found return; } } } } //! check if the tasks plasmoid exist in the dock bool DockView::tasksPresent() { if (!this->containment()) { return false; } foreach (Plasma::Applet *applet, this->containment()->applets()) { const auto &provides = KPluginMetaData::readStringList(applet->pluginMetaData().rawData(), QStringLiteral("X-Plasma-Provides")); if (provides.contains(QLatin1String("org.kde.plasma.multitasking"))) { return true; } } return false; } //! check if the tasks plasmoid exist in the dock bool DockView::latteTasksPresent() { if (!this->containment()) { return false; } foreach (Plasma::Applet *applet, this->containment()->applets()) { KPluginMetaData metadata = applet->pluginMetaData(); if (metadata.pluginId() == "org.kde.latte.plasmoid") { return true; } } return false; } //!check if the plasmoid with _name_ exists in the midedata bool DockView::mimeContainsPlasmoid(QMimeData *mimeData, QString name) { if (!mimeData) { return false; } if (mimeData->hasFormat(QStringLiteral("text/x-plasmoidservicename"))) { QString data = mimeData->data(QStringLiteral("text/x-plasmoidservicename")); const QStringList appletNames = data.split('\n', QString::SkipEmptyParts); foreach (const QString &appletName, appletNames) { if (appletName == name) return true; } } return false; } View::Effects *DockView::effects() const { return m_effects; } View::Positioner *DockView::positioner() const { return m_positioner; } VisibilityManager *DockView::visibility() const { return m_visibility; } bool DockView::event(QEvent *e) { if (!m_inDelete) { emit eventTriggered(e); switch (e->type()) { case QEvent::Leave: engine()->trimComponentCache(); break; case QEvent::PlatformSurface: if (auto pe = dynamic_cast(e)) { switch (pe->surfaceEventType()) { case QPlatformSurfaceEvent::SurfaceCreated: setupWaylandIntegration(); if (m_shellSurface) { m_positioner->syncGeometry(); m_effects->updateShadows(); } break; case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: if (m_shellSurface) { delete m_shellSurface; m_shellSurface = nullptr; qDebug() << "WAYLAND dock window surface was deleted..."; m_effects->clearShadows(); } break; } } break; default: break; } } return ContainmentView::event(e);; } void DockView::deactivateApplets() { if (!containment()) { return; } foreach (auto applet, containment()->applets()) { PlasmaQuick::AppletQuickItem *ai = applet->property("_plasma_graphicObject").value(); if (ai) { ai->setExpanded(false); } } } void DockView::toggleAppletExpanded(const int id) { if (!containment()) { return; } foreach (auto applet, containment()->applets()) { if (applet->id() == id) { PlasmaQuick::AppletQuickItem *ai = applet->property("_plasma_graphicObject").value(); if (ai) { if (!ai->isActivationTogglesExpanded()) { ai->setActivationTogglesExpanded(true); } emit applet->activated(); } } } } QVariantList DockView::containmentActions() { QVariantList actions; /*if (containment()->corona()->immutability() != Plasma::Types::Mutable) { return actions; }*/ //FIXME: the trigger string it should be better to be supported this way //const QString trigger = Plasma::ContainmentActions::eventToString(event); const QString trigger = "RightButton;NoModifier"; Plasma::ContainmentActions *plugin = this->containment()->containmentActions().value(trigger); if (!plugin) { return actions; } if (plugin->containment() != this->containment()) { plugin->setContainment(this->containment()); // now configure it KConfigGroup cfg(this->containment()->corona()->config(), "ActionPlugins"); cfg = KConfigGroup(&cfg, QString::number(this->containment()->containmentType())); KConfigGroup pluginConfig = KConfigGroup(&cfg, trigger); plugin->restore(pluginConfig); } foreach (QAction *ac, plugin->contextualActions()) { actions << QVariant::fromValue(ac); } return actions; } void DockView::disableGrabItemBehavior() { setMouseGrabEnabled(false); } void DockView::restoreGrabItemBehavior() { setMouseGrabEnabled(true); if (mouseGrabberItem()) { mouseGrabberItem()->ungrabMouse(); } } //!BEGIN overriding context menus behavior void DockView::mousePressEvent(QMouseEvent *event) { - bool result = m_menuManager->mousePressEvent(event); + bool result = m_contextMenu->mousePressEvent(event); emit contextMenuIsShownChanged(); if (result) { PlasmaQuick::ContainmentView::mousePressEvent(event); } } //!END overriding context menus behavior //!BEGIN configuration functions void DockView::saveConfig() { if (!this->containment()) return; auto config = this->containment()->config(); config.writeEntry("onPrimary", onPrimary()); config.writeEntry("dockWindowBehavior", dockWinBehavior()); config.writeEntry("isPreferredForShortcuts", isPreferredForShortcuts()); config.sync(); } void DockView::restoreConfig() { if (!this->containment()) return; auto config = this->containment()->config(); m_onPrimary = config.readEntry("onPrimary", true); m_dockWinBehavior = config.readEntry("dockWindowBehavior", true); m_isPreferredForShortcuts = config.readEntry("isPreferredForShortcuts", false); //! Send changed signals at the end in order to be sure that saveConfig //! wont rewrite default/invalid values emit onPrimaryChanged(); emit dockWinBehaviorChanged(); } //!END configuration functions } //!END namespace diff --git a/app/dock/dockview.h b/app/dock/dockview.h index f97020ec..ebaf1fe8 100644 --- a/app/dock/dockview.h +++ b/app/dock/dockview.h @@ -1,280 +1,283 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * 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 . */ #ifndef DOCKVIEW_H #define DOCKVIEW_H #include "dockconfigview.h" #include "effects.h" #include "positioner.h" #include "visibilitymanager.h" #include "../layout.h" #include "../plasmaquick/containmentview.h" #include "../plasmaquick/configview.h" #include "../../liblattedock/dock.h" #include #include #include #include #include #include #include namespace Plasma { class Types; class Corona; class Containment; } namespace KWayland { namespace Client { class PlasmaShellSurface; } } namespace Latte { -class DockMenuManager; class Layout; + +namespace View { +class ContextMenu; +} } namespace Latte { class DockView : public PlasmaQuick::ContainmentView { Q_OBJECT Q_PROPERTY(bool alternativesIsShown READ alternativesIsShown NOTIFY alternativesIsShownChanged) Q_PROPERTY(bool behaveAsPlasmaPanel READ behaveAsPlasmaPanel WRITE setBehaveAsPlasmaPanel NOTIFY behaveAsPlasmaPanelChanged) Q_PROPERTY(bool contextMenuIsShown READ contextMenuIsShown NOTIFY contextMenuIsShownChanged) Q_PROPERTY(bool dockWinBehavior READ dockWinBehavior WRITE setDockWinBehavior NOTIFY dockWinBehaviorChanged) //! Because Latte uses animations, changing to edit mode it may be different than //! when the isUserConfiguring changes value Q_PROPERTY(bool inEditMode READ inEditMode WRITE setInEditMode NOTIFY inEditModeChanged) Q_PROPERTY(bool isPreferredForShortcuts READ isPreferredForShortcuts WRITE setIsPreferredForShortcuts NOTIFY isPreferredForShortcutsChanged) Q_PROPERTY(bool onPrimary READ onPrimary WRITE setOnPrimary NOTIFY onPrimaryChanged) Q_PROPERTY(int alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged) Q_PROPERTY(int fontPixelSize READ fontPixelSize WRITE setFontPixelSize NOTIFY fontPixelSizeChanged) Q_PROPERTY(int x READ x NOTIFY xChanged) Q_PROPERTY(int y READ y NOTIFY yChanged) Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int height READ height NOTIFY heightChanged) Q_PROPERTY(int maxThickness READ maxThickness WRITE setMaxThickness NOTIFY maxThicknessChanged) Q_PROPERTY(int normalThickness READ normalThickness WRITE setNormalThickness NOTIFY normalThicknessChanged) Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged) Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged) Q_PROPERTY(Latte::View::Effects *effects READ effects NOTIFY effectsChanged) Q_PROPERTY(Layout *managedLayout READ managedLayout WRITE setManagedLayout NOTIFY managedLayoutChanged) Q_PROPERTY(Latte::View::Positioner *positioner READ positioner NOTIFY positionerChanged) Q_PROPERTY(VisibilityManager *visibility READ visibility NOTIFY visibilityChanged) Q_PROPERTY(QRect absoluteGeometry READ absGeometry NOTIFY absGeometryChanged) Q_PROPERTY(QRect localGeometry READ localGeometry WRITE setLocalGeometry NOTIFY localGeometryChanged) Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged) public: DockView(Plasma::Corona *corona, QScreen *targetScreen = nullptr, bool dockWindowBehavior = false); virtual ~DockView(); void init(); bool alternativesIsShown() const; void setAlternativesIsShown(bool show); bool inDelete() const; bool onPrimary() const; void setOnPrimary(bool flag); int currentThickness() const; bool behaveAsPlasmaPanel() const; void setBehaveAsPlasmaPanel(bool behavior); bool contextMenuIsShown() const; bool dockWinBehavior() const; void setDockWinBehavior(bool dock); bool inEditMode() const; void setInEditMode(bool edit); bool isPreferredForShortcuts() const; void setIsPreferredForShortcuts(bool preferred); float maxLength() const; void setMaxLength(float length); int fontPixelSize() const; void setFontPixelSize(int size); int maxThickness() const; void setMaxThickness(int thickness); int normalThickness() const; void setNormalThickness(int thickness); int offset() const; void setOffset(int offset); int alignment() const; void setAlignment(int alignment); QRect absGeometry() const; QRect screenGeometry() const; QRect localGeometry() const; void setLocalGeometry(const QRect &geometry); bool settingsWindowIsShown(); void showSettingsWindow(); View::Effects *effects() const; View::Positioner *positioner() const; VisibilityManager *visibility() const; Layout *managedLayout() const; void setManagedLayout(Layout *layout); KWayland::Client::PlasmaShellSurface *surface(); void reconsiderScreen(); //! these are signals that create crashes, such a example is the availableScreenRectChanged from corona //! when its containment is destroyed void disconnectSensitiveSignals(); public slots: Q_INVOKABLE void removeDock(); Q_INVOKABLE void copyDock(); Q_INVOKABLE QVariantList containmentActions(); Q_INVOKABLE void deactivateApplets(); Q_INVOKABLE void moveToLayout(QString layoutName); Q_INVOKABLE void removeTasksPlasmoid(); Q_INVOKABLE void setBlockHiding(bool block); Q_INVOKABLE void toggleAppletExpanded(const int id); Q_INVOKABLE bool mimeContainsPlasmoid(QMimeData *mimeData, QString name); Q_INVOKABLE bool tasksPresent(); Q_INVOKABLE bool latteTasksPresent(); void updateAbsDockGeometry(bool bypassChecks = false); Q_INVOKABLE void disableGrabItemBehavior(); Q_INVOKABLE void restoreGrabItemBehavior(); protected slots: void showConfigurationInterface(Plasma::Applet *applet) override; protected: bool event(QEvent *ev) override; void mousePressEvent(QMouseEvent *event) override; signals: void addInternalViewSplitter(); void removeInternalViewSplitter(); void eventTriggered(QEvent *ev); void activitiesChanged(); void alternativesIsShownChanged(); void alignmentChanged(); void behaveAsPlasmaPanelChanged(); void contextMenuIsShownChanged(); void dockLocationChanged(); void dockWinBehaviorChanged(); void effectsChanged(); void fontPixelSizeChanged(); void widthChanged(); void heightChanged(); void inEditModeChanged(); void isPreferredForShortcutsChanged(); void localGeometryChanged(); void managedLayoutChanged(); void maxLengthChanged(); void maxThicknessChanged(); void normalThicknessChanged(); void offsetChanged(); void onPrimaryChanged(); void visibilityChanged(); void positionerChanged(); void screenGeometryChanged(); void xChanged(); void yChanged(); void absGeometryChanged(const QRect &geometry); private slots: void availableScreenRectChanged(); void hideWindowsForSlidingOut(); void preferredViewForShortcutsChangedSlot(DockView *view); void statusChanged(Plasma::Types::ItemStatus); void restoreConfig(); void saveConfig(); private: void applyActivitiesToWindows(); void initSignalingForLocationChangeSliding(); void setupWaylandIntegration(); void updateAppletContainsMethod(); private: Plasma::Containment *containmentById(uint id); bool m_alternativesIsShown{false}; bool m_behaveAsPlasmaPanel{false}; bool m_dockWinBehavior{true}; bool m_inDelete{false}; bool m_inEditMode{false}; bool m_isPreferredForShortcuts{false}; bool m_onPrimary{true}; int m_fontPixelSize{ -1}; int m_maxThickness{24}; int m_normalThickness{24}; int m_offset{0}; float m_maxLength{1}; Dock::Alignment m_alignment{Dock::Center}; QRect m_localGeometry; QRect m_absGeometry; Layout *m_managedLayout{nullptr}; QPointer m_configView; - QPointer m_menuManager; + QPointer m_contextMenu; QPointer m_effects; QPointer m_positioner; QPointer m_visibility; //! Connections to release and bound for the managed layout std::array connectionsManagedLayout; KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr}; }; } #endif