Skip to content

Commit f95e7db

Browse files
committed
hyprland/focus_grab: wait for surface creation if null
Fixes an occasional crash with QWaylandWindow::surface() returning null.
1 parent fe1d15e commit f95e7db

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

src/wayland/hyprland/focus_grab/grab.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,34 @@ FocusGrab::~FocusGrab() {
1919
bool FocusGrab::isActive() const { return this->active; }
2020

2121
void FocusGrab::addWindow(QWindow* window) {
22+
auto tryAddWayland = [this](QWaylandWindow* waylandWindow) {
23+
if (waylandWindow->surface()) {
24+
this->addWaylandWindow(waylandWindow);
25+
this->sync();
26+
} else {
27+
QObject::connect(
28+
waylandWindow,
29+
&QWaylandWindow::surfaceCreated,
30+
this,
31+
[this, waylandWindow]() {
32+
this->addWaylandWindow(waylandWindow);
33+
this->sync();
34+
}
35+
);
36+
}
37+
};
38+
2239
if (auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle())) {
23-
this->addWaylandWindow(waylandWindow);
40+
tryAddWayland(waylandWindow);
2441
} else {
25-
QObject::connect(window, &QWindow::visibleChanged, this, [this, window]() {
42+
QObject::connect(window, &QWindow::visibleChanged, this, [this, window, tryAddWayland]() {
2643
if (window->isVisible()) {
2744
if (window->handle() == nullptr) {
2845
window->create();
2946
}
3047

3148
auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle());
32-
this->addWaylandWindow(waylandWindow);
33-
this->sync();
49+
tryAddWayland(waylandWindow);
3450
}
3551
});
3652
}
@@ -53,6 +69,8 @@ void FocusGrab::addWaylandWindow(QWaylandWindow* window) {
5369
}
5470

5571
void FocusGrab::sync() {
72+
if (this->transactionActive) return;
73+
5674
if (this->commitRequired) {
5775
this->commit();
5876
this->commitRequired = false;
@@ -70,6 +88,13 @@ void FocusGrab::sync() {
7088
}
7189
}
7290

91+
void FocusGrab::startTransaction() { this->transactionActive = true; }
92+
93+
void FocusGrab::completeTransaction() {
94+
this->transactionActive = false;
95+
this->sync();
96+
}
97+
7398
void FocusGrab::hyprland_focus_grab_v1_cleared() {
7499
this->active = false;
75100
emit this->cleared();

src/wayland/hyprland/focus_grab/grab.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class FocusGrab
2828
void addWindow(QWindow* window);
2929
void removeWindow(QWindow* window);
3030
void sync();
31+
void startTransaction();
32+
void completeTransaction();
3133

3234
signals:
3335
void activated();
@@ -40,6 +42,7 @@ class FocusGrab
4042

4143
QList<QWaylandWindow*> pendingAdditions;
4244
bool commitRequired = false;
45+
bool transactionActive = false;
4346
bool active = false;
4447
};
4548

src/wayland/hyprland/focus_grab/qml.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ void HyprlandFocusGrab::tryActivate() {
7474
QObject::connect(this->grab, &FocusGrab::activated, this, &HyprlandFocusGrab::onGrabActivated);
7575
QObject::connect(this->grab, &FocusGrab::cleared, this, &HyprlandFocusGrab::onGrabCleared);
7676

77+
this->grab->startTransaction();
7778
for (auto* proxy: this->trackedProxies) {
7879
if (proxy->backingWindow() != nullptr) {
7980
this->grab->addWindow(proxy->backingWindow());
8081
}
8182
}
82-
83-
this->grab->sync();
83+
this->grab->completeTransaction();
8484
}
8585

8686
void HyprlandFocusGrab::syncWindows() {
@@ -99,6 +99,8 @@ void HyprlandFocusGrab::syncWindows() {
9999
}
100100
}
101101

102+
if (this->grab) this->grab->startTransaction();
103+
102104
for (auto* oldWindow: this->trackedProxies) {
103105
if (!newProxy.contains(oldWindow)) {
104106
QObject::disconnect(oldWindow, nullptr, this, nullptr);
@@ -125,7 +127,7 @@ void HyprlandFocusGrab::syncWindows() {
125127
}
126128

127129
this->trackedProxies = newProxy;
128-
if (this->grab != nullptr) this->grab->sync();
130+
if (this->grab) this->grab->completeTransaction();
129131
}
130132

131133
} // namespace qs::hyprland

0 commit comments

Comments
 (0)