diff --git a/plugins/kdecorations/aurorae/src/aurorae.h b/plugins/kdecorations/aurorae/src/aurorae.h --- a/plugins/kdecorations/aurorae/src/aurorae.h +++ b/plugins/kdecorations/aurorae/src/aurorae.h @@ -1,5 +1,6 @@ /******************************************************************** Copyright (C) 2009, 2010, 2012 Martin Gräßlin +Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -74,8 +75,11 @@ void mouseReleaseEvent(QMouseEvent *event) override; private: + KWin::Borders *currentBorders() const; + KWin::Borders *currentResizeOnlyBorders() const; void setupBorders(QQuickItem *item); void updateBorders(); + void updateResizeOnlyBorders(); QMouseEvent translatedMouseEvent(QMouseEvent *orig); QScopedPointer m_fbo; QImage m_buffer; @@ -85,6 +89,7 @@ KWin::Borders *m_borders; KWin::Borders *m_maximizedBorders; KWin::Borders *m_extendedBorders; + KWin::Borders *m_maximizedExtendedBorders; KWin::Borders *m_padding; QString m_themeName; QQuickRenderControl *m_renderControl = nullptr; diff --git a/plugins/kdecorations/aurorae/src/aurorae.cpp b/plugins/kdecorations/aurorae/src/aurorae.cpp --- a/plugins/kdecorations/aurorae/src/aurorae.cpp +++ b/plugins/kdecorations/aurorae/src/aurorae.cpp @@ -1,5 +1,6 @@ /******************************************************************** Copyright (C) 2009, 2010, 2012 Martin Gräßlin +Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -257,6 +258,7 @@ , m_borders(nullptr) , m_maximizedBorders(nullptr) , m_extendedBorders(nullptr) + , m_maximizedExtendedBorders(nullptr) , m_padding(nullptr) , m_themeName(s_defaultTheme) { @@ -306,7 +308,6 @@ const KConfigGroup themeGroup(conf, m_themeName.mid(16)); theme->setButtonSize((KDecoration2::BorderSize)(themeGroup.readEntry("ButtonSize", int(KDecoration2::BorderSize::Normal) - s_indexMapper) + s_indexMapper)); - updateBorders(); }; connect(this, &Decoration::configChanged, theme, readButtonSize); readButtonSize(); @@ -404,19 +405,40 @@ } } setupBorders(m_item); - if (m_extendedBorders) { - auto updateExtendedBorders = [this] { - setResizeOnlyBorders(*m_extendedBorders); - }; - updateExtendedBorders(); - connect(m_extendedBorders, &KWin::Borders::leftChanged, this, updateExtendedBorders); - connect(m_extendedBorders, &KWin::Borders::rightChanged, this, updateExtendedBorders); - connect(m_extendedBorders, &KWin::Borders::topChanged, this, updateExtendedBorders); - connect(m_extendedBorders, &KWin::Borders::bottomChanged, this, updateExtendedBorders); - } + + // TODO: Is there a more efficient way to react to border changes? + auto trackBorders = [this](KWin::Borders *borders) { + if (!borders) { + return; + } + connect(borders, &KWin::Borders::leftChanged, this, &Decoration::updateBorders); + connect(borders, &KWin::Borders::rightChanged, this, &Decoration::updateBorders); + connect(borders, &KWin::Borders::topChanged, this, &Decoration::updateBorders); + connect(borders, &KWin::Borders::bottomChanged, this, &Decoration::updateBorders); + }; + trackBorders(m_borders); + trackBorders(m_maximizedBorders); + + // TODO: Is there a more efficient way to react to border changes? + auto trackResizeOnlyBorders = [this](KWin::Borders *borders) { + if (!borders) { + return; + } + connect(borders, &KWin::Borders::leftChanged, this, &Decoration::updateResizeOnlyBorders); + connect(borders, &KWin::Borders::rightChanged, this, &Decoration::updateResizeOnlyBorders); + connect(borders, &KWin::Borders::topChanged, this, &Decoration::updateResizeOnlyBorders); + connect(borders, &KWin::Borders::bottomChanged, this, &Decoration::updateResizeOnlyBorders); + }; + trackResizeOnlyBorders(m_extendedBorders); + trackResizeOnlyBorders(m_maximizedExtendedBorders); + connect(client().data(), &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateBorders, Qt::QueuedConnection); + connect(client().data(), &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateResizeOnlyBorders, Qt::QueuedConnection); connect(client().data(), &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateBorders); + connect(client().data(), &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateResizeOnlyBorders); updateBorders(); + updateResizeOnlyBorders(); + if (!m_view.isNull()) { auto resizeWindow = [this] { QRect rect(QPoint(0, 0), size()); @@ -453,19 +475,52 @@ m_borders = item->findChild(QStringLiteral("borders")); m_maximizedBorders = item->findChild(QStringLiteral("maximizedBorders")); m_extendedBorders = item->findChild(QStringLiteral("extendedBorders")); + m_maximizedExtendedBorders = item->findChild(QStringLiteral("maximizedExtendedBorders")); m_padding = item->findChild(QStringLiteral("padding")); } -void Decoration::updateBorders() +KWin::Borders *Decoration::currentBorders() const { - KWin::Borders *b = m_borders; - if (client().data()->isMaximized() && m_maximizedBorders) { - b = m_maximizedBorders; + const KDecoration2::DecoratedClient *decoratedClient = client().data(); + + // Some decoration themes may allow the user resizing maximized clients. + if (decoratedClient->isMaximized()) { + return m_maximizedBorders; } - if (!b) { - return; + + return m_borders; +} + +KWin::Borders *Decoration::currentResizeOnlyBorders() const +{ + const KDecoration2::DecoratedClient *decoratedClient = client().data(); + + // Even though shaded clients cannot be resized, we still want to unset the + // resize only borders in order to get rid of the dead zone around the client. + // This is quite generic behavior, so decoration themes don't have to worry + // about it. + if (decoratedClient->isShaded()) { + return nullptr; } - setBorders(*b); + + // Some decoration themes may allow the user resizing maximized clients. + if (decoratedClient->isMaximized()) { + return m_maximizedExtendedBorders; + } + + return m_extendedBorders; +} + +void Decoration::updateBorders() +{ + const KWin::Borders *borders = currentBorders(); + setBorders(borders ? *borders : QMargins()); +} + +void Decoration::updateResizeOnlyBorders() +{ + const KWin::Borders *resizeBorders = currentResizeOnlyBorders(); + setResizeOnlyBorders(resizeBorders ? *resizeBorders : QMargins()); } void Decoration::paint(QPainter *painter, const QRect &repaintRegion) diff --git a/plugins/kdecorations/aurorae/src/lib/auroraetheme.h b/plugins/kdecorations/aurorae/src/lib/auroraetheme.h --- a/plugins/kdecorations/aurorae/src/lib/auroraetheme.h +++ b/plugins/kdecorations/aurorae/src/lib/auroraetheme.h @@ -1,6 +1,7 @@ /* Library for Aurorae window decoration themes. Copyright (C) 2009, 2010, 2012 Martin Gräßlin + Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -69,6 +70,14 @@ Q_PROPERTY(int borderRightMaximized READ rightBorderMaximized NOTIFY borderSizesChanged) Q_PROPERTY(int borderTopMaximized READ topBorderMaximized NOTIFY borderSizesChanged) Q_PROPERTY(int borderBottomMaximized READ bottomBorderMaximized NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderLeft READ resizeOnlyLeftBorder NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderRight READ resizeOnlyRightBorder NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderTop READ resizeOnlyTopBorder NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderBottom READ resizeOnlyBottomBorder NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderLeftMaximized READ resizeOnlyLeftBorderMaximized NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderRightMaximized READ resizeOnlyRightBorderMaximized NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderTopMaximized READ resizeOnlyTopBorderMaximized NOTIFY borderSizesChanged) + Q_PROPERTY(int resizeOnlyBorderBottomMaximized READ resizeOnlyBottomBorderMaximized NOTIFY borderSizesChanged) Q_PROPERTY(int paddingLeft READ paddingLeft NOTIFY themeChanged) Q_PROPERTY(int paddingRight READ paddingRight NOTIFY themeChanged) Q_PROPERTY(int paddingTop READ paddingTop NOTIFY themeChanged) @@ -129,6 +138,14 @@ int rightBorderMaximized() const; int topBorderMaximized() const; int bottomBorderMaximized() const; + int resizeOnlyLeftBorder() const; + int resizeOnlyRightBorder() const; + int resizeOnlyTopBorder() const; + int resizeOnlyBottomBorder() const; + int resizeOnlyLeftBorderMaximized() const; + int resizeOnlyRightBorderMaximized() const; + int resizeOnlyTopBorderMaximized() const; + int resizeOnlyBottomBorderMaximized() const; int paddingLeft() const; int paddingRight() const; int paddingTop() const; diff --git a/plugins/kdecorations/aurorae/src/lib/auroraetheme.cpp b/plugins/kdecorations/aurorae/src/lib/auroraetheme.cpp --- a/plugins/kdecorations/aurorae/src/lib/auroraetheme.cpp +++ b/plugins/kdecorations/aurorae/src/lib/auroraetheme.cpp @@ -1,6 +1,7 @@ /* Library for Aurorae window decoration themes. Copyright (C) 2009, 2010, 2012 Martin Gräßlin + Copyright (C) 2019 Vlad Zagorodniy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -337,6 +338,76 @@ return top; } +int AuroraeTheme::resizeOnlyLeftBorder() const +{ + if (d->themeConfig.decorationPosition() == DecorationLeft) { + return 0; + } + switch (d->borderSize) { + case KDecoration2::BorderSize::None: + case KDecoration2::BorderSize::NoSides: + return d->themeConfig.resizeOnlyBorderLeft(); + default: + return 0; + } +} + +int AuroraeTheme::resizeOnlyRightBorder() const +{ + if (d->themeConfig.decorationPosition() == DecorationRight) { + return 0; + } + switch (d->borderSize) { + case KDecoration2::BorderSize::None: + case KDecoration2::BorderSize::NoSides: + return d->themeConfig.resizeOnlyBorderRight(); + default: + return 0; + } +} + +int AuroraeTheme::resizeOnlyTopBorder() const +{ + if (d->themeConfig.decorationPosition() == DecorationTop) { + return 0; + } + if (d->borderSize == KDecoration2::BorderSize::None) { + return d->themeConfig.resizeOnlyBorderTop(); + } + return 0; +} + +int AuroraeTheme::resizeOnlyBottomBorder() const +{ + if (d->themeConfig.decorationPosition() == DecorationBottom) { + return 0; + } + if (d->borderSize == KDecoration2::BorderSize::None) { + return d->themeConfig.resizeOnlyBorderBottom(); + } + return 0; +} + +int AuroraeTheme::resizeOnlyLeftBorderMaximized() const +{ + return 0; +} + +int AuroraeTheme::resizeOnlyRightBorderMaximized() const +{ + return 0; +} + +int AuroraeTheme::resizeOnlyTopBorderMaximized() const +{ + return 0; +} + +int AuroraeTheme::resizeOnlyBottomBorderMaximized() const +{ + return 0; +} + void AuroraeTheme::padding(int& left, int& top, int& right, int& bottom) const { left = d->themeConfig.paddingLeft(); diff --git a/plugins/kdecorations/aurorae/src/lib/themeconfig.h b/plugins/kdecorations/aurorae/src/lib/themeconfig.h --- a/plugins/kdecorations/aurorae/src/lib/themeconfig.h +++ b/plugins/kdecorations/aurorae/src/lib/themeconfig.h @@ -81,6 +81,19 @@ return m_borderTop; } + int resizeOnlyBorderLeft() const { + return m_resizeOnlyBorderLeft; + } + int resizeOnlyBorderRight() const { + return m_resizeOnlyBorderRight; + } + int resizeOnlyBorderBottom() const { + return m_resizeOnlyBorderBottom; + } + int resizeOnlyBorderTop() const { + return m_resizeOnlyBorderTop; + } + int titleEdgeTop() const { return m_titleEdgeTop; } @@ -240,6 +253,19 @@ static int defaultBorderTop() { return 0; } + // resize only borders + static int defaultResizeOnlyBorderLeft() { + return 5; + } + static int defaultResizeOnlyBorderRight() { + return 5; + } + static int defaultResizeOnlyBorderBottom() { + return 5; + } + static int defaultResizeOnlyBorderTop() { + return 5; + } // title static int defaultTitleEdgeTop() { return 5; @@ -365,6 +391,12 @@ int m_borderBottom; int m_borderTop; + // resize only borders + int m_resizeOnlyBorderLeft; + int m_resizeOnlyBorderRight; + int m_resizeOnlyBorderBottom; + int m_resizeOnlyBorderTop; + // title int m_titleEdgeTop; int m_titleEdgeBottom; diff --git a/plugins/kdecorations/aurorae/src/lib/themeconfig.cpp b/plugins/kdecorations/aurorae/src/lib/themeconfig.cpp --- a/plugins/kdecorations/aurorae/src/lib/themeconfig.cpp +++ b/plugins/kdecorations/aurorae/src/lib/themeconfig.cpp @@ -46,6 +46,11 @@ , m_borderRight(defaultBorderRight()) , m_borderBottom(defaultBorderBottom()) , m_borderTop(defaultBorderTop()) + // resize only borders + , m_resizeOnlyBorderLeft(defaultResizeOnlyBorderLeft()) + , m_resizeOnlyBorderRight(defaultResizeOnlyBorderRight()) + , m_resizeOnlyBorderBottom(defaultResizeOnlyBorderBottom()) + , m_resizeOnlyBorderTop(defaultResizeOnlyBorderTop()) // title , m_titleEdgeTop(defaultTitleEdgeTop()) , m_titleEdgeBottom(defaultTitleEdgeBottom()) @@ -139,6 +144,11 @@ m_borderBottom = qRound(scaleFactor * border.readEntry("BorderBottom", defaultBorderBottom())); m_borderTop = qRound(scaleFactor * border.readEntry("BorderTop", defaultBorderTop())); + m_resizeOnlyBorderLeft = qRound(scaleFactor * border.readEntry("ResizeOnlyBorderLeft", defaultResizeOnlyBorderLeft())); + m_resizeOnlyBorderRight = qRound(scaleFactor * border.readEntry("ResizeOnlyBorderRight", defaultResizeOnlyBorderRight())); + m_resizeOnlyBorderBottom = qRound(scaleFactor * border.readEntry("ResizeOnlyBorderBottom", defaultResizeOnlyBorderBottom())); + m_resizeOnlyBorderTop = qRound(scaleFactor * border.readEntry("ResizeOnlyBorderTop", defaultResizeOnlyBorderTop())); + m_titleEdgeTop = qRound(scaleFactor * border.readEntry("TitleEdgeTop", defaultTitleEdgeTop())); m_titleEdgeBottom = qRound(scaleFactor * border.readEntry("TitleEdgeBottom", defaultTitleEdgeBottom())); m_titleEdgeLeft = qRound(scaleFactor * border.readEntry("TitleEdgeLeft", defaultTitleEdgeLeft())); diff --git a/plugins/kdecorations/aurorae/src/qml/Decoration.qml b/plugins/kdecorations/aurorae/src/qml/Decoration.qml --- a/plugins/kdecorations/aurorae/src/qml/Decoration.qml +++ b/plugins/kdecorations/aurorae/src/qml/Decoration.qml @@ -27,6 +27,9 @@ property QtObject extendedBorders: Borders { objectName: "extendedBorders" } + property QtObject maximizedExtendedBorders: Borders { + objectName: "maximizedExtendedBorders" + } property QtObject padding: Borders { objectName: "padding" } diff --git a/plugins/kdecorations/aurorae/src/qml/aurorae.qml b/plugins/kdecorations/aurorae/src/qml/aurorae.qml --- a/plugins/kdecorations/aurorae/src/qml/aurorae.qml +++ b/plugins/kdecorations/aurorae/src/qml/aurorae.qml @@ -30,6 +30,14 @@ maximizedBorders.right = Qt.binding(function() { return Math.max(0, auroraeTheme.borderRightMaximized);}); maximizedBorders.bottom = Qt.binding(function() { return Math.max(0, auroraeTheme.borderBottomMaximized);}); maximizedBorders.top = Qt.binding(function() { return Math.max(0, auroraeTheme.borderTopMaximized);}); + extendedBorders.left = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderLeft)); + extendedBorders.right = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderRight)); + extendedBorders.top = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderTop)); + extendedBorders.bottom = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderBottom)); + maximizedExtendedBorders.left = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderLeftMaximized)); + maximizedExtendedBorders.right = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderRightMaximized)); + maximizedExtendedBorders.top = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderTopMaximized)); + maximizedExtendedBorders.bottom = Qt.binding(() => Math.max(0, auroraeTheme.resizeOnlyBorderBottomMaximized)); padding.left = auroraeTheme.paddingLeft; padding.right = auroraeTheme.paddingRight; padding.bottom = auroraeTheme.paddingBottom; diff --git a/plugins/kdecorations/aurorae/theme-description b/plugins/kdecorations/aurorae/theme-description --- a/plugins/kdecorations/aurorae/theme-description +++ b/plugins/kdecorations/aurorae/theme-description @@ -125,6 +125,9 @@ BorderLeft=5 BorderRight=5 BorderBottom=5 +ResizeOnlyBorderLeft=10 +ResizeOnlyBorderRight=10 +ResizeOnlyBorderBottom=10 TitleEdgeTop=5 TitleEdgeBottom=5 TitleEdgeLeft=5