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.
icc-effect-5.14.5
Martin Gräßlin 2015-12-03 13:24:44 +01:00
parent 5f502c141a
commit ebe2989649
6 changed files with 78 additions and 71 deletions

View File

@ -34,6 +34,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_server.h"
#include <KWayland/Server/plasmawindowmanagement_interface.h>
#include <KDecoration2/Decoration>
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;
}
}

View File

@ -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<TabBox::TabBoxClientImpl> m_tabBoxClient;
@ -838,6 +858,8 @@ private:
QTimer *delayedTimer = nullptr;
} m_moveResize;
KDecoration2::Decoration *m_decoration = nullptr;
static bool s_haveResizeEffect;
};

View File

@ -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();
}
}

View File

@ -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<Decoration::DecoratedClientImpl> decoratedClient() const;
bool isDecorated() const override {
return m_decoration != nullptr;
}
void setDecoratedClient(QPointer<Decoration::DecoratedClientImpl> 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<Decoration::DecoratedClientImpl> m_decoratedClient;
QElapsedTimer m_decorationDoubleClickTimer;
QStringList activityList;

View File

@ -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();

View File

@ -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) {