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