From ebe29896490177089436a6537ad48c20b9d39859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 3 Dec 2015 13:24:44 +0100 Subject: [PATCH] Move the KDecoration2::Decoration to AbstractClient This includes the methods: * decoration() * decoration() const * isDecorated() const In addition new protected methods are added to destroy the Decoration and to set it. Usage of m_decoration in Client code is adjusted. --- abstract_client.cpp | 14 +++++++---- abstract_client.h | 24 ++++++++++++++++++- client.cpp | 58 +++++++++++++++++++++------------------------ client.h | 17 +------------ events.cpp | 28 +++++++++++----------- geometry.cpp | 8 +++---- 6 files changed, 78 insertions(+), 71 deletions(-) diff --git a/abstract_client.cpp b/abstract_client.cpp index cbe5eb6a06..37f6d34247 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -34,6 +34,8 @@ along with this program. If not, see . #include "wayland_server.h" #include +#include + namespace KWin { @@ -60,6 +62,7 @@ AbstractClient::AbstractClient() AbstractClient::~AbstractClient() { assert(m_blockGeometryUpdates == 0); + Q_ASSERT(m_decoration == nullptr); } void AbstractClient::updateMouseGrab() @@ -1075,11 +1078,6 @@ QSize AbstractClient::sizeForClientSize(const QSize &wsize, Sizemode mode, bool return wsize; } -bool AbstractClient::isDecorated() const -{ - return false; -} - void AbstractClient::addRepaintDuringGeometryUpdates() { const QRect deco_rect = visibleRect(); @@ -1307,4 +1305,10 @@ void AbstractClient::endMoveResize() updateCursor(); } +void AbstractClient::destroyDecoration() +{ + delete m_decoration; + m_decoration = nullptr; +} + } diff --git a/abstract_client.h b/abstract_client.h index 3e363ddec4..f39ff98c7d 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -35,6 +35,11 @@ class PlasmaWindowInterface; } } +namespace KDecoration2 +{ +class Decoration; +} + namespace KWin { @@ -331,7 +336,6 @@ public: virtual void blockActivityUpdates(bool b = true) = 0; QPalette palette() const; const Decoration::DecorationPalette *decorationPalette() const; - virtual bool isDecorated() const; virtual bool isResizable() const = 0; virtual bool isMovable() const = 0; virtual bool isMovableAcrossScreens() const = 0; @@ -477,6 +481,17 @@ public: Options::MouseCommand getMouseCommand(Qt::MouseButton button, bool *handled) const; Options::MouseCommand getWheelCommand(Qt::Orientation orientation, bool *handled) const; + // decoration related + KDecoration2::Decoration *decoration() { + return m_decoration; + } + const KDecoration2::Decoration *decoration() const { + return m_decoration; + } + bool isDecorated() const { + return m_decoration != nullptr; + } + // TODO: remove boolean trap static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, bool active_hack = false); @@ -777,6 +792,11 @@ protected: s_haveResizeEffect = false; } + void setDecoration(KDecoration2::Decoration *decoration) { + m_decoration = decoration; + } + virtual void destroyDecoration(); + private: void handlePaletteChange(); QSharedPointer m_tabBoxClient; @@ -838,6 +858,8 @@ private: QTimer *delayedTimer = nullptr; } m_moveResize; + KDecoration2::Decoration *m_decoration = nullptr; + static bool s_haveResizeEffect; }; diff --git a/client.cpp b/client.cpp index e2d31ddcbd..846ed7307b 100644 --- a/client.cpp +++ b/client.cpp @@ -97,7 +97,6 @@ Client::Client() , m_client() , m_wrapper() , m_frame() - , m_decoration(nullptr) , m_activityUpdatesBlocked(false) , m_blockedActivityUpdatesRequireTransients(false) , m_moveResizeGrabWindow() @@ -191,7 +190,6 @@ Client::~Client() assert(m_client == XCB_WINDOW_NONE); assert(m_wrapper == XCB_WINDOW_NONE); //assert( frameId() == None ); - Q_ASSERT(m_decoration == nullptr); assert(!check_active_modal); for (auto it = m_connections.constBegin(); it != m_connections.constEnd(); ++it) { disconnect(*it); @@ -320,8 +318,8 @@ void Client::updateInputWindow() QRegion region; - if (!noBorder() && m_decoration) { - const QMargins &r = m_decoration->resizeOnlyBorders(); + if (!noBorder() && isDecorated()) { + const QMargins &r = decoration()->resizeOnlyBorders(); const int left = r.left(); const int top = r.top(); const int right = r.right(); @@ -329,9 +327,9 @@ void Client::updateInputWindow() if (left != 0 || top != 0 || right != 0 || bottom != 0) { region = QRegion(-left, -top, - m_decoration->size().width() + left + right, - m_decoration->size().height() + top + bottom); - region = region.subtracted(m_decoration->rect()); + decoration()->size().width() + left + right, + decoration()->size().height() + top + bottom); + region = region.subtracted(decoration()->rect()); } } @@ -373,7 +371,7 @@ void Client::updateInputWindow() void Client::updateDecoration(bool check_workspace_pos, bool force) { if (!force && - ((m_decoration == NULL && noBorder()) || (m_decoration != NULL && !noBorder()))) + ((!isDecorated() && noBorder()) || (isDecorated() && !noBorder()))) return; QRect oldgeom = geometry(); QRect oldClientGeom = oldgeom.adjusted(borderLeft(), borderTop(), -borderRight(), -borderBottom()); @@ -394,12 +392,12 @@ void Client::updateDecoration(bool check_workspace_pos, bool force) void Client::createDecoration(const QRect& oldgeom) { - m_decoration = Decoration::DecorationBridge::self()->createDecoration(this); - if (m_decoration) { - QMetaObject::invokeMethod(m_decoration, "update", Qt::QueuedConnection); - connect(m_decoration, &KDecoration2::Decoration::shadowChanged, this, &Toplevel::getShadow); - connect(m_decoration, &KDecoration2::Decoration::resizeOnlyBordersChanged, this, &Client::updateInputWindow); - connect(m_decoration, &KDecoration2::Decoration::bordersChanged, this, + KDecoration2::Decoration *decoration = Decoration::DecorationBridge::self()->createDecoration(this); + if (decoration) { + QMetaObject::invokeMethod(decoration, "update", Qt::QueuedConnection); + connect(decoration, &KDecoration2::Decoration::shadowChanged, this, &Toplevel::getShadow); + connect(decoration, &KDecoration2::Decoration::resizeOnlyBordersChanged, this, &Client::updateInputWindow); + connect(decoration, &KDecoration2::Decoration::bordersChanged, this, [this]() { updateFrameExtents(); GeometryUpdatesBlocker blocker(this); @@ -415,6 +413,7 @@ void Client::createDecoration(const QRect& oldgeom) } ); } + setDecoration(decoration); move(calculateGravitation(false)); plainResize(sizeForClientSize(clientSize()), ForceGeometrySet); @@ -427,10 +426,9 @@ void Client::createDecoration(const QRect& oldgeom) void Client::destroyDecoration() { QRect oldgeom = geometry(); - if (m_decoration) { + if (isDecorated()) { QPoint grav = calculateGravitation(true); - delete m_decoration; - m_decoration = nullptr; + AbstractClient::destroyDecoration(); plainResize(sizeForClientSize(clientSize()), ForceGeometrySet); move(grav); if (compositing()) @@ -444,17 +442,17 @@ void Client::destroyDecoration() void Client::triggerDecorationRepaint() { - if (m_decoration) { - m_decoration->update(); + if (isDecorated()) { + decoration()->update(); } } void Client::layoutDecorationRects(QRect &left, QRect &top, QRect &right, QRect &bottom) const { - if (!m_decoration) { + if (!isDecorated()) { return; } - QRect r = m_decoration->rect(); + QRect r = decoration()->rect(); NETStrut strut = info->frameOverlap(); @@ -571,9 +569,7 @@ void Client::detectGtkFrameExtents() */ void Client::resizeDecoration() { - if (m_decoration) { - m_decoration->update(); - } + triggerDecorationRepaint(); updateInputWindow(); } @@ -784,7 +780,7 @@ void Client::setShade(ShadeMode mode) return; // No real change in shaded state } - assert(m_decoration != NULL); // noborder windows can't be shaded + assert(isDecorated()); // noborder windows can't be shaded GeometryUpdatesBlocker blocker(this); // TODO: All this unmapping, resizing etc. feels too much duplicated from elsewhere @@ -1850,8 +1846,8 @@ void Client::setBlockingCompositing(bool block) Client::Position Client::mousePosition() const { - if (m_decoration) { - switch (m_decoration->sectionUnderMouse()) { + if (isDecorated()) { + switch (decoration()->sectionUnderMouse()) { case Qt::BottomLeftSection: return PositionBottomLeft; case Qt::BottomRightSection: @@ -2066,7 +2062,7 @@ NET::WindowType Client::windowType(bool direct, int supportedTypes) const bool Client::decorationHasAlpha() const { - if (!m_decoration || m_decoration->isOpaque()) { + if (!isDecorated() || decoration()->isOpaque()) { // either no decoration or decoration has alpha disabled return false; } @@ -2171,7 +2167,7 @@ void Client::showOnScreenEdge() #define BORDER(which) \ int Client::border##which() const \ { \ - return m_decoration ? m_decoration->border##which() : 0; \ + return isDecorated() ? decoration()->border##which() : 0; \ } BORDER(Bottom) @@ -2219,8 +2215,8 @@ bool Client::processDecorationButtonPress(QMouseEvent *event) void Client::processDecorationButtonRelease(QMouseEvent *event) { - if (m_decoration) { - if (!event->isAccepted() && m_decoration->titleBar().contains(event->pos()) && event->button() == Qt::LeftButton) { + if (isDecorated()) { + if (!event->isAccepted() && decoration()->titleBar().contains(event->pos()) && event->button() == Qt::LeftButton) { m_decorationDoubleClickTimer.start(); } } diff --git a/client.h b/client.h index c6b598dd64..1556c64d6b 100644 --- a/client.h +++ b/client.h @@ -45,11 +45,6 @@ class KStartupInfoId; struct xcb_sync_alarm_notify_event_t; -namespace KDecoration2 -{ -class Decoration; -} - namespace KWin { @@ -356,16 +351,7 @@ public: bool hasOffscreenXineramaStrut() const; // Decorations <-> Effects - KDecoration2::Decoration *decoration() { - return m_decoration; - } - const KDecoration2::Decoration *decoration() const { - return m_decoration; - } QPointer decoratedClient() const; - bool isDecorated() const override { - return m_decoration != nullptr; - } void setDecoratedClient(QPointer client); QRect decorationRect() const; @@ -550,7 +536,7 @@ private: Xcb::Property fetchGtkFrameExtents() const; void readGtkFrameExtents(Xcb::Property &prop); void detectGtkFrameExtents(); - void destroyDecoration(); + void destroyDecoration() override; void updateFrameExtents(); void internalShow(); @@ -582,7 +568,6 @@ private: Xcb::Window m_client; Xcb::Window m_wrapper; Xcb::Window m_frame; - KDecoration2::Decoration *m_decoration; QPointer m_decoratedClient; QElapsedTimer m_decorationDoubleClickTimer; QStringList activityList; diff --git a/events.cpp b/events.cpp index 508934727b..6324d15032 100644 --- a/events.cpp +++ b/events.cpp @@ -1006,10 +1006,10 @@ void Client::leaveNotifyEvent(xcb_leave_notify_event_t *e) shadeHoverTimer->setSingleShot(true); shadeHoverTimer->start(options->shadeHoverInterval()); } - if (m_decoration) { + if (isDecorated()) { // sending a move instead of a leave. With leave we need to send proper coords, with move it's handled internally QHoverEvent leaveEvent(QEvent::HoverMove, QPointF(-1, -1), QPointF(-1, -1), Qt::NoModifier); - QCoreApplication::sendEvent(m_decoration, &leaveEvent); + QCoreApplication::sendEvent(decoration(), &leaveEvent); } } if (options->focusPolicy() == Options::FocusStrictlyUnderMouse && isActive() && lostMouse) { @@ -1170,7 +1170,7 @@ bool Client::buttonPressEvent(xcb_window_t w, int button, int state, int x, int // New API processes core events FIRST and only passes unused ones to the decoration return processDecorationButtonPress(button, state, x, y, x_root, y_root, true); } - if (w == frameId() && m_decoration) { + if (w == frameId() && isDecorated()) { if (button >= 4 && button <= 7) { const Qt::KeyboardModifiers modifiers = x11ToQtKeyboardModifiers(state); // Logic borrowed from qapplication_x11.cpp @@ -1188,9 +1188,9 @@ bool Client::buttonPressEvent(xcb_window_t w, int button, int state, int x, int x11ToQtMouseButtons(state), modifiers); event.setAccepted(false); - QCoreApplication::sendEvent(m_decoration, &event); + QCoreApplication::sendEvent(decoration(), &event); if (!event.isAccepted() && !hor) { - if (m_decoration->titleBar().contains(x, y)) { + if (decoration()->titleBar().contains(x, y)) { performMouseCommand(options->operationTitlebarMouseWheel(delta), QPoint(x_root, y_root)); } } @@ -1198,7 +1198,7 @@ bool Client::buttonPressEvent(xcb_window_t w, int button, int state, int x, int QMouseEvent event(QEvent::MouseButtonPress, QPointF(x, y), QPointF(x_root, y_root), x11ToQtMouseButton(button), x11ToQtMouseButtons(state), x11ToQtKeyboardModifiers(state)); event.setAccepted(false); - QCoreApplication::sendEvent(m_decoration, &event); + QCoreApplication::sendEvent(decoration(), &event); if (!event.isAccepted()) { processDecorationButtonPress(button, state, x, y, x_root, y_root); } @@ -1222,7 +1222,7 @@ bool Client::processDecorationButtonPress(int button, int /*state*/, int x, int // check whether it is a double click if (button == XCB_BUTTON_INDEX_1) { if (m_decorationDoubleClickTimer.isValid() && - m_decoration->titleBar().contains(x, y) && + decoration()->titleBar().contains(x, y) && !m_decorationDoubleClickTimer.hasExpired(QGuiApplication::styleHints()->mouseDoubleClickInterval())) { Workspace::self()->performWindowOperation(this, options->operationTitlebarDblClick()); dontMoveResize(); @@ -1268,7 +1268,7 @@ bool Client::processDecorationButtonPress(int button, int /*state*/, int x, int // return value matters only when filtering events before decoration gets them bool Client::buttonReleaseEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root) { - if (w == frameId() && m_decoration) { + if (w == frameId() && isDecorated()) { // wheel handled on buttonPress if (button < 4 || button > 7) { QMouseEvent event(QEvent::MouseButtonRelease, @@ -1278,8 +1278,8 @@ bool Client::buttonReleaseEvent(xcb_window_t w, int button, int state, int x, in x11ToQtMouseButtons(state) & ~x11ToQtMouseButton(button), x11ToQtKeyboardModifiers(state)); event.setAccepted(false); - QCoreApplication::sendEvent(m_decoration, &event); - if (!event.isAccepted() && m_decoration->titleBar().contains(x, y) && button == XCB_BUTTON_INDEX_1) { + QCoreApplication::sendEvent(decoration(), &event); + if (!event.isAccepted() && decoration()->titleBar().contains(x, y) && button == XCB_BUTTON_INDEX_1) { m_decorationDoubleClickTimer.start(); } } @@ -1314,10 +1314,10 @@ bool Client::buttonReleaseEvent(xcb_window_t w, int button, int state, int x, in // return value matters only when filtering events before decoration gets them bool Client::motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_root, int y_root) { - if (w == frameId() && m_decoration && !isMinimized()) { + if (w == frameId() && isDecorated() && !isMinimized()) { // TODO Mouse move event dependent on state QHoverEvent event(QEvent::HoverMove, QPointF(x, y), QPointF(x, y)); - QCoreApplication::instance()->sendEvent(m_decoration, &event); + QCoreApplication::instance()->sendEvent(decoration(), &event); } if (w != frameId() && w != inputId() && w != moveResizeGrabWindow()) return true; // care only about the whole frame @@ -1326,9 +1326,9 @@ bool Client::motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_ro int x = x_root - geometry().x();// + padding_left; int y = y_root - geometry().y();// + padding_top; - if (m_decoration) { + if (isDecorated()) { QHoverEvent event(QEvent::HoverMove, QPointF(x, y), QPointF(x, y)); - QCoreApplication::instance()->sendEvent(m_decoration, &event); + QCoreApplication::instance()->sendEvent(decoration(), &event); } } Position newmode = modKeyDown(state) ? PositionCenter : mousePosition(); diff --git a/geometry.cpp b/geometry.cpp index ab73001b0f..0ba2c6dc88 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1311,7 +1311,7 @@ QSize Client::sizeForClientSize(const QSize& wsize, Sizemode mode, bool noframe) // even if they're not set in flags - see getWmNormalHints() QSize min_size = tabGroup() ? tabGroup()->minSize() : minSize(); QSize max_size = tabGroup() ? tabGroup()->maxSize() : maxSize(); - if (m_decoration != NULL) { + if (isDecorated()) { QSize decominsize(0, 0); QSize border_size(borderLeft() + borderRight(), borderTop() + borderBottom()); if (border_size.width() > decominsize.width()) // just in case @@ -2237,9 +2237,9 @@ void Client::changeMaximize(bool vertical, bool horizontal, bool adjust) } // call into decoration update borders - if (m_decoration && m_decoration->client() && !(options->borderlessMaximizedWindows() && max_mode == KWin::MaximizeFull)) { + if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && max_mode == KWin::MaximizeFull)) { changeMaximizeRecursion = true; - const auto c = m_decoration->client().data(); + const auto c = decoration()->client().data(); if ((max_mode & MaximizeVertical) != (old_mode & MaximizeVertical)) { emit c->maximizedVerticallyChanged(max_mode & MaximizeVertical); } @@ -2260,7 +2260,7 @@ void Client::changeMaximize(bool vertical, bool horizontal, bool adjust) changeMaximizeRecursion = false; } - const ForceGeometry_t geom_mode = m_decoration ? ForceGeometrySet : NormalGeometrySet; + const ForceGeometry_t geom_mode = isDecorated() ? ForceGeometrySet : NormalGeometrySet; // Conditional quick tiling exit points if (quickTileMode() != QuickTileNone) {