Skip to content

Commit 5cb7422

Browse files
committed
wayland: safely handle session lock surface destruction during unlock/DPMS
1 parent 0e69f1c commit 5cb7422

3 files changed

Lines changed: 32 additions & 5 deletions

File tree

src/wayland/session_lock.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,14 @@ void WlSessionLock::realizeLockTarget(WlSessionLock* old) {
142142
void WlSessionLock::unlock() {
143143
if (this->isLocked()) {
144144
this->lockTarget = false;
145+
146+
this->manager->unlock();
147+
145148
for (auto* surface: this->surfaces) {
146149
delete surface;
147150
}
148151
this->surfaces.clear();
149152

150-
this->manager->unlock();
151-
152153
emit this->lockStateChanged();
153154
}
154155
}
@@ -209,6 +210,7 @@ WlSessionLockSurface::WlSessionLockSurface(QObject* parent)
209210

210211
WlSessionLockSurface::~WlSessionLockSurface() {
211212
if (this->window != nullptr) {
213+
this->window->destroy();
212214
this->window->deleteLater();
213215
}
214216
}

src/wayland/session_lock/session_lock.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <qtclasshelpermacros.h>
55
#include <qtmetamacros.h>
66
#include <qwindow.h>
7+
#include <qpointer.h>
78

89
class QSWaylandSessionLock;
910
class QSWaylandSessionLockSurface;
@@ -87,7 +88,7 @@ class LockWindowExtension: public QObject {
8788

8889
private:
8990
QSWaylandSessionLockSurface* surface = nullptr;
90-
QSWaylandSessionLock* lock = nullptr;
91+
QPointer<QSWaylandSessionLock> lock = nullptr;
9192
bool immediatelyVisible = false;
9293

9394
friend class QSWaylandSessionLockSurface;

src/wayland/session_lock/surface.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <qobject.h>
99
#include <qtversionchecks.h>
1010
#include <qtypes.h>
11+
#include <wayland-client.h>
1112

1213
#include "lock.hpp"
1314
#include "session_lock.hpp"
@@ -38,8 +39,31 @@ QSWaylandSessionLockSurface::QSWaylandSessionLockSurface(QtWaylandClient::QWayla
3839
}
3940

4041
QSWaylandSessionLockSurface::~QSWaylandSessionLockSurface() {
41-
if (this->ext != nullptr) this->ext->surface = nullptr;
42-
this->destroy();
42+
bool shouldDestroyOnServer = true;
43+
44+
if (this->ext != nullptr) {
45+
this->ext->surface = nullptr;
46+
if (this->ext->lock == nullptr || !this->ext->lock->active()) {
47+
shouldDestroyOnServer = false;
48+
} else {
49+
auto* qwindow = this->window() ? this->window()->window() : nullptr;
50+
auto* screen = qwindow ? qwindow->screen() : nullptr;
51+
auto* waylandScreen = screen ? dynamic_cast<QtWaylandClient::QWaylandScreen*>(screen->handle()) : nullptr;
52+
if (waylandScreen == nullptr || waylandScreen->isPlaceholder() || waylandScreen->output() == nullptr) {
53+
shouldDestroyOnServer = false;
54+
}
55+
}
56+
} else {
57+
shouldDestroyOnServer = false;
58+
}
59+
60+
if (shouldDestroyOnServer) {
61+
this->destroy();
62+
} else {
63+
if (auto* obj = this->object()) {
64+
wl_proxy_destroy(reinterpret_cast<wl_proxy*>(obj));
65+
}
66+
}
4367
}
4468

4569
bool QSWaylandSessionLockSurface::isExposed() const { return this->configured; }

0 commit comments

Comments
 (0)