Use universal helper for writing toplevels to QDebug streams

Toplevel::debug() is one of annoyances that you need to deal with when
implementing a new client type. It can be tempting to just write "this"
to the stream, but it will result in a crash.

In order to make implementing new client types easier, this change
introduces a debug stream insertion operator overload that works for all
kinds of the Toplevel class.
master
Vlad Zahorodnii 2020-08-20 20:34:15 +03:00
parent 29afd62e9c
commit 90b53f416c
15 changed files with 32 additions and 65 deletions

View File

@ -195,11 +195,6 @@ QPoint Deleted::clientPos() const
return contentsRect.topLeft();
}
void Deleted::debug(QDebug& stream) const
{
stream << "\'ID:" << window() << "\' (deleted)";
}
void Deleted::layoutDecorationRects(QRect& left, QRect& top, QRect& right, QRect& bottom) const
{
left = decoration_left;

View File

@ -171,9 +171,6 @@ public:
return m_wasOutline;
}
protected:
void debug(QDebug& stream) const override;
private Q_SLOTS:
void mainClientClosed(KWin::Toplevel *client);
void transientForClosed(Toplevel *toplevel, Deleted *deleted);

View File

@ -114,11 +114,6 @@ void InputPanelV1Client::destroyClient()
delete this;
}
void InputPanelV1Client::debug(QDebug &stream) const
{
stream << "InputPanelClient(" << static_cast<const void*>(this) << "," << resourceClass() << m_frameGeometry << ')';
}
NET::WindowType InputPanelV1Client::windowType(bool, int) const
{
return NET::Utility;

View File

@ -44,7 +44,6 @@ public:
bool isInputMethod() const override { return true; }
bool isInitialPositionSet() const override { return true; }
NET::WindowType windowType(bool /*direct*/, int /*supported_types*/) const override;
void debug(QDebug & stream) const override;
QRect inputGeometry() const override;
private:

View File

@ -137,11 +137,6 @@ QSize InternalClient::maxSize() const
return m_internalWindow->maximumSize();
}
void InternalClient::debug(QDebug &stream) const
{
stream.nospace() << "\'InternalClient:" << m_internalWindow << "\'";
}
QRect InternalClient::transparentRect() const
{
return QRect();

View File

@ -33,7 +33,6 @@ public:
QPoint clientContentPos() const override;
QSize minSize() const override;
QSize maxSize() const override;
void debug(QDebug &stream) const override;
QRect transparentRect() const override;
NET::WindowType windowType(bool direct = false, int supported_types = 0) const override;
double opacity() const override;

View File

@ -54,8 +54,8 @@ QScriptValue kwinScriptPrint(QScriptContext *context, QScriptEngine *engine)
stream << " ";
}
QScriptValue argument = context->argument(i);
if (KWin::X11Client *client = qscriptvalue_cast<KWin::X11Client *>(argument)) {
client->print<QTextStream>(stream);
if (KWin::AbstractClient *client = qscriptvalue_cast<KWin::AbstractClient *>(argument)) {
stream << client;
} else {
stream << argument.toString();
}

View File

@ -8,6 +8,7 @@
*/
#include "toplevel.h"
#include "abstract_client.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
@ -60,12 +61,35 @@ Toplevel::~Toplevel()
delete info;
}
QDebug& operator<<(QDebug& stream, const Toplevel* cl)
QDebug operator<<(QDebug debug, const Toplevel *toplevel)
{
if (cl == nullptr)
return stream << "\'NULL\'";
cl->debug(stream);
return stream;
QDebugStateSaver saver(debug);
debug.nospace();
if (toplevel) {
debug << toplevel->metaObject()->className() << '(' << static_cast<const void *>(toplevel);
debug << ", windowId=0x" << Qt::hex << toplevel->windowId() << Qt::dec;
if (const KWaylandServer::SurfaceInterface *surface = toplevel->surface()) {
debug << ", surface=" << surface;
}
const AbstractClient *client = qobject_cast<const AbstractClient *>(toplevel);
if (client) {
if (!client->isPopupWindow()) {
debug << ", caption=" << client->caption();
}
if (client->transientFor()) {
debug << ", transientFor=" << client->transientFor();
}
}
if (debug.verbosity() > 2) {
debug << ", frameGeometry=" << toplevel->frameGeometry();
debug << ", resourceName=" << toplevel->resourceName();
debug << ", resourceClass=" << toplevel->resourceClass();
}
debug << ')';
} else {
debug << "Toplevel(0x0)";
}
return debug;
}
void Toplevel::detectShape(xcb_window_t id)

View File

@ -700,10 +700,8 @@ protected:
Xcb::Property fetchSkipCloseAnimation() const;
void readSkipCloseAnimation(Xcb::Property &prop);
void getSkipCloseAnimation();
virtual void debug(QDebug& stream) const = 0;
void copyToDeleted(Toplevel* c);
void disownDataPassedToDeleted();
friend QDebug& operator<<(QDebug& stream, const Toplevel*);
void deleteEffectWindow();
void setDepth(int depth);
QRect m_frameGeometry;
@ -1054,7 +1052,7 @@ inline bool Toplevel::isPopupWindow() const
}
}
QDebug& operator<<(QDebug& stream, const Toplevel*);
QDebug operator<<(QDebug debug, const Toplevel *toplevel);
} // namespace
Q_DECLARE_METATYPE(KWin::Toplevel*)

View File

@ -147,11 +147,6 @@ QRect Unmanaged::transparentRect() const
return QRect(clientPos(), clientSize());
}
void Unmanaged::debug(QDebug& stream) const
{
stream << "\'ID:" << window() << "\'";
}
NET::WindowType Unmanaged::windowType(bool direct, int supportedTypes) const
{
// for unmanaged windows the direct does not make any difference

View File

@ -43,7 +43,6 @@ public:
public Q_SLOTS:
void release(ReleaseReason releaseReason = ReleaseReason::Release);
protected:
void debug(QDebug& stream) const override;
void addDamage(const QRegion &damage) override;
private:
~Unmanaged() override; // use release()

View File

@ -2450,12 +2450,6 @@ void X11Client::updateAllowedActions(bool force)
}
}
void X11Client::debug(QDebug& stream) const
{
stream.nospace();
print<QDebug>(stream);
}
Xcb::StringProperty X11Client::fetchActivities() const
{
#ifdef KWIN_BUILD_ACTIVITIES

View File

@ -273,9 +273,6 @@ public:
void setSessionActivityOverride(bool needed);
bool isClient() const override;
template <typename T>
void print(T &stream) const;
void cancelFocusOutTimer();
/**
@ -331,7 +328,6 @@ private:
bool motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_root, int y_root);
protected:
void debug(QDebug& stream) const override;
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override;
void doSetActive() override;
@ -641,13 +637,6 @@ inline bool X11Client::hiddenPreview() const
return mapping_state == Kept;
}
template <typename T>
inline void X11Client::print(T &stream) const
{
stream << "\'Client:" << window() << ";WMCLASS:" << resourceClass() << ":"
<< resourceName() << ";Caption:" << caption() << "\'";
}
} // namespace
Q_DECLARE_METATYPE(KWin::X11Client *)
Q_DECLARE_METATYPE(QList<KWin::X11Client *>)

View File

@ -601,11 +601,6 @@ XdgToplevelInterface *XdgToplevelClient::shellSurface() const
return m_shellSurface;
}
void XdgToplevelClient::debug(QDebug &stream) const
{
stream << "XdgToplevelClient:" << resourceClass() << caption();
}
NET::WindowType XdgToplevelClient::windowType(bool direct, int supported_types) const
{
Q_UNUSED(direct)
@ -1774,11 +1769,6 @@ XdgPopupClient::~XdgPopupClient()
{
}
void XdgPopupClient::debug(QDebug &stream) const
{
stream << "XdgPopupClient: transientFor:" << transientFor();
}
NET::WindowType XdgPopupClient::windowType(bool direct, int supported_types) const
{
Q_UNUSED(direct)

View File

@ -127,7 +127,6 @@ public:
KWaylandServer::XdgToplevelInterface *shellSurface() const;
void debug(QDebug &stream) const override;
NET::WindowType windowType(bool direct = false, int supported_types = 0) const override;
MaximizeMode maximizeMode() const override;
MaximizeMode requestedMaximizeMode() const override;
@ -233,7 +232,6 @@ public:
explicit XdgPopupClient(KWaylandServer::XdgPopupInterface *shellSurface);
~XdgPopupClient() override;
void debug(QDebug &stream) const override;
NET::WindowType windowType(bool direct = false, int supported_types = 0) const override;
bool hasPopupGrab() const override;
void popupDone() override;