diff --git a/src/wayland/hyprland/focus_grab/grab.cpp b/src/wayland/hyprland/focus_grab/grab.cpp index a45cf4ec..62298699 100644 --- a/src/wayland/hyprland/focus_grab/grab.cpp +++ b/src/wayland/hyprland/focus_grab/grab.cpp @@ -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(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(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(); diff --git a/src/wayland/hyprland/focus_grab/grab.hpp b/src/wayland/hyprland/focus_grab/grab.hpp index 2a9384d9..99d5125c 100644 --- a/src/wayland/hyprland/focus_grab/grab.hpp +++ b/src/wayland/hyprland/focus_grab/grab.hpp @@ -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 pendingAdditions; bool commitRequired = false; + bool transactionActive = false; bool active = false; }; diff --git a/src/wayland/hyprland/focus_grab/qml.cpp b/src/wayland/hyprland/focus_grab/qml.cpp index ca644b9d..9ae309ff 100644 --- a/src/wayland/hyprland/focus_grab/qml.cpp +++ b/src/wayland/hyprland/focus_grab/qml.cpp @@ -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