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

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

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

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

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

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

@ -33,10 +33,11 @@ namespace Latte {
//! BEGIN: VisiblityManagerPrivate implementation
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);
dockCorona = qobject_cast<DockCorona *>(view->corona());
wm = dockCorona->wm();
if (dockView) {
connect(dockView, &DockView::eventTriggered, this, &VisibilityManagerPrivate::viewEventManager);

@ -28,6 +28,8 @@
#include "layoutmanager.h"
#include "screenpool.h"
#include "universalsettings.h"
#include "waylandinterface.h"
#include "xwindowinterface.h"
#include "dock/dockview.h"
#include "packageplugins/shell/dockpackage.h"
@ -64,6 +66,7 @@
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h>
#include <KWayland/Client/plasmashell.h>
#include <KWayland/Client/plasmawindowmanagement.h>
namespace Latte {
@ -78,6 +81,14 @@ DockCorona::DockCorona(bool defaultLayoutOnStartup, QString layoutNameOnStartUp,
m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), 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();
KPackage::Package package(new DockPackage(this));
@ -139,6 +150,7 @@ DockCorona::~DockCorona()
m_layoutManager->unload();
m_wm->deleteLater();
m_globalShortcuts->deleteLater();
m_layoutManager->deleteLater();
m_screenPool->deleteLater();
@ -228,6 +240,17 @@ void DockCorona::setupWaylandIntegration()
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();
connection->roundtrip();
}
@ -323,6 +346,11 @@ LayoutManager *DockCorona::layoutManager() const
return m_layoutManager;
}
AbstractWindowInterface *DockCorona::wm() const
{
return m_wm;
}
int DockCorona::numScreens() const
{
return qGuiApp->screens().count();
@ -613,8 +641,8 @@ void DockCorona::aboutApplication()
aboutDialog = new KAboutApplicationDialog(KAboutData::applicationData());
connect(aboutDialog.data(), &QDialog::finished, aboutDialog.data(), &QObject::deleteLater);
WindowSystem::self().skipTaskBar(*aboutDialog);
WindowSystem::self().setKeepAbove(*aboutDialog, true);
m_wm->skipTaskBar(*aboutDialog);
m_wm->setKeepAbove(*aboutDialog, true);
aboutDialog->show();
}

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

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

@ -19,6 +19,7 @@
*/
#include "waylandinterface.h"
#include "dockcorona.h"
#include "../liblattedock/extras.h"
#include <QDebug>
@ -72,7 +73,7 @@ public:
if (!s)
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...";
m_shellSurface->setSkipTaskbar(true);
@ -88,58 +89,13 @@ public:
WaylandInterface::WaylandInterface(QObject *parent)
: AbstractWindowInterface(parent)
{
m_activities = new KActivities::Consumer(this);
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();
m_corona = qobject_cast<DockCorona *>(parent);
const auto wmInterface = m_registry->interface(Registry::Interface::PlasmaWindowManagement);
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_activities = new KActivities::Consumer(this);
m_plasmaShell = m_registry->createPlasmaShell(shellInterface.name, shellInterface.version, this);
connect(m_activities.data(), &KActivities::Consumer::currentActivityChanged
, this, &WaylandInterface::currentActivityChanged);
}
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)
{
Q_UNUSED(view)
@ -192,7 +164,11 @@ void WaylandInterface::removeDockStruts(QWindow &view) 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;
}
@ -251,7 +227,11 @@ void WaylandInterface::enableBlurBehind(QWindow &view) const
WindowInfoWrap WaylandInterface::requestInfoActive() const
{
auto w = m_wm->activeWindow();
if (!m_windowManagement) {
return {};
}
auto w = m_windowManagement->activeWindow();
if (!w) return {};
@ -282,33 +262,37 @@ WindowInfoWrap WaylandInterface::requestInfoActive() 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;
});
//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 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
{
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;
});
//TODO: Not yet implemented
return it != m_wm->windows().constEnd() && true;
return it != m_windowManagement->windows().constEnd() && true;
}
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;
});
if (it == m_wm->windows().constEnd())
if (it == m_windowManagement->windows().constEnd())
return {};
WindowInfoWrap winfoWrap;

@ -39,6 +39,8 @@
namespace Latte {
class DockCorona;
namespace Private {
/**
* @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 enableBlurBehind(QWindow &view) const override;
void initWindowManagement(KWayland::Client::PlasmaWindowManagement *windowManagement);
private:
void init();
inline bool isValidWindow(const KWayland::Client::PlasmaWindow *w) const;
void windowCreatedProxy(KWayland::Client::PlasmaWindow *w);
KWayland::Client::PlasmaShell *waylandDockCoronaInterface() const;
QSignalMapper *mapper{nullptr};
friend class Private::GhostWindow;
mutable QMap<WindowId, Private::GhostWindow *> m_ghostWindows;
KWayland::Client::Registry *m_registry{nullptr};
KWayland::Client::ConnectionThread *m_connection{nullptr};
KWayland::Client::PlasmaWindowManagement *m_wm{nullptr};
KWayland::Client::PlasmaShell *m_plasmaShell{nullptr};
KWayland::Client::PlasmaWindowManagement *m_windowManagement{nullptr};
DockCorona *m_corona{nullptr};
};

Loading…
Cancel
Save