diff --git a/kdecoration/breezebutton.cpp b/kdecoration/breezebutton.cpp index 2ae2ea6a..e2e043bc 100644 --- a/kdecoration/breezebutton.cpp +++ b/kdecoration/breezebutton.cpp @@ -1,475 +1,475 @@ /* * Copyright 2014 Martin Gräßlin * Copyright 2014 Hugo Pereira Da Costa * * 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 the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "breezebutton.h" #include #include #include namespace Breeze { using KDecoration2::ColorRole; using KDecoration2::ColorGroup; using KDecoration2::DecorationButtonType; //__________________________________________________________________ Button::Button(DecorationButtonType type, Decoration* decoration, QObject* parent) : DecorationButton(type, decoration, parent) , m_animation( new QPropertyAnimation( this ) ) { // setup animation m_animation->setStartValue( 0 ); m_animation->setEndValue( 1.0 ); m_animation->setTargetObject( this ); m_animation->setPropertyName( "opacity" ); m_animation->setEasingCurve( QEasingCurve::InOutQuad ); // setup default geometry const int height = decoration->buttonHeight(); setGeometry(QRect(0, 0, height, height)); setIconSize(QSize( height, height )); // connections connect(decoration->client().data(), SIGNAL(iconChanged(QIcon)), this, SLOT(update())); connect(decoration->settings().data(), &KDecoration2::DecorationSettings::reconfigured, this, &Button::reconfigure); connect( this, &KDecoration2::DecorationButton::hoveredChanged, this, &Button::updateAnimationState ); reconfigure(); } //__________________________________________________________________ Button::Button(QObject *parent, const QVariantList &args) : DecorationButton(args.at(0).value(), args.at(1).value(), parent) , m_flag(FlagStandalone) , m_animation( new QPropertyAnimation( this ) ) {} //__________________________________________________________________ Button *Button::create(DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent) { if (auto d = qobject_cast(decoration)) { Button *b = new Button(type, d, parent); switch( type ) { case DecorationButtonType::Close: b->setVisible( d->client().data()->isCloseable() ); QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::closeableChanged, b, &Breeze::Button::setVisible ); break; case DecorationButtonType::Maximize: b->setVisible( d->client().data()->isMaximizeable() ); QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::maximizeableChanged, b, &Breeze::Button::setVisible ); break; case DecorationButtonType::Minimize: b->setVisible( d->client().data()->isMinimizeable() ); QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::minimizeableChanged, b, &Breeze::Button::setVisible ); break; case DecorationButtonType::ContextHelp: b->setVisible( d->client().data()->providesContextHelp() ); QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::providesContextHelpChanged, b, &Breeze::Button::setVisible ); break; case DecorationButtonType::Shade: b->setVisible( d->client().data()->isShadeable() ); QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::shadeableChanged, b, &Breeze::Button::setVisible ); break; case DecorationButtonType::Menu: QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::iconChanged, b, [b]() { b->update(); }); break; default: break; } return b; } return nullptr; } //__________________________________________________________________ void Button::paint(QPainter *painter, const QRect &repaintRegion) { Q_UNUSED(repaintRegion) if (!decoration()) return; painter->save(); // translate from offset if( m_flag == FlagFirstInList ) painter->translate( m_offset ); else painter->translate( 0, m_offset.y() ); if( !m_iconSize.isValid() ) m_iconSize = geometry().size().toSize(); // menu button if (type() == DecorationButtonType::Menu) { const QRectF iconRect( geometry().topLeft(), m_iconSize ); decoration()->client().data()->icon().paint(painter, iconRect.toRect()); } else { drawIcon( painter ); } painter->restore(); } //__________________________________________________________________ void Button::drawIcon( QPainter *painter ) const { painter->setRenderHints( QPainter::Antialiasing ); /* scale painter so that its window matches QRect( -1, -1, 20, 20 ) this makes all further rendering and scaling simpler all further rendering is preformed inside QRect( 0, 0, 18, 18 ) */ painter->translate( geometry().topLeft() ); const qreal width( m_iconSize.width() ); painter->scale( width/20, width/20 ); painter->translate( 1, 1 ); // render background const QColor backgroundColor( this->backgroundColor() ); if( backgroundColor.isValid() ) { painter->setPen( Qt::NoPen ); painter->setBrush( backgroundColor ); painter->drawEllipse( QRectF( 0, 0, 18, 18 ) ); } // render mark const QColor foregroundColor( this->foregroundColor() ); if( foregroundColor.isValid() ) { // setup painter QPen pen( foregroundColor ); pen.setCapStyle( Qt::RoundCap ); pen.setJoinStyle( Qt::MiterJoin ); pen.setWidthF( 1.1*qMax((qreal)1.0, 20/width ) ); painter->setPen( pen ); painter->setBrush( Qt::NoBrush ); switch( type() ) { case DecorationButtonType::Close: { painter->drawLine( QPointF( 5, 5 ), QPointF( 13, 13 ) ); painter->drawLine( 13, 5, 5, 13 ); break; } case DecorationButtonType::Maximize: { if( isChecked() ) { pen.setJoinStyle( Qt::RoundJoin ); painter->setPen( pen ); painter->drawPolygon( QPolygonF() << QPointF( 4, 9 ) << QPointF( 9, 4 ) << QPointF( 14, 9 ) << QPointF( 9, 14 ) ); } else { painter->drawPolyline( QPolygonF() << QPointF( 4, 11 ) << QPointF( 9, 6 ) << QPointF( 14, 11 ) ); } break; } case DecorationButtonType::Minimize: { painter->drawPolyline( QPolygonF() << QPointF( 4, 7 ) << QPointF( 9, 12 ) << QPointF( 14, 7 ) ); break; } case DecorationButtonType::OnAllDesktops: { painter->setPen( Qt::NoPen ); painter->setBrush( foregroundColor ); if( isChecked()) { // outer ring painter->drawEllipse( QRectF( 3, 3, 12, 12 ) ); // center dot QColor backgroundColor( this->backgroundColor() ); auto d = qobject_cast( decoration() ); if( !backgroundColor.isValid() && d ) backgroundColor = d->titleBarColor(); if( backgroundColor.isValid() ) { painter->setBrush( backgroundColor ); painter->drawEllipse( QRectF( 8, 8, 2, 2 ) ); } } else { painter->drawPolygon( QPolygonF() << QPointF( 6.5, 8.5 ) << QPointF( 12, 3 ) << QPointF( 15, 6 ) << QPointF( 9.5, 11.5 ) ); painter->setPen( pen ); painter->drawLine( QPointF( 5.5, 7.5 ), QPointF( 10.5, 12.5 ) ); painter->drawLine( QPointF( 12, 6 ), QPointF( 4.5, 13.5 ) ); } break; } case DecorationButtonType::Shade: { if (isChecked()) { painter->drawLine( 4, 5, 14, 5 ); painter->drawPolyline( QPolygonF() << QPointF( 4, 8 ) << QPointF( 9, 13 ) << QPointF( 14, 8 ) ); } else { painter->drawLine( 4, 5, 14, 5 ); painter->drawPolyline( QPolygonF() << QPointF( 4, 13 ) << QPointF( 9, 8 ) << QPointF( 14, 13 ) ); } break; } case DecorationButtonType::KeepBelow: { painter->drawPolyline( QPolygonF() << QPointF( 4, 5 ) << QPointF( 9, 10 ) << QPointF( 14, 5 ) ); painter->drawPolyline( QPolygonF() << QPointF( 4, 9 ) << QPointF( 9, 14 ) << QPointF( 14, 9 ) ); break; } case DecorationButtonType::KeepAbove: { painter->drawPolyline( QPolygonF() << QPointF( 4, 9 ) << QPointF( 9, 4 ) << QPointF( 14, 9 ) ); painter->drawPolyline( QPolygonF() << QPointF( 4, 13 ) << QPointF( 9, 8 ) << QPointF( 14, 13 ) ); break; } case DecorationButtonType::ApplicationMenu: { painter->drawLine( QPointF( 3.5, 5 ), QPointF( 14.5, 5 ) ); painter->drawLine( QPointF( 3.5, 9 ), QPointF( 14.5, 9 ) ); painter->drawLine( QPointF( 3.5, 13 ), QPointF( 14.5, 13 ) ); break; } case DecorationButtonType::ContextHelp: { QPainterPath path; path.moveTo( 5, 6 ); path.arcTo( QRectF( 5, 3.5, 8, 5 ), 180, -180 ); path.cubicTo( QPointF(12.5, 9.5), QPointF( 9, 7.5 ), QPointF( 9, 11.5 ) ); painter->drawPath( path ); painter->drawPoint( 9, 15 ); break; } default: break; } } } //__________________________________________________________________ - QColor Button::foregroundColor( void ) const + QColor Button::foregroundColor() const { auto d = qobject_cast( decoration() ); if( !d ) { return QColor(); } else if( isPressed() ) { return d->titleBarColor(); } else if( type() == DecorationButtonType::Close && d->internalSettings()->outlineCloseButton() ) { return d->titleBarColor(); } else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove ) && isChecked() ) { return d->titleBarColor(); } else if( m_animation->state() == QPropertyAnimation::Running ) { return KColorUtils::mix( d->fontColor(), d->titleBarColor(), m_opacity ); } else if( isHovered() ) { return d->titleBarColor(); } else { return d->fontColor(); } } //__________________________________________________________________ - QColor Button::backgroundColor( void ) const + QColor Button::backgroundColor() const { auto d = qobject_cast( decoration() ); if( !d ) { return QColor(); } auto c = d->client().data(); if( isPressed() ) { if( type() == DecorationButtonType::Close ) return c->color( ColorGroup::Warning, ColorRole::Foreground ); else return KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.3 ); } else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove ) && isChecked() ) { return d->fontColor(); } else if( m_animation->state() == QPropertyAnimation::Running ) { if( type() == DecorationButtonType::Close ) { if( d->internalSettings()->outlineCloseButton() ) { return KColorUtils::mix( d->fontColor(), c->color( ColorGroup::Warning, ColorRole::Foreground ).lighter(), m_opacity ); } else { QColor color( c->color( ColorGroup::Warning, ColorRole::Foreground ).lighter() ); color.setAlpha( color.alpha()*m_opacity ); return color; } } else { QColor color( d->fontColor() ); color.setAlpha( color.alpha()*m_opacity ); return color; } } else if( isHovered() ) { if( type() == DecorationButtonType::Close ) return c->color( ColorGroup::Warning, ColorRole::Foreground ).lighter(); else return d->fontColor(); } else if( type() == DecorationButtonType::Close && d->internalSettings()->outlineCloseButton() ) { return d->fontColor(); } else { return QColor(); } } //________________________________________________________________ void Button::reconfigure() { // animation auto d = qobject_cast(decoration()); if( d ) m_animation->setDuration( d->internalSettings()->animationsDuration() ); } //__________________________________________________________________ void Button::updateAnimationState( bool hovered ) { auto d = qobject_cast(decoration()); if( !(d && d->internalSettings()->animationsEnabled() ) ) return; m_animation->setDirection( hovered ? QPropertyAnimation::Forward : QPropertyAnimation::Backward ); if( m_animation->state() != QPropertyAnimation::Running ) m_animation->start(); } } // namespace diff --git a/kdecoration/breezebutton.h b/kdecoration/breezebutton.h index fd28e774..835d119d 100644 --- a/kdecoration/breezebutton.h +++ b/kdecoration/breezebutton.h @@ -1,140 +1,140 @@ #ifndef BREEZE_BUTTONS_H #define BREEZE_BUTTONS_H /* * Copyright 2014 Martin Gräßlin * Copyright 2014 Hugo Pereira Da Costa * * 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 the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "breezedecoration.h" #include #include #include namespace Breeze { class Button : public KDecoration2::DecorationButton { Q_OBJECT //* declare active state opacity Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity ) public: //* constructor explicit Button(QObject *parent, const QVariantList &args); //* destructor virtual ~Button() = default; //* button creation static Button *create(KDecoration2::DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent); //* render virtual void paint(QPainter *painter, const QRect &repaintRegion) override; //* flag enum Flag { FlagNone, FlagStandalone, FlagFirstInList, FlagLastInList }; //* flag void setFlag( Flag value ) { m_flag = value; } //* standalone buttons bool isStandAlone() const { return m_flag == FlagStandalone; } //* offset void setOffset( const QPointF& value ) { m_offset = value; } //* horizontal offset, for rendering void setHorizontalOffset( qreal value ) { m_offset.setX( value ); } //* vertical offset, for rendering void setVerticalOffset( qreal value ) { m_offset.setY( value ); } //* set icon size void setIconSize( const QSize& value ) { m_iconSize = value; } //*@name active state change animation //@{ void setOpacity( qreal value ) { if( m_opacity == value ) return; m_opacity = value; update(); } - qreal opacity( void ) const + qreal opacity() const { return m_opacity; } //@} private Q_SLOTS: //* apply configuration changes void reconfigure(); //* animation state void updateAnimationState(bool); private: //* private constructor explicit Button(KDecoration2::DecorationButtonType type, Decoration *decoration, QObject *parent = nullptr); //* draw button icon void drawIcon( QPainter *) const; //*@name colors //@{ - QColor foregroundColor( void ) const; - QColor backgroundColor( void ) const; + QColor foregroundColor() const; + QColor backgroundColor() const; //@} Flag m_flag = FlagNone; //* active state change animation QPropertyAnimation *m_animation; //* vertical offset (for rendering) QPointF m_offset; //* icon size QSize m_iconSize; //* active state change opacity qreal m_opacity = 0; }; } // namespace #endif diff --git a/kdecoration/breezedecoration.cpp b/kdecoration/breezedecoration.cpp index 800a5174..71cdab70 100644 --- a/kdecoration/breezedecoration.cpp +++ b/kdecoration/breezedecoration.cpp @@ -1,764 +1,764 @@ /* * Copyright 2014 Martin Gräßlin * Copyright 2014 Hugo Pereira Da Costa * * 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 the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "breezedecoration.h" #include "breeze.h" #include "breezesettingsprovider.h" #include "config-breeze.h" #include "config/breezeconfigwidget.h" #include "breezebutton.h" #include "breezesizegrip.h" #include #include #include #include #include #include #include #include #include #include #include #if BREEZE_HAVE_X11 #include #endif #include K_PLUGIN_FACTORY_WITH_JSON( BreezeDecoFactory, "breeze.json", registerPlugin(); registerPlugin(QStringLiteral("button")); registerPlugin(QStringLiteral("kcmodule")); ) namespace Breeze { using KDecoration2::ColorRole; using KDecoration2::ColorGroup; //________________________________________________________________ static int g_sDecoCount = 0; static int g_shadowSizeEnum = InternalSettings::ShadowLarge; static int g_shadowStrength = 90; static QColor g_shadowColor = Qt::black; static QSharedPointer g_sShadow; //________________________________________________________________ Decoration::Decoration(QObject *parent, const QVariantList &args) : KDecoration2::Decoration(parent, args) , m_animation( new QPropertyAnimation( this ) ) { g_sDecoCount++; } //________________________________________________________________ Decoration::~Decoration() { g_sDecoCount--; if (g_sDecoCount == 0) { // last deco destroyed, clean up shadow g_sShadow.clear(); } deleteSizeGrip(); } //________________________________________________________________ void Decoration::setOpacity( qreal value ) { if( m_opacity == value ) return; m_opacity = value; update(); if( m_sizeGrip ) m_sizeGrip->update(); } //________________________________________________________________ QColor Decoration::titleBarColor() const { auto c = client().data(); if( hideTitleBar() ) return c->color( ColorGroup::Inactive, ColorRole::TitleBar ); else if( m_animation->state() == QPropertyAnimation::Running ) { return KColorUtils::mix( c->color( ColorGroup::Inactive, ColorRole::TitleBar ), c->color( ColorGroup::Active, ColorRole::TitleBar ), m_opacity ); } else return c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::TitleBar ); } //________________________________________________________________ QColor Decoration::outlineColor() const { auto c( client().data() ); if( !m_internalSettings->drawTitleBarSeparator() ) return QColor(); if( m_animation->state() == QPropertyAnimation::Running ) { QColor color( c->palette().color( QPalette::Highlight ) ); color.setAlpha( color.alpha()*m_opacity ); return color; } else if( c->isActive() ) return c->palette().color( QPalette::Highlight ); else return QColor(); } //________________________________________________________________ QColor Decoration::fontColor() const { auto c = client().data(); if( m_animation->state() == QPropertyAnimation::Running ) { return KColorUtils::mix( c->color( ColorGroup::Inactive, ColorRole::Foreground ), c->color( ColorGroup::Active, ColorRole::Foreground ), m_opacity ); } else return c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Foreground ); } //________________________________________________________________ void Decoration::init() { auto c = client().data(); // active state change animation m_animation->setStartValue( 0 ); m_animation->setEndValue( 1.0 ); m_animation->setTargetObject( this ); m_animation->setPropertyName( "opacity" ); m_animation->setEasingCurve( QEasingCurve::InOutQuad ); reconfigure(); updateTitleBar(); auto s = settings(); connect(s.data(), &KDecoration2::DecorationSettings::borderSizeChanged, this, &Decoration::recalculateBorders); // a change in font might cause the borders to change connect(s.data(), &KDecoration2::DecorationSettings::fontChanged, this, &Decoration::recalculateBorders); connect(s.data(), &KDecoration2::DecorationSettings::spacingChanged, this, &Decoration::recalculateBorders); // buttons connect(s.data(), &KDecoration2::DecorationSettings::spacingChanged, this, &Decoration::updateButtonsGeometryDelayed); connect(s.data(), &KDecoration2::DecorationSettings::decorationButtonsLeftChanged, this, &Decoration::updateButtonsGeometryDelayed); connect(s.data(), &KDecoration2::DecorationSettings::decorationButtonsRightChanged, this, &Decoration::updateButtonsGeometryDelayed); // full reconfiguration connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, this, &Decoration::reconfigure); connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, SettingsProvider::self(), &SettingsProvider::reconfigure, Qt::UniqueConnection ); connect(s.data(), &KDecoration2::DecorationSettings::reconfigured, this, &Decoration::updateButtonsGeometryDelayed); connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::recalculateBorders); connect(c, &KDecoration2::DecoratedClient::maximizedHorizontallyChanged, this, &Decoration::recalculateBorders); connect(c, &KDecoration2::DecoratedClient::maximizedVerticallyChanged, this, &Decoration::recalculateBorders); connect(c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::recalculateBorders); connect(c, &KDecoration2::DecoratedClient::captionChanged, this, [this]() { // update the caption area update(titleBar()); } ); connect(c, &KDecoration2::DecoratedClient::activeChanged, this, &Decoration::updateAnimationState); connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateTitleBar); connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateTitleBar); connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::setOpaque); connect(c, &KDecoration2::DecoratedClient::widthChanged, this, &Decoration::updateButtonsGeometry); connect(c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateButtonsGeometry); connect(c, &KDecoration2::DecoratedClient::adjacentScreenEdgesChanged, this, &Decoration::updateButtonsGeometry); connect(c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateButtonsGeometry); createButtons(); createShadow(); } //________________________________________________________________ void Decoration::updateTitleBar() { auto s = settings(); auto c = client().data(); const bool maximized = isMaximized(); const int width = maximized ? c->width() : c->width() - 2*s->largeSpacing()*Metrics::TitleBar_SideMargin; const int height = maximized ? borderTop() : borderTop() - s->smallSpacing()*Metrics::TitleBar_TopMargin; const int x = maximized ? 0 : s->largeSpacing()*Metrics::TitleBar_SideMargin; const int y = maximized ? 0 : s->smallSpacing()*Metrics::TitleBar_TopMargin; setTitleBar(QRect(x, y, width, height)); } //________________________________________________________________ void Decoration::updateAnimationState() { if( m_internalSettings->animationsEnabled() ) { auto c = client().data(); m_animation->setDirection( c->isActive() ? QPropertyAnimation::Forward : QPropertyAnimation::Backward ); if( m_animation->state() != QPropertyAnimation::Running ) m_animation->start(); } else { update(); } } //________________________________________________________________ void Decoration::updateSizeGripVisibility() { auto c = client().data(); if( m_sizeGrip ) { m_sizeGrip->setVisible( c->isResizeable() && !isMaximized() && !c->isShaded() ); } } //________________________________________________________________ int Decoration::borderSize(bool bottom) const { const int baseSize = settings()->smallSpacing(); if( m_internalSettings && (m_internalSettings->mask() & BorderSize ) ) { switch (m_internalSettings->borderSize()) { case InternalSettings::BorderNone: return 0; case InternalSettings::BorderNoSides: return bottom ? qMax(4, baseSize) : 0; default: case InternalSettings::BorderTiny: return bottom ? qMax(4, baseSize) : baseSize; case InternalSettings::BorderNormal: return baseSize*2; case InternalSettings::BorderLarge: return baseSize*3; case InternalSettings::BorderVeryLarge: return baseSize*4; case InternalSettings::BorderHuge: return baseSize*5; case InternalSettings::BorderVeryHuge: return baseSize*6; case InternalSettings::BorderOversized: return baseSize*10; } } else { switch (settings()->borderSize()) { case KDecoration2::BorderSize::None: return 0; case KDecoration2::BorderSize::NoSides: return bottom ? qMax(4, baseSize) : 0; default: case KDecoration2::BorderSize::Tiny: return bottom ? qMax(4, baseSize) : baseSize; case KDecoration2::BorderSize::Normal: return baseSize*2; case KDecoration2::BorderSize::Large: return baseSize*3; case KDecoration2::BorderSize::VeryLarge: return baseSize*4; case KDecoration2::BorderSize::Huge: return baseSize*5; case KDecoration2::BorderSize::VeryHuge: return baseSize*6; case KDecoration2::BorderSize::Oversized: return baseSize*10; } } } //________________________________________________________________ void Decoration::reconfigure() { m_internalSettings = SettingsProvider::self()->internalSettings( this ); // animation m_animation->setDuration( m_internalSettings->animationsDuration() ); // borders recalculateBorders(); // shadow createShadow(); // size grip if( hasNoBorders() && m_internalSettings->drawSizeGrip() ) createSizeGrip(); else deleteSizeGrip(); } //________________________________________________________________ void Decoration::recalculateBorders() { auto c = client().data(); auto s = settings(); // left, right and bottom borders const int left = isLeftEdge() ? 0 : borderSize(); const int right = isRightEdge() ? 0 : borderSize(); const int bottom = (c->isShaded() || isBottomEdge()) ? 0 : borderSize(true); int top = 0; if( hideTitleBar() ) top = bottom; else { QFontMetrics fm(s->font()); top += qMax(fm.height(), buttonHeight() ); // padding below // extra pixel is used for the active window outline const int baseSize = s->smallSpacing(); top += baseSize*Metrics::TitleBar_BottomMargin + 1; // padding above top += baseSize*TitleBar_TopMargin; } setBorders(QMargins(left, top, right, bottom)); // extended sizes const int extSize = s->largeSpacing(); int extSides = 0; int extBottom = 0; if( hasNoBorders() ) { extSides = extSize; extBottom = extSize; } else if( hasNoSideBorders() ) { extSides = extSize; } setResizeOnlyBorders(QMargins(extSides, 0, extSides, extBottom)); } //________________________________________________________________ void Decoration::createButtons() { m_leftButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Left, this, &Button::create); m_rightButtons = new KDecoration2::DecorationButtonGroup(KDecoration2::DecorationButtonGroup::Position::Right, this, &Button::create); updateButtonsGeometry(); } //________________________________________________________________ void Decoration::updateButtonsGeometryDelayed() { QTimer::singleShot( 0, this, &Decoration::updateButtonsGeometry ); } //________________________________________________________________ void Decoration::updateButtonsGeometry() { const auto s = settings(); // adjust button position const int bHeight = captionHeight() + (isTopEdge() ? s->smallSpacing()*Metrics::TitleBar_TopMargin:0); const int bWidth = buttonHeight(); const int verticalOffset = (isTopEdge() ? s->smallSpacing()*Metrics::TitleBar_TopMargin:0) + (captionHeight()-buttonHeight())/2; foreach( const QPointer& button, m_leftButtons->buttons() + m_rightButtons->buttons() ) { button.data()->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( bWidth, bHeight ) ) ); static_cast( button.data() )->setOffset( QPointF( 0, verticalOffset ) ); static_cast( button.data() )->setIconSize( QSize( bWidth, bWidth ) ); } // left buttons if( !m_leftButtons->buttons().isEmpty() ) { // spacing m_leftButtons->setSpacing(s->smallSpacing()*Metrics::TitleBar_ButtonSpacing); // padding const int vPadding = isTopEdge() ? 0 : s->smallSpacing()*Metrics::TitleBar_TopMargin; const int hPadding = s->smallSpacing()*Metrics::TitleBar_SideMargin; if( isLeftEdge() ) { // add offsets on the side buttons, to preserve padding, but satisfy Fitts law auto button = static_cast( m_leftButtons->buttons().front().data() ); button->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( bWidth + hPadding, bHeight ) ) ); button->setFlag( Button::FlagFirstInList ); button->setHorizontalOffset( hPadding ); m_leftButtons->setPos(QPointF(0, vPadding)); } else m_leftButtons->setPos(QPointF(hPadding + borderLeft(), vPadding)); } // right buttons if( !m_rightButtons->buttons().isEmpty() ) { // spacing m_rightButtons->setSpacing(s->smallSpacing()*Metrics::TitleBar_ButtonSpacing); // padding const int vPadding = isTopEdge() ? 0 : s->smallSpacing()*Metrics::TitleBar_TopMargin; const int hPadding = s->smallSpacing()*Metrics::TitleBar_SideMargin; if( isRightEdge() ) { auto button = static_cast( m_rightButtons->buttons().back().data() ); button->setGeometry( QRectF( QPoint( 0, 0 ), QSizeF( bWidth + hPadding, bHeight ) ) ); button->setFlag( Button::FlagLastInList ); m_rightButtons->setPos(QPointF(size().width() - m_rightButtons->geometry().width(), vPadding)); } else m_rightButtons->setPos(QPointF(size().width() - m_rightButtons->geometry().width() - hPadding - borderRight(), vPadding)); } update(); } //________________________________________________________________ void Decoration::paint(QPainter *painter, const QRect &repaintRegion) { // TODO: optimize based on repaintRegion auto c = client().data(); auto s = settings(); // paint background if( !c->isShaded() ) { painter->fillRect(rect(), Qt::transparent); painter->save(); painter->setRenderHint(QPainter::Antialiasing); painter->setPen(Qt::NoPen); painter->setBrush( c->color( c->isActive() ? ColorGroup::Active : ColorGroup::Inactive, ColorRole::Frame ) ); // clip away the top part if( !hideTitleBar() ) painter->setClipRect(0, borderTop(), size().width(), size().height() - borderTop(), Qt::IntersectClip); if( s->isAlphaChannelSupported() ) painter->drawRoundedRect(rect(), Metrics::Frame_FrameRadius, Metrics::Frame_FrameRadius); else painter->drawRect( rect() ); painter->restore(); } if( !hideTitleBar() ) paintTitleBar(painter, repaintRegion); if( hasBorders() && !s->isAlphaChannelSupported() ) { painter->save(); painter->setRenderHint(QPainter::Antialiasing, false); painter->setBrush( Qt::NoBrush ); painter->setPen( c->isActive() ? c->color( ColorGroup::Active, ColorRole::TitleBar ): c->color( ColorGroup::Inactive, ColorRole::Foreground ) ); painter->drawRect( rect().adjusted( 0, 0, -1, -1 ) ); painter->restore(); } } //________________________________________________________________ void Decoration::paintTitleBar(QPainter *painter, const QRect &repaintRegion) { const auto c = client().data(); const QRect titleRect(QPoint(0, 0), QSize(size().width(), borderTop())); if ( !titleRect.intersects(repaintRegion) ) return; painter->save(); painter->setPen(Qt::NoPen); // render a linear gradient on title area if( c->isActive() && m_internalSettings->drawBackgroundGradient() ) { const QColor titleBarColor( this->titleBarColor() ); QLinearGradient gradient( 0, 0, 0, titleRect.height() ); gradient.setColorAt(0.0, titleBarColor.lighter( 120 ) ); gradient.setColorAt(0.8, titleBarColor); painter->setBrush(gradient); } else { painter->setBrush( titleBarColor() ); } auto s = settings(); if( isMaximized() || !s->isAlphaChannelSupported() ) { painter->drawRect(titleRect); } else if( c->isShaded() ) { painter->drawRoundedRect(titleRect, Metrics::Frame_FrameRadius, Metrics::Frame_FrameRadius); } else { painter->setClipRect(titleRect, Qt::IntersectClip); // the rect is made a little bit larger to be able to clip away the rounded corners at the bottom and sides painter->drawRoundedRect(titleRect.adjusted( isLeftEdge() ? -Metrics::Frame_FrameRadius:0, isTopEdge() ? -Metrics::Frame_FrameRadius:0, isRightEdge() ? Metrics::Frame_FrameRadius:0, Metrics::Frame_FrameRadius), Metrics::Frame_FrameRadius, Metrics::Frame_FrameRadius); } const QColor outlineColor( this->outlineColor() ); if( !c->isShaded() && outlineColor.isValid() ) { // outline painter->setRenderHint( QPainter::Antialiasing, false ); painter->setBrush( Qt::NoBrush ); painter->setPen( outlineColor ); painter->drawLine( titleRect.bottomLeft(), titleRect.bottomRight() ); } painter->restore(); // draw caption painter->setFont(s->font()); painter->setPen( fontColor() ); const auto cR = captionRect(); const QString caption = painter->fontMetrics().elidedText(c->caption(), Qt::ElideMiddle, cR.first.width()); painter->drawText(cR.first, cR.second | Qt::TextSingleLine, caption); // draw all buttons m_leftButtons->paint(painter, repaintRegion); m_rightButtons->paint(painter, repaintRegion); } //________________________________________________________________ int Decoration::buttonHeight() const { const int baseSize = settings()->gridUnit(); switch( m_internalSettings->buttonSize() ) { case InternalSettings::ButtonTiny: return baseSize; case InternalSettings::ButtonSmall: return baseSize*1.5; default: case InternalSettings::ButtonDefault: return baseSize*2; case InternalSettings::ButtonLarge: return baseSize*2.5; case InternalSettings::ButtonVeryLarge: return baseSize*3.5; } } //________________________________________________________________ int Decoration::captionHeight() const { return hideTitleBar() ? borderTop() : borderTop() - settings()->smallSpacing()*(Metrics::TitleBar_BottomMargin + Metrics::TitleBar_TopMargin ) - 1; } //________________________________________________________________ QPair Decoration::captionRect() const { if( hideTitleBar() ) return qMakePair( QRect(), Qt::AlignCenter ); else { auto c = client().data(); const int leftOffset = m_leftButtons->buttons().isEmpty() ? Metrics::TitleBar_SideMargin*settings()->smallSpacing(): m_leftButtons->geometry().x() + m_leftButtons->geometry().width() + Metrics::TitleBar_SideMargin*settings()->smallSpacing(); const int rightOffset = m_rightButtons->buttons().isEmpty() ? Metrics::TitleBar_SideMargin*settings()->smallSpacing() : size().width() - m_rightButtons->geometry().x() + Metrics::TitleBar_SideMargin*settings()->smallSpacing(); const int yOffset = settings()->smallSpacing()*Metrics::TitleBar_TopMargin; const QRect maxRect( leftOffset, yOffset, size().width() - leftOffset - rightOffset, captionHeight() ); switch( m_internalSettings->titleAlignment() ) { case InternalSettings::AlignLeft: return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignLeft ); case InternalSettings::AlignRight: return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignRight ); case InternalSettings::AlignCenter: return qMakePair( maxRect, Qt::AlignCenter ); default: case InternalSettings::AlignCenterFullWidth: { // full caption rect const QRect fullRect = QRect( 0, yOffset, size().width(), captionHeight() ); QRect boundingRect( settings()->fontMetrics().boundingRect( c->caption()).toRect() ); // text bounding rect boundingRect.setTop( yOffset ); boundingRect.setHeight( captionHeight() ); boundingRect.moveLeft( ( size().width() - boundingRect.width() )/2 ); if( boundingRect.left() < leftOffset ) return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignLeft ); else if( boundingRect.right() > size().width() - rightOffset ) return qMakePair( maxRect, Qt::AlignVCenter|Qt::AlignRight ); else return qMakePair(fullRect, Qt::AlignCenter); } } } } //________________________________________________________________ void Decoration::createShadow() { // assign global shadow if exists and parameters match if( !g_sShadow || g_shadowSizeEnum != m_internalSettings->shadowSize() || g_shadowStrength != m_internalSettings->shadowStrength() || g_shadowColor != m_internalSettings->shadowColor() ) { // assign parameters g_shadowSizeEnum = m_internalSettings->shadowSize(); g_shadowStrength = m_internalSettings->shadowStrength(); g_shadowColor = m_internalSettings->shadowColor(); // shadow size from enum int shadowSize = 0; switch( g_shadowSizeEnum ) { default: case InternalSettings::ShadowLarge: shadowSize = 64; break; case InternalSettings::ShadowNone: shadowSize = Metrics::Shadow_Overlap + 1; break; case InternalSettings::ShadowSmall: shadowSize = 16; break; case InternalSettings::ShadowMedium: shadowSize = 32; break; case InternalSettings::ShadowVeryLarge: shadowSize = 96; break; } // offset int shadowOffset = (g_shadowSizeEnum == InternalSettings::ShadowNone) ? 0 : qMax( 6*shadowSize/16, Metrics::Shadow_Overlap*2 ); // create image QImage image(2*shadowSize, 2*shadowSize, QImage::Format_ARGB32_Premultiplied); image.fill(Qt::transparent); // painter QPainter painter(&image); painter.setRenderHint( QPainter::Antialiasing, true ); // color calculation delta function auto gradientStopColor = [](QColor color, int alpha) { color.setAlpha(alpha); return color; }; // create gradient if( g_shadowSizeEnum != InternalSettings::ShadowNone ) { // gaussian lambda function auto alpha = [](qreal x) { return std::exp( -x*x/0.15 ); }; QRadialGradient radialGradient( shadowSize, shadowSize, shadowSize ); for( int i = 0; i < 10; ++i ) { const qreal x( qreal( i )/9 ); radialGradient.setColorAt(x, gradientStopColor( g_shadowColor, alpha(x)*g_shadowStrength ) ); } radialGradient.setColorAt(1, gradientStopColor( g_shadowColor, 0 ) ); // fill painter.fillRect( image.rect(), radialGradient); } // contrast pixel QRectF innerRect = QRectF( shadowSize - Metrics::Shadow_Overlap, shadowSize - shadowOffset - Metrics::Shadow_Overlap, 2*Metrics::Shadow_Overlap, shadowOffset + 2*Metrics::Shadow_Overlap ); painter.setPen( gradientStopColor( g_shadowColor, (g_shadowSizeEnum == InternalSettings::ShadowNone) ? g_shadowStrength:(g_shadowStrength*0.5) ) ); painter.setBrush( Qt::NoBrush ); painter.drawRoundedRect( innerRect, -0.5 + Metrics::Frame_FrameRadius, -0.5 + Metrics::Frame_FrameRadius ); // mask out inner rect painter.setPen( Qt::NoPen ); painter.setBrush( Qt::black ); painter.setCompositionMode(QPainter::CompositionMode_DestinationOut ); painter.drawRoundedRect( innerRect, 0.5 + Metrics::Frame_FrameRadius, 0.5 + Metrics::Frame_FrameRadius ); painter.end(); g_sShadow = QSharedPointer::create(); g_sShadow->setPadding( QMargins( shadowSize - Metrics::Shadow_Overlap, shadowSize - shadowOffset - Metrics::Shadow_Overlap, shadowSize - Metrics::Shadow_Overlap, shadowSize - Metrics::Shadow_Overlap ) ); g_sShadow->setInnerShadowRect(QRect( shadowSize, shadowSize, 1, 1) ); // assign image g_sShadow->setShadow(image); } setShadow(g_sShadow); } //_________________________________________________________________ - void Decoration::createSizeGrip( void ) + void Decoration::createSizeGrip() { // do nothing if size grip already exist if( m_sizeGrip ) return; #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; // access client auto c = client().data(); if( !c ) return; if( c->windowId() != 0 ) { m_sizeGrip = new SizeGrip( this ); connect( c, &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateSizeGripVisibility ); connect( c, &KDecoration2::DecoratedClient::shadedChanged, this, &Decoration::updateSizeGripVisibility ); connect( c, &KDecoration2::DecoratedClient::resizeableChanged, this, &Decoration::updateSizeGripVisibility ); } #endif } //_________________________________________________________________ - void Decoration::deleteSizeGrip( void ) + void Decoration::deleteSizeGrip() { if( m_sizeGrip ) { m_sizeGrip->deleteLater(); m_sizeGrip = nullptr; } } } // namespace #include "breezedecoration.moc" diff --git a/kdecoration/breezedecoration.h b/kdecoration/breezedecoration.h index 0dd9e2a8..b2ab31a6 100644 --- a/kdecoration/breezedecoration.h +++ b/kdecoration/breezedecoration.h @@ -1,200 +1,200 @@ #ifndef BREEZE_DECORATION_H #define BREEZE_DECORATION_H /* * Copyright 2014 Martin Gräßlin * Copyright 2014 Hugo Pereira Da Costa * * 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 the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "breeze.h" #include "breezesettings.h" #include #include #include #include #include #include namespace KDecoration2 { class DecorationButton; class DecorationButtonGroup; } namespace Breeze { class SizeGrip; class Decoration : public KDecoration2::Decoration { Q_OBJECT //* declare active state opacity Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity ) public: //* constructor explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList()); //* destructor virtual ~Decoration(); //* paint void paint(QPainter *painter, const QRect &repaintRegion) override; //* internal settings InternalSettingsPtr internalSettings() const { return m_internalSettings; } //* caption height int captionHeight() const; //* button height int buttonHeight() const; //*@name active state change animation //@{ void setOpacity( qreal ); - qreal opacity( void ) const + qreal opacity() const { return m_opacity; } //@} //*@name colors //@{ - QColor titleBarColor( void ) const; - QColor outlineColor( void ) const; - QColor fontColor( void ) const; + QColor titleBarColor() const; + QColor outlineColor() const; + QColor fontColor() const; //@} //*@name maximization modes //@{ - inline bool isMaximized( void ) const; - inline bool isMaximizedHorizontally( void ) const; - inline bool isMaximizedVertically( void ) const; + inline bool isMaximized() const; + inline bool isMaximizedHorizontally() const; + inline bool isMaximizedVertically() const; - inline bool isLeftEdge( void ) const; - inline bool isRightEdge( void ) const; - inline bool isTopEdge( void ) const; - inline bool isBottomEdge( void ) const; + inline bool isLeftEdge() const; + inline bool isRightEdge() const; + inline bool isTopEdge() const; + inline bool isBottomEdge() const; - inline bool hideTitleBar( void ) const; + inline bool hideTitleBar() const; //@} public Q_SLOTS: void init() override; private Q_SLOTS: void reconfigure(); void recalculateBorders(); void updateButtonsGeometry(); void updateButtonsGeometryDelayed(); void updateTitleBar(); void updateAnimationState(); void updateSizeGripVisibility(); private: //* return the rect in which caption will be drawn - QPair captionRect( void ) const; + QPair captionRect() const; void createButtons(); void paintTitleBar(QPainter *painter, const QRect &repaintRegion); void createShadow(); //*@name border size //@{ int borderSize(bool bottom = false) const; - inline bool hasBorders( void ) const; - inline bool hasNoBorders( void ) const; - inline bool hasNoSideBorders( void ) const; + inline bool hasBorders() const; + inline bool hasNoBorders() const; + inline bool hasNoSideBorders() const; //@} //*@name size grip //@{ - void createSizeGrip( void ); - void deleteSizeGrip( void ); - SizeGrip* sizeGrip( void ) const + void createSizeGrip(); + void deleteSizeGrip(); + SizeGrip* sizeGrip() const { return m_sizeGrip; } //@} InternalSettingsPtr m_internalSettings; QList m_buttons; KDecoration2::DecorationButtonGroup *m_leftButtons = nullptr; KDecoration2::DecorationButtonGroup *m_rightButtons = nullptr; //* size grip widget SizeGrip *m_sizeGrip = nullptr; //* active state change animation QPropertyAnimation *m_animation; //* active state change opacity qreal m_opacity = 0; }; - bool Decoration::hasBorders( void ) const + bool Decoration::hasBorders() const { if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() > InternalSettings::BorderNoSides; else return settings()->borderSize() > KDecoration2::BorderSize::NoSides; } - bool Decoration::hasNoBorders( void ) const + bool Decoration::hasNoBorders() const { if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNone; else return settings()->borderSize() == KDecoration2::BorderSize::None; } - bool Decoration::hasNoSideBorders( void ) const + bool Decoration::hasNoSideBorders() const { if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNoSides; else return settings()->borderSize() == KDecoration2::BorderSize::NoSides; } - bool Decoration::isMaximized( void ) const + bool Decoration::isMaximized() const { return client().data()->isMaximized() && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::isMaximizedHorizontally( void ) const + bool Decoration::isMaximizedHorizontally() const { return client().data()->isMaximizedHorizontally() && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::isMaximizedVertically( void ) const + bool Decoration::isMaximizedVertically() const { return client().data()->isMaximizedVertically() && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::isLeftEdge( void ) const + bool Decoration::isLeftEdge() const { return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::LeftEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::isRightEdge( void ) const + bool Decoration::isRightEdge() const { return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::RightEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::isTopEdge( void ) const + bool Decoration::isTopEdge() const { return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::TopEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::isBottomEdge( void ) const + bool Decoration::isBottomEdge() const { return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::BottomEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } - bool Decoration::hideTitleBar( void ) const + bool Decoration::hideTitleBar() const { return m_internalSettings->hideTitleBar() && !client().data()->isShaded(); } } #endif diff --git a/kdecoration/breezesettingsprovider.cpp b/kdecoration/breezesettingsprovider.cpp index f1e07cf4..229ec9e6 100644 --- a/kdecoration/breezesettingsprovider.cpp +++ b/kdecoration/breezesettingsprovider.cpp @@ -1,130 +1,130 @@ /* * Copyright 2014 Hugo Pereira Da Costa * * 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 the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "breezesettingsprovider.h" #include "breezeexceptionlist.h" #include #include namespace Breeze { SettingsProvider *SettingsProvider::s_self = nullptr; //__________________________________________________________________ SettingsProvider::SettingsProvider(): m_config( KSharedConfig::openConfig( QStringLiteral("breezerc") ) ) { reconfigure(); } //__________________________________________________________________ SettingsProvider::~SettingsProvider() { s_self = nullptr; } //__________________________________________________________________ SettingsProvider *SettingsProvider::self() { // TODO: this is not thread safe! if (!s_self) { s_self = new SettingsProvider(); } return s_self; } //__________________________________________________________________ - void SettingsProvider::reconfigure( void ) + void SettingsProvider::reconfigure() { if( !m_defaultSettings ) { m_defaultSettings = InternalSettingsPtr(new InternalSettings()); m_defaultSettings->setCurrentGroup( QStringLiteral("Windeco") ); } m_defaultSettings->load(); ExceptionList exceptions; exceptions.readConfig( m_config ); m_exceptions = exceptions.get(); } //__________________________________________________________________ InternalSettingsPtr SettingsProvider::internalSettings( Decoration *decoration ) const { QString windowTitle; QString className; // get the client auto client = decoration->client().data(); foreach( auto internalSettings, m_exceptions ) { // discard disabled exceptions if( !internalSettings->enabled() ) continue; // discard exceptions with empty exception pattern if( internalSettings->exceptionPattern().isEmpty() ) continue; /* decide which value is to be compared to the regular expression, based on exception type */ QString value; switch( internalSettings->exceptionType() ) { case InternalSettings::ExceptionWindowTitle: { value = windowTitle.isEmpty() ? (windowTitle = client->caption()):windowTitle; break; } default: case InternalSettings::ExceptionWindowClassName: { if( className.isEmpty() ) { // retrieve class name KWindowInfo info( client->windowId(), nullptr, NET::WM2WindowClass ); QString window_className( QString::fromUtf8(info.windowClassName()) ); QString window_class( QString::fromUtf8(info.windowClassClass()) ); className = window_className + QStringLiteral(" ") + window_class; } value = className; break; } } // check matching if( QRegExp( internalSettings->exceptionPattern() ).indexIn( value ) >= 0 ) { return internalSettings; } } return m_defaultSettings; } } diff --git a/kdecoration/breezesettingsprovider.h b/kdecoration/breezesettingsprovider.h index e6362a1c..25e02577 100644 --- a/kdecoration/breezesettingsprovider.h +++ b/kdecoration/breezesettingsprovider.h @@ -1,76 +1,76 @@ #ifndef breezesettingsprovider_h #define breezesettingsprovider_h /* * Copyright 2014 Hugo Pereira Da Costa * * 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 the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "breezedecoration.h" #include "breezesettings.h" #include "breeze.h" #include #include namespace Breeze { class SettingsProvider: public QObject { Q_OBJECT public: //* destructor ~SettingsProvider(); //* singleton static SettingsProvider *self(); //* internal settings for given decoration InternalSettingsPtr internalSettings(Decoration *) const; public Q_SLOTS: //* reconfigure - void reconfigure( void ); + void reconfigure(); private: //* contructor - SettingsProvider( void ); + SettingsProvider(); //* default configuration InternalSettingsPtr m_defaultSettings; //* exceptions InternalSettingsList m_exceptions; //* config object KSharedConfigPtr m_config; //* singleton static SettingsProvider *s_self; }; } #endif diff --git a/kdecoration/breezesizegrip.cpp b/kdecoration/breezesizegrip.cpp index 08b2f99f..6599b4b5 100644 --- a/kdecoration/breezesizegrip.cpp +++ b/kdecoration/breezesizegrip.cpp @@ -1,308 +1,308 @@ /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * 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 * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezesizegrip.h" #include #include #include #include #if BREEZE_HAVE_X11 #include #endif namespace Breeze { //* scoped pointer convenience typedef template using ScopedPointer = QScopedPointer; //_____________________________________________ SizeGrip::SizeGrip( Decoration* decoration ):QWidget(nullptr) ,m_decoration( decoration ) { setAttribute(Qt::WA_NoSystemBackground ); setAutoFillBackground( false ); // cursor setCursor( Qt::SizeFDiagCursor ); // size setFixedSize( QSize( GripSize, GripSize ) ); // mask QPolygon p; p << QPoint( 0, GripSize ) << QPoint( GripSize, 0 ) << QPoint( GripSize, GripSize ) << QPoint( 0, GripSize ); setMask( QRegion( p ) ); // embed embed(); updatePosition(); // connections auto c = decoration->client().data(); connect( c, &KDecoration2::DecoratedClient::widthChanged, this, &SizeGrip::updatePosition ); connect( c, &KDecoration2::DecoratedClient::heightChanged, this, &SizeGrip::updatePosition ); connect( c, &KDecoration2::DecoratedClient::activeChanged, this, &SizeGrip::updateActiveState ); // show show(); } //_____________________________________________ - SizeGrip::~SizeGrip( void ) + SizeGrip::~SizeGrip() {} //_____________________________________________ - void SizeGrip::updateActiveState( void ) + void SizeGrip::updateActiveState() { #if BREEZE_HAVE_X11 if( QX11Info::isPlatformX11() ) { const quint32 value = XCB_STACK_MODE_ABOVE; xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_STACK_MODE, &value ); xcb_map_window( QX11Info::connection(), winId() ); } #endif update(); } //_____________________________________________ - void SizeGrip::embed( void ) + void SizeGrip::embed() { #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; auto c = m_decoration.data()->client().data(); xcb_window_t windowId = c->windowId(); if( windowId ) { /* find client's parent we want the size grip to be at the same level as the client in the stack */ xcb_window_t current = windowId; auto connection = QX11Info::connection(); xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current ); ScopedPointer tree(xcb_query_tree_reply( connection, cookie, nullptr ) ); if( !tree.isNull() && tree->parent ) current = tree->parent; // reparent xcb_reparent_window( connection, winId(), current, 0, 0 ); setWindowTitle( "Breeze::SizeGrip" ); } else { hide(); } #endif } //_____________________________________________ void SizeGrip::paintEvent( QPaintEvent* ) { if( !m_decoration ) return; // get relevant colors const QColor backgroundColor( m_decoration.data()->titleBarColor() ); // create and configure painter QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing ); painter.setPen( Qt::NoPen ); painter.setBrush( backgroundColor ); // polygon QPolygon p; p << QPoint( 0, GripSize ) << QPoint( GripSize, 0 ) << QPoint( GripSize, GripSize ) << QPoint( 0, GripSize ); painter.drawPolygon( p ); } //_____________________________________________ void SizeGrip::mousePressEvent( QMouseEvent* event ) { switch (event->button()) { case Qt::RightButton: { hide(); QTimer::singleShot(5000, this, SLOT(show())); break; } case Qt::MidButton: { hide(); break; } case Qt::LeftButton: if( rect().contains( event->pos() ) ) { sendMoveResizeEvent( event->pos() ); } break; default: break; } return; } //_______________________________________________________________________________ - void SizeGrip::updatePosition( void ) + void SizeGrip::updatePosition() { #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; auto c = m_decoration.data()->client().data(); QPoint position( c->width() - GripSize - Offset, c->height() - GripSize - Offset ); quint32 values[2] = { quint32(position.x()), quint32(position.y()) }; xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values ); #endif } //_____________________________________________ void SizeGrip::sendMoveResizeEvent( QPoint position ) { #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) return; // pointer to connection auto connection( QX11Info::connection() ); // client auto c = m_decoration.data()->client().data(); /* get root position matching position need to use xcb because the embedding of the widget breaks QT's mapToGlobal and other methods */ QPoint rootPosition( position ); xcb_get_geometry_cookie_t cookie( xcb_get_geometry( connection, winId() ) ); ScopedPointer reply( xcb_get_geometry_reply( connection, cookie, nullptr ) ); if( reply ) { // translate coordinates xcb_translate_coordinates_cookie_t coordCookie( xcb_translate_coordinates( connection, winId(), reply.data()->root, -reply.data()->border_width, -reply.data()->border_width ) ); ScopedPointer< xcb_translate_coordinates_reply_t> coordReply( xcb_translate_coordinates_reply( connection, coordCookie, nullptr ) ); if( coordReply ) { rootPosition.rx() += coordReply.data()->dst_x; rootPosition.ry() += coordReply.data()->dst_y; } } // move/resize atom if( !m_moveResizeAtom ) { // create atom if not found const QString atomName( "_NET_WM_MOVERESIZE" ); xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) ); ScopedPointer reply( xcb_intern_atom_reply( connection, cookie, nullptr ) ); m_moveResizeAtom = reply ? reply->atom:0; } if( !m_moveResizeAtom ) return; // button release event xcb_button_release_event_t releaseEvent; memset(&releaseEvent, 0, sizeof(releaseEvent)); releaseEvent.response_type = XCB_BUTTON_RELEASE; releaseEvent.event = winId(); releaseEvent.child = XCB_WINDOW_NONE; releaseEvent.root = QX11Info::appRootWindow(); releaseEvent.event_x = position.x(); releaseEvent.event_y = position.y(); releaseEvent.root_x = rootPosition.x(); releaseEvent.root_y = rootPosition.y(); releaseEvent.detail = XCB_BUTTON_INDEX_1; releaseEvent.state = XCB_BUTTON_MASK_1; releaseEvent.time = XCB_CURRENT_TIME; releaseEvent.same_screen = true; xcb_send_event( connection, false, winId(), XCB_EVENT_MASK_BUTTON_RELEASE, reinterpret_cast(&releaseEvent)); xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME ); // move resize event xcb_client_message_event_t clientMessageEvent; memset(&clientMessageEvent, 0, sizeof(clientMessageEvent)); clientMessageEvent.response_type = XCB_CLIENT_MESSAGE; clientMessageEvent.type = m_moveResizeAtom; clientMessageEvent.format = 32; clientMessageEvent.window = c->windowId(); clientMessageEvent.data.data32[0] = rootPosition.x(); clientMessageEvent.data.data32[1] = rootPosition.y(); clientMessageEvent.data.data32[2] = 4; // bottom right clientMessageEvent.data.data32[3] = Qt::LeftButton; clientMessageEvent.data.data32[4] = 0; xcb_send_event( connection, false, QX11Info::appRootWindow(), XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, reinterpret_cast(&clientMessageEvent) ); xcb_flush( connection ); #endif } } diff --git a/kdecoration/breezesizegrip.h b/kdecoration/breezesizegrip.h index cb28fcb9..b240d90b 100644 --- a/kdecoration/breezesizegrip.h +++ b/kdecoration/breezesizegrip.h @@ -1,100 +1,100 @@ #ifndef breezesizegrip_h #define breezesizegrip_h /************************************************************************* * Copyright (C) 2014 by Hugo Pereira Da Costa * * * * 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 * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * *************************************************************************/ #include "breezedecoration.h" #include "config-breeze.h" #include #include #include #include #if BREEZE_HAVE_X11 #include #endif namespace Breeze { //* implements size grip for all widgets class SizeGrip: public QWidget { Q_OBJECT public: //* constructor explicit SizeGrip( Decoration* ); //* constructor - virtual ~SizeGrip( void ); + virtual ~SizeGrip(); protected Q_SLOTS: //* update background color - void updateActiveState( void ); + void updateActiveState(); //* update position - void updatePosition( void ); + void updatePosition(); //* embed into parent widget - void embed( void ); + void embed(); protected: //*@name event handlers //@{ //* paint virtual void paintEvent( QPaintEvent* ) override; //* mouse press virtual void mousePressEvent( QMouseEvent* ) override; //@} private: //* send resize event void sendMoveResizeEvent( QPoint ); //* grip size enum { Offset = 0, GripSize = 14 }; //* decoration QPointer m_decoration; //* move/resize atom #if BREEZE_HAVE_X11 xcb_atom_t m_moveResizeAtom = 0; #endif }; } #endif diff --git a/kdecoration/config/breezeconfigwidget.cpp b/kdecoration/config/breezeconfigwidget.cpp index 1e5476c8..49f5a123 100644 --- a/kdecoration/config/breezeconfigwidget.cpp +++ b/kdecoration/config/breezeconfigwidget.cpp @@ -1,217 +1,217 @@ ////////////////////////////////////////////////////////////////////////////// // breezeconfigurationui.cpp // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeconfigwidget.h" #include "breezeexceptionlist.h" #include "breezesettings.h" #include #include #include namespace Breeze { //_________________________________________________________ ConfigWidget::ConfigWidget( QWidget* parent, const QVariantList &args ): KCModule(parent, args), m_configuration( KSharedConfig::openConfig( QStringLiteral( "breezerc" ) ) ), m_changed( false ) { // configuration m_ui.setupUi( this ); // track ui changes connect( m_ui.titleAlignment, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( m_ui.buttonSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( m_ui.outlineCloseButton, SIGNAL(clicked()), SLOT(updateChanged()) ); connect( m_ui.drawBorderOnMaximizedWindows, SIGNAL(clicked()), SLOT(updateChanged()) ); connect( m_ui.drawSizeGrip, SIGNAL(clicked()), SLOT(updateChanged()) ); connect( m_ui.drawBackgroundGradient, SIGNAL(clicked()), SLOT(updateChanged()) ); connect( m_ui.drawTitleBarSeparator, SIGNAL(clicked()), SLOT(updateChanged()) ); // track animations changes connect( m_ui.animationsEnabled, SIGNAL(clicked()), SLOT(updateChanged()) ); connect( m_ui.animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); // track shadows changes connect( m_ui.shadowSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( m_ui.shadowStrength, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); connect( m_ui.shadowColor, SIGNAL(changed(QColor)), SLOT(updateChanged()) ); // track exception changes connect( m_ui.exceptions, SIGNAL(changed(bool)), SLOT(updateChanged()) ); } //_________________________________________________________ - void ConfigWidget::load( void ) + void ConfigWidget::load() { // create internal settings and load from rc files m_internalSettings = InternalSettingsPtr( new InternalSettings() ); m_internalSettings->load(); // assign to ui m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); m_ui.outlineCloseButton->setChecked( m_internalSettings->outlineCloseButton() ); m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() ); m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() ); // load shadows if( m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge ) m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); else m_ui.shadowSize->setCurrentIndex( InternalSettings::ShadowLarge ); m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); // load exceptions ExceptionList exceptions; exceptions.readConfig( m_configuration ); m_ui.exceptions->setExceptions( exceptions.get() ); setChanged( false ); } //_________________________________________________________ - void ConfigWidget::save( void ) + void ConfigWidget::save() { // create internal settings and load from rc files m_internalSettings = InternalSettingsPtr( new InternalSettings() ); m_internalSettings->load(); // apply modifications from ui m_internalSettings->setTitleAlignment( m_ui.titleAlignment->currentIndex() ); m_internalSettings->setButtonSize( m_ui.buttonSize->currentIndex() ); m_internalSettings->setOutlineCloseButton( m_ui.outlineCloseButton->isChecked() ); m_internalSettings->setDrawBorderOnMaximizedWindows( m_ui.drawBorderOnMaximizedWindows->isChecked() ); m_internalSettings->setDrawSizeGrip( m_ui.drawSizeGrip->isChecked() ); m_internalSettings->setDrawBackgroundGradient( m_ui.drawBackgroundGradient->isChecked() ); m_internalSettings->setAnimationsEnabled( m_ui.animationsEnabled->isChecked() ); m_internalSettings->setAnimationsDuration( m_ui.animationsDuration->value() ); m_internalSettings->setDrawTitleBarSeparator(m_ui.drawTitleBarSeparator->isChecked()); m_internalSettings->setShadowSize( m_ui.shadowSize->currentIndex() ); m_internalSettings->setShadowStrength( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) ); m_internalSettings->setShadowColor( m_ui.shadowColor->color() ); // save configuration m_internalSettings->save(); // get list of exceptions and write InternalSettingsList exceptions( m_ui.exceptions->exceptions() ); ExceptionList( exceptions ).writeConfig( m_configuration ); // sync configuration m_configuration->sync(); setChanged( false ); // needed to tell kwin to reload when running from external kcmshell { QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); QDBusConnection::sessionBus().send(message); } // needed for breeze style to reload shadows { QDBusMessage message( QDBusMessage::createSignal("/BreezeDecoration", "org.kde.Breeze.Style", "reparseConfiguration") ); QDBusConnection::sessionBus().send(message); } } //_________________________________________________________ - void ConfigWidget::defaults( void ) + void ConfigWidget::defaults() { // create internal settings and load from rc files m_internalSettings = InternalSettingsPtr( new InternalSettings() ); m_internalSettings->setDefaults(); // assign to ui m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() ); m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() ); m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); } //_______________________________________________ - void ConfigWidget::updateChanged( void ) + void ConfigWidget::updateChanged() { // check configuration if( !m_internalSettings ) return; // track modifications bool modified( false ); if (m_ui.drawTitleBarSeparator->isChecked() != m_internalSettings->drawTitleBarSeparator()) modified = true; if( m_ui.titleAlignment->currentIndex() != m_internalSettings->titleAlignment() ) modified = true; else if( m_ui.buttonSize->currentIndex() != m_internalSettings->buttonSize() ) modified = true; else if( m_ui.outlineCloseButton->isChecked() != m_internalSettings->outlineCloseButton() ) modified = true; else if( m_ui.drawBorderOnMaximizedWindows->isChecked() != m_internalSettings->drawBorderOnMaximizedWindows() ) modified = true; else if( m_ui.drawSizeGrip->isChecked() != m_internalSettings->drawSizeGrip() ) modified = true; else if( m_ui.drawBackgroundGradient->isChecked() != m_internalSettings->drawBackgroundGradient() ) modified = true; // animations else if( m_ui.animationsEnabled->isChecked() != m_internalSettings->animationsEnabled() ) modified = true; else if( m_ui.animationsDuration->value() != m_internalSettings->animationsDuration() ) modified = true; // shadows else if( m_ui.shadowSize->currentIndex() != m_internalSettings->shadowSize() ) modified = true; else if( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) != m_internalSettings->shadowStrength() ) modified = true; else if( m_ui.shadowColor->color() != m_internalSettings->shadowColor() ) modified = true; // exceptions else if( m_ui.exceptions->isChanged() ) modified = true; setChanged( modified ); } //_______________________________________________ void ConfigWidget::setChanged( bool value ) { emit changed( value ); } } diff --git a/kdecoration/config/breezeconfigwidget.h b/kdecoration/config/breezeconfigwidget.h index fda0de9d..a2fc6d14 100644 --- a/kdecoration/config/breezeconfigwidget.h +++ b/kdecoration/config/breezeconfigwidget.h @@ -1,93 +1,93 @@ #ifndef breezeconfigwidget_h #define breezeconfigwidget_h ////////////////////////////////////////////////////////////////////////////// // breezeconfigurationui.h // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "ui_breezeconfigurationui.h" #include "breezeexceptionlistwidget.h" #include "breezesettings.h" #include "breeze.h" #include #include #include #include namespace Breeze { //_____________________________________________ class ConfigWidget: public KCModule { Q_OBJECT public: //* constructor explicit ConfigWidget( QWidget*, const QVariantList& ); //* destructor - virtual ~ConfigWidget( void ) = default; + virtual ~ConfigWidget() = default; //* default void defaults() override; //* load configuration - void load( void ) override; + void load() override; //* save configuration - void save( void ) override; + void save() override; protected Q_SLOTS: //* update changed state virtual void updateChanged(); protected: //* set changed state void setChanged( bool ); private: //* ui Ui_BreezeConfigurationUI m_ui; //* kconfiguration object KSharedConfig::Ptr m_configuration; //* internal exception InternalSettingsPtr m_internalSettings; //* changed state bool m_changed; }; } #endif diff --git a/kdecoration/config/breezedetectwidget.h b/kdecoration/config/breezedetectwidget.h index 83b92d8c..54e51da7 100644 --- a/kdecoration/config/breezedetectwidget.h +++ b/kdecoration/config/breezedetectwidget.h @@ -1,113 +1,113 @@ #ifndef breezedetectwidget_h #define breezedetectwidget_h ////////////////////////////////////////////////////////////////////////////// // breezedetectwidget.h // Note: this class is a stripped down version of // /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.h // Copyright (c) 2004 Lubos Lunak // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezesettings.h" #include "ui_breezedetectwidget.h" #include #include #include #include #include #include namespace Breeze { class DetectDialog : public QDialog { Q_OBJECT public: //* constructor explicit DetectDialog( QWidget* ); //* read window properties or select one from mouse grab void detect( WId window ); //* selected class QByteArray selectedClass() const; //* window information const KWindowInfo& windowInfo() const { return *(m_info.data()); } //* exception type InternalSettings::EnumExceptionType exceptionType() const { if( m_ui.windowClassCheckBox->isChecked() ) return InternalSettings::ExceptionWindowClassName; else if( m_ui.windowTitleCheckBox->isChecked() ) return InternalSettings::ExceptionWindowTitle; else return InternalSettings::ExceptionWindowClassName; } Q_SIGNALS: void detectionDone( bool ); protected: bool eventFilter( QObject* o, QEvent* e ) override; private: //* select window from grab void selectWindow(); //* read window properties void readWindow( WId window ); //* find window under cursor WId findWindow(); //* execute - void executeDialog( void ); + void executeDialog(); //* ui Ui::BreezeDetectWidget m_ui; //* invisible dialog used to grab mouse QDialog* m_grabber = nullptr; //* current window information QScopedPointer m_info; //* wm state atom quint32 m_wmStateAtom = 0; }; } // namespace #endif diff --git a/kdecoration/config/breezeexceptiondialog.cpp b/kdecoration/config/breezeexceptiondialog.cpp index f3ca3f09..d2b348ab 100644 --- a/kdecoration/config/breezeexceptiondialog.cpp +++ b/kdecoration/config/breezeexceptiondialog.cpp @@ -1,184 +1,184 @@ ////////////////////////////////////////////////////////////////////////////// // breezeexceptiondialog.cpp // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeexceptiondialog.h" #include "breezedetectwidget.h" #include "config-breeze.h" #if BREEZE_HAVE_X11 #include #endif namespace Breeze { //___________________________________________ ExceptionDialog::ExceptionDialog( QWidget* parent ): QDialog( parent ) { m_ui.setupUi( this ); connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) ); // store checkboxes from ui into list m_checkboxes.insert( BorderSize, m_ui.borderSizeCheckBox ); // detect window properties connect( m_ui.detectDialogButton, SIGNAL(clicked()), SLOT(selectWindowProperties()) ); // connections connect( m_ui.exceptionType, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); connect( m_ui.exceptionEditor, SIGNAL(textChanged(QString)), SLOT(updateChanged()) ); connect( m_ui.borderSizeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { connect( iter.value(), SIGNAL(clicked()), SLOT(updateChanged()) ); } connect( m_ui.hideTitleBar, SIGNAL(clicked()), SLOT(updateChanged()) ); // hide detection dialog on non X11 platforms #if BREEZE_HAVE_X11 if( !QX11Info::isPlatformX11() ) m_ui.detectDialogButton->hide(); #else m_ui.detectDialogButton->hide(); #endif } //___________________________________________ void ExceptionDialog::setException( InternalSettingsPtr exception ) { // store exception internally m_exception = exception; // type m_ui.exceptionType->setCurrentIndex(m_exception->exceptionType() ); m_ui.exceptionEditor->setText( m_exception->exceptionPattern() ); m_ui.borderSizeComboBox->setCurrentIndex( m_exception->borderSize() ); m_ui.hideTitleBar->setChecked( m_exception->hideTitleBar() ); // mask for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { iter.value()->setChecked( m_exception->mask() & iter.key() ); } setChanged( false ); } //___________________________________________ - void ExceptionDialog::save( void ) + void ExceptionDialog::save() { m_exception->setExceptionType( m_ui.exceptionType->currentIndex() ); m_exception->setExceptionPattern( m_ui.exceptionEditor->text() ); m_exception->setBorderSize( m_ui.borderSizeComboBox->currentIndex() ); m_exception->setHideTitleBar( m_ui.hideTitleBar->isChecked() ); // mask unsigned int mask = None; for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { if( iter.value()->isChecked() ) mask |= iter.key(); } m_exception->setMask( mask ); setChanged( false ); } //___________________________________________ - void ExceptionDialog::updateChanged( void ) + void ExceptionDialog::updateChanged() { bool modified( false ); if( m_exception->exceptionType() != m_ui.exceptionType->currentIndex() ) modified = true; else if( m_exception->exceptionPattern() != m_ui.exceptionEditor->text() ) modified = true; else if( m_exception->borderSize() != m_ui.borderSizeComboBox->currentIndex() ) modified = true; else if( m_exception->hideTitleBar() != m_ui.hideTitleBar->isChecked() ) modified = true; else { // check mask for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) { if( iter.value()->isChecked() != (bool)( m_exception->mask() & iter.key() ) ) { modified = true; break; } } } setChanged( modified ); } //___________________________________________ - void ExceptionDialog::selectWindowProperties( void ) + void ExceptionDialog::selectWindowProperties() { // create widget if( !m_detectDialog ) { m_detectDialog = new DetectDialog( this ); connect( m_detectDialog, SIGNAL(detectionDone(bool)), SLOT(readWindowProperties(bool)) ); } m_detectDialog->detect(0); } //___________________________________________ void ExceptionDialog::readWindowProperties( bool valid ) { Q_CHECK_PTR( m_detectDialog ); if( valid ) { // type m_ui.exceptionType->setCurrentIndex( m_detectDialog->exceptionType() ); // window info const KWindowInfo& info( m_detectDialog->windowInfo() ); switch( m_detectDialog->exceptionType() ) { default: case InternalSettings::ExceptionWindowClassName: m_ui.exceptionEditor->setText( QString::fromUtf8( info.windowClassClass() ) ); break; case InternalSettings::ExceptionWindowTitle: m_ui.exceptionEditor->setText( info.name() ); break; } } delete m_detectDialog; m_detectDialog = nullptr; } } diff --git a/kdecoration/config/breezeexceptiondialog.h b/kdecoration/config/breezeexceptiondialog.h index 37fc4789..9846ff28 100644 --- a/kdecoration/config/breezeexceptiondialog.h +++ b/kdecoration/config/breezeexceptiondialog.h @@ -1,114 +1,114 @@ #ifndef breezeexceptiondialog_h #define breezeexceptiondialog_h ////////////////////////////////////////////////////////////////////////////// // breezeexceptiondialog.h // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "ui_breezeexceptiondialog.h" #include "breeze.h" #include #include namespace Breeze { class DetectDialog; //* breeze exceptions list class ExceptionDialog: public QDialog { Q_OBJECT public: //* constructor explicit ExceptionDialog( QWidget* parent ); //* destructor - virtual ~ExceptionDialog( void ) + virtual ~ExceptionDialog() {} //* set exception void setException( InternalSettingsPtr ); //* save exception - void save( void ); + void save(); //* true if changed - virtual bool isChanged( void ) const + virtual bool isChanged() const { return m_changed; } Q_SIGNALS: //* emmited when changed void changed( bool ); protected: //* set changed state virtual void setChanged( bool value ) { m_changed = value; emit changed( value ); } protected Q_SLOTS: //* check whether configuration is changed and emit appropriate signal if yes virtual void updateChanged(); private Q_SLOTS: //* select window properties from grabbed pointers - void selectWindowProperties( void ); + void selectWindowProperties(); //* read properties of selected window void readWindowProperties( bool ); private: //* map mask and checkbox using CheckBoxMap=QMap< ExceptionMask, QCheckBox*>; Ui::BreezeExceptionDialog m_ui; //* map mask and checkbox CheckBoxMap m_checkboxes; //* internal exception InternalSettingsPtr m_exception; //* detection dialog DetectDialog* m_detectDialog = nullptr; //* changed state bool m_changed = false; }; } #endif diff --git a/kdecoration/config/breezeexceptionlistwidget.cpp b/kdecoration/config/breezeexceptionlistwidget.cpp index 3d3703d9..74aa9068 100644 --- a/kdecoration/config/breezeexceptionlistwidget.cpp +++ b/kdecoration/config/breezeexceptionlistwidget.cpp @@ -1,355 +1,355 @@ ////////////////////////////////////////////////////////////////////////////// // breezeexceptionlistwidget.cpp // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeexceptionlistwidget.h" #include "breezeexceptiondialog.h" #include #include #include #include //__________________________________________________________ namespace Breeze { //__________________________________________________________ ExceptionListWidget::ExceptionListWidget( QWidget* parent ): QWidget( parent ) { // ui m_ui.setupUi( this ); // list m_ui.exceptionListView->setAllColumnsShowFocus( true ); m_ui.exceptionListView->setRootIsDecorated( false ); m_ui.exceptionListView->setSortingEnabled( false ); m_ui.exceptionListView->setModel( &model() ); m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType ); m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) ); m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) ); m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) ); m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) ); m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) ); m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) ); connect( m_ui.addButton, SIGNAL(clicked()), SLOT(add()) ); connect( m_ui.editButton, SIGNAL(clicked()), SLOT(edit()) ); connect( m_ui.removeButton, SIGNAL(clicked()), SLOT(remove()) ); connect( m_ui.moveUpButton, SIGNAL(clicked()), SLOT(up()) ); connect( m_ui.moveDownButton, SIGNAL(clicked()), SLOT(down()) ); connect( m_ui.exceptionListView, SIGNAL(activated(QModelIndex)), SLOT(edit()) ); connect( m_ui.exceptionListView, SIGNAL(clicked(QModelIndex)), SLOT(toggle(QModelIndex)) ); connect( m_ui.exceptionListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateButtons()) ); updateButtons(); resizeColumns(); } //__________________________________________________________ void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions ) { model().set( exceptions ); resizeColumns(); setChanged( false ); } //__________________________________________________________ - InternalSettingsList ExceptionListWidget::exceptions( void ) + InternalSettingsList ExceptionListWidget::exceptions() { return model().get(); setChanged( false ); } //__________________________________________________________ - void ExceptionListWidget::updateButtons( void ) + void ExceptionListWidget::updateButtons() { bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() ); m_ui.removeButton->setEnabled( hasSelection ); m_ui.editButton->setEnabled( hasSelection ); m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) ); m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) ); } //_______________________________________________________ - void ExceptionListWidget::add( void ) + void ExceptionListWidget::add() { QPointer dialog = new ExceptionDialog( this ); dialog->setWindowTitle( i18n( "New Exception - Breeze Settings" ) ); InternalSettingsPtr exception( new InternalSettings() ); exception->load(); dialog->setException( exception ); // run dialog and check existence if( !dialog->exec() ) { delete dialog; return; } dialog->save(); delete dialog; // check exceptions if( !checkException( exception ) ) return; // create new item model().add( exception ); setChanged( true ); // make sure item is selected QModelIndex index( model().index( exception ) ); if( index != m_ui.exceptionListView->selectionModel()->currentIndex() ) { m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows ); } resizeColumns(); return; } //_______________________________________________________ - void ExceptionListWidget::edit( void ) + void ExceptionListWidget::edit() { // retrieve selection QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() ); if( ! model().contains( current ) ) return; InternalSettingsPtr exception( model().get( current ) ); // create dialog QPointer dialog( new ExceptionDialog( this ) ); dialog->setWindowTitle( i18n( "Edit Exception - Breeze Settings" ) ); dialog->setException( exception ); // map dialog if( !dialog->exec() ) { delete dialog; return; } // check modifications if( !dialog->isChanged() ) return; // retrieve exception dialog->save(); delete dialog; // check new exception validity checkException( exception ); resizeColumns(); setChanged( true ); return; } //_______________________________________________________ - void ExceptionListWidget::remove( void ) + void ExceptionListWidget::remove() { // confirmation dialog { QMessageBox messageBox( QMessageBox::Question, i18n("Question - Breeze Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel ); messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") ); messageBox.setDefaultButton( QMessageBox::Cancel ); if( messageBox.exec() == QMessageBox::Cancel ) return; } // remove model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); resizeColumns(); updateButtons(); setChanged( true ); return; } //_______________________________________________________ void ExceptionListWidget::toggle( const QModelIndex& index ) { if( !model().contains( index ) ) return; if( index.column() != ExceptionModel::ColumnEnabled ) return; // get matching exception InternalSettingsPtr exception( model().get( index ) ); exception->setEnabled( !exception->enabled() ); setChanged( true ); return; } //_______________________________________________________ - void ExceptionListWidget::up( void ) + void ExceptionListWidget::up() { InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); if( selection.empty() ) { return; } // retrieve selected indexes in list and store in model QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() ); InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); InternalSettingsList currentException( model().get() ); InternalSettingsList newExceptions; for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter ) { // check if new list is not empty, current index is selected and last index is not. // if yes, move. if( !( newExceptions.empty() || selectedIndices.indexOf( model().index( *iter ) ) == -1 || selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1 ) ) { InternalSettingsPtr last( newExceptions.back() ); newExceptions.removeLast(); newExceptions.append( *iter ); newExceptions.append( last ); } else newExceptions.append( *iter ); } model().set( newExceptions ); // restore selection m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } setChanged( true ); return; } //_______________________________________________________ - void ExceptionListWidget::down( void ) + void ExceptionListWidget::down() { InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); if( selection.empty() ) { return; } // retrieve selected indexes in list and store in model QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() ); InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); InternalSettingsList currentExceptions( model().get() ); InternalSettingsList newExceptions; InternalSettingsListIterator iter( currentExceptions ); iter.toBack(); while( iter.hasPrevious() ) { InternalSettingsPtr current( iter.previous() ); // check if new list is not empty, current index is selected and last index is not. // if yes, move. if( !( newExceptions.empty() || selectedIndices.indexOf( model().index( current ) ) == -1 || selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1 ) ) { InternalSettingsPtr first( newExceptions.front() ); newExceptions.removeFirst(); newExceptions.prepend( current ); newExceptions.prepend( first ); } else newExceptions.prepend( current ); } model().set( newExceptions ); // restore selection m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } setChanged( true ); return; } //_______________________________________________________ - void ExceptionListWidget::resizeColumns( void ) const + void ExceptionListWidget::resizeColumns() const { m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled ); m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType ); m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp ); } //_______________________________________________________ bool ExceptionListWidget::checkException( InternalSettingsPtr exception ) { while( exception->exceptionPattern().isEmpty() || !QRegExp( exception->exceptionPattern() ).isValid() ) { QMessageBox::warning( this, i18n( "Warning - Breeze Settings" ), i18n("Regular Expression syntax is incorrect") ); QPointer dialog( new ExceptionDialog( this ) ); dialog->setException( exception ); if( dialog->exec() == QDialog::Rejected ) { delete dialog; return false; } dialog->save(); delete dialog; } return true; } } diff --git a/kdecoration/config/breezeexceptionlistwidget.h b/kdecoration/config/breezeexceptionlistwidget.h index 45e18eff..cbbf0c10 100644 --- a/kdecoration/config/breezeexceptionlistwidget.h +++ b/kdecoration/config/breezeexceptionlistwidget.h @@ -1,124 +1,124 @@ #ifndef breezeexceptionlistwidget_h #define breezeexceptionlistwidget_h ////////////////////////////////////////////////////////////////////////////// // breezeexceptionlistwidget.h // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "ui_breezeexceptionlistwidget.h" #include "breezeexceptionmodel.h" //* QDialog used to commit selected files namespace Breeze { class ExceptionListWidget: public QWidget { //* Qt meta object Q_OBJECT public: //* constructor explicit ExceptionListWidget( QWidget* = nullptr ); //* set exceptions void setExceptions( const InternalSettingsList& ); //* get exceptions - InternalSettingsList exceptions( void ); + InternalSettingsList exceptions(); //* true if changed - virtual bool isChanged( void ) const + virtual bool isChanged() const { return m_changed; } Q_SIGNALS: //* emitted when changed void changed( bool ); protected: //* model const ExceptionModel& model() const { return m_model; } //* model ExceptionModel& model() { return m_model; } protected Q_SLOTS: //* update button states - virtual void updateButtons( void ); + virtual void updateButtons(); //* add - virtual void add( void ); + virtual void add(); //* edit - virtual void edit( void ); + virtual void edit(); //* remove - virtual void remove( void ); + virtual void remove(); //* toggle virtual void toggle( const QModelIndex& ); //* move up - virtual void up( void ); + virtual void up(); //* move down - virtual void down( void ); + virtual void down(); protected: //* resize columns - void resizeColumns( void ) const; + void resizeColumns() const; //* check exception bool checkException( InternalSettingsPtr ); //* set changed state virtual void setChanged( bool value ) { m_changed = value; emit changed( value ); } private: //* model ExceptionModel m_model; //* ui Ui_BreezeExceptionListWidget m_ui; //* changed state bool m_changed = false; }; } #endif diff --git a/kdecoration/config/breezeitemmodel.h b/kdecoration/config/breezeitemmodel.h index 71bf85e1..3af4ab30 100644 --- a/kdecoration/config/breezeitemmodel.h +++ b/kdecoration/config/breezeitemmodel.h @@ -1,113 +1,113 @@ #ifndef ItemModel_h #define ItemModel_h ////////////////////////////////////////////////////////////////////////////// // itemmodel.h // ------------------- // // Copyright (c) 2009-2010 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include namespace Breeze { //* Job model. Stores job information for display in lists class ItemModel : public QAbstractItemModel { public: //* constructor explicit ItemModel(QObject *parent = nullptr); //* destructor virtual ~ItemModel() {} //* return all indexes in model starting from parent [recursive] QModelIndexList indexes( int column = 0, const QModelIndex& parent = QModelIndex() ) const; //*@name sorting //@{ //* sort - virtual void sort( void ) + virtual void sort() { sort( sortColumn(), sortOrder() ); } //* sort void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override; //* current sorting column - const int& sortColumn( void ) const + const int& sortColumn() const { return m_sortColumn; } //* current sort order - const Qt::SortOrder& sortOrder( void ) const + const Qt::SortOrder& sortOrder() const { return m_sortOrder; } //@} protected: //* this sort columns without calling the layout changed callbacks - void privateSort( void ) + void privateSort() { privateSort( m_sortColumn, m_sortOrder ); } //* private sort, with no signals emmitted virtual void privateSort( int column, Qt::SortOrder order ) = 0; //* used to sort items in list class SortFTor { public: //* constructor explicit SortFTor( const int& type, Qt::SortOrder order = Qt::AscendingOrder ): _type( type ), _order( order ) {} protected: //* column int _type; //* order Qt::SortOrder _order; }; private: //* sorting column int m_sortColumn = 0; //* sorting order Qt::SortOrder m_sortOrder = Qt::AscendingOrder; }; } #endif diff --git a/kdecoration/config/breezelistmodel.h b/kdecoration/config/breezelistmodel.h index 1cc0e548..9ec59896 100644 --- a/kdecoration/config/breezelistmodel.h +++ b/kdecoration/config/breezelistmodel.h @@ -1,369 +1,369 @@ #ifndef ListModel_h #define ListModel_h ////////////////////////////////////////////////////////////////////////////// // listmodel.h // ------------------- // // Copyright (c) 2009 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breezeitemmodel.h" #include #include #include namespace Breeze { //! Job model. Stores job information for display in lists template class ListModel : public ItemModel { public: //! value type typedef T ValueType; //! reference typedef T& Reference; //! pointer typedef T* Pointer; //! value list and iterators typedef QList List; typedef QListIterator ListIterator; typedef QMutableListIterator MutableListIterator; //! list of vector // typedef QSet Set; //! constructor ListModel(QObject *parent = nullptr): ItemModel( parent ) {} //! destructor virtual ~ListModel() {} //!@name methods reimplemented from base class //@{ //! flags Qt::ItemFlags flags(const QModelIndex &index) const override { if (!index.isValid()) return nullptr; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } //! unique index for given row, column and parent index QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override { // check if index is valid if( !hasIndex( row, column, parent ) ) return QModelIndex(); // return invalid index if parent is valid if( parent.isValid() ) return QModelIndex(); // check against _values return ( row < (int) _values.size() ) ? createIndex( row, column ):QModelIndex(); } //! index of parent QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); } //! number of rows below given index int rowCount(const QModelIndex &parent = QModelIndex()) const override { return parent.isValid() ? 0:_values.size(); } //@} //!@name selection //@{ //! clear internal list selected items - virtual void clearSelectedIndexes( void ) + virtual void clearSelectedIndexes() { _selection.clear(); } //! store index internal selection state virtual void setIndexSelected( const QModelIndex& index, bool value ) { if( value ) _selection.push_back( get(index) ); else _selection.erase( std::remove( _selection.begin(), _selection.end(), get(index) ), _selection.end() ); } //! get list of internal selected items - virtual QModelIndexList selectedIndexes( void ) const + virtual QModelIndexList selectedIndexes() const { QModelIndexList out; for( typename List::const_iterator iter = _selection.begin(); iter != _selection.end(); iter++ ) { QModelIndex index( ListModel::index( *iter ) ); if( index.isValid() ) out.push_back( index ); } return out; } //@} //!@name interface //@{ //! add value virtual void add( const ValueType& value ) { emit layoutAboutToBeChanged(); _add( value ); privateSort(); emit layoutChanged(); } //! add values virtual void add( const List& values ) { // check if not empty // this avoids sending useless signals if( values.empty() ) return; emit layoutAboutToBeChanged(); for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ ) { _add( *iter ); } privateSort(); emit layoutChanged(); } //! insert values virtual void insert( const QModelIndex& index, const ValueType& value ) { emit layoutAboutToBeChanged(); _insert( index, value ); emit layoutChanged(); } //! insert values virtual void insert( const QModelIndex& index, const List& values ) { emit layoutAboutToBeChanged(); // need to loop in reverse order so that the "values" ordering is preserved ListIterator iter( values ); iter.toBack(); while( iter.hasPrevious() ) { _insert( index, iter.previous() ); } emit layoutChanged(); } //! insert values virtual void replace( const QModelIndex& index, const ValueType& value ) { if( !index.isValid() ) add( value ); else { emit layoutAboutToBeChanged(); setIndexSelected( index, false ); _values[index.row()] = value; setIndexSelected( index, true ); emit layoutChanged(); } } //! remove virtual void remove( const ValueType& value ) { emit layoutAboutToBeChanged(); _remove( value ); emit layoutChanged(); return; } //! remove virtual void remove( const List& values ) { // check if not empty // this avoids sending useless signals if( values.empty() ) return; emit layoutAboutToBeChanged(); for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ ) { _remove( *iter ); } emit layoutChanged(); return; } //! clear - virtual void clear( void ) + virtual void clear() { set( List() ); } //! update values from list /*! values that are not found in current are removed new values are set to the end. This is slower than the "set" method, but the selection is not cleared in the process */ virtual void update( List values ) { emit layoutAboutToBeChanged(); // store values to be removed List removed_values; // update values that are common to both lists for( typename List::iterator iter = _values.begin(); iter != _values.end(); iter++ ) { // see if iterator is in list typename List::iterator found_iter( std::find( values.begin(), values.end(), *iter ) ); if( found_iter == values.end() ) removed_values.push_back( *iter ); else { *iter = *found_iter; values.erase( found_iter ); } } // remove values that have not been found in new list for( typename List::const_iterator iter = removed_values.constBegin(); iter != removed_values.constEnd(); iter++ ) { _remove( *iter ); } // add remaining values for( typename List::const_iterator iter = values.constBegin(); iter != values.constEnd(); iter++ ) { _add( *iter ); } privateSort(); emit layoutChanged(); } //! set all values virtual void set( const List& values ) { emit layoutAboutToBeChanged(); _values = values; _selection.clear(); privateSort(); emit layoutChanged(); return; } //! return all values const List& get( void ) const { return _values; } //! return value for given index virtual ValueType get( const QModelIndex& index ) const { return (index.isValid() && index.row() < int(_values.size()) ) ? _values[index.row()]:ValueType(); } //! return value for given index virtual ValueType& get( const QModelIndex& index ) { Q_ASSERT( index.isValid() && index.row() < int( _values.size() ) ); return _values[index.row()]; } //! return all values List get( const QModelIndexList& indexes ) const { List out; for( QModelIndexList::const_iterator iter = indexes.begin(); iter != indexes.end(); iter++ ) { if( iter->isValid() && iter->row() < int(_values.size()) ) out.push_back( get( *iter ) ); } return out; } //! return index associated to a given value virtual QModelIndex index( const ValueType& value, int column = 0 ) const { for( int row = 0; row < _values.size(); ++row ) { if( value == _values[row] ) return index( row, column ); } return QModelIndex(); } //@} //! return true if model contains given index virtual bool contains( const QModelIndex& index ) const { return index.isValid() && index.row() < _values.size(); } protected: //! return all values List& _get( void ) { return _values; } //! add, without update virtual void _add( const ValueType& value ) { typename List::iterator iter = std::find( _values.begin(), _values.end(), value ); if( iter == _values.end() ) _values.push_back( value ); else *iter = value; } //! add, without update virtual void _insert( const QModelIndex& index, const ValueType& value ) { if( !index.isValid() ) add( value ); int row = 0; typename List::iterator iter( _values.begin() ); for( ;iter != _values.end() && row != index.row(); iter++, row++ ) {} _values.insert( iter, value ); } //! remove, without update virtual void _remove( const ValueType& value ) { _values.erase( std::remove( _values.begin(), _values.end(), value ), _values.end() ); _selection.erase( std::remove( _selection.begin(), _selection.end(), value ), _selection.end() ); } private: //! values List _values; //! selection List _selection; }; } #endif diff --git a/kstyle/breezeblurhelper.h b/kstyle/breezeblurhelper.h index 1fb5e93d..ed7cbd1c 100644 --- a/kstyle/breezeblurhelper.h +++ b/kstyle/breezeblurhelper.h @@ -1,84 +1,84 @@ #ifndef breezeblurhelper_h #define breezeblurhelper_h ////////////////////////////////////////////////////////////////////////////// // breezeblurhelper.h // handle regions passed to kwin for blurring // ------------------- // // Copyright (C) 2018 Alex Nemeth // // Largely rewritten from Oxygen widget style // Copyright (C) 2007 Thomas Luebking // Copyright (c) 2010 Hugo Pereira Da Costa // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// #include "breeze.h" #include "breezehelper.h" #include #include #if BREEZE_HAVE_X11 #include #endif namespace Breeze { class BlurHelper: public QObject { Q_OBJECT public: //! constructor BlurHelper( QObject* ); //! destructor - virtual ~BlurHelper( void ) + virtual ~BlurHelper() {} //! register widget void registerWidget( QWidget* ); //! register widget void unregisterWidget( QWidget* ); //! event filter bool eventFilter( QObject*, QEvent* ) ; protected: //! install event filter to object, in a unique way void addEventFilter( QObject* object ) { object->removeEventFilter( this ); object->installEventFilter( this ); } //! update blur regions for given widget void update( QWidget* ) const; }; } #endif