forked from quickshell/quickshell
hyprland/focus_grab: wait for surface creation if null
Fixes an occasional crash with QWaylandWindow::surface() returning null.
This commit is contained in:
parent
fe1d15e8f6
commit
f95e7dbaf6
3 changed files with 37 additions and 7 deletions
|
@ -19,18 +19,34 @@ FocusGrab::~FocusGrab() {
|
||||||
bool FocusGrab::isActive() const { return this->active; }
|
bool FocusGrab::isActive() const { return this->active; }
|
||||||
|
|
||||||
void FocusGrab::addWindow(QWindow* window) {
|
void FocusGrab::addWindow(QWindow* window) {
|
||||||
if (auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle())) {
|
auto tryAddWayland = [this](QWaylandWindow* waylandWindow) {
|
||||||
|
if (waylandWindow->surface()) {
|
||||||
this->addWaylandWindow(waylandWindow);
|
this->addWaylandWindow(waylandWindow);
|
||||||
|
this->sync();
|
||||||
} else {
|
} else {
|
||||||
QObject::connect(window, &QWindow::visibleChanged, this, [this, window]() {
|
QObject::connect(
|
||||||
|
waylandWindow,
|
||||||
|
&QWaylandWindow::surfaceCreated,
|
||||||
|
this,
|
||||||
|
[this, waylandWindow]() {
|
||||||
|
this->addWaylandWindow(waylandWindow);
|
||||||
|
this->sync();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle())) {
|
||||||
|
tryAddWayland(waylandWindow);
|
||||||
|
} else {
|
||||||
|
QObject::connect(window, &QWindow::visibleChanged, this, [this, window, tryAddWayland]() {
|
||||||
if (window->isVisible()) {
|
if (window->isVisible()) {
|
||||||
if (window->handle() == nullptr) {
|
if (window->handle() == nullptr) {
|
||||||
window->create();
|
window->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle());
|
auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle());
|
||||||
this->addWaylandWindow(waylandWindow);
|
tryAddWayland(waylandWindow);
|
||||||
this->sync();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -53,6 +69,8 @@ void FocusGrab::addWaylandWindow(QWaylandWindow* window) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FocusGrab::sync() {
|
void FocusGrab::sync() {
|
||||||
|
if (this->transactionActive) return;
|
||||||
|
|
||||||
if (this->commitRequired) {
|
if (this->commitRequired) {
|
||||||
this->commit();
|
this->commit();
|
||||||
this->commitRequired = false;
|
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() {
|
void FocusGrab::hyprland_focus_grab_v1_cleared() {
|
||||||
this->active = false;
|
this->active = false;
|
||||||
emit this->cleared();
|
emit this->cleared();
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
void addWindow(QWindow* window);
|
void addWindow(QWindow* window);
|
||||||
void removeWindow(QWindow* window);
|
void removeWindow(QWindow* window);
|
||||||
void sync();
|
void sync();
|
||||||
|
void startTransaction();
|
||||||
|
void completeTransaction();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void activated();
|
void activated();
|
||||||
|
@ -40,6 +42,7 @@ private:
|
||||||
|
|
||||||
QList<QWaylandWindow*> pendingAdditions;
|
QList<QWaylandWindow*> pendingAdditions;
|
||||||
bool commitRequired = false;
|
bool commitRequired = false;
|
||||||
|
bool transactionActive = false;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,13 +74,13 @@ void HyprlandFocusGrab::tryActivate() {
|
||||||
QObject::connect(this->grab, &FocusGrab::activated, this, &HyprlandFocusGrab::onGrabActivated);
|
QObject::connect(this->grab, &FocusGrab::activated, this, &HyprlandFocusGrab::onGrabActivated);
|
||||||
QObject::connect(this->grab, &FocusGrab::cleared, this, &HyprlandFocusGrab::onGrabCleared);
|
QObject::connect(this->grab, &FocusGrab::cleared, this, &HyprlandFocusGrab::onGrabCleared);
|
||||||
|
|
||||||
|
this->grab->startTransaction();
|
||||||
for (auto* proxy: this->trackedProxies) {
|
for (auto* proxy: this->trackedProxies) {
|
||||||
if (proxy->backingWindow() != nullptr) {
|
if (proxy->backingWindow() != nullptr) {
|
||||||
this->grab->addWindow(proxy->backingWindow());
|
this->grab->addWindow(proxy->backingWindow());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->grab->completeTransaction();
|
||||||
this->grab->sync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprlandFocusGrab::syncWindows() {
|
void HyprlandFocusGrab::syncWindows() {
|
||||||
|
@ -99,6 +99,8 @@ void HyprlandFocusGrab::syncWindows() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->grab) this->grab->startTransaction();
|
||||||
|
|
||||||
for (auto* oldWindow: this->trackedProxies) {
|
for (auto* oldWindow: this->trackedProxies) {
|
||||||
if (!newProxy.contains(oldWindow)) {
|
if (!newProxy.contains(oldWindow)) {
|
||||||
QObject::disconnect(oldWindow, nullptr, this, nullptr);
|
QObject::disconnect(oldWindow, nullptr, this, nullptr);
|
||||||
|
@ -125,7 +127,7 @@ void HyprlandFocusGrab::syncWindows() {
|
||||||
}
|
}
|
||||||
|
|
||||||
this->trackedProxies = newProxy;
|
this->trackedProxies = newProxy;
|
||||||
if (this->grab != nullptr) this->grab->sync();
|
if (this->grab) this->grab->completeTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace qs::hyprland
|
} // namespace qs::hyprland
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue