fix #889,dont crash on applcation exit

--the wayland interface couldnt orchestrate correctly
with the corona and the application exit. The whole
architecture changed and the window manager now is
provided by corona and corona is also responsible to
keep only one instance of it and close on exit.
pull/2/head
Michail Vourlakos 7 years ago
parent b4b68e5bb1
commit cb88d134f4

@ -51,21 +51,5 @@ void AbstractWindowInterface::removeDock(WindowId wid)
m_docks.erase(it); m_docks.erase(it);
} }
AbstractWindowInterface &AbstractWindowInterface::self()
{
if (m_wm)
return *m_wm;
if (KWindowSystem::isPlatformWayland()) {
//! TODO: WaylandWindowInterface
m_wm = std::make_unique<WaylandInterface>();
} else { /* if(KWindowSystem::isPlatformX11) */
m_wm = std::make_unique<XWindowInterface>();
}
return *m_wm;
}
} }
std::unique_ptr<Latte::AbstractWindowInterface> Latte::AbstractWindowInterface::m_wm;

@ -80,8 +80,6 @@ public:
void addDock(WindowId wid); void addDock(WindowId wid);
void removeDock(WindowId wid); void removeDock(WindowId wid);
static AbstractWindowInterface &self();
signals: signals:
void activeWindowChanged(WindowId wid); void activeWindowChanged(WindowId wid);
void windowChanged(WindowId winfo); void windowChanged(WindowId winfo);
@ -94,8 +92,6 @@ protected:
std::list<WindowId> m_windows; std::list<WindowId> m_windows;
std::list<WindowId> m_docks; std::list<WindowId> m_docks;
QPointer<KActivities::Consumer> m_activities; QPointer<KActivities::Consumer> m_activities;
static std::unique_ptr<AbstractWindowInterface> m_wm;
}; };
// namespace alias // namespace alias

@ -52,6 +52,8 @@ DockConfigView::DockConfigView(Plasma::Containment *containment, DockView *dockV
: PlasmaQuick::ConfigView(containment, parent), : PlasmaQuick::ConfigView(containment, parent),
m_dockView(dockView) m_dockView(dockView)
{ {
m_corona = qobject_cast<DockCorona *>(m_dockView->containment()->corona());
setupWaylandIntegration(); setupWaylandIntegration();
setScreen(m_dockView->screen()); setScreen(m_dockView->screen());
@ -281,17 +283,17 @@ void DockConfigView::syncSlideEffect()
break; break;
} }
WindowSystem::self().slideWindow(*this, slideLocation); m_corona->wm()->slideWindow(*this, slideLocation);
} }
void DockConfigView::showEvent(QShowEvent *ev) void DockConfigView::showEvent(QShowEvent *ev)
{ {
QQuickWindow::showEvent(ev); QQuickWindow::showEvent(ev);
WindowSystem::self().setDockExtraFlags(*this); m_corona->wm()->setDockExtraFlags(*this);
setFlags(wFlags()); setFlags(wFlags());
WindowSystem::self().enableBlurBehind(*this); m_corona->wm()->enableBlurBehind(*this);
syncGeometry(); syncGeometry();
syncSlideEffect(); syncSlideEffect();

@ -48,6 +48,7 @@ class PlasmaShellSurface;
namespace Latte { namespace Latte {
class DockCorona;
class DockView; class DockView;
class DockConfigView : public PlasmaQuick::ConfigView { class DockConfigView : public PlasmaQuick::ConfigView {
@ -122,6 +123,7 @@ private:
Plasma::FrameSvg::EnabledBorders m_enabledBorders{Plasma::FrameSvg::AllBorders}; Plasma::FrameSvg::EnabledBorders m_enabledBorders{Plasma::FrameSvg::AllBorders};
DockCorona *m_corona{nullptr};
KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr}; KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr};
}; };

@ -48,6 +48,8 @@ DockSecConfigView::DockSecConfigView(DockView *dockView, QWindow *parent)
m_parent(parent), m_parent(parent),
m_dockView(dockView) m_dockView(dockView)
{ {
m_corona = qobject_cast<DockCorona *>(m_dockView->containment()->corona());
setupWaylandIntegration(); setupWaylandIntegration();
setResizeMode(QQuickView::SizeViewToRootObject); setResizeMode(QQuickView::SizeViewToRootObject);
@ -225,17 +227,17 @@ void DockSecConfigView::syncSlideEffect()
break; break;
} }
WindowSystem::self().slideWindow(*this, slideLocation); m_corona->wm()->slideWindow(*this, slideLocation);
} }
void DockSecConfigView::showEvent(QShowEvent *ev) void DockSecConfigView::showEvent(QShowEvent *ev)
{ {
QQuickWindow::showEvent(ev); QQuickWindow::showEvent(ev);
WindowSystem::self().setDockExtraFlags(*this); m_corona->wm()->setDockExtraFlags(*this);
setFlags(wFlags()); setFlags(wFlags());
WindowSystem::self().enableBlurBehind(*this); m_corona->wm()->enableBlurBehind(*this);
syncGeometry(); syncGeometry();
syncSlideEffect(); syncSlideEffect();

@ -45,6 +45,7 @@ class PlasmaShellSurface;
namespace Latte { namespace Latte {
class DockCorona;
class DockView; class DockView;
class DockSecConfigView : public QQuickView { class DockSecConfigView : public QQuickView {
@ -90,6 +91,7 @@ private:
Plasma::FrameSvg::EnabledBorders m_enabledBorders{Plasma::FrameSvg::AllBorders}; Plasma::FrameSvg::EnabledBorders m_enabledBorders{Plasma::FrameSvg::AllBorders};
DockCorona *m_corona{nullptr};
KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr}; KWayland::Client::PlasmaShellSurface *m_shellSurface{nullptr};
}; };

@ -167,12 +167,6 @@ DockView::~DockView()
if (m_visibility) if (m_visibility)
delete m_visibility; delete m_visibility;
if (m_shellSurface) {
m_shellSurface->release();
delete m_shellSurface;
m_shellSurface = nullptr;
}
} }
void DockView::init() void DockView::init()

@ -33,10 +33,11 @@ namespace Latte {
//! BEGIN: VisiblityManagerPrivate implementation //! BEGIN: VisiblityManagerPrivate implementation
VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q) VisibilityManagerPrivate::VisibilityManagerPrivate(PlasmaQuick::ContainmentView *view, VisibilityManager *q)
: QObject(nullptr), q(q), view(view), wm(&WindowSystem::self()) : QObject(nullptr), q(q), view(view)
{ {
dockView = qobject_cast<DockView *>(view); dockView = qobject_cast<DockView *>(view);
dockCorona = qobject_cast<DockCorona *>(view->corona()); dockCorona = qobject_cast<DockCorona *>(view->corona());
wm = dockCorona->wm();
if (dockView) { if (dockView) {
connect(dockView, &DockView::eventTriggered, this, &VisibilityManagerPrivate::viewEventManager); connect(dockView, &DockView::eventTriggered, this, &VisibilityManagerPrivate::viewEventManager);

@ -28,6 +28,8 @@
#include "layoutmanager.h" #include "layoutmanager.h"
#include "screenpool.h" #include "screenpool.h"
#include "universalsettings.h" #include "universalsettings.h"
#include "waylandinterface.h"
#include "xwindowinterface.h"
#include "dock/dockview.h" #include "dock/dockview.h"
#include "packageplugins/shell/dockpackage.h" #include "packageplugins/shell/dockpackage.h"
@ -64,6 +66,7 @@
#include <KWayland/Client/connection_thread.h> #include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h> #include <KWayland/Client/registry.h>
#include <KWayland/Client/plasmashell.h> #include <KWayland/Client/plasmashell.h>
#include <KWayland/Client/plasmawindowmanagement.h>
namespace Latte { namespace Latte {
@ -78,6 +81,14 @@ DockCorona::DockCorona(bool defaultLayoutOnStartup, QString layoutNameOnStartUp,
m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), this)), m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), this)),
m_layoutManager(new LayoutManager(this)) m_layoutManager(new LayoutManager(this))
{ {
//! create the window manager
if (KWindowSystem::isPlatformWayland()) {
m_wm = new WaylandInterface(this);
} else {
m_wm = new XWindowInterface(this);
}
setupWaylandIntegration(); setupWaylandIntegration();
KPackage::Package package(new DockPackage(this)); KPackage::Package package(new DockPackage(this));
@ -139,6 +150,7 @@ DockCorona::~DockCorona()
m_layoutManager->unload(); m_layoutManager->unload();
m_wm->deleteLater();
m_globalShortcuts->deleteLater(); m_globalShortcuts->deleteLater();
m_layoutManager->deleteLater(); m_layoutManager->deleteLater();
m_screenPool->deleteLater(); m_screenPool->deleteLater();
@ -228,6 +240,17 @@ void DockCorona::setupWaylandIntegration()
m_waylandDockCorona = registry->createPlasmaShell(name, version, this); m_waylandDockCorona = registry->createPlasmaShell(name, version, this);
}); });
QObject::connect(registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced,
[this, registry](quint32 name, quint32 version) {
KWayland::Client::PlasmaWindowManagement *pwm = registry->createPlasmaWindowManagement(name, version, this);
WaylandInterface *wI = qobject_cast<WaylandInterface *>(m_wm);
if (wI) {
wI->initWindowManagement(pwm);
}
});
registry->setup(); registry->setup();
connection->roundtrip(); connection->roundtrip();
} }
@ -323,6 +346,11 @@ LayoutManager *DockCorona::layoutManager() const
return m_layoutManager; return m_layoutManager;
} }
AbstractWindowInterface *DockCorona::wm() const
{
return m_wm;
}
int DockCorona::numScreens() const int DockCorona::numScreens() const
{ {
return qGuiApp->screens().count(); return qGuiApp->screens().count();
@ -613,8 +641,8 @@ void DockCorona::aboutApplication()
aboutDialog = new KAboutApplicationDialog(KAboutData::applicationData()); aboutDialog = new KAboutApplicationDialog(KAboutData::applicationData());
connect(aboutDialog.data(), &QDialog::finished, aboutDialog.data(), &QObject::deleteLater); connect(aboutDialog.data(), &QDialog::finished, aboutDialog.data(), &QObject::deleteLater);
WindowSystem::self().skipTaskBar(*aboutDialog); m_wm->skipTaskBar(*aboutDialog);
WindowSystem::self().setKeepAbove(*aboutDialog, true); m_wm->setKeepAbove(*aboutDialog, true);
aboutDialog->show(); aboutDialog->show();
} }

@ -57,6 +57,7 @@ class PlasmaShell;
} }
namespace Latte { namespace Latte {
class AbstractWindowInterface;
class ScreenPool; class ScreenPool;
class GlobalShortcuts; class GlobalShortcuts;
class UniversalSettings; class UniversalSettings;
@ -97,6 +98,7 @@ public:
void closeApplication(); void closeApplication();
AbstractWindowInterface *wm() const;
KActivities::Consumer *activitiesConsumer() const; KActivities::Consumer *activitiesConsumer() const;
ScreenPool *screenPool() const; ScreenPool *screenPool() const;
UniversalSettings *universalSettings() const; UniversalSettings *universalSettings() const;
@ -162,6 +164,7 @@ private:
KActivities::Consumer *m_activityConsumer; KActivities::Consumer *m_activityConsumer;
QPointer<KAboutApplicationDialog> aboutDialog; QPointer<KAboutApplicationDialog> aboutDialog;
AbstractWindowInterface *m_wm{nullptr};
ScreenPool *m_screenPool{nullptr}; ScreenPool *m_screenPool{nullptr};
GlobalShortcuts *m_globalShortcuts{nullptr}; GlobalShortcuts *m_globalShortcuts{nullptr};
UniversalSettings *m_universalSettings{nullptr}; UniversalSettings *m_universalSettings{nullptr};

@ -119,10 +119,10 @@ void InfoView::showEvent(QShowEvent *ev)
{ {
QQuickWindow::showEvent(ev); QQuickWindow::showEvent(ev);
WindowSystem::self().setDockExtraFlags(*this); m_corona->wm()->setDockExtraFlags(*this);
setFlags(wFlags()); setFlags(wFlags());
WindowSystem::self().enableBlurBehind(*this); m_corona->wm()->enableBlurBehind(*this);
syncGeometry(); syncGeometry();

@ -19,6 +19,7 @@
*/ */
#include "waylandinterface.h" #include "waylandinterface.h"
#include "dockcorona.h"
#include "../liblattedock/extras.h" #include "../liblattedock/extras.h"
#include <QDebug> #include <QDebug>
@ -72,7 +73,7 @@ public:
if (!s) if (!s)
return; return;
m_shellSurface = m_waylandInterface->m_plasmaShell->createSurface(s, this); m_shellSurface = m_waylandInterface->waylandDockCoronaInterface()->createSurface(s, this);
qDebug() << "wayland ghost window surface was created..."; qDebug() << "wayland ghost window surface was created...";
m_shellSurface->setSkipTaskbar(true); m_shellSurface->setSkipTaskbar(true);
@ -88,58 +89,13 @@ public:
WaylandInterface::WaylandInterface(QObject *parent) WaylandInterface::WaylandInterface(QObject *parent)
: AbstractWindowInterface(parent) : AbstractWindowInterface(parent)
{ {
m_activities = new KActivities::Consumer(this); m_corona = qobject_cast<DockCorona *>(parent);
m_connection = ConnectionThread::fromApplication(this);
if (!m_connection) {
qWarning() << "Failed getting Wayland connection from QPA";
return;
}
m_registry = new Registry(this);
m_registry->create(m_connection);
connect(qApp, &QCoreApplication::aboutToQuit, this, [&]() {
if (m_wm)
m_wm->release();
if (m_plasmaShell)
m_plasmaShell->release();
m_registry->release();
});
m_registry->setup();
m_connection->roundtrip();
const auto wmInterface = m_registry->interface(Registry::Interface::PlasmaWindowManagement); m_activities = new KActivities::Consumer(this);
if (wmInterface.name == 0) {
qWarning() << "This compositor does not support the Plasma Window Management interface";
return;
}
m_wm = m_registry->createPlasmaWindowManagement(wmInterface.name, wmInterface.version, this);
connect(m_wm, &PlasmaWindowManagement::windowCreated, this, &WaylandInterface::windowCreatedProxy);
connect(m_wm, &PlasmaWindowManagement::activeWindowChanged, this, [&]() noexcept {
auto w = m_wm->activeWindow();
emit activeWindowChanged(w ? w->internalId() : 0);
}, Qt::QueuedConnection);
const auto shellInterface = m_registry->interface(Registry::Interface::PlasmaShell);
if (shellInterface.name == 0) {
qWarning() << "Plasma Shell interface can't be created";
return;
}
m_plasmaShell = m_registry->createPlasmaShell(shellInterface.name, shellInterface.version, this);
connect(m_activities.data(), &KActivities::Consumer::currentActivityChanged connect(m_activities.data(), &KActivities::Consumer::currentActivityChanged
, this, &WaylandInterface::currentActivityChanged); , this, &WaylandInterface::currentActivityChanged);
} }
WaylandInterface::~WaylandInterface() WaylandInterface::~WaylandInterface()
@ -150,6 +106,22 @@ void WaylandInterface::init()
{ {
} }
void WaylandInterface::initWindowManagement(KWayland::Client::PlasmaWindowManagement *windowManagement)
{
m_windowManagement = windowManagement;
connect(m_windowManagement, &PlasmaWindowManagement::windowCreated, this, &WaylandInterface::windowCreatedProxy);
connect(m_windowManagement, &PlasmaWindowManagement::activeWindowChanged, this, [&]() noexcept {
auto w = m_windowManagement->activeWindow();
emit activeWindowChanged(w ? w->internalId() : 0);
}, Qt::QueuedConnection);
}
KWayland::Client::PlasmaShell *WaylandInterface::waylandDockCoronaInterface() const
{
return m_corona->waylandDockCoronaInterface();
}
void WaylandInterface::setDockExtraFlags(QWindow &view) void WaylandInterface::setDockExtraFlags(QWindow &view)
{ {
Q_UNUSED(view) Q_UNUSED(view)
@ -192,7 +164,11 @@ void WaylandInterface::removeDockStruts(QWindow &view) const
WindowId WaylandInterface::activeWindow() const WindowId WaylandInterface::activeWindow() const
{ {
auto wid = m_wm->activeWindow(); if (!m_windowManagement) {
return 0;
}
auto wid = m_windowManagement->activeWindow();
return wid ? wid->internalId() : 0; return wid ? wid->internalId() : 0;
} }
@ -251,7 +227,11 @@ void WaylandInterface::enableBlurBehind(QWindow &view) const
WindowInfoWrap WaylandInterface::requestInfoActive() const WindowInfoWrap WaylandInterface::requestInfoActive() const
{ {
auto w = m_wm->activeWindow(); if (!m_windowManagement) {
return {};
}
auto w = m_windowManagement->activeWindow();
if (!w) return {}; if (!w) return {};
@ -282,33 +262,37 @@ WindowInfoWrap WaylandInterface::requestInfoActive() const
bool WaylandInterface::isOnCurrentDesktop(WindowId wid) const bool WaylandInterface::isOnCurrentDesktop(WindowId wid) const
{ {
auto it = std::find_if(m_wm->windows().constBegin(), m_wm->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept { if (!m_windowManagement) {
return false;
}
auto it = std::find_if(m_windowManagement->windows().constBegin(), m_windowManagement->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept {
return w->isValid() && w->internalId() == wid; return w->isValid() && w->internalId() == wid;
}); });
//qDebug() << "desktop:" << (it != m_wm->windows().constEnd() ? (*it)->virtualDesktop() : -1) << KWindowSystem::currentDesktop(); //qDebug() << "desktop:" << (it != m_windowManagement->windows().constEnd() ? (*it)->virtualDesktop() : -1) << KWindowSystem::currentDesktop();
//return true; //return true;
return it != m_wm->windows().constEnd() && ((*it)->virtualDesktop() == KWindowSystem::currentDesktop() || (*it)->isOnAllDesktops()); return it != m_windowManagement->windows().constEnd() && ((*it)->virtualDesktop() == KWindowSystem::currentDesktop() || (*it)->isOnAllDesktops());
} }
bool WaylandInterface::isOnCurrentActivity(WindowId wid) const bool WaylandInterface::isOnCurrentActivity(WindowId wid) const
{ {
auto it = std::find_if(m_wm->windows().constBegin(), m_wm->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept { auto it = std::find_if(m_windowManagement->windows().constBegin(), m_windowManagement->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept {
return w->isValid() && w->internalId() == wid; return w->isValid() && w->internalId() == wid;
}); });
//TODO: Not yet implemented //TODO: Not yet implemented
return it != m_wm->windows().constEnd() && true; return it != m_windowManagement->windows().constEnd() && true;
} }
WindowInfoWrap WaylandInterface::requestInfo(WindowId wid) const WindowInfoWrap WaylandInterface::requestInfo(WindowId wid) const
{ {
auto it = std::find_if(m_wm->windows().constBegin(), m_wm->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept { auto it = std::find_if(m_windowManagement->windows().constBegin(), m_windowManagement->windows().constEnd(), [&wid](PlasmaWindow * w) noexcept {
return w->isValid() && w->internalId() == wid; return w->isValid() && w->internalId() == wid;
}); });
if (it == m_wm->windows().constEnd()) if (it == m_windowManagement->windows().constEnd())
return {}; return {};
WindowInfoWrap winfoWrap; WindowInfoWrap winfoWrap;

@ -39,6 +39,8 @@
namespace Latte { namespace Latte {
class DockCorona;
namespace Private { namespace Private {
/** /**
* @brief this class is use for create the struts inside wayland * @brief this class is use for create the struts inside wayland
@ -72,20 +74,22 @@ public:
void slideWindow(QWindow &view, Slide location) const override; void slideWindow(QWindow &view, Slide location) const override;
void enableBlurBehind(QWindow &view) const override; void enableBlurBehind(QWindow &view) const override;
void initWindowManagement(KWayland::Client::PlasmaWindowManagement *windowManagement);
private: private:
void init(); void init();
inline bool isValidWindow(const KWayland::Client::PlasmaWindow *w) const; inline bool isValidWindow(const KWayland::Client::PlasmaWindow *w) const;
void windowCreatedProxy(KWayland::Client::PlasmaWindow *w); void windowCreatedProxy(KWayland::Client::PlasmaWindow *w);
KWayland::Client::PlasmaShell *waylandDockCoronaInterface() const;
QSignalMapper *mapper{nullptr}; QSignalMapper *mapper{nullptr};
friend class Private::GhostWindow; friend class Private::GhostWindow;
mutable QMap<WindowId, Private::GhostWindow *> m_ghostWindows; mutable QMap<WindowId, Private::GhostWindow *> m_ghostWindows;
KWayland::Client::Registry *m_registry{nullptr}; KWayland::Client::PlasmaWindowManagement *m_windowManagement{nullptr};
KWayland::Client::ConnectionThread *m_connection{nullptr};
KWayland::Client::PlasmaWindowManagement *m_wm{nullptr}; DockCorona *m_corona{nullptr};
KWayland::Client::PlasmaShell *m_plasmaShell{nullptr};
}; };

Loading…
Cancel
Save