Switch ThumbnailItem to internal uuid instead of WId
Summary: So far the ThumbnailItem in TabBox mode used the window id for finding the window it should render a thumbnail on. In the Wayland world this is not unique. The window id could be either an X11 window or a wayland window. We don't guarantee that there are no conflicting ids. With the internal id we have a way to properly identify the windows, so this element should use them. To support this the property changed the type to QUuid and the clientmodel also provides the QUuid. As in TabBox the way to get the window is through the model this should be compatible for all themes. It's tested and verified with the Breeze switcher. For declarative KWin scripts the ThumbnailItem also provides the AbstractClient as a property, so there should not be any script which uses wid. If it does, this could break, but well the script should use the intended API. Test Plan: ctest passes, manual testing of Breeze alt-tab switcher Reviewers: #kwin Differential Revision: https://phabricator.kde.org/D18405
This commit is contained in:
parent
02a0561016
commit
932ccb2ac3
11 changed files with 49 additions and 18 deletions
|
@ -137,6 +137,9 @@ public:
|
|||
KWin::EffectWindow *findWindow(QWindow *w) const override {
|
||||
return nullptr;
|
||||
}
|
||||
KWin::EffectWindow *findWindow(const QUuid &id) const override {
|
||||
return nullptr;
|
||||
}
|
||||
void *getProxy(QString) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../../tabbox/tabboxhandler.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QUuid>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -65,6 +66,10 @@ public:
|
|||
return QIcon();
|
||||
}
|
||||
|
||||
QUuid internalId() const override {
|
||||
return QUuid{};
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_caption;
|
||||
WId m_wId;
|
||||
|
|
12
effects.cpp
12
effects.cpp
|
@ -1099,6 +1099,16 @@ EffectWindow *EffectsHandlerImpl::findWindow(QWindow *w) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
EffectWindow *EffectsHandlerImpl::findWindow(const QUuid &id) const
|
||||
{
|
||||
if (const auto client = workspace()->findAbstractClient([&id] (const AbstractClient *c) { return c->internalId() == id; })) {
|
||||
return client->effectWindow();
|
||||
}
|
||||
if (const auto unmanaged = workspace()->findUnmanaged([&id] (const Unmanaged *c) { return c->internalId() == id; })) {
|
||||
return unmanaged->effectWindow();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EffectWindowList EffectsHandlerImpl::stackingOrder() const
|
||||
{
|
||||
|
@ -2023,7 +2033,7 @@ void EffectWindowImpl::registerThumbnail(AbstractThumbnailItem *item)
|
|||
if (WindowThumbnailItem *thumb = qobject_cast<WindowThumbnailItem*>(item)) {
|
||||
insertThumbnail(thumb);
|
||||
connect(thumb, SIGNAL(destroyed(QObject*)), SLOT(thumbnailDestroyed(QObject*)));
|
||||
connect(thumb, SIGNAL(wIdChanged(qulonglong)), SLOT(thumbnailTargetChanged()));
|
||||
connect(thumb, &WindowThumbnailItem::wIdChanged, this, &EffectWindowImpl::thumbnailTargetChanged);
|
||||
} else if (DesktopThumbnailItem *desktopThumb = qobject_cast<DesktopThumbnailItem*>(item)) {
|
||||
m_desktopThumbnails.append(desktopThumb);
|
||||
connect(desktopThumb, SIGNAL(destroyed(QObject*)), SLOT(desktopThumbnailDestroyed(QObject*)));
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
EffectWindow* findWindow(WId id) const override;
|
||||
EffectWindow* findWindow(KWayland::Server::SurfaceInterface *surf) const override;
|
||||
EffectWindow *findWindow(QWindow *w) const override;
|
||||
EffectWindow *findWindow(const QUuid &id) const override;
|
||||
EffectWindowList stackingOrder() const override;
|
||||
void setElevatedWindow(KWin::EffectWindow* w, bool set) override;
|
||||
|
||||
|
|
|
@ -1088,6 +1088,13 @@ public:
|
|||
* @since 5.16
|
||||
**/
|
||||
Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(QWindow *w) const = 0;
|
||||
/**
|
||||
* Finds the EffectWindow for the Toplevel with KWin internal @p id.
|
||||
* If there is no such window @c null is returned.
|
||||
*
|
||||
* @since 5.16
|
||||
**/
|
||||
Q_SCRIPTABLE virtual KWin::EffectWindow *findWindow(const QUuid &id) const = 0;
|
||||
virtual EffectWindowList stackingOrder() const = 0;
|
||||
// window will be temporarily painted as if being at the top of the stack
|
||||
Q_SCRIPTABLE virtual void setElevatedWindow(KWin::EffectWindow* w, bool set) = 0;
|
||||
|
|
|
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "tabboxhandler.h"
|
||||
// Qt
|
||||
#include <QIcon>
|
||||
#include <QUuid>
|
||||
// TODO: remove with Qt 5, only for HTML escaping the caption
|
||||
#include <QTextDocument>
|
||||
#include <QTextStream>
|
||||
|
@ -84,7 +85,7 @@ QVariant ClientModel::data(const QModelIndex& index, int role) const
|
|||
return tabBox->desktopName(client.data());
|
||||
}
|
||||
case WIdRole:
|
||||
return qulonglong(client->window());
|
||||
return client->internalId();
|
||||
case MinimizedRole:
|
||||
return client->isMinimized();
|
||||
case CloseableRole:
|
||||
|
|
|
@ -441,6 +441,11 @@ bool TabBoxClientImpl::isFirstInTabBox() const
|
|||
return m_client->isFirstInTabBox();
|
||||
}
|
||||
|
||||
QUuid TabBoxClientImpl::internalId() const
|
||||
{
|
||||
return m_client->internalId();
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* TabBox
|
||||
*********************************************************/
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
virtual bool isCloseable() const;
|
||||
virtual void close();
|
||||
virtual bool isFirstInTabBox() const;
|
||||
QUuid internalId() const override;
|
||||
|
||||
AbstractClient* client() const {
|
||||
return m_client;
|
||||
|
|
|
@ -395,6 +395,7 @@ public:
|
|||
virtual bool isCloseable() const = 0;
|
||||
virtual void close() = 0;
|
||||
virtual bool isFirstInTabBox() const = 0;
|
||||
virtual QUuid internalId() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -77,7 +77,7 @@ void AbstractThumbnailItem::findParentEffectWindow()
|
|||
qCDebug(KWIN_CORE) << "No QQuickWindow assigned yet";
|
||||
return;
|
||||
}
|
||||
if (auto *w = static_cast<EffectWindowImpl*>(effects->findWindow(qw->winId()))) {
|
||||
if (auto *w = static_cast<EffectWindowImpl*>(effects->findWindow(qw))) {
|
||||
m_parent = QWeakPointer<EffectWindowImpl>(w);
|
||||
}
|
||||
}
|
||||
|
@ -132,18 +132,14 @@ WindowThumbnailItem::~WindowThumbnailItem()
|
|||
{
|
||||
}
|
||||
|
||||
void WindowThumbnailItem::setWId(qulonglong wId)
|
||||
void WindowThumbnailItem::setWId(const QUuid &wId)
|
||||
{
|
||||
if (m_wId == wId) {
|
||||
return;
|
||||
}
|
||||
m_wId = wId;
|
||||
if (m_wId != 0) {
|
||||
AbstractClient *c = Workspace::self()->findClient(Predicate::WindowMatch, m_wId);
|
||||
if (!c && waylandServer()) {
|
||||
c = waylandServer()->findClient(m_wId);
|
||||
}
|
||||
setClient(c);
|
||||
setClient(workspace()->findAbstractClient([this] (const AbstractClient *c) { return c->internalId() == m_wId; }));
|
||||
} else if (m_client) {
|
||||
m_client = NULL;
|
||||
emit clientChanged();
|
||||
|
@ -158,9 +154,9 @@ void WindowThumbnailItem::setClient(AbstractClient *client)
|
|||
}
|
||||
m_client = client;
|
||||
if (m_client) {
|
||||
setWId(m_client->windowId());
|
||||
setWId(m_client->internalId());
|
||||
} else {
|
||||
setWId(0);
|
||||
setWId({});
|
||||
}
|
||||
emit clientChanged();
|
||||
}
|
||||
|
@ -170,7 +166,7 @@ void WindowThumbnailItem::paint(QPainter *painter)
|
|||
if (effects) {
|
||||
return;
|
||||
}
|
||||
Client *client = Workspace::self()->findClient(Predicate::WindowMatch, m_wId);
|
||||
auto client = workspace()->findAbstractClient([this] (const AbstractClient *c) { return c->internalId() == m_wId; });
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
|
@ -182,7 +178,7 @@ void WindowThumbnailItem::paint(QPainter *painter)
|
|||
|
||||
void WindowThumbnailItem::repaint(KWin::EffectWindow *w)
|
||||
{
|
||||
if (static_cast<KWin::EffectWindowImpl*>(w)->window()->windowId() == m_wId) {
|
||||
if (static_cast<KWin::EffectWindowImpl*>(w)->window()->internalId() == m_wId) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define KWIN_THUMBNAILITEM_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <QUuid>
|
||||
#include <QWeakPointer>
|
||||
#include <QQuickPaintedItem>
|
||||
|
||||
|
@ -76,26 +77,26 @@ private:
|
|||
class WindowThumbnailItem : public AbstractThumbnailItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qulonglong wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
|
||||
Q_PROPERTY(QUuid wId READ wId WRITE setWId NOTIFY wIdChanged SCRIPTABLE true)
|
||||
Q_PROPERTY(KWin::AbstractClient *client READ client WRITE setClient NOTIFY clientChanged)
|
||||
public:
|
||||
explicit WindowThumbnailItem(QQuickItem *parent = 0);
|
||||
virtual ~WindowThumbnailItem();
|
||||
|
||||
qulonglong wId() const {
|
||||
QUuid wId() const {
|
||||
return m_wId;
|
||||
}
|
||||
void setWId(qulonglong wId);
|
||||
void setWId(const QUuid &wId);
|
||||
AbstractClient *client() const;
|
||||
void setClient(AbstractClient *client);
|
||||
virtual void paint(QPainter *painter);
|
||||
Q_SIGNALS:
|
||||
void wIdChanged(qulonglong wid);
|
||||
void wIdChanged(const QUuid &wid);
|
||||
void clientChanged();
|
||||
protected Q_SLOTS:
|
||||
virtual void repaint(KWin::EffectWindow* w);
|
||||
private:
|
||||
qulonglong m_wId;
|
||||
QUuid m_wId;
|
||||
AbstractClient *m_client;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue