1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-11 13:18:13 +03:00

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.
This commit is contained in:
Michail Vourlakos 2018-03-01 23:53:28 +02:00
parent b4b68e5bb1
commit cb88d134f4
13 changed files with 100 additions and 98 deletions

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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};
};

View File

@ -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();

View File

@ -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};
};

View File

@ -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()

View File

@ -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);

View File

@ -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();
}

View File

@ -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};

View File

@ -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();

View File

@ -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_corona = qobject_cast<DockCorona *>(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();
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_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;

View File

@ -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};
};