hyprland/focus_grab: wait for surface creation if null

Fixes an occasional crash with QWaylandWindow::surface() returning null.
This commit is contained in:
outfoxxed 2024-08-20 16:41:04 -07:00
parent fe1d15e8f6
commit f95e7dbaf6
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
3 changed files with 37 additions and 7 deletions

View file

@ -19,18 +19,34 @@ FocusGrab::~FocusGrab() {
bool FocusGrab::isActive() const { return this->active; }
void FocusGrab::addWindow(QWindow* window) {
auto tryAddWayland = [this](QWaylandWindow* waylandWindow) {
if (waylandWindow->surface()) {
this->addWaylandWindow(waylandWindow);
this->sync();
} else {
QObject::connect(
waylandWindow,
&QWaylandWindow::surfaceCreated,
this,
[this, waylandWindow]() {
this->addWaylandWindow(waylandWindow);
this->sync();
}
);
}
};
if (auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle())) {
this->addWaylandWindow(waylandWindow);
tryAddWayland(waylandWindow);
} else {
QObject::connect(window, &QWindow::visibleChanged, this, [this, window]() {
QObject::connect(window, &QWindow::visibleChanged, this, [this, window, tryAddWayland]() {
if (window->isVisible()) {
if (window->handle() == nullptr) {
window->create();
}
auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle());
this->addWaylandWindow(waylandWindow);
this->sync();
tryAddWayland(waylandWindow);
}
});
}
@ -53,6 +69,8 @@ void FocusGrab::addWaylandWindow(QWaylandWindow* window) {
}
void FocusGrab::sync() {
if (this->transactionActive) return;
if (this->commitRequired) {
this->commit();
this->commitRequired = false;
@ -70,6 +88,13 @@ void FocusGrab::sync() {
}
}
void FocusGrab::startTransaction() { this->transactionActive = true; }
void FocusGrab::completeTransaction() {
this->transactionActive = false;
this->sync();
}
void FocusGrab::hyprland_focus_grab_v1_cleared() {
this->active = false;
emit this->cleared();

View file

@ -28,6 +28,8 @@ public:
void addWindow(QWindow* window);
void removeWindow(QWindow* window);
void sync();
void startTransaction();
void completeTransaction();
signals:
void activated();
@ -40,6 +42,7 @@ private:
QList<QWaylandWindow*> pendingAdditions;
bool commitRequired = false;
bool transactionActive = false;
bool active = false;
};

View file

@ -74,13 +74,13 @@ void HyprlandFocusGrab::tryActivate() {
QObject::connect(this->grab, &FocusGrab::activated, this, &HyprlandFocusGrab::onGrabActivated);
QObject::connect(this->grab, &FocusGrab::cleared, this, &HyprlandFocusGrab::onGrabCleared);
this->grab->startTransaction();
for (auto* proxy: this->trackedProxies) {
if (proxy->backingWindow() != nullptr) {
this->grab->addWindow(proxy->backingWindow());
}
}
this->grab->sync();
this->grab->completeTransaction();
}
void HyprlandFocusGrab::syncWindows() {
@ -99,6 +99,8 @@ void HyprlandFocusGrab::syncWindows() {
}
}
if (this->grab) this->grab->startTransaction();
for (auto* oldWindow: this->trackedProxies) {
if (!newProxy.contains(oldWindow)) {
QObject::disconnect(oldWindow, nullptr, this, nullptr);
@ -125,7 +127,7 @@ void HyprlandFocusGrab::syncWindows() {
}
this->trackedProxies = newProxy;
if (this->grab != nullptr) this->grab->sync();
if (this->grab) this->grab->completeTransaction();
}
} // namespace qs::hyprland