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) {
 | 
				
			||||||
 | 
						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())) {
 | 
						if (auto* waylandWindow = dynamic_cast<QWaylandWindow*>(window->handle())) {
 | 
				
			||||||
		this->addWaylandWindow(waylandWindow);
 | 
							tryAddWayland(waylandWindow);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		QObject::connect(window, &QWindow::visibleChanged, this, [this, window]() {
 | 
							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