[Window Thumbnail] Also monitor scene visibility and clean up
Just because the item is visible doesn't mean the window itself is. Keep track of the window it's in. Use itemChange instead of connects and move the check for starting to startRedirect so we don't have to check the conditions for that in every change handler (visible && enabled && window->visible). It also saves three connects in the constructor. Also, don't unredirect if we didn't redirect in the first place to avoid warnings printed on console. BUG: 406303 Differential Revision: https://phabricator.kde.org/D20805
This commit is contained in:
parent
9aeaf7cbb5
commit
1b2424879a
@ -137,6 +137,7 @@ WindowThumbnail::WindowThumbnail(QQuickItem *parent)
|
||||
, m_winId(0)
|
||||
, m_paintedSize(QSizeF())
|
||||
, m_thumbnailAvailable(false)
|
||||
, m_redirecting(false)
|
||||
, m_damaged(false)
|
||||
, m_depth(0)
|
||||
#if HAVE_XCB_COMPOSITE
|
||||
@ -160,33 +161,7 @@ WindowThumbnail::WindowThumbnail(QQuickItem *parent)
|
||||
#endif
|
||||
{
|
||||
setFlag(ItemHasContents);
|
||||
connect(this, &QQuickItem::windowChanged, [this](QQuickWindow * window) {
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
// restart the redirection, it might not have been active yet
|
||||
stopRedirecting();
|
||||
startRedirecting();
|
||||
update();
|
||||
});
|
||||
connect(this, &QQuickItem::enabledChanged, [this]() {
|
||||
if (!isEnabled()) {
|
||||
stopRedirecting();
|
||||
releaseResources();
|
||||
} else if (isVisible()) {
|
||||
startRedirecting();
|
||||
update();
|
||||
}
|
||||
});
|
||||
connect(this, &QQuickItem::visibleChanged, [this]() {
|
||||
if (!isVisible()) {
|
||||
stopRedirecting();
|
||||
releaseResources();
|
||||
} else if (isEnabled()) {
|
||||
startRedirecting();
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
if (QGuiApplication *gui = dynamic_cast<QGuiApplication *>(QCoreApplication::instance())) {
|
||||
m_xcb = (gui->platformName() == QStringLiteral("xcb"));
|
||||
if (m_xcb) {
|
||||
@ -216,6 +191,42 @@ WindowThumbnail::~WindowThumbnail()
|
||||
}
|
||||
}
|
||||
|
||||
void WindowThumbnail::itemChange(ItemChange change, const ItemChangeData &data)
|
||||
{
|
||||
switch (change) {
|
||||
case ItemSceneChange:
|
||||
if (m_scene) {
|
||||
disconnect(m_scene.data(), &QWindow::visibleChanged, this, &WindowThumbnail::sceneVisibilityChanged);
|
||||
}
|
||||
m_scene = data.window;
|
||||
if (m_scene) {
|
||||
connect(m_scene.data(), &QWindow::visibleChanged, this, &WindowThumbnail::sceneVisibilityChanged);
|
||||
// restart the redirection, it might not have been active yet
|
||||
stopRedirecting();
|
||||
if (startRedirecting()) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ItemEnabledHasChanged:
|
||||
Q_FALLTHROUGH();
|
||||
case ItemVisibleHasChanged:
|
||||
if (data.boolValue) {
|
||||
if (startRedirecting()) {
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
stopRedirecting();
|
||||
releaseResources();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowThumbnail::releaseResources()
|
||||
{
|
||||
#if HAVE_XCB_COMPOSITE
|
||||
@ -843,7 +854,10 @@ void WindowThumbnail::stopRedirecting()
|
||||
if (m_winId == XCB_WINDOW_NONE) {
|
||||
return;
|
||||
}
|
||||
xcb_composite_unredirect_window(c, m_winId, XCB_COMPOSITE_REDIRECT_AUTOMATIC);
|
||||
if (m_redirecting) {
|
||||
xcb_composite_unredirect_window(c, m_winId, XCB_COMPOSITE_REDIRECT_AUTOMATIC);
|
||||
}
|
||||
m_redirecting = false;
|
||||
if (m_damage == XCB_NONE) {
|
||||
return;
|
||||
}
|
||||
@ -852,14 +866,14 @@ void WindowThumbnail::stopRedirecting()
|
||||
#endif
|
||||
}
|
||||
|
||||
void WindowThumbnail::startRedirecting()
|
||||
bool WindowThumbnail::startRedirecting()
|
||||
{
|
||||
if (!m_xcb || !m_composite || !window() || window()->winId() == m_winId) {
|
||||
return;
|
||||
if (!m_xcb || !m_composite || !window() || !window()->isVisible() || window()->winId() == m_winId || !isEnabled() || !isVisible()) {
|
||||
return false;
|
||||
}
|
||||
#if HAVE_XCB_COMPOSITE
|
||||
if (m_winId == XCB_WINDOW_NONE) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
xcb_connection_t *c = QX11Info::connection();
|
||||
|
||||
@ -868,6 +882,7 @@ void WindowThumbnail::startRedirecting()
|
||||
|
||||
// redirect the window
|
||||
xcb_composite_redirect_window(c, m_winId, XCB_COMPOSITE_REDIRECT_AUTOMATIC);
|
||||
m_redirecting = true;
|
||||
|
||||
// generate the damage handle
|
||||
m_damage = xcb_generate_id(c);
|
||||
@ -883,6 +898,9 @@ void WindowThumbnail::startRedirecting()
|
||||
xcb_change_window_attributes(c, m_winId, XCB_CW_EVENT_MASK, &events);
|
||||
// force to update the texture
|
||||
m_damaged = true;
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -896,4 +914,16 @@ void WindowThumbnail::setThumbnailAvailable(bool thumbnailAvailable)
|
||||
}
|
||||
}
|
||||
|
||||
void WindowThumbnail::sceneVisibilityChanged(bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
if (startRedirecting()) {
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
stopRedirecting();
|
||||
releaseResources();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QSGSimpleTextureNode>
|
||||
#include <QQuickItem>
|
||||
#include <QPointer>
|
||||
#include <QWindow>
|
||||
// xcb
|
||||
#if HAVE_XCB_COMPOSITE
|
||||
#include <xcb/damage.h>
|
||||
@ -100,21 +102,25 @@ Q_SIGNALS:
|
||||
void thumbnailAvailableChanged();
|
||||
|
||||
protected:
|
||||
void itemChange(ItemChange change, const ItemChangeData &data) override;
|
||||
void releaseResources() override;
|
||||
|
||||
private:
|
||||
void iconToTexture(WindowTextureNode *textureNode);
|
||||
void windowToTexture(WindowTextureNode *textureNode);
|
||||
void startRedirecting();
|
||||
bool startRedirecting();
|
||||
void stopRedirecting();
|
||||
void resetDamaged();
|
||||
void setThumbnailAvailable(bool thumbnailAvailable);
|
||||
void sceneVisibilityChanged(bool visible);
|
||||
|
||||
bool m_xcb;
|
||||
bool m_composite;
|
||||
QPointer<QWindow> m_scene;
|
||||
uint32_t m_winId;
|
||||
QSizeF m_paintedSize;
|
||||
bool m_thumbnailAvailable;
|
||||
bool m_redirecting;
|
||||
bool m_damaged;
|
||||
int m_depth;
|
||||
#if HAVE_XCB_COMPOSITE
|
||||
|
Loading…
Reference in New Issue
Block a user