forked from quickshell/quickshell
		
	core/window: handle graphics context loss
This commit is contained in:
		
							parent
							
								
									a2146f6394
								
							
						
					
					
						commit
						3dfb7d8827
					
				
					 4 changed files with 33 additions and 2 deletions
				
			
		| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#include "proxywindow.hpp"
 | 
					#include "proxywindow.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <private/qquickwindow_p.h>
 | 
					#include <private/qquickwindow_p.h>
 | 
				
			||||||
 | 
					#include <qcontainerfwd.h>
 | 
				
			||||||
#include <qcoreevent.h>
 | 
					#include <qcoreevent.h>
 | 
				
			||||||
#include <qevent.h>
 | 
					#include <qevent.h>
 | 
				
			||||||
#include <qguiapplication.h>
 | 
					#include <qguiapplication.h>
 | 
				
			||||||
| 
						 | 
					@ -112,6 +113,8 @@ void ProxyWindowBase::ensureQWindow() {
 | 
				
			||||||
		auto opaque = this->qsSurfaceFormat.opaqueModified ? this->qsSurfaceFormat.opaque
 | 
							auto opaque = this->qsSurfaceFormat.opaqueModified ? this->qsSurfaceFormat.opaque
 | 
				
			||||||
		                                                   : this->mColor.alpha() >= 255;
 | 
							                                                   : this->mColor.alpha() >= 255;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							format.setOption(QSurfaceFormat::ResetNotification);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (opaque) format.setAlphaBufferSize(0);
 | 
							if (opaque) format.setAlphaBufferSize(0);
 | 
				
			||||||
		else format.setAlphaBufferSize(8);
 | 
							else format.setAlphaBufferSize(8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -195,6 +198,7 @@ void ProxyWindowBase::connectWindow() {
 | 
				
			||||||
	QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyWindowBase::heightChanged);
 | 
						QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyWindowBase::heightChanged);
 | 
				
			||||||
	QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyWindowBase::screenChanged);
 | 
						QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyWindowBase::screenChanged);
 | 
				
			||||||
	QObject::connect(this->window, &QQuickWindow::colorChanged, this, &ProxyWindowBase::colorChanged);
 | 
						QObject::connect(this->window, &QQuickWindow::colorChanged, this, &ProxyWindowBase::colorChanged);
 | 
				
			||||||
 | 
						QObject::connect(this->window, &QQuickWindow::sceneGraphError, this, &ProxyWindowBase::onSceneGraphError);
 | 
				
			||||||
	QObject::connect(this->window, &ProxiedWindow::exposed, this, &ProxyWindowBase::onExposed);
 | 
						QObject::connect(this->window, &ProxiedWindow::exposed, this, &ProxyWindowBase::onExposed);
 | 
				
			||||||
	QObject::connect(this->window, &ProxiedWindow::devicePixelRatioChanged, this, &ProxyWindowBase::devicePixelRatioChanged);
 | 
						QObject::connect(this->window, &ProxiedWindow::devicePixelRatioChanged, this, &ProxyWindowBase::devicePixelRatioChanged);
 | 
				
			||||||
	// clang-format on
 | 
						// clang-format on
 | 
				
			||||||
| 
						 | 
					@ -226,6 +230,22 @@ void ProxyWindowBase::completeWindow() {
 | 
				
			||||||
	emit this->screenChanged();
 | 
						emit this->screenChanged();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProxyWindowBase::onSceneGraphError(
 | 
				
			||||||
 | 
					    QQuickWindow::SceneGraphError error,
 | 
				
			||||||
 | 
					    const QString& message
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						if (error == QQuickWindow::ContextNotAvailable) {
 | 
				
			||||||
 | 
							qCritical().nospace() << "Failed to create graphics context for " << this << ": " << message;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							qCritical().nospace() << "Scene graph error " << error << " occurred for " << this << ": "
 | 
				
			||||||
 | 
							                      << message;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						emit this->resourcesLost();
 | 
				
			||||||
 | 
						this->mVisible = false;
 | 
				
			||||||
 | 
						this->setVisibleDirect(false);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ProxyWindowBase::onVisibleChanged() {
 | 
					void ProxyWindowBase::onVisibleChanged() {
 | 
				
			||||||
	if (this->mVisible && !this->window->isVisible()) {
 | 
						if (this->mVisible && !this->window->isVisible()) {
 | 
				
			||||||
		this->mVisible = false;
 | 
							this->mVisible = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void closed();
 | 
						void closed();
 | 
				
			||||||
 | 
						void resourcesLost();
 | 
				
			||||||
	void windowConnected();
 | 
						void windowConnected();
 | 
				
			||||||
	void windowDestroyed();
 | 
						void windowDestroyed();
 | 
				
			||||||
	void visibleChanged();
 | 
						void visibleChanged();
 | 
				
			||||||
| 
						 | 
					@ -161,13 +162,16 @@ signals:
 | 
				
			||||||
	void polished();
 | 
						void polished();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected slots:
 | 
					protected slots:
 | 
				
			||||||
	void onVisibleChanged();
 | 
					 | 
				
			||||||
	virtual void onWidthChanged();
 | 
						virtual void onWidthChanged();
 | 
				
			||||||
	virtual void onHeightChanged();
 | 
						virtual void onHeightChanged();
 | 
				
			||||||
 | 
						virtual void onPolished();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private slots:
 | 
				
			||||||
 | 
						void onSceneGraphError(QQuickWindow::SceneGraphError error, const QString& message);
 | 
				
			||||||
 | 
						void onVisibleChanged();
 | 
				
			||||||
	void onMaskChanged();
 | 
						void onMaskChanged();
 | 
				
			||||||
	void onMaskDestroyed();
 | 
						void onMaskDestroyed();
 | 
				
			||||||
	void onScreenDestroyed();
 | 
						void onScreenDestroyed();
 | 
				
			||||||
	virtual void onPolished();
 | 
					 | 
				
			||||||
	void onExposed();
 | 
						void onExposed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,6 +134,7 @@ void WindowInterface::connectSignals() const {
 | 
				
			||||||
	auto* window = this->proxyWindow();
 | 
						auto* window = this->proxyWindow();
 | 
				
			||||||
	// clang-format off
 | 
						// clang-format off
 | 
				
			||||||
	QObject::connect(window, &ProxyWindowBase::closed, this, &WindowInterface::closed);
 | 
						QObject::connect(window, &ProxyWindowBase::closed, this, &WindowInterface::closed);
 | 
				
			||||||
 | 
						QObject::connect(window, &ProxyWindowBase::resourcesLost, this, &WindowInterface::resourcesLost);
 | 
				
			||||||
	QObject::connect(window, &ProxyWindowBase::windowConnected, this, &WindowInterface::windowConnected);
 | 
						QObject::connect(window, &ProxyWindowBase::windowConnected, this, &WindowInterface::windowConnected);
 | 
				
			||||||
	QObject::connect(window, &ProxyWindowBase::visibleChanged, this, &WindowInterface::visibleChanged);
 | 
						QObject::connect(window, &ProxyWindowBase::visibleChanged, this, &WindowInterface::visibleChanged);
 | 
				
			||||||
	QObject::connect(window, &ProxyWindowBase::backerVisibilityChanged, this, &WindowInterface::backingWindowVisibleChanged);
 | 
						QObject::connect(window, &ProxyWindowBase::backerVisibilityChanged, this, &WindowInterface::backingWindowVisibleChanged);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,6 +239,12 @@ signals:
 | 
				
			||||||
	/// This signal is emitted when the window is closed by the user, the display server,
 | 
						/// This signal is emitted when the window is closed by the user, the display server,
 | 
				
			||||||
	/// or an error. It is not emitted when @@visible is set to false.
 | 
						/// or an error. It is not emitted when @@visible is set to false.
 | 
				
			||||||
	void closed();
 | 
						void closed();
 | 
				
			||||||
 | 
						/// This signal is emitted when resources a window depends on to display are lost,
 | 
				
			||||||
 | 
						/// or could not be acquired during window creation. The most common trigger for
 | 
				
			||||||
 | 
						/// this signal is a lack of VRAM when creating or resizing a window.
 | 
				
			||||||
 | 
						///
 | 
				
			||||||
 | 
						/// Following this signal, @@closed(s) will be sent.
 | 
				
			||||||
 | 
						void resourcesLost();
 | 
				
			||||||
	void windowConnected();
 | 
						void windowConnected();
 | 
				
			||||||
	void visibleChanged();
 | 
						void visibleChanged();
 | 
				
			||||||
	void backingWindowVisibleChanged();
 | 
						void backingWindowVisibleChanged();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue