diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt --- a/shell/CMakeLists.txt +++ b/shell/CMakeLists.txt @@ -36,6 +36,7 @@ standaloneappcorona osd.cpp coronatesthelper.cpp + othershellhelper.cpp debug.cpp screenpool.cpp softwarerendernotifier.cpp diff --git a/shell/othershellhelper.h b/shell/othershellhelper.h new file mode 100644 --- /dev/null +++ b/shell/othershellhelper.h @@ -0,0 +1,39 @@ +#ifndef OTHERSHELLHELPER_H +#define OTHERSHELLHELPER_H + +#include +#include + +class ShellCorona; + +class OtherShellHelper : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface","org.kde.plasmashell") + + public: + explicit OtherShellHelper(ShellCorona *plasmashellCorona); + QRegion availableScreenRegion(quint32 id) const; + + signals: + // these signals are from plasmashellCorona + Q_SCRIPTABLE void _availableScreenRectChanged(); + Q_SCRIPTABLE void _availableScreenRegionChanged(); + + public Q_SLOTS: + QRect availableScreenRect(int id, bool plasmashell=false) const; + QByteArray availableScreenRegion(int id, bool plasmashell=false) const; + bool connected() const; + void setConnected(bool connected); + void setAvailableScreenRect(int screenId, QRect rect); + void setAvailableScreenRegion(int screenId, QByteArray region); + void test(int screenId, int x, int y, int width, int height); + + private: + bool m_connected; + ShellCorona *m_plasmashellCorona; + QHash m_availableScreenRects; + QHash m_availableScreenRegions; +}; + +#endif diff --git a/shell/othershellhelper.cpp b/shell/othershellhelper.cpp new file mode 100644 --- /dev/null +++ b/shell/othershellhelper.cpp @@ -0,0 +1,78 @@ +#include "othershellhelper.h" +#include "shellcorona.h" + +#include +#include + +OtherShellHelper::OtherShellHelper(ShellCorona *plasmashellCorona) : QObject(qobject_cast(plasmashellCorona)), + m_plasmashellCorona(plasmashellCorona), + m_connected(false) +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerObject("/otherShellHelper", this, QDBusConnection::ExportAllSlots|QDBusConnection::ExportScriptableSignals); +} + +QRect OtherShellHelper::availableScreenRect(int id, bool plasmashell) const +{ + return plasmashell? m_plasmashellCorona->_availableScreenRect(id) : m_availableScreenRects[id]; +} + +QByteArray OtherShellHelper::availableScreenRegion(int id, bool plasmashell) const +{ + QByteArray ba; + QDataStream d(&ba, QIODevice::WriteOnly); + d << (plasmashell? m_plasmashellCorona->_availableScreenRegion(id) : m_availableScreenRegions[id]); + + return ba; +} + +QRegion OtherShellHelper::availableScreenRegion(quint32 id) const { + return m_availableScreenRegions[id]; +} + +void OtherShellHelper::setAvailableScreenRect(int screenId, QRect rect) { + if (m_availableScreenRects[screenId] == rect) { + return; + } + m_availableScreenRects[screenId] = rect; + emit m_plasmashellCorona->availableScreenRectChanged(); +} + +void OtherShellHelper::setAvailableScreenRegion(int screenId, QByteArray region) { + QRegion r; + QDataStream d(®ion, QIODevice::ReadOnly); + d >> r; + + if (m_availableScreenRegions[screenId] != r) { + m_availableScreenRegions[screenId] = r; + emit m_plasmashellCorona->availableScreenRegionChanged(); + } + return; +} + +bool OtherShellHelper::connected() const +{ + return m_connected; +} + +void OtherShellHelper::setConnected(bool connected) +{ + if (m_connected == connected) { + return; + } + + m_connected = connected; + + if (!connected) { + emit m_plasmashellCorona->availableScreenRectChanged(); + emit m_plasmashellCorona->availableScreenRegionChanged(); + + m_availableScreenRects.clear(); + m_availableScreenRegions.clear(); + } +} + +void OtherShellHelper::test(int screenId, int x, int y, int width, int height) { + setConnected(true); + setAvailableScreenRect(screenId, QRect(x, y, width, height)); +} diff --git a/shell/shellcorona.h b/shell/shellcorona.h --- a/shell/shellcorona.h +++ b/shell/shellcorona.h @@ -38,6 +38,7 @@ class QMenu; class QScreen; class ScreenPool; +class OtherShellHelper; namespace KActivities { @@ -89,6 +90,10 @@ Q_INVOKABLE QRegion availableScreenRegion(int id) const override; Q_INVOKABLE QRect availableScreenRect(int id) const override; + // expose to otherShellHelper + QRegion _availableScreenRegion(int id) const; + QRect _availableScreenRect(int id) const; + Q_INVOKABLE QStringList availableActivities() const; PanelView *panelView(Plasma::Containment *containment) const; @@ -116,6 +121,8 @@ Q_SIGNALS: void glInitializationFailed(); + void _availableScreenRectChanged(); + void _availableScreenRegionChanged(); public Q_SLOTS: /** @@ -256,6 +263,8 @@ KWayland::Client::PlasmaShell *m_waylandPlasmaShell; bool m_closingDown : 1; QString m_testModeLayout; + + OtherShellHelper *m_otherShellHelper; }; #endif // SHELLCORONA_H diff --git a/shell/shellcorona.cpp b/shell/shellcorona.cpp --- a/shell/shellcorona.cpp +++ b/shell/shellcorona.cpp @@ -21,6 +21,7 @@ */ #include "shellcorona.h" +#include "othershellhelper.h" #include @@ -107,7 +108,8 @@ m_addPanelsMenu(nullptr), m_interactiveConsole(nullptr), m_waylandPlasmaShell(nullptr), - m_closingDown(false) + m_closingDown(false), + m_otherShellHelper(new OtherShellHelper(this)) { setupWaylandIntegration(); qmlRegisterUncreatableType("org.kde.plasma.shell", 2, 0, "Desktop", QStringLiteral("It is not possible to create objects of type Desktop")); @@ -124,7 +126,22 @@ executeSetupPlasmoidScript(c, c); }); - connect(this, &Plasma::Corona::availableScreenRectChanged, this, &Plasma::Corona::availableScreenRegionChanged); + connect(this, &ShellCorona::_availableScreenRectChanged, this, [=](){ + if (m_otherShellHelper->connected()) { + emit m_otherShellHelper->_availableScreenRectChanged(); + } else { + emit availableScreenRectChanged(); + } + }); + connect(this, &ShellCorona::_availableScreenRegionChanged, this, [=](){ + if (m_otherShellHelper->connected()) { + emit m_otherShellHelper->_availableScreenRegionChanged(); + } else { + emit availableScreenRegionChanged(); + } + }); + connect(this, &ShellCorona::_availableScreenRectChanged, this, &ShellCorona::_availableScreenRegionChanged); + m_appConfigSyncTimer.setSingleShot(true); m_appConfigSyncTimer.setInterval(s_configSyncDelay); @@ -1042,6 +1059,14 @@ } QRegion ShellCorona::availableScreenRegion(int id) const +{ + if (m_otherShellHelper->connected() && !m_otherShellHelper->availableScreenRegion(static_cast(id)).isNull()) { + return m_otherShellHelper->availableScreenRegion(static_cast(id)); + } + return _availableScreenRegion(id); +} + +QRegion ShellCorona::_availableScreenRegion(int id) const { DesktopView* view = m_desktopViewforId.value(id); if (!view) { @@ -1062,6 +1087,14 @@ } QRect ShellCorona::availableScreenRect(int id) const +{ + if (m_otherShellHelper->connected() && !m_otherShellHelper->availableScreenRect(id).isNull()) { + return m_otherShellHelper->availableScreenRect(id); + } + return _availableScreenRect(id); +} + +QRect ShellCorona::_availableScreenRect(int id) const { DesktopView *view = m_desktopViewforId.value(id); if (!view) { @@ -1258,8 +1291,8 @@ const int id = m_screenPool->id(screen->name()); if (id >= 0) { emit screenGeometryChanged(id); - emit availableScreenRegionChanged(); - emit availableScreenRectChanged(); + emit _availableScreenRegionChanged(); + emit _availableScreenRectChanged(); } }); @@ -1288,7 +1321,7 @@ m_waitingPanelsTimer.start(); } - emit availableScreenRectChanged(); + emit _availableScreenRectChanged(); emit screenAdded(m_screenPool->id(screen->name())); CHECK_SCREEN_INVARIANTS @@ -1365,19 +1398,19 @@ if (panel->rendererInterface()->graphicsApi() != QSGRendererInterface::Software) { connect(panel, &QQuickWindow::sceneGraphError, this, &ShellCorona::glInitializationFailed); } - connect(panel, &QWindow::visibleChanged, this, &Plasma::Corona::availableScreenRectChanged); - connect(panel, &PanelView::locationChanged, this, &Plasma::Corona::availableScreenRectChanged); - connect(panel, &PanelView::visibilityModeChanged, this, &Plasma::Corona::availableScreenRectChanged); - connect(panel, &PanelView::thicknessChanged, this, &Plasma::Corona::availableScreenRectChanged); + connect(panel, &QWindow::visibleChanged, this, &ShellCorona::_availableScreenRectChanged); + connect(panel, &PanelView::locationChanged, this, &ShellCorona::_availableScreenRectChanged); + connect(panel, &PanelView::visibilityModeChanged, this, &ShellCorona::_availableScreenRectChanged); + connect(panel, &PanelView::thicknessChanged, this, &ShellCorona::_availableScreenRectChanged); m_panelViews[cont] = panel; panel->setContainment(cont); cont->reactToScreenChange(); connect(cont, &QObject::destroyed, this, &ShellCorona::panelContainmentDestroyed); } m_waitingPanels = stillWaitingPanels; - emit availableScreenRectChanged(); + emit _availableScreenRectChanged(); } void ShellCorona::panelContainmentDestroyed(QObject *cont) @@ -1387,7 +1420,7 @@ //don't make things relayout when the application is quitting //NOTE: qApp->closingDown() is still false here if (!m_closingDown) { - emit availableScreenRectChanged(); + emit _availableScreenRectChanged(); } } @@ -1772,7 +1805,7 @@ //Save now as we now have a screen, so lastScreen will not be -1 newContainment->save(newCg); requestConfigSync(); - emit availableScreenRectChanged(); + emit _availableScreenRectChanged(); return newContainment; }