Introduce AbstractClient::createDecoration()

Summary:
We have duplicated code in InternalClient and XdgShellClient to create
decorations. In order to get rid of the code duplication, this change
introduces a method that AbstractClient subclasses can call to create
a window decoration.

Test Plan: Tests pass.

Reviewers: #kwin, apol

Reviewed By: apol

Subscribers: apol, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D27822
master
Vlad Zahorodnii 2020-02-25 14:57:44 +02:00
parent 17e6bd8587
commit 4ae6c99c6b
7 changed files with 23 additions and 66 deletions

View File

@ -2137,6 +2137,27 @@ void AbstractClient::endMoveResize()
updateCursor();
}
void AbstractClient::createDecoration(const QRect &oldGeometry)
{
KDecoration2::Decoration *decoration = Decoration::DecorationBridge::self()->createDecoration(this);
if (decoration) {
QMetaObject::invokeMethod(decoration, "update", Qt::QueuedConnection);
connect(decoration, &KDecoration2::Decoration::shadowChanged, this, &Toplevel::updateShadow);
connect(decoration, &KDecoration2::Decoration::bordersChanged, this, [this]() {
GeometryUpdatesBlocker blocker(this);
const QRect oldGeometry = frameGeometry();
if (!isShade()) {
checkWorkspacePosition(oldGeometry);
}
emit geometryShapeChanged(this, oldGeometry);
});
}
setDecoration(decoration);
setFrameGeometry(QRect(oldGeometry.topLeft(), clientSizeToFrameSize(clientSize())));
emit geometryShapeChanged(this, oldGeometry);
}
void AbstractClient::destroyDecoration()
{
delete m_decoration.decoration;

View File

@ -1176,6 +1176,7 @@ protected:
void setDecoration(KDecoration2::Decoration *decoration) {
m_decoration.decoration = decoration;
}
virtual void createDecoration(const QRect &oldGeometry);
virtual void destroyDecoration();
void startDecorationDoubleClickTimer();
void invalidateDecorationDoubleClickTimer();

View File

@ -496,17 +496,6 @@ bool InternalClient::belongsToSameApplication(const AbstractClient *other, SameA
return qobject_cast<const InternalClient *>(other) != nullptr;
}
void InternalClient::destroyDecoration()
{
if (!isDecorated()) {
return;
}
const QRect clientGeometry = frameRectToClientRect(frameGeometry());
AbstractClient::destroyDecoration();
setFrameGeometry(clientGeometry);
}
void InternalClient::doMove(int x, int y)
{
Q_UNUSED(x)
@ -537,32 +526,6 @@ void InternalClient::updateCaption()
}
}
void InternalClient::createDecoration(const QRect &rect)
{
KDecoration2::Decoration *decoration = Decoration::DecorationBridge::self()->createDecoration(this);
if (decoration) {
QMetaObject::invokeMethod(decoration, "update", Qt::QueuedConnection);
connect(decoration, &KDecoration2::Decoration::shadowChanged, this, &Toplevel::updateShadow);
connect(decoration, &KDecoration2::Decoration::bordersChanged, this,
[this]() {
GeometryUpdatesBlocker blocker(this);
const QRect oldGeometry = frameGeometry();
if (!isShade()) {
checkWorkspacePosition(oldGeometry);
}
emit geometryShapeChanged(this, oldGeometry);
}
);
}
const QRect oldFrameGeometry = frameGeometry();
setDecoration(decoration);
setFrameGeometry(clientRectToFrameRect(rect));
emit geometryShapeChanged(this, oldFrameGeometry);
}
void InternalClient::requestGeometry(const QRect &rect)
{
if (m_internalWindow) {

View File

@ -90,13 +90,11 @@ public:
protected:
bool acceptsFocus() const override;
bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override;
void destroyDecoration() override;
void doMove(int x, int y) override;
void doResizeSync() override;
void updateCaption() override;
private:
void createDecoration(const QRect &rect);
void requestGeometry(const QRect &rect);
void commitGeometry(const QRect &rect);
void setCaption(const QString &caption);

View File

@ -433,7 +433,7 @@ private:
void grabButton(int mod);
void ungrabButton(int mod);
void resizeDecoration();
void createDecoration(const QRect &oldgeom);
void createDecoration(const QRect &oldgeom) override;
void pingWindow();
void killProcess(bool ask, xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME);

View File

@ -460,31 +460,6 @@ void XdgShellClient::markAsMapped()
updateShowOnScreenEdge();
}
void XdgShellClient::createDecoration(const QRect &oldGeom)
{
KDecoration2::Decoration *decoration = Decoration::DecorationBridge::self()->createDecoration(this);
if (decoration) {
QMetaObject::invokeMethod(decoration, "update", Qt::QueuedConnection);
connect(decoration, &KDecoration2::Decoration::shadowChanged, this, &Toplevel::updateShadow);
connect(decoration, &KDecoration2::Decoration::bordersChanged, this,
[this]() {
GeometryUpdatesBlocker blocker(this);
RequestGeometryBlocker requestBlocker(this);
const QRect oldGeometry = frameGeometry();
if (!isShade()) {
checkWorkspacePosition(oldGeometry);
}
emit geometryShapeChanged(this, oldGeometry);
}
);
}
setDecoration(decoration);
// TODO: ensure the new geometry still fits into the client area (e.g. maximized windows)
doSetGeometry(QRect(oldGeom.topLeft(), m_windowGeometry.size() + QSize(borderLeft() + borderRight(), borderBottom() + borderTop())));
emit geometryShapeChanged(this, oldGeom);
}
void XdgShellClient::updateDecoration(bool check_workspace_pos, bool force)
{
if (!force &&

View File

@ -170,7 +170,6 @@ private:
* At this point all initial properties should have been set by the client.
*/
void finishInit();
void createDecoration(const QRect &oldgeom);
void createWindowId();
void updateIcon();
bool shouldExposeToWindowManagement();