Skip to content

Commit c272c97

Browse files
committed
wayland: fix session lock crashes and Qt 6.6.3 compatibility
1 parent 1ea83fc commit c272c97

6 files changed

Lines changed: 36 additions & 9 deletions

File tree

changelog/next.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
- Fixed ScreencopyView not displaying when only lock surfaces are shown.
44
- Fixed WlSessionLockSurface.visible crashing if accessed before backing surface creation.
5+
- Fixed multiple session lock client crashes on sleep, wake, DPMS, and unlocking.

src/wayland/session_lock.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,19 @@ void WlSessionLock::unlock() {
143143
if (this->isLocked()) {
144144
this->lockTarget = false;
145145

146-
this->manager->unlock();
146+
for (auto* surface: this->surfaces) {
147+
if (surface->ext != nullptr) {
148+
surface->ext->destroySurface();
149+
}
150+
}
147151

148152
for (auto* surface: this->surfaces) {
149153
delete surface;
150154
}
151155
this->surfaces.clear();
152156

157+
this->manager->unlock();
158+
153159
emit this->lockStateChanged();
154160
}
155161
}
@@ -209,6 +215,10 @@ WlSessionLockSurface::WlSessionLockSurface(QObject* parent)
209215
}
210216

211217
WlSessionLockSurface::~WlSessionLockSurface() {
218+
if (this->ext != nullptr) {
219+
this->ext->destroySurface();
220+
}
221+
212222
if (this->window != nullptr) {
213223
this->window->destroy();
214224
this->window->deleteLater();

src/wayland/session_lock.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,6 @@ private slots:
185185
QScreen* mScreen = nullptr;
186186
QColor mColor = Qt::white;
187187
LockWindowExtension* ext;
188+
189+
friend class WlSessionLock;
188190
};

src/wayland/session_lock/session_lock.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <qlogging.h>
55
#include <qobject.h>
66
#include <qwindow.h>
7+
#include <wayland-client.h> // NOLINT(misc-include-cleaner)
78

89
#include "lock.hpp"
910
#include "manager.hpp"
@@ -117,3 +118,13 @@ void LockWindowExtension::setVisible() {
117118
if (this->surface == nullptr) this->immediatelyVisible = true;
118119
else this->surface->setVisible();
119120
}
121+
122+
void LockWindowExtension::destroySurface() {
123+
if (this->surface != nullptr) {
124+
auto* lockObj = qobject_cast<QSWaylandSessionLock*>(this->lock.data());
125+
if (lockObj != nullptr && lockObj->active()) {
126+
this->surface->destroy();
127+
this->surface = nullptr;
128+
}
129+
}
130+
}

src/wayland/session_lock/session_lock.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#pragma once
22

33
#include <qobject.h>
4+
#include <qpointer.h>
45
#include <qtclasshelpermacros.h>
56
#include <qtmetamacros.h>
67
#include <qwindow.h>
7-
#include <qpointer.h>
88

99
class QSWaylandSessionLock;
1010
class QSWaylandSessionLockSurface;
@@ -74,6 +74,7 @@ class LockWindowExtension: public QObject {
7474
// This must be called in place of QWindow::setVisible. Calling QWindow::setVisible will result in a crash.
7575
// To make a window invisible, destroy it as it cannot be recovered.
7676
void setVisible();
77+
void destroySurface();
7778

7879
static LockWindowExtension* get(QWindow* window);
7980

src/wayland/session_lock/surface.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <qobject.h>
99
#include <qtversionchecks.h>
1010
#include <qtypes.h>
11-
#include <wayland-client.h> // NOLINT(misc-include-cleaner)
1211

1312
#include "lock.hpp"
1413
#include "session_lock.hpp"
@@ -40,6 +39,10 @@ QSWaylandSessionLockSurface::QSWaylandSessionLockSurface(QtWaylandClient::QWayla
4039
}
4140

4241
QSWaylandSessionLockSurface::~QSWaylandSessionLockSurface() {
42+
if (this->object() == nullptr) {
43+
return;
44+
}
45+
4346
bool shouldDestroyOnServer = true;
4447

4548
if (this->ext != nullptr) {
@@ -50,8 +53,11 @@ QSWaylandSessionLockSurface::~QSWaylandSessionLockSurface() {
5053
} else {
5154
auto* qwindow = this->window() ? this->window()->window() : nullptr;
5255
auto* screen = qwindow ? qwindow->screen() : nullptr;
53-
auto* waylandScreen = screen ? dynamic_cast<QtWaylandClient::QWaylandScreen*>(screen->handle()) : nullptr;
54-
if (waylandScreen == nullptr || waylandScreen->isPlaceholder() || waylandScreen->output() == nullptr) {
56+
auto* waylandScreen =
57+
screen ? dynamic_cast<QtWaylandClient::QWaylandScreen*>(screen->handle()) : nullptr;
58+
if (waylandScreen == nullptr || waylandScreen->isPlaceholder()
59+
|| waylandScreen->output() == nullptr)
60+
{
5561
shouldDestroyOnServer = false;
5662
}
5763
}
@@ -61,10 +67,6 @@ QSWaylandSessionLockSurface::~QSWaylandSessionLockSurface() {
6167

6268
if (shouldDestroyOnServer) {
6369
this->destroy();
64-
} else {
65-
if (auto* obj = this->object()) {
66-
wl_proxy_destroy(reinterpret_cast<wl_proxy*>(obj)); // NOLINT(misc-include-cleaner)
67-
}
6870
}
6971
}
7072

0 commit comments

Comments
 (0)