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:
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_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;
|
||||
|
@ -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…
Reference in New Issue
Block a user