├── .gitignore ├── CMakeLists.txt ├── ChangeLog ├── LICENSE ├── Messages.sh ├── NEWS ├── README.md ├── breeze.h ├── breeze.json ├── breezebutton.cpp ├── breezebutton.h ├── breezedecoration.cpp ├── breezedecoration.h ├── breezeexceptionlist.cpp ├── breezeexceptionlist.h ├── breezesettings.kcfgc ├── breezesettingsdata.kcfg ├── breezesettingsprovider.cpp ├── breezesettingsprovider.h ├── breezesizegrip.cpp ├── breezesizegrip.h ├── cmake └── Modules │ └── FindFFTW.cmake ├── config-breeze.h.cmake ├── config ├── breeze10config.desktop ├── breezeconfigwidget.cpp ├── breezeconfigwidget.h ├── breezedecorationconfig.desktop ├── breezedetectwidget.cpp ├── breezedetectwidget.h ├── breezeexceptiondialog.cpp ├── breezeexceptiondialog.h ├── breezeexceptionlistwidget.cpp ├── breezeexceptionlistwidget.h ├── breezeexceptionmodel.cpp ├── breezeexceptionmodel.h ├── breezeitemmodel.cpp ├── breezeitemmodel.h ├── breezelistmodel.h └── ui │ ├── breezeconfigurationui.ui │ ├── breezedetectwidget.ui │ ├── breezeexceptiondialog.ui │ └── breezeexceptionlistwidget.ui ├── libbreezecommon ├── CMakeLists.txt ├── breezeboxshadowrenderer.cpp ├── breezeboxshadowrenderer.h └── config-breezecommon.h.cmake └── screenshots ├── Desktop.png └── Settings.png /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | build -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | project(breeze10) 3 | set(PROJECT_VERSION "0.1") 4 | set(PROJECT_VERSION_MAJOR 0) 5 | 6 | cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) 7 | 8 | include(WriteBasicConfigVersionFile) 9 | include(FeatureSummary) 10 | 11 | find_package(ECM 0.0.9 REQUIRED NO_MODULE) 12 | 13 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules") 14 | 15 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake) 16 | 17 | include(ECMInstallIcons) 18 | include(KDEInstallDirs) 19 | include(KDECMakeSettings) 20 | include(KDECompilerSettings NO_POLICY_SCOPE) 21 | include(GenerateExportHeader) 22 | # include(GtkUpdateIconCache) 23 | 24 | find_package(KDecoration2 REQUIRED) 25 | 26 | 27 | # old stuff 28 | add_definitions(-DTRANSLATION_DOMAIN="breeze_kwin_deco") 29 | 30 | find_package(KF5 REQUIRED COMPONENTS CoreAddons GuiAddons ConfigWidgets WindowSystem I18n) 31 | find_package(Qt5 CONFIG REQUIRED COMPONENTS DBus) 32 | 33 | ### XCB 34 | find_package(XCB COMPONENTS XCB) 35 | set_package_properties(XCB PROPERTIES 36 | DESCRIPTION "X protocol C-language Binding" 37 | URL "http://xcb.freedesktop.org" 38 | TYPE OPTIONAL 39 | PURPOSE "Required to pass style properties to native Windows on X11 Platform" 40 | ) 41 | 42 | if(UNIX AND NOT APPLE) 43 | 44 | set(BREEZE_HAVE_X11 ${XCB_XCB_FOUND}) 45 | if (XCB_XCB_FOUND) 46 | find_package(Qt5 REQUIRED CONFIG COMPONENTS X11Extras) 47 | endif() 48 | 49 | else() 50 | 51 | set(BREEZE_HAVE_X11 FALSE) 52 | 53 | endif() 54 | 55 | ################# configuration ################# 56 | configure_file(config-breeze.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-breeze.h ) 57 | 58 | ################# includes ################# 59 | add_subdirectory(libbreezecommon) 60 | 61 | ################# newt target ################# 62 | ### plugin classes 63 | set(breeze10_SRCS 64 | breezebutton.cpp 65 | breezedecoration.cpp 66 | breezeexceptionlist.cpp 67 | breezesettingsprovider.cpp 68 | breezesizegrip.cpp) 69 | 70 | kconfig_add_kcfg_files(breeze10_SRCS breezesettings.kcfgc) 71 | 72 | ### config classes 73 | ### they are kept separately because they might move in a separate library in the future 74 | set(breeze10_config_SRCS 75 | config/breezeconfigwidget.cpp 76 | config/breezedetectwidget.cpp 77 | config/breezeexceptiondialog.cpp 78 | config/breezeexceptionlistwidget.cpp 79 | config/breezeexceptionmodel.cpp 80 | config/breezeitemmodel.cpp 81 | ) 82 | 83 | set(breeze10_config_PART_FORMS 84 | config/ui/breezeconfigurationui.ui 85 | config/ui/breezedetectwidget.ui 86 | config/ui/breezeexceptiondialog.ui 87 | config/ui/breezeexceptionlistwidget.ui 88 | ) 89 | 90 | ki18n_wrap_ui(breeze10_config_PART_FORMS_HEADERS ${breeze10_config_PART_FORMS}) 91 | 92 | ### build library 93 | add_library(breeze10 MODULE 94 | ${breeze10_SRCS} 95 | ${breeze10_config_SRCS} 96 | ${breeze10_config_PART_FORMS_HEADERS}) 97 | 98 | target_link_libraries(breeze10 99 | PUBLIC 100 | Qt5::Core 101 | Qt5::Gui 102 | Qt5::DBus 103 | PRIVATE 104 | breeze10common5 105 | KDecoration2::KDecoration 106 | KF5::ConfigCore 107 | KF5::CoreAddons 108 | KF5::ConfigWidgets 109 | KF5::GuiAddons 110 | KF5::I18n 111 | KF5::WindowSystem) 112 | 113 | if(BREEZE_HAVE_X11) 114 | target_link_libraries(breeze10 115 | PUBLIC 116 | Qt5::X11Extras 117 | XCB::XCB) 118 | endif() 119 | 120 | 121 | install(TARGETS breeze10 DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2) 122 | install(FILES config/breeze10config.desktop DESTINATION ${SERVICES_INSTALL_DIR}) 123 | # install(TARGETS breezedecoration DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2) 124 | # install(FILES config/breezedecorationconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR}) 125 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | V5.16 2 | --------- 3 | * Initial release. 4 | -------------------------------------------------------------------------------- /Messages.sh: -------------------------------------------------------------------------------- 1 | #!bin/sh 2 | $EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp 3 | $XGETTEXT `find . -name \*.cc -o -name \*.cpp -o -name \*.h` -o $podir/breeze_kwin_deco.pot 4 | rm -f rc.cpp 5 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Latest version: 2 | 3 | 18 Jun 2019, V5.16 4 | 5 | See "ChangeLog" for changes. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Breeze10 2 | 3 | ## Overview 4 | 5 | Breeze10 is a fork of KDE Breeze decoration with the following changes: 6 | 7 | * The title-bar opacity is configurable. 8 | * The separator between title-bar and window is removed. 9 | * Opaqueness, opacity override is added to the exception list properties. 10 | * Title-bar font is set indpendent from the KDE font settings (for use outside KDE). 11 | 12 | ## Credits 13 | 14 | Breeze10 was started from BreezeEnhanced (https://github.com/tsujan/BreezeEnhanced), a former fork of Breeze with title-bar translucency and blurring. 15 | 16 | ## Dependencies 17 | 18 | There are some dependencies you'll need to install. Some people suggested using the following commands: 19 | 20 | ### Ubuntu, KDE Neon 21 | ``` shell 22 | sudo apt install git g++ extra-cmake-modules cmake gettext libkf5config-dev libkdecorations2-dev libqt5x11extras5-dev qtdeclarative5-dev libkf5guiaddons-dev libkf5configwidgets-dev libkf5windowsystem-dev libkf5coreaddons-dev libfftw3-dev 23 | ``` 24 | 25 | ### Arch Linux, Manjaro, Antergos 26 | ``` shell 27 | sudo pacman -S kdecoration qt5-declarative qt5-x11extras kcoreaddons kguiaddons kconfigwidgets kwindowsystem fftw cmake extra-cmake-modules 28 | ``` 29 | 30 | ### OpenSUSE 31 | ``` shell 32 | sudo zypper install git extra-cmake-modules libkdecoration2-devel kcoreaddons-devel kguiaddons-devel kconfig-devel kwindowsystem-devel ki18n-devel kconfigwidgets-devel libQt5DBus-devel libqt5-qtx11extras-devel fftw3-devel 33 | ``` 34 | 35 | ## Installation 36 | 37 | The version number in the file NEWS shows the main version of KWin that is required for the compilation. *Compilation should not be done against other versions of KWin!*. 38 | 39 | Open a terminal inside the source directory and do: 40 | ```sh 41 | mkdir build && cd build 42 | cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DKDE_INSTALL_LIBDIR=lib -DBUILD_TESTING=OFF -DKDE_INSTALL_USE_QT_SYS_PATHS=ON 43 | make 44 | sudo make install 45 | ``` 46 | After the intallation, restart KWin by logging out and in. Then, Breeze10 will appear in *System Settings → Application Style → Window Decorations*. 47 | 48 | ## Known Issues 49 | 50 | None so far. 51 | 52 | ## Screenshots 53 | 54 | ![Settings](screenshots/Settings.png?raw=true "Settings") 55 | 56 | ![Desktop](screenshots/Desktop.png?raw=true "Desktop") 57 | -------------------------------------------------------------------------------- /breeze.h: -------------------------------------------------------------------------------- 1 | #ifndef breeze_h 2 | #define breeze_h 3 | 4 | /* 5 | * Copyright 2014 Hugo Pereira Da Costa 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License as 9 | * published by the Free Software Foundation; either version 2 of 10 | * the License or (at your option) version 3 or any later version 11 | * accepted by the membership of KDE e.V. (or its successor approved 12 | * by the membership of KDE e.V.), which shall act as a proxy 13 | * defined in Section 14 of version 3 of the license. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program. If not, see . 22 | */ 23 | 24 | #include "breezesettings.h" 25 | 26 | #include 27 | #include 28 | 29 | namespace Breeze 30 | { 31 | //* convenience typedefs 32 | using InternalSettingsPtr = QSharedPointer; 33 | using InternalSettingsList = QList; 34 | using InternalSettingsListIterator = QListIterator; 35 | 36 | //* metrics 37 | enum Metrics 38 | { 39 | 40 | // shadow dimensions (pixels) 41 | Shadow_Overlap = 3, 42 | 43 | }; 44 | 45 | //* exception 46 | enum ExceptionMask 47 | { 48 | None = 0, 49 | BorderSize = 1<<4 50 | }; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /breeze.json: -------------------------------------------------------------------------------- 1 | { 2 | "KPlugin": { 3 | "Description": "Window decoration using the Breeze visual style for the Plasma Desktop", 4 | "EnabledByDefault": true, 5 | "Id": "com.github.fauzie811.breeze10", 6 | "Name": "Breeze10", 7 | "ServiceTypes": [ 8 | "org.kde.kdecoration2" 9 | ] 10 | }, 11 | "org.kde.kdecoration2": { 12 | "blur": true, 13 | "defaultTheme": "Breeze10", 14 | "kcmodule": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /breezebutton.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Martin Gräßlin 3 | * Copyright 2014 Hugo Pereira Da Costa 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License as 7 | * published by the Free Software Foundation; either version 2 of 8 | * the License or (at your option) version 3 or any later version 9 | * accepted by the membership of KDE e.V. (or its successor approved 10 | * by the membership of KDE e.V.), which shall act as a proxy 11 | * defined in Section 14 of version 3 of the license. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | #include "breezebutton.h" 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | namespace Breeze 30 | { 31 | 32 | using KDecoration2::ColorRole; 33 | using KDecoration2::ColorGroup; 34 | using KDecoration2::DecorationButtonType; 35 | 36 | 37 | //__________________________________________________________________ 38 | Button::Button(DecorationButtonType type, Decoration* decoration, QObject* parent) 39 | : DecorationButton(type, decoration, parent) 40 | , m_animation( new QPropertyAnimation( this ) ) 41 | { 42 | 43 | // setup animation 44 | m_animation->setStartValue( 0 ); 45 | m_animation->setEndValue( 1.0 ); 46 | m_animation->setTargetObject( this ); 47 | m_animation->setPropertyName( "opacity" ); 48 | m_animation->setEasingCurve( QEasingCurve::InOutQuad ); 49 | 50 | // setup default geometry 51 | const int height = decoration->buttonHeight(); 52 | const int width = height * (type == DecorationButtonType::Menu ? 1.0 : 1.5); 53 | setGeometry(QRect(0, 0, width, height)); 54 | setIconSize(QSize( width, height )); 55 | 56 | // connections 57 | connect(decoration->client().data(), SIGNAL(iconChanged(QIcon)), this, SLOT(update())); 58 | connect(decoration->settings().data(), &KDecoration2::DecorationSettings::reconfigured, this, &Button::reconfigure); 59 | connect( this, &KDecoration2::DecorationButton::hoveredChanged, this, &Button::updateAnimationState ); 60 | 61 | reconfigure(); 62 | 63 | } 64 | 65 | //__________________________________________________________________ 66 | Button::Button(QObject *parent, const QVariantList &args) 67 | : Button(args.at(0).value(), args.at(1).value(), parent) 68 | { 69 | m_flag = FlagStandalone; 70 | //! icon size must return to !valid because it was altered from the default constructor, 71 | //! in Standalone mode the button is not using the decoration metrics but its geometry 72 | m_iconSize = QSize(-1, -1); 73 | } 74 | 75 | //__________________________________________________________________ 76 | Button *Button::create(DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent) 77 | { 78 | if (auto d = qobject_cast(decoration)) 79 | { 80 | Button *b = new Button(type, d, parent); 81 | switch( type ) 82 | { 83 | 84 | case DecorationButtonType::Close: 85 | b->setVisible( d->client().data()->isCloseable() ); 86 | QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::closeableChanged, b, &Breeze::Button::setVisible ); 87 | break; 88 | 89 | case DecorationButtonType::Maximize: 90 | b->setVisible( d->client().data()->isMaximizeable() ); 91 | QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::maximizeableChanged, b, &Breeze::Button::setVisible ); 92 | break; 93 | 94 | case DecorationButtonType::Minimize: 95 | b->setVisible( d->client().data()->isMinimizeable() ); 96 | QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::minimizeableChanged, b, &Breeze::Button::setVisible ); 97 | break; 98 | 99 | case DecorationButtonType::ContextHelp: 100 | b->setVisible( d->client().data()->providesContextHelp() ); 101 | QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::providesContextHelpChanged, b, &Breeze::Button::setVisible ); 102 | break; 103 | 104 | case DecorationButtonType::Shade: 105 | b->setVisible( d->client().data()->isShadeable() ); 106 | QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::shadeableChanged, b, &Breeze::Button::setVisible ); 107 | break; 108 | 109 | case DecorationButtonType::Menu: 110 | QObject::connect(d->client().data(), &KDecoration2::DecoratedClient::iconChanged, b, [b]() { b->update(); }); 111 | break; 112 | 113 | default: break; 114 | 115 | } 116 | 117 | return b; 118 | } 119 | 120 | return nullptr; 121 | 122 | } 123 | 124 | //__________________________________________________________________ 125 | void Button::paint(QPainter *painter, const QRect &repaintRegion) 126 | { 127 | Q_UNUSED(repaintRegion) 128 | 129 | if (!decoration()) return; 130 | 131 | painter->save(); 132 | 133 | // translate from offset 134 | if( m_flag == FlagFirstInList ) painter->translate( m_offset ); 135 | else painter->translate( 0, m_offset.y() ); 136 | 137 | if( !m_iconSize.isValid() ) m_iconSize = geometry().size().toSize(); 138 | 139 | // menu button 140 | if (type() == DecorationButtonType::Menu) 141 | { 142 | 143 | // const QRectF iconRect( geometry().topLeft(), m_iconSize ); 144 | const int menuIconSize = (qobject_cast(decoration()))->iconSize(); 145 | const qreal topLeft = (geometry().width()/2) - (menuIconSize/2); 146 | 147 | const QRectF iconRect(topLeft + geometry().left(), topLeft + geometry().top(), menuIconSize, menuIconSize); 148 | decoration()->client().data()->icon().paint(painter, iconRect.toRect()); 149 | 150 | } else { 151 | 152 | drawIcon( painter ); 153 | 154 | } 155 | 156 | painter->restore(); 157 | 158 | } 159 | 160 | //__________________________________________________________________ 161 | void Button::drawIcon( QPainter *painter ) const 162 | { 163 | 164 | painter->setRenderHints( QPainter::Antialiasing ); 165 | 166 | /* 167 | scale painter so that its window matches QRect( 0, 0, 45, 30 ) 168 | this makes all further rendering and scaling simpler 169 | all further rendering is preformed inside QRect( 0, 0, 45, 30 ) 170 | */ 171 | painter->translate( geometry().topLeft() ); 172 | 173 | const qreal height( m_iconSize.height() ); 174 | const qreal width( m_iconSize.width() ); 175 | if ( height != 30 ) 176 | painter->scale( width/45, height/30 ); 177 | 178 | // render background 179 | const QColor backgroundColor( this->backgroundColor() ); 180 | 181 | auto d = qobject_cast( decoration() ); 182 | bool isInactive(d && !d->client().data()->isActive() 183 | && !isHovered() && !isPressed() 184 | && m_animation->state() != QPropertyAnimation::Running); 185 | QColor inactiveCol(Qt::gray); 186 | if (isInactive) 187 | { 188 | int gray = qGray(d->titleBarColor().rgb()); 189 | if (gray <= 200) { 190 | gray += 55; 191 | gray = qMax(gray, 115); 192 | } 193 | else gray -= 45; 194 | inactiveCol = QColor(gray, gray, gray); 195 | } 196 | 197 | // render mark 198 | const QColor foregroundColor( this->foregroundColor() ); 199 | if( foregroundColor.isValid() ) 200 | { 201 | 202 | // setup painter 203 | QPen pen( foregroundColor ); 204 | pen.setCapStyle( Qt::FlatCap ); 205 | pen.setJoinStyle( Qt::MiterJoin ); 206 | // pen.setWidthF( 1.0*qMax((qreal)1.0, 30/width ) ); 207 | pen.setWidthF( 1.0 ); 208 | 209 | switch( type() ) 210 | { 211 | 212 | case DecorationButtonType::Close: 213 | { 214 | if( backgroundColor.isValid() ) 215 | { 216 | painter->setPen( Qt::NoPen ); 217 | painter->setBrush( backgroundColor ); 218 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 219 | } 220 | pen.setWidthF( 1.1 ); 221 | painter->setPen( pen ); 222 | painter->setBrush( Qt::NoBrush ); 223 | 224 | painter->drawLine( QPointF( 18, 10 ), QPointF( 28, 20 ) ); 225 | painter->drawLine( QPointF( 18, 20 ), QPointF( 28, 10 ) ); 226 | pen.setWidthF( 1.0 ); 227 | break; 228 | } 229 | 230 | case DecorationButtonType::Maximize: 231 | { 232 | if( backgroundColor.isValid() ) 233 | { 234 | painter->setPen( Qt::NoPen ); 235 | painter->setBrush( backgroundColor ); 236 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 237 | } 238 | 239 | painter->setPen( pen ); 240 | painter->setBrush( Qt::NoBrush ); 241 | 242 | if (isChecked()) 243 | { 244 | painter->drawRect(QRectF(18.5, 12.5, 7.0, 7.0)); 245 | painter->drawPolyline(QPolygonF() 246 | << QPointF(20.5, 12.5) << QPointF(20.5, 10.5) << QPointF(27.5, 10.5) << QPointF(27.5, 17.5) << QPointF(25.5, 17.5)); 247 | } 248 | else { 249 | painter->drawRect(QRectF(18.5, 10.5, 9.0, 9.0)); 250 | } 251 | 252 | break; 253 | } 254 | 255 | case DecorationButtonType::Minimize: 256 | { 257 | if( backgroundColor.isValid() ) 258 | { 259 | painter->setPen( Qt::NoPen ); 260 | painter->setBrush( backgroundColor ); 261 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 262 | } 263 | 264 | painter->setPen( pen ); 265 | painter->setBrush( Qt::NoBrush ); 266 | 267 | painter->drawLine( QPointF( 18, 15.5 ), QPointF( 28, 15.5 ) ); 268 | 269 | break; 270 | } 271 | 272 | case DecorationButtonType::OnAllDesktops: 273 | { 274 | painter->setPen( Qt::NoPen ); 275 | if( backgroundColor.isValid() ) 276 | { 277 | painter->setBrush( backgroundColor ); 278 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 279 | } 280 | painter->setBrush( foregroundColor ); 281 | 282 | if( isChecked()) { 283 | 284 | // outer ring 285 | painter->drawRect( QRectF( 16, 9, 12, 12 ) ); 286 | 287 | // center dot 288 | QColor backgroundColor( this->backgroundColor() ); 289 | if( !backgroundColor.isValid() && d ) backgroundColor = d->titleBarColor(); 290 | 291 | if( backgroundColor.isValid() ) 292 | { 293 | painter->setBrush( backgroundColor ); 294 | painter->drawRect( QRectF( 21, 14, 2, 2 ) ); 295 | } 296 | 297 | } else { 298 | 299 | painter->drawPolygon( QPolygonF() 300 | << QPointF( 19.5, 14.5 ) 301 | << QPointF( 25, 9 ) 302 | << QPointF( 28, 12 ) 303 | << QPointF( 22.5, 17.5 ) ); 304 | 305 | painter->setPen( pen ); 306 | painter->drawLine( QPointF( 18.5, 13.5 ), QPointF( 23.5, 18.5 ) ); 307 | painter->drawLine( QPointF( 25, 12 ), QPointF( 17.5, 19.5 ) ); 308 | } 309 | break; 310 | } 311 | 312 | case DecorationButtonType::Shade: 313 | { 314 | if( backgroundColor.isValid() ) 315 | { 316 | painter->setPen( Qt::NoPen ); 317 | painter->setBrush( backgroundColor ); 318 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 319 | } 320 | painter->setPen( pen ); 321 | painter->setBrush( Qt::NoBrush ); 322 | 323 | painter->drawLine( 18, 12, 26, 12 ); 324 | if (isChecked()) { 325 | painter->drawPolyline( QPolygonF() 326 | << QPointF( 18, 15 ) 327 | << QPointF( 22, 19 ) 328 | << QPointF( 26, 15 ) ); 329 | 330 | } else { 331 | painter->drawPolyline( QPolygonF() 332 | << QPointF( 18, 19 ) 333 | << QPointF( 22, 15 ) 334 | << QPointF( 26, 19 ) ); 335 | } 336 | 337 | break; 338 | 339 | } 340 | 341 | case DecorationButtonType::KeepBelow: 342 | { 343 | if( backgroundColor.isValid() ) 344 | { 345 | painter->setPen( Qt::NoPen ); 346 | painter->setBrush( backgroundColor ); 347 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 348 | } 349 | painter->setPen( pen ); 350 | painter->setBrush( Qt::NoBrush ); 351 | 352 | painter->drawPolyline( QPolygonF() 353 | << QPointF( 18, 11 ) 354 | << QPointF( 22, 15 ) 355 | << QPointF( 26, 11 ) ); 356 | 357 | painter->drawPolyline( QPolygonF() 358 | << QPointF( 18, 15 ) 359 | << QPointF( 22, 19 ) 360 | << QPointF( 26, 15 ) ); 361 | break; 362 | 363 | } 364 | 365 | case DecorationButtonType::KeepAbove: 366 | { 367 | if( backgroundColor.isValid() ) 368 | { 369 | painter->setPen( Qt::NoPen ); 370 | painter->setBrush( backgroundColor ); 371 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 372 | } 373 | painter->setPen( pen ); 374 | painter->setBrush( Qt::NoBrush ); 375 | 376 | painter->drawPolyline( QPolygonF() 377 | << QPointF( 18, 15 ) 378 | << QPointF( 22, 11 ) 379 | << QPointF( 26, 15 ) ); 380 | 381 | painter->drawPolyline( QPolygonF() 382 | << QPointF( 18, 19 ) 383 | << QPointF( 22, 15 ) 384 | << QPointF( 26, 19 ) ); 385 | break; 386 | } 387 | 388 | 389 | case DecorationButtonType::ApplicationMenu: 390 | { 391 | if( backgroundColor.isValid() ) 392 | { 393 | painter->setPen( Qt::NoPen ); 394 | painter->setBrush( backgroundColor ); 395 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 396 | } 397 | painter->setPen( pen ); 398 | painter->setBrush( Qt::NoBrush ); 399 | 400 | painter->drawLine( QPointF( 15, 11.5 ), QPointF( 30, 11.5 ) ); 401 | painter->drawLine( QPointF( 15, 15.5 ), QPointF( 30, 15.5 ) ); 402 | painter->drawLine( QPointF( 15, 19.5 ), QPointF( 30, 19.5 ) ); 403 | break; 404 | } 405 | 406 | case DecorationButtonType::ContextHelp: 407 | { 408 | if( backgroundColor.isValid() ) 409 | { 410 | painter->setPen( Qt::NoPen ); 411 | painter->setBrush( backgroundColor ); 412 | painter->drawRect( QRectF( 0, 0, 45, 30 ) ); 413 | } 414 | painter->setPen( pen ); 415 | painter->setBrush( Qt::NoBrush ); 416 | 417 | QPainterPath path; 418 | path.moveTo( 18, 12 ); 419 | path.arcTo( QRectF( 18, 9.5, 8, 5 ), 180, -180 ); 420 | path.cubicTo( QPointF(26.5, 15.5), QPointF( 22, 13.5 ), QPointF( 22, 17.5 ) ); 421 | painter->drawPath( path ); 422 | 423 | painter->drawPoint( 22, 21 ); 424 | 425 | break; 426 | } 427 | 428 | default: break; 429 | 430 | } 431 | 432 | } 433 | 434 | } 435 | 436 | //__________________________________________________________________ 437 | QColor Button::foregroundColor() const 438 | { 439 | auto d = qobject_cast( decoration() ); 440 | if( !d ) { 441 | 442 | return QColor(); 443 | 444 | } else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove ) && isChecked() ) { 445 | 446 | return d->titleBarColor(); 447 | 448 | } else if( m_animation->state() == QPropertyAnimation::Running && type() == DecorationButtonType::Close ) { 449 | 450 | return KColorUtils::mix( d->fontColor(), Qt::white, m_opacity ); 451 | 452 | } else if( isHovered() && type() == DecorationButtonType::Close ) { 453 | 454 | return Qt::white; 455 | 456 | } else { 457 | 458 | return d->fontColor(); 459 | 460 | } 461 | 462 | } 463 | 464 | //__________________________________________________________________ 465 | QColor Button::backgroundColor() const 466 | { 467 | auto d = qobject_cast( decoration() ); 468 | if( !d ) { 469 | 470 | return QColor(); 471 | 472 | } 473 | 474 | if( isPressed() ) { 475 | 476 | if( type() == DecorationButtonType::Close ) return KColorUtils::mix( Qt::red, Qt::black, 0.3 ); 477 | else return KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.3 ); 478 | 479 | } else if( ( type() == DecorationButtonType::KeepBelow || type() == DecorationButtonType::KeepAbove ) && isChecked() ) { 480 | 481 | return d->fontColor(); 482 | 483 | } else if( m_animation->state() == QPropertyAnimation::Running ) { 484 | 485 | if( type() == DecorationButtonType::Close ) return KColorUtils::mix( d->titleBarColor(), Qt::red, m_opacity ); 486 | else { 487 | 488 | QColor color( KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.2 ) ); 489 | color.setAlpha( color.alpha()*m_opacity ); 490 | return color; 491 | 492 | } 493 | 494 | } else if( isHovered() ) { 495 | 496 | if( type() == DecorationButtonType::Close ) return Qt::red; 497 | else return KColorUtils::mix( d->titleBarColor(), d->fontColor(), 0.2 ); 498 | 499 | } else { 500 | 501 | return QColor(); 502 | 503 | } 504 | 505 | } 506 | 507 | //________________________________________________________________ 508 | void Button::reconfigure() 509 | { 510 | 511 | // animation 512 | auto d = qobject_cast(decoration()); 513 | if( d ) m_animation->setDuration( d->internalSettings()->animationsDuration() ); 514 | 515 | } 516 | 517 | //__________________________________________________________________ 518 | void Button::updateAnimationState( bool hovered ) 519 | { 520 | 521 | auto d = qobject_cast(decoration()); 522 | if( !(d && d->internalSettings()->animationsEnabled() ) ) return; 523 | 524 | QAbstractAnimation::Direction dir = hovered ? QPropertyAnimation::Forward : QPropertyAnimation::Backward; 525 | if( m_animation->state() == QPropertyAnimation::Running && m_animation->direction() != dir ) 526 | m_animation->stop(); 527 | m_animation->setDirection( dir ); 528 | if( m_animation->state() != QPropertyAnimation::Running ) m_animation->start(); 529 | 530 | } 531 | 532 | } // namespace 533 | -------------------------------------------------------------------------------- /breezebutton.h: -------------------------------------------------------------------------------- 1 | #ifndef BREEZE_BUTTONS_H 2 | #define BREEZE_BUTTONS_H 3 | 4 | /* 5 | * Copyright 2014 Martin Gräßlin 6 | * Copyright 2014 Hugo Pereira Da Costa 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation; either version 2 of 11 | * the License or (at your option) version 3 or any later version 12 | * accepted by the membership of KDE e.V. (or its successor approved 13 | * by the membership of KDE e.V.), which shall act as a proxy 14 | * defined in Section 14 of version 3 of the license. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program. If not, see . 23 | */ 24 | #include 25 | #include "breezedecoration.h" 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace Breeze 32 | { 33 | 34 | class Button : public KDecoration2::DecorationButton 35 | { 36 | Q_OBJECT 37 | 38 | //* declare active state opacity 39 | Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity ) 40 | 41 | public: 42 | 43 | //* constructor 44 | explicit Button(QObject *parent, const QVariantList &args); 45 | 46 | //* destructor 47 | virtual ~Button() = default; 48 | 49 | //* button creation 50 | static Button *create(KDecoration2::DecorationButtonType type, KDecoration2::Decoration *decoration, QObject *parent); 51 | 52 | //* render 53 | virtual void paint(QPainter *painter, const QRect &repaintRegion) override; 54 | 55 | //* flag 56 | enum Flag 57 | { 58 | FlagNone, 59 | FlagStandalone, 60 | FlagFirstInList, 61 | FlagLastInList 62 | }; 63 | 64 | //* flag 65 | void setFlag( Flag value ) 66 | { m_flag = value; } 67 | 68 | //* standalone buttons 69 | bool isStandAlone() const { return m_flag == FlagStandalone; } 70 | 71 | //* offset 72 | void setOffset( const QPointF& value ) 73 | { m_offset = value; } 74 | 75 | //* horizontal offset, for rendering 76 | void setHorizontalOffset( qreal value ) 77 | { m_offset.setX( value ); } 78 | 79 | //* vertical offset, for rendering 80 | void setVerticalOffset( qreal value ) 81 | { m_offset.setY( value ); } 82 | 83 | //* set icon size 84 | void setIconSize( const QSize& value ) 85 | { m_iconSize = value; } 86 | 87 | //*@name active state change animation 88 | //@{ 89 | void setOpacity( qreal value ) 90 | { 91 | if( m_opacity == value ) return; 92 | m_opacity = value; 93 | update(); 94 | } 95 | 96 | qreal opacity() const 97 | { return m_opacity; } 98 | 99 | //@} 100 | 101 | private Q_SLOTS: 102 | 103 | //* apply configuration changes 104 | void reconfigure(); 105 | 106 | //* animation state 107 | void updateAnimationState(bool); 108 | 109 | private: 110 | 111 | //* private constructor 112 | explicit Button(KDecoration2::DecorationButtonType type, Decoration *decoration, QObject *parent = nullptr); 113 | 114 | //* draw button icon 115 | void drawIcon( QPainter *) const; 116 | 117 | //*@name colors 118 | //@{ 119 | QColor foregroundColor() const; 120 | QColor backgroundColor() const; 121 | //@} 122 | 123 | Flag m_flag = FlagNone; 124 | 125 | //* active state change animation 126 | QPropertyAnimation *m_animation; 127 | 128 | //* vertical offset (for rendering) 129 | QPointF m_offset; 130 | 131 | //* icon size 132 | QSize m_iconSize; 133 | 134 | //* active state change opacity 135 | qreal m_opacity = 0; 136 | }; 137 | 138 | } // namespace 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /breezedecoration.h: -------------------------------------------------------------------------------- 1 | #ifndef BREEZE_DECORATION_H 2 | #define BREEZE_DECORATION_H 3 | 4 | /* 5 | * Copyright 2014 Martin Gräßlin 6 | * Copyright 2014 Hugo Pereira Da Costa 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation; either version 2 of 11 | * the License or (at your option) version 3 or any later version 12 | * accepted by the membership of KDE e.V. (or its successor approved 13 | * by the membership of KDE e.V.), which shall act as a proxy 14 | * defined in Section 14 of version 3 of the license. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program. If not, see . 23 | */ 24 | 25 | #include "breeze.h" 26 | #include "breezesettings.h" 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | namespace KDecoration2 37 | { 38 | class DecorationButton; 39 | class DecorationButtonGroup; 40 | } 41 | 42 | namespace Breeze 43 | { 44 | class SizeGrip; 45 | class Decoration : public KDecoration2::Decoration 46 | { 47 | Q_OBJECT 48 | 49 | //* declare active state opacity 50 | Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity ) 51 | 52 | public: 53 | 54 | //* constructor 55 | explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList()); 56 | 57 | //* destructor 58 | virtual ~Decoration(); 59 | 60 | //* paint 61 | void paint(QPainter *painter, const QRect &repaintRegion) override; 62 | 63 | //* internal settings 64 | InternalSettingsPtr internalSettings() const 65 | { return m_internalSettings; } 66 | 67 | //* caption height 68 | int captionHeight() const; 69 | 70 | //* button height 71 | int buttonHeight() const; 72 | 73 | //* icon size 74 | int iconSize() const; 75 | 76 | //*@name active state change animation 77 | //@{ 78 | void setOpacity( qreal ); 79 | 80 | qreal opacity() const 81 | { return m_opacity; } 82 | 83 | //@} 84 | 85 | //*@name colors 86 | //@{ 87 | QColor titleBarColor() const; 88 | QColor outlineColor() const; 89 | QColor fontColor() const; 90 | //@} 91 | 92 | //*@name maximization modes 93 | //@{ 94 | inline bool isMaximized() const; 95 | inline bool isMaximizedHorizontally() const; 96 | inline bool isMaximizedVertically() const; 97 | 98 | inline bool isLeftEdge() const; 99 | inline bool isRightEdge() const; 100 | inline bool isTopEdge() const; 101 | inline bool isBottomEdge() const; 102 | 103 | inline bool hideTitleBar() const; 104 | //@} 105 | 106 | public Q_SLOTS: 107 | void init() override; 108 | 109 | private Q_SLOTS: 110 | void reconfigure(); 111 | void recalculateBorders(); 112 | void updateButtonsGeometry(); 113 | void updateButtonsGeometryDelayed(); 114 | void updateTitleBar(); 115 | void updateAnimationState(); 116 | void updateSizeGripVisibility(); 117 | 118 | private: 119 | 120 | //* return the rect in which caption will be drawn 121 | QPair captionRect() const; 122 | 123 | void createButtons(); 124 | void paintTitleBar(QPainter *painter, const QRect &repaintRegion); 125 | void createShadow(); 126 | 127 | //*@name border size 128 | //@{ 129 | int borderSize(bool bottom = false) const; 130 | inline bool hasBorders() const; 131 | inline bool hasNoBorders() const; 132 | inline bool hasNoSideBorders() const; 133 | //@} 134 | 135 | //*@name color customization 136 | //@{ 137 | inline bool opaqueTitleBar() const; 138 | inline int titleBarAlpha() const; 139 | //@} 140 | 141 | //*@name size grip 142 | //@{ 143 | void createSizeGrip(); 144 | void deleteSizeGrip(); 145 | SizeGrip* sizeGrip() const 146 | { return m_sizeGrip; } 147 | //@} 148 | 149 | InternalSettingsPtr m_internalSettings; 150 | KDecoration2::DecorationButtonGroup *m_leftButtons = nullptr; 151 | KDecoration2::DecorationButtonGroup *m_rightButtons = nullptr; 152 | 153 | //* size grip widget 154 | SizeGrip *m_sizeGrip = nullptr; 155 | 156 | //* active state change animation 157 | QPropertyAnimation *m_animation; 158 | 159 | //* active state change opacity 160 | qreal m_opacity = 0; 161 | 162 | }; 163 | 164 | bool Decoration::hasBorders() const 165 | { 166 | if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() > InternalSettings::BorderNoSides; 167 | else return settings()->borderSize() > KDecoration2::BorderSize::NoSides; 168 | } 169 | 170 | bool Decoration::hasNoBorders() const 171 | { 172 | if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNone; 173 | else return settings()->borderSize() == KDecoration2::BorderSize::None; 174 | } 175 | 176 | bool Decoration::hasNoSideBorders() const 177 | { 178 | if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNoSides; 179 | else return settings()->borderSize() == KDecoration2::BorderSize::NoSides; 180 | } 181 | 182 | bool Decoration::isMaximized() const 183 | { return client().data()->isMaximized() && !m_internalSettings->drawBorderOnMaximizedWindows(); } 184 | 185 | bool Decoration::isMaximizedHorizontally() const 186 | { return client().data()->isMaximizedHorizontally() && !m_internalSettings->drawBorderOnMaximizedWindows(); } 187 | 188 | bool Decoration::isMaximizedVertically() const 189 | { return client().data()->isMaximizedVertically() && !m_internalSettings->drawBorderOnMaximizedWindows(); } 190 | 191 | bool Decoration::isLeftEdge() const 192 | { return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::LeftEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 193 | 194 | bool Decoration::isRightEdge() const 195 | { return (client().data()->isMaximizedHorizontally() || client().data()->adjacentScreenEdges().testFlag( Qt::RightEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 196 | 197 | bool Decoration::isTopEdge() const 198 | { return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::TopEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 199 | 200 | bool Decoration::isBottomEdge() const 201 | { return (client().data()->isMaximizedVertically() || client().data()->adjacentScreenEdges().testFlag( Qt::BottomEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 202 | 203 | bool Decoration::hideTitleBar() const 204 | { return m_internalSettings->hideTitleBar() && !client().data()->isShaded(); } 205 | 206 | bool Decoration::opaqueTitleBar() const 207 | { return m_internalSettings->opaqueTitleBar(); } 208 | 209 | int Decoration::titleBarAlpha() const 210 | { 211 | if (m_internalSettings->opaqueTitleBar()) 212 | return 255; 213 | int a = m_internalSettings->opacityOverride() > -1 ? m_internalSettings->opacityOverride() 214 | : m_internalSettings->backgroundOpacity(); 215 | a = qBound(0, a, 100); 216 | return qRound(static_cast(a) * static_cast(2.55)); 217 | } 218 | 219 | } 220 | 221 | #endif 222 | -------------------------------------------------------------------------------- /breezeexceptionlist.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // breezeexceptionlist.cpp 3 | // window decoration exceptions 4 | // ------------------- 5 | // 6 | // Copyright (c) 2009 Hugo Pereira Da Costa 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to 10 | // deal in the Software without restriction, including without limitation the 11 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | // sell copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | // IN THE SOFTWARE. 25 | ////////////////////////////////////////////////////////////////////////////// 26 | 27 | #include "breezeexceptionlist.h" 28 | 29 | 30 | namespace Breeze 31 | { 32 | 33 | //______________________________________________________________ 34 | void ExceptionList::readConfig( KSharedConfig::Ptr config ) 35 | { 36 | 37 | _exceptions.clear(); 38 | 39 | QString groupName; 40 | for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index ) 41 | { 42 | 43 | // create exception 44 | InternalSettings exception; 45 | 46 | // reset group 47 | readConfig( &exception, config.data(), groupName ); 48 | 49 | // create new configuration 50 | InternalSettingsPtr configuration( new InternalSettings() ); 51 | configuration.data()->load(); 52 | 53 | // apply changes from exception 54 | configuration->setEnabled( exception.enabled() ); 55 | configuration->setExceptionType( exception.exceptionType() ); 56 | configuration->setExceptionPattern( exception.exceptionPattern() ); 57 | configuration->setMask( exception.mask() ); 58 | 59 | // propagate all features found in mask to the output configuration 60 | if( exception.mask() & BorderSize ) configuration->setBorderSize( exception.borderSize() ); 61 | configuration->setHideTitleBar( exception.hideTitleBar() ); 62 | configuration->setOpaqueTitleBar( exception.opaqueTitleBar() ); 63 | configuration->setOpacityOverride( exception.opacityOverride() ); 64 | configuration->setIsDialog( exception.isDialog() ); 65 | 66 | // append to exceptions 67 | _exceptions.append( configuration ); 68 | 69 | } 70 | 71 | } 72 | 73 | //______________________________________________________________ 74 | void ExceptionList::writeConfig( KSharedConfig::Ptr config ) 75 | { 76 | 77 | // remove all existing exceptions 78 | QString groupName; 79 | for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index ) 80 | { config->deleteGroup( groupName ); } 81 | 82 | // rewrite current exceptions 83 | int index = 0; 84 | foreach( const InternalSettingsPtr& exception, _exceptions ) 85 | { 86 | 87 | writeConfig( exception.data(), config.data(), exceptionGroupName( index ) ); 88 | ++index; 89 | 90 | } 91 | 92 | } 93 | 94 | //_______________________________________________________________________ 95 | QString ExceptionList::exceptionGroupName( int index ) 96 | { return QString( "Windeco Exception %1" ).arg( index ); } 97 | 98 | //______________________________________________________________ 99 | void ExceptionList::writeConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName ) 100 | { 101 | 102 | // list of items to be written 103 | QStringList keys = { "Enabled", "ExceptionPattern", "ExceptionType", "HideTitleBar", "IsDialog", "OpaqueTitleBar", "OpacityOverride", "Mask", "BorderSize"}; 104 | 105 | // write all items 106 | foreach( auto key, keys ) 107 | { 108 | KConfigSkeletonItem* item( skeleton->findItem( key ) ); 109 | if( !item ) continue; 110 | 111 | if( !groupName.isEmpty() ) item->setGroup( groupName ); 112 | KConfigGroup configGroup( config, item->group() ); 113 | configGroup.writeEntry( item->key(), item->property() ); 114 | 115 | } 116 | 117 | } 118 | 119 | //______________________________________________________________ 120 | void ExceptionList::readConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName ) 121 | { 122 | 123 | foreach( KConfigSkeletonItem* item, skeleton->items() ) 124 | { 125 | if( !groupName.isEmpty() ) item->setGroup( groupName ); 126 | item->readConfig( config ); 127 | } 128 | 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /breezeexceptionlist.h: -------------------------------------------------------------------------------- 1 | #ifndef breezeexceptionlist_h 2 | #define breezeexceptionlist_h 3 | 4 | ////////////////////////////////////////////////////////////////////////////// 5 | // breezeexceptionlist.h 6 | // window decoration exceptions 7 | // ------------------- 8 | // 9 | // Copyright (c) 2009 Hugo Pereira Da Costa 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to 13 | // deal in the Software without restriction, including without limitation the 14 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 15 | // sell copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27 | // IN THE SOFTWARE. 28 | ////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "breezesettings.h" 31 | #include "breeze.h" 32 | 33 | #include 34 | 35 | namespace Breeze 36 | { 37 | 38 | //! breeze exceptions list 39 | class ExceptionList 40 | { 41 | 42 | public: 43 | 44 | //! constructor from list 45 | explicit ExceptionList( const InternalSettingsList& exceptions = InternalSettingsList() ): 46 | _exceptions( exceptions ) 47 | {} 48 | 49 | //! exceptions 50 | const InternalSettingsList& get( void ) const 51 | { return _exceptions; } 52 | 53 | //! read from KConfig 54 | void readConfig( KSharedConfig::Ptr ); 55 | 56 | //! write to kconfig 57 | void writeConfig( KSharedConfig::Ptr ); 58 | 59 | protected: 60 | 61 | //! generate exception group name for given exception index 62 | static QString exceptionGroupName( int index ); 63 | 64 | //! read configuration 65 | static void readConfig( KCoreConfigSkeleton*, KConfig*, const QString& ); 66 | 67 | //! write configuration 68 | static void writeConfig( KCoreConfigSkeleton*, KConfig*, const QString& ); 69 | 70 | private: 71 | 72 | //! exceptions 73 | InternalSettingsList _exceptions; 74 | 75 | }; 76 | 77 | } 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /breezesettings.kcfgc: -------------------------------------------------------------------------------- 1 | File=breezesettingsdata.kcfg 2 | ClassName=InternalSettings 3 | NameSpace=Breeze 4 | Singleton=false 5 | Mutators=true 6 | GlobalEnums=true 7 | -------------------------------------------------------------------------------- /breezesettingsdata.kcfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 255 11 | 25 12 | 255 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | ShadowLarge 25 | 26 | 27 | 28 | 0, 0, 0 29 | 30 | 31 | 32 | 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | BorderNoSides 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | AlignCenterFullWidth 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | ButtonDefault 81 | 82 | 83 | 84 | 85 | false 86 | 87 | 88 | 89 | false 90 | 91 | 92 | 93 | 100 94 | 95 | 96 | 97 | 98 | 99 | 100 | false 101 | 102 | 103 | 104 | 105 | true 106 | 107 | 108 | 109 | 150 110 | 111 | 112 | 113 | 114 | false 115 | 116 | 117 | 118 | 119 | false 120 | 121 | 122 | 123 | -1 124 | 125 | 126 | 127 | 128 | false 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ExceptionWindowClassName 138 | 139 | 140 | 141 | 142 | 143 | true 144 | 145 | 146 | 147 | 0 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /breezesettingsprovider.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Hugo Pereira Da Costa 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License as 6 | * published by the Free Software Foundation; either version 2 of 7 | * the License or (at your option) version 3 or any later version 8 | * accepted by the membership of KDE e.V. (or its successor approved 9 | * by the membership of KDE e.V.), which shall act as a proxy 10 | * defined in Section 14 of version 3 of the license. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "breezesettingsprovider.h" 22 | 23 | #include "breezeexceptionlist.h" 24 | 25 | #include 26 | 27 | #include 28 | 29 | namespace Breeze 30 | { 31 | 32 | SettingsProvider *SettingsProvider::s_self = nullptr; 33 | 34 | //__________________________________________________________________ 35 | SettingsProvider::SettingsProvider(): 36 | m_config( KSharedConfig::openConfig( QStringLiteral("breezerc") ) ) 37 | { reconfigure(); } 38 | 39 | //__________________________________________________________________ 40 | SettingsProvider::~SettingsProvider() 41 | { s_self = nullptr; } 42 | 43 | //__________________________________________________________________ 44 | SettingsProvider *SettingsProvider::self() 45 | { 46 | // TODO: this is not thread safe! 47 | if (!s_self) 48 | { s_self = new SettingsProvider(); } 49 | 50 | return s_self; 51 | } 52 | 53 | //__________________________________________________________________ 54 | void SettingsProvider::reconfigure() 55 | { 56 | if( !m_defaultSettings ) 57 | { 58 | m_defaultSettings = InternalSettingsPtr(new InternalSettings()); 59 | m_defaultSettings->setCurrentGroup( QStringLiteral("Windeco") ); 60 | } 61 | 62 | m_defaultSettings->load(); 63 | 64 | ExceptionList exceptions; 65 | exceptions.readConfig( m_config ); 66 | m_exceptions = exceptions.get(); 67 | 68 | } 69 | 70 | //__________________________________________________________________ 71 | InternalSettingsPtr SettingsProvider::internalSettings( Decoration *decoration ) const 72 | { 73 | 74 | QString windowTitle; 75 | QString className; 76 | 77 | // get the client 78 | auto client = decoration->client().data(); 79 | 80 | foreach( auto internalSettings, m_exceptions ) 81 | { 82 | 83 | // discard disabled exceptions 84 | if( !internalSettings->enabled() ) continue; 85 | 86 | // discard exceptions with empty exception pattern 87 | if( internalSettings->exceptionPattern().isEmpty() ) continue; 88 | 89 | if (internalSettings->isDialog()) 90 | { 91 | KWindowInfo info(client->windowId(), NET::WMWindowType); 92 | if (info.valid() 93 | && info.windowType(NET::NormalMask | NET::DialogMask) != NET::Dialog) { 94 | continue; 95 | } 96 | } 97 | 98 | /* 99 | decide which value is to be compared 100 | to the regular expression, based on exception type 101 | */ 102 | QString value; 103 | switch( internalSettings->exceptionType() ) 104 | { 105 | case InternalSettings::ExceptionWindowTitle: 106 | { 107 | value = windowTitle.isEmpty() ? (windowTitle = client->caption()):windowTitle; 108 | break; 109 | } 110 | 111 | default: 112 | case InternalSettings::ExceptionWindowClassName: 113 | { 114 | if( className.isEmpty() ) 115 | { 116 | // retrieve class name 117 | KWindowInfo info( client->windowId(), nullptr, NET::WM2WindowClass ); 118 | QString window_className( QString::fromUtf8(info.windowClassName()) ); 119 | QString window_class( QString::fromUtf8(info.windowClassClass()) ); 120 | className = window_className + QStringLiteral(" ") + window_class; 121 | } 122 | 123 | value = className; 124 | break; 125 | } 126 | 127 | } 128 | 129 | // check matching 130 | if( QRegExp( internalSettings->exceptionPattern() ).indexIn( value ) >= 0 ) 131 | { return internalSettings; } 132 | 133 | } 134 | 135 | return m_defaultSettings; 136 | 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /breezesettingsprovider.h: -------------------------------------------------------------------------------- 1 | #ifndef breezesettingsprovider_h 2 | #define breezesettingsprovider_h 3 | /* 4 | * Copyright 2014 Hugo Pereira Da Costa 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License as 8 | * published by the Free Software Foundation; either version 2 of 9 | * the License or (at your option) version 3 or any later version 10 | * accepted by the membership of KDE e.V. (or its successor approved 11 | * by the membership of KDE e.V.), which shall act as a proxy 12 | * defined in Section 14 of version 3 of the license. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see . 21 | */ 22 | 23 | #include "breezedecoration.h" 24 | #include "breezesettings.h" 25 | #include "breeze.h" 26 | 27 | #include 28 | 29 | #include 30 | 31 | namespace Breeze 32 | { 33 | 34 | class SettingsProvider: public QObject 35 | { 36 | 37 | Q_OBJECT 38 | 39 | public: 40 | 41 | //* destructor 42 | ~SettingsProvider(); 43 | 44 | //* singleton 45 | static SettingsProvider *self(); 46 | 47 | //* internal settings for given decoration 48 | InternalSettingsPtr internalSettings(Decoration *) const; 49 | 50 | public Q_SLOTS: 51 | 52 | //* reconfigure 53 | void reconfigure(); 54 | 55 | private: 56 | 57 | //* contructor 58 | SettingsProvider(); 59 | 60 | //* default configuration 61 | InternalSettingsPtr m_defaultSettings; 62 | 63 | //* exceptions 64 | InternalSettingsList m_exceptions; 65 | 66 | //* config object 67 | KSharedConfigPtr m_config; 68 | 69 | //* singleton 70 | static SettingsProvider *s_self; 71 | 72 | }; 73 | 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /breezesizegrip.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * Copyright (C) 2014 by Hugo Pereira Da Costa * 3 | * * 4 | * This program is free software; you can redistribute it and/or modify * 5 | * it under the terms of the GNU General Public License as published by * 6 | * the Free Software Foundation; either version 2 of the License, or * 7 | * (at your option) any later version. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 18 | *************************************************************************/ 19 | 20 | 21 | #include "breezesizegrip.h" 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #if BREEZE_HAVE_X11 30 | #include 31 | #endif 32 | 33 | namespace Breeze 34 | { 35 | 36 | //* scoped pointer convenience typedef 37 | template using ScopedPointer = QScopedPointer; 38 | 39 | //_____________________________________________ 40 | SizeGrip::SizeGrip( Decoration* decoration ):QWidget(nullptr) 41 | ,m_decoration( decoration ) 42 | { 43 | 44 | setAttribute(Qt::WA_NoSystemBackground ); 45 | setAutoFillBackground( false ); 46 | 47 | // cursor 48 | setCursor( Qt::SizeFDiagCursor ); 49 | 50 | // size 51 | setFixedSize( QSize( GripSize, GripSize ) ); 52 | 53 | // mask 54 | setMask( QRegion( QVector{ 55 | QPoint( 0, GripSize ), 56 | QPoint( GripSize, 0 ), 57 | QPoint( GripSize, GripSize ), 58 | QPoint( 0, GripSize )} ) ); 59 | 60 | // embed 61 | embed(); 62 | updatePosition(); 63 | 64 | // connections 65 | auto c = decoration->client().data(); 66 | connect( c, &KDecoration2::DecoratedClient::widthChanged, this, &SizeGrip::updatePosition ); 67 | connect( c, &KDecoration2::DecoratedClient::heightChanged, this, &SizeGrip::updatePosition ); 68 | connect( c, &KDecoration2::DecoratedClient::activeChanged, this, &SizeGrip::updateActiveState ); 69 | 70 | // show 71 | show(); 72 | 73 | } 74 | 75 | //_____________________________________________ 76 | SizeGrip::~SizeGrip() 77 | {} 78 | 79 | //_____________________________________________ 80 | void SizeGrip::updateActiveState() 81 | { 82 | #if BREEZE_HAVE_X11 83 | if( QX11Info::isPlatformX11() ) 84 | { 85 | const quint32 value = XCB_STACK_MODE_ABOVE; 86 | xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_STACK_MODE, &value ); 87 | xcb_map_window( QX11Info::connection(), winId() ); 88 | } 89 | #endif 90 | 91 | update(); 92 | 93 | } 94 | 95 | //_____________________________________________ 96 | void SizeGrip::embed() 97 | { 98 | 99 | #if BREEZE_HAVE_X11 100 | 101 | if( !QX11Info::isPlatformX11() ) return; 102 | auto c = m_decoration.data()->client().data(); 103 | 104 | xcb_window_t windowId = c->windowId(); 105 | if( windowId ) 106 | { 107 | 108 | /* 109 | find client's parent 110 | we want the size grip to be at the same level as the client in the stack 111 | */ 112 | xcb_window_t current = windowId; 113 | auto connection = QX11Info::connection(); 114 | xcb_query_tree_cookie_t cookie = xcb_query_tree_unchecked( connection, current ); 115 | ScopedPointer tree(xcb_query_tree_reply( connection, cookie, nullptr ) ); 116 | if( !tree.isNull() && tree->parent ) current = tree->parent; 117 | 118 | // reparent 119 | xcb_reparent_window( connection, winId(), current, 0, 0 ); 120 | setWindowTitle( "Breeze::SizeGrip" ); 121 | 122 | } else { 123 | 124 | hide(); 125 | 126 | } 127 | 128 | #endif 129 | } 130 | 131 | //_____________________________________________ 132 | void SizeGrip::paintEvent( QPaintEvent* ) 133 | { 134 | 135 | if( !m_decoration ) return; 136 | 137 | // get relevant colors 138 | const QColor backgroundColor( m_decoration.data()->titleBarColor() ); 139 | 140 | // create and configure painter 141 | QPainter painter(this); 142 | painter.setRenderHints(QPainter::Antialiasing ); 143 | 144 | painter.setPen( Qt::NoPen ); 145 | painter.setBrush( backgroundColor ); 146 | 147 | // polygon 148 | painter.drawPolygon( QVector { 149 | QPoint( 0, GripSize ), 150 | QPoint( GripSize, 0 ), 151 | QPoint( GripSize, GripSize ), 152 | QPoint( 0, GripSize )} ); 153 | } 154 | 155 | //_____________________________________________ 156 | void SizeGrip::mousePressEvent( QMouseEvent* event ) 157 | { 158 | 159 | switch (event->button()) 160 | { 161 | 162 | case Qt::RightButton: 163 | { 164 | hide(); 165 | QTimer::singleShot(5000, this, SLOT(show())); 166 | break; 167 | } 168 | 169 | case Qt::MidButton: 170 | { 171 | hide(); 172 | break; 173 | } 174 | 175 | case Qt::LeftButton: 176 | if( rect().contains( event->pos() ) ) 177 | { sendMoveResizeEvent( event->pos() ); } 178 | break; 179 | 180 | default: break; 181 | 182 | } 183 | 184 | 185 | } 186 | 187 | //_______________________________________________________________________________ 188 | void SizeGrip::updatePosition() 189 | { 190 | 191 | #if BREEZE_HAVE_X11 192 | if( !QX11Info::isPlatformX11() ) return; 193 | 194 | auto c = m_decoration.data()->client().data(); 195 | QPoint position( 196 | c->width() - GripSize - Offset, 197 | c->height() - GripSize - Offset ); 198 | 199 | quint32 values[2] = { quint32(position.x()), quint32(position.y()) }; 200 | xcb_configure_window( QX11Info::connection(), winId(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values ); 201 | #endif 202 | 203 | } 204 | 205 | //_____________________________________________ 206 | void SizeGrip::sendMoveResizeEvent( QPoint position ) 207 | { 208 | 209 | #if BREEZE_HAVE_X11 210 | if( !QX11Info::isPlatformX11() ) return; 211 | 212 | // pointer to connection 213 | auto connection( QX11Info::connection() ); 214 | 215 | // client 216 | auto c = m_decoration.data()->client().data(); 217 | 218 | /* 219 | get root position matching position 220 | need to use xcb because the embedding of the widget 221 | breaks QT's mapToGlobal and other methods 222 | */ 223 | QPoint rootPosition( position ); 224 | xcb_get_geometry_cookie_t cookie( xcb_get_geometry( connection, winId() ) ); 225 | ScopedPointer reply( xcb_get_geometry_reply( connection, cookie, nullptr ) ); 226 | if( reply ) 227 | { 228 | 229 | // translate coordinates 230 | xcb_translate_coordinates_cookie_t coordCookie( xcb_translate_coordinates( 231 | connection, winId(), reply.data()->root, 232 | -reply.data()->border_width, 233 | -reply.data()->border_width ) ); 234 | 235 | ScopedPointer< xcb_translate_coordinates_reply_t> coordReply( xcb_translate_coordinates_reply( connection, coordCookie, nullptr ) ); 236 | 237 | if( coordReply ) 238 | { 239 | rootPosition.rx() += coordReply.data()->dst_x; 240 | rootPosition.ry() += coordReply.data()->dst_y; 241 | } 242 | 243 | } 244 | 245 | // move/resize atom 246 | if( !m_moveResizeAtom ) 247 | { 248 | 249 | // create atom if not found 250 | const QString atomName( "_NET_WM_MOVERESIZE" ); 251 | xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) ); 252 | ScopedPointer reply( xcb_intern_atom_reply( connection, cookie, nullptr ) ); 253 | m_moveResizeAtom = reply ? reply->atom:0; 254 | 255 | } 256 | 257 | if( !m_moveResizeAtom ) return; 258 | 259 | // button release event 260 | xcb_button_release_event_t releaseEvent; 261 | memset(&releaseEvent, 0, sizeof(releaseEvent)); 262 | 263 | releaseEvent.response_type = XCB_BUTTON_RELEASE; 264 | releaseEvent.event = winId(); 265 | releaseEvent.child = XCB_WINDOW_NONE; 266 | releaseEvent.root = QX11Info::appRootWindow(); 267 | releaseEvent.event_x = position.x(); 268 | releaseEvent.event_y = position.y(); 269 | releaseEvent.root_x = rootPosition.x(); 270 | releaseEvent.root_y = rootPosition.y(); 271 | releaseEvent.detail = XCB_BUTTON_INDEX_1; 272 | releaseEvent.state = XCB_BUTTON_MASK_1; 273 | releaseEvent.time = XCB_CURRENT_TIME; 274 | releaseEvent.same_screen = true; 275 | xcb_send_event( connection, false, winId(), XCB_EVENT_MASK_BUTTON_RELEASE, reinterpret_cast(&releaseEvent)); 276 | 277 | xcb_ungrab_pointer( connection, XCB_TIME_CURRENT_TIME ); 278 | 279 | // move resize event 280 | xcb_client_message_event_t clientMessageEvent; 281 | memset(&clientMessageEvent, 0, sizeof(clientMessageEvent)); 282 | 283 | clientMessageEvent.response_type = XCB_CLIENT_MESSAGE; 284 | clientMessageEvent.type = m_moveResizeAtom; 285 | clientMessageEvent.format = 32; 286 | clientMessageEvent.window = c->windowId(); 287 | clientMessageEvent.data.data32[0] = rootPosition.x(); 288 | clientMessageEvent.data.data32[1] = rootPosition.y(); 289 | clientMessageEvent.data.data32[2] = 4; // bottom right 290 | clientMessageEvent.data.data32[3] = Qt::LeftButton; 291 | clientMessageEvent.data.data32[4] = 0; 292 | 293 | xcb_send_event( connection, false, QX11Info::appRootWindow(), 294 | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | 295 | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, 296 | reinterpret_cast(&clientMessageEvent) ); 297 | 298 | xcb_flush( connection ); 299 | #endif 300 | 301 | } 302 | 303 | } 304 | -------------------------------------------------------------------------------- /breezesizegrip.h: -------------------------------------------------------------------------------- 1 | #ifndef breezesizegrip_h 2 | #define breezesizegrip_h 3 | 4 | /************************************************************************* 5 | * Copyright (C) 2014 by Hugo Pereira Da Costa * 6 | * * 7 | * This program is free software; you can redistribute it and/or modify * 8 | * it under the terms of the GNU General Public License as published by * 9 | * the Free Software Foundation; either version 2 of the License, or * 10 | * (at your option) any later version. * 11 | * * 12 | * This program is distributed in the hope that it will be useful, * 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 15 | * GNU General Public License for more details. * 16 | * * 17 | * You should have received a copy of the GNU General Public License * 18 | * along with this program; if not, write to the * 19 | * Free Software Foundation, Inc., * 20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 21 | *************************************************************************/ 22 | 23 | #include "breezedecoration.h" 24 | #include "config-breeze.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #if BREEZE_HAVE_X11 32 | #include 33 | #endif 34 | 35 | namespace Breeze 36 | { 37 | 38 | //* implements size grip for all widgets 39 | class SizeGrip: public QWidget 40 | { 41 | 42 | Q_OBJECT 43 | 44 | public: 45 | 46 | //* constructor 47 | explicit SizeGrip( Decoration* ); 48 | 49 | //* constructor 50 | virtual ~SizeGrip(); 51 | 52 | protected Q_SLOTS: 53 | 54 | //* update background color 55 | void updateActiveState(); 56 | 57 | //* update position 58 | void updatePosition(); 59 | 60 | //* embed into parent widget 61 | void embed(); 62 | 63 | protected: 64 | 65 | //*@name event handlers 66 | //@{ 67 | 68 | //* paint 69 | virtual void paintEvent( QPaintEvent* ) override; 70 | 71 | //* mouse press 72 | virtual void mousePressEvent( QMouseEvent* ) override; 73 | 74 | //@} 75 | 76 | private: 77 | 78 | //* send resize event 79 | void sendMoveResizeEvent( QPoint ); 80 | 81 | //* grip size 82 | enum { 83 | Offset = 0, 84 | GripSize = 14 85 | }; 86 | 87 | //* decoration 88 | QPointer m_decoration; 89 | 90 | //* move/resize atom 91 | #if BREEZE_HAVE_X11 92 | xcb_atom_t m_moveResizeAtom = 0; 93 | #endif 94 | 95 | }; 96 | 97 | 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /cmake/Modules/FindFFTW.cmake: -------------------------------------------------------------------------------- 1 | # Find the FFTW library 2 | # 3 | # Usage: 4 | # find_package(FFTW [REQUIRED]) 5 | # 6 | # It sets the following variables: 7 | # FFTW_FOUND 8 | # FFTW_INCLUDES 9 | # FFTW_LIBRARIES 10 | 11 | 12 | find_path(FFTW_INCLUDES fftw3.h) 13 | 14 | find_library(FFTW_LIBRARIES NAMES fftw3) 15 | 16 | include(FindPackageHandleStandardArgs) 17 | find_package_handle_standard_args(FFTW DEFAULT_MSG 18 | FFTW_INCLUDES FFTW_LIBRARIES) 19 | 20 | mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES) 21 | -------------------------------------------------------------------------------- /config-breeze.h.cmake: -------------------------------------------------------------------------------- 1 | /* config-breeze.h. Generated by cmake from config-breeze.h.cmake */ 2 | 3 | /************************************************************************* 4 | * Copyright (C) 2014 by Hugo Pereira Da Costa * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the * 18 | * Free Software Foundation, Inc., * 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 20 | *************************************************************************/ 21 | 22 | #ifndef config_breeze_h 23 | #define config_breeze_h 24 | 25 | /* Define to 1 if XCB libraries are found */ 26 | #cmakedefine01 BREEZE_HAVE_X11 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /config/breeze10config.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Exec=kcmshell5 breeze10config 3 | Icon=preferences-system-windows 4 | Type=Service 5 | X-KDE-ServiceTypes=KCModule 6 | 7 | X-KDE-Library=org.kde.kdecoration2/breeze10 8 | X-KDE-PluginKeyword=kcmodule 9 | X-KDE-ParentApp=kcontrol 10 | X-KDE-Weight=60 11 | X-KDE-PluginInfo-Name=Breeze10 12 | 13 | Name=Breeze10 14 | Comment=Modify the appearance of window decorations 15 | X-KDE-Keywords=breeze10,decoration 16 | -------------------------------------------------------------------------------- /config/breezeconfigwidget.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // breezeconfigurationui.cpp 3 | // ------------------- 4 | // 5 | // Copyright (c) 2009 Hugo Pereira Da Costa 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to 9 | // deal in the Software without restriction, including without limitation the 10 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | // sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | // IN THE SOFTWARE. 24 | ////////////////////////////////////////////////////////////////////////////// 25 | 26 | #include "breezeconfigwidget.h" 27 | #include "breezeexceptionlist.h" 28 | #include "breezesettings.h" 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | namespace Breeze 36 | { 37 | 38 | //_________________________________________________________ 39 | ConfigWidget::ConfigWidget( QWidget* parent, const QVariantList &args ): 40 | KCModule(parent, args), 41 | m_configuration( KSharedConfig::openConfig( QStringLiteral( "breezerc" ) ) ), 42 | m_changed( false ) 43 | { 44 | 45 | // configuration 46 | m_ui.setupUi( this ); 47 | 48 | // track ui changes 49 | connect( m_ui.titleAlignment, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 50 | connect( m_ui.buttonSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 51 | connect( m_ui.drawBorderOnMaximizedWindows, SIGNAL(clicked()), SLOT(updateChanged()) ); 52 | connect( m_ui.drawSizeGrip, SIGNAL(clicked()), SLOT(updateChanged()) ); 53 | connect( m_ui.opacitySpinBox, QOverload::of(&QSpinBox::valueChanged), [=](int /*i*/){updateChanged();} ); 54 | 55 | connect( m_ui.fontComboBox, &QFontComboBox::currentFontChanged, [this] { updateChanged(); } ); 56 | connect( m_ui.fontSizeSpinBox, QOverload::of(&QSpinBox::valueChanged), [=](int /*i*/){updateChanged();} ); 57 | connect(m_ui.weightComboBox, QOverload::of(&QComboBox::currentIndexChanged), [this] { updateChanged(); } ); 58 | connect( m_ui.italicCheckBox, &QCheckBox::stateChanged, [this] { updateChanged(); } ); 59 | 60 | // track animations changes 61 | connect( m_ui.animationsEnabled, SIGNAL(clicked()), SLOT(updateChanged()) ); 62 | connect( m_ui.animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 63 | 64 | // track shadows changes 65 | connect( m_ui.shadowSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 66 | connect( m_ui.shadowStrength, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 67 | connect( m_ui.shadowColor, SIGNAL(changed(QColor)), SLOT(updateChanged()) ); 68 | 69 | // track exception changes 70 | connect( m_ui.exceptions, SIGNAL(changed(bool)), SLOT(updateChanged()) ); 71 | 72 | } 73 | 74 | //_________________________________________________________ 75 | void ConfigWidget::load() 76 | { 77 | 78 | // create internal settings and load from rc files 79 | m_internalSettings = InternalSettingsPtr( new InternalSettings() ); 80 | m_internalSettings->load(); 81 | 82 | // assign to ui 83 | m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); 84 | m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); 85 | m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); 86 | m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); 87 | m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); 88 | m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); 89 | m_ui.opacitySpinBox->setValue( m_internalSettings->backgroundOpacity() ); 90 | 91 | QString fontStr = m_internalSettings->titleBarFont(); 92 | if (fontStr.isEmpty()) 93 | fontStr = QLatin1String("Sans,11,-1,5,50,0,0,0,0,0"); 94 | QFont f; f.fromString( fontStr ); 95 | m_ui.fontComboBox->setCurrentFont( f ); 96 | m_ui.fontSizeSpinBox->setValue( f.pointSize() ); 97 | int w = f.weight(); 98 | switch (w) { 99 | case QFont::Medium: 100 | m_ui.weightComboBox->setCurrentIndex(1); 101 | break; 102 | case QFont::DemiBold: 103 | m_ui.weightComboBox->setCurrentIndex(2); 104 | break; 105 | case QFont::Bold: 106 | m_ui.weightComboBox->setCurrentIndex(3); 107 | break; 108 | case QFont::ExtraBold: 109 | m_ui.weightComboBox->setCurrentIndex(4); 110 | break; 111 | case QFont::Black: 112 | m_ui.weightComboBox->setCurrentIndex(5); 113 | break; 114 | default: 115 | m_ui.weightComboBox->setCurrentIndex(0); 116 | break; 117 | } 118 | m_ui.italicCheckBox->setChecked( f.italic() ); 119 | 120 | // load shadows 121 | if( m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge ) m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); 122 | else m_ui.shadowSize->setCurrentIndex( InternalSettings::ShadowLarge ); 123 | 124 | m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); 125 | m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); 126 | 127 | // load exceptions 128 | ExceptionList exceptions; 129 | exceptions.readConfig( m_configuration ); 130 | m_ui.exceptions->setExceptions( exceptions.get() ); 131 | setChanged( false ); 132 | 133 | } 134 | 135 | //_________________________________________________________ 136 | void ConfigWidget::save() 137 | { 138 | 139 | // create internal settings and load from rc files 140 | m_internalSettings = InternalSettingsPtr( new InternalSettings() ); 141 | m_internalSettings->load(); 142 | 143 | // apply modifications from ui 144 | m_internalSettings->setTitleAlignment( m_ui.titleAlignment->currentIndex() ); 145 | m_internalSettings->setButtonSize( m_ui.buttonSize->currentIndex() ); 146 | m_internalSettings->setDrawBorderOnMaximizedWindows( m_ui.drawBorderOnMaximizedWindows->isChecked() ); 147 | m_internalSettings->setDrawSizeGrip( m_ui.drawSizeGrip->isChecked() ); 148 | m_internalSettings->setAnimationsEnabled( m_ui.animationsEnabled->isChecked() ); 149 | m_internalSettings->setAnimationsDuration( m_ui.animationsDuration->value() ); 150 | m_internalSettings->setBackgroundOpacity(m_ui.opacitySpinBox->value()); 151 | 152 | QFont f = m_ui.fontComboBox->currentFont(); 153 | f.setPointSize(m_ui.fontSizeSpinBox->value()); 154 | int indx = m_ui.weightComboBox->currentIndex(); 155 | switch (indx) { 156 | case 1: 157 | f.setWeight(QFont::Medium); 158 | break; 159 | case 2: 160 | f.setWeight(QFont::DemiBold); 161 | break; 162 | case 3: 163 | f.setWeight(QFont::Bold); 164 | break; 165 | case 4: 166 | f.setWeight(QFont::ExtraBold); 167 | break; 168 | case 5: 169 | f.setWeight(QFont::Black); 170 | break; 171 | default: 172 | f.setBold(false); 173 | break; 174 | } 175 | f.setItalic(m_ui.italicCheckBox->isChecked()); 176 | m_internalSettings->setTitleBarFont(f.toString()); 177 | 178 | m_internalSettings->setShadowSize( m_ui.shadowSize->currentIndex() ); 179 | m_internalSettings->setShadowStrength( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) ); 180 | m_internalSettings->setShadowColor( m_ui.shadowColor->color() ); 181 | 182 | // save configuration 183 | m_internalSettings->save(); 184 | 185 | // get list of exceptions and write 186 | InternalSettingsList exceptions( m_ui.exceptions->exceptions() ); 187 | ExceptionList( exceptions ).writeConfig( m_configuration ); 188 | 189 | // sync configuration 190 | m_configuration->sync(); 191 | setChanged( false ); 192 | 193 | // needed to tell kwin to reload when running from external kcmshell 194 | { 195 | QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); 196 | QDBusConnection::sessionBus().send(message); 197 | } 198 | 199 | // needed for breeze style to reload shadows 200 | { 201 | QDBusMessage message( QDBusMessage::createSignal("/BreezeDecoration", "org.kde.Breeze.Style", "reparseConfiguration") ); 202 | QDBusConnection::sessionBus().send(message); 203 | } 204 | 205 | } 206 | 207 | //_________________________________________________________ 208 | void ConfigWidget::defaults() 209 | { 210 | 211 | // create internal settings and load from rc files 212 | m_internalSettings = InternalSettingsPtr( new InternalSettings() ); 213 | m_internalSettings->setDefaults(); 214 | 215 | // assign to ui 216 | m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); 217 | m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); 218 | m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); 219 | m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); 220 | m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); 221 | m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); 222 | m_ui.opacitySpinBox->setValue( m_internalSettings->backgroundOpacity() ); 223 | 224 | QFont f; f.fromString("Sans,11,-1,5,50,0,0,0,0,0"); 225 | m_ui.fontComboBox->setCurrentFont( f ); 226 | m_ui.fontSizeSpinBox->setValue( f.pointSize() ); 227 | int w = f.weight(); 228 | switch (w) { 229 | case QFont::Medium: 230 | m_ui.weightComboBox->setCurrentIndex(1); 231 | break; 232 | case QFont::DemiBold: 233 | m_ui.weightComboBox->setCurrentIndex(2); 234 | break; 235 | case QFont::Bold: 236 | m_ui.weightComboBox->setCurrentIndex(3); 237 | break; 238 | case QFont::ExtraBold: 239 | m_ui.weightComboBox->setCurrentIndex(4); 240 | break; 241 | case QFont::Black: 242 | m_ui.weightComboBox->setCurrentIndex(5); 243 | break; 244 | default: 245 | m_ui.weightComboBox->setCurrentIndex(0); 246 | break; 247 | } 248 | m_ui.italicCheckBox->setChecked( f.italic() ); 249 | 250 | m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); 251 | m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); 252 | m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); 253 | 254 | } 255 | 256 | //_______________________________________________ 257 | void ConfigWidget::updateChanged() 258 | { 259 | 260 | // check configuration 261 | if( !m_internalSettings ) return; 262 | 263 | // track modifications 264 | bool modified( false ); 265 | QFont f; f.fromString( m_internalSettings->titleBarFont() ); 266 | 267 | if( m_ui.titleAlignment->currentIndex() != m_internalSettings->titleAlignment() ) modified = true; 268 | else if( m_ui.buttonSize->currentIndex() != m_internalSettings->buttonSize() ) modified = true; 269 | else if( m_ui.drawBorderOnMaximizedWindows->isChecked() != m_internalSettings->drawBorderOnMaximizedWindows() ) modified = true; 270 | else if( m_ui.drawSizeGrip->isChecked() != m_internalSettings->drawSizeGrip() ) modified = true; 271 | else if( m_ui.opacitySpinBox->value() != m_internalSettings->backgroundOpacity() ) modified = true; 272 | 273 | // font (also see below) 274 | else if( m_ui.fontComboBox->currentFont().toString() != f.family() ) modified = true; 275 | else if( m_ui.fontSizeSpinBox->value() != f.pointSize() ) modified = true; 276 | else if( m_ui.italicCheckBox->isChecked() != f.italic() ) modified = true; 277 | 278 | // animations 279 | else if( m_ui.animationsEnabled->isChecked() != m_internalSettings->animationsEnabled() ) modified = true; 280 | else if( m_ui.animationsDuration->value() != m_internalSettings->animationsDuration() ) modified = true; 281 | 282 | // shadows 283 | else if( m_ui.shadowSize->currentIndex() != m_internalSettings->shadowSize() ) modified = true; 284 | else if( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) != m_internalSettings->shadowStrength() ) modified = true; 285 | else if( m_ui.shadowColor->color() != m_internalSettings->shadowColor() ) modified = true; 286 | 287 | // exceptions 288 | else if( m_ui.exceptions->isChanged() ) modified = true; 289 | else { 290 | int indx = m_ui.weightComboBox->currentIndex(); 291 | switch (indx) { 292 | case 1: 293 | if (f.weight() != QFont::Medium) modified = true; 294 | break; 295 | case 2: 296 | if (f.weight() != QFont::DemiBold) modified = true; 297 | break; 298 | case 3: 299 | if (f.weight() != QFont::Bold) modified = true; 300 | break; 301 | case 4: 302 | if (f.weight() != QFont::ExtraBold) modified = true; 303 | break; 304 | case 5: 305 | if (f.weight() != QFont::Black) modified = true; 306 | break; 307 | default: 308 | if (f.bold()) modified = true; 309 | break; 310 | } 311 | } 312 | 313 | setChanged( modified ); 314 | 315 | } 316 | 317 | //_______________________________________________ 318 | void ConfigWidget::setChanged( bool value ) 319 | { 320 | emit changed( value ); 321 | } 322 | 323 | } 324 | -------------------------------------------------------------------------------- /config/breezeconfigwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef breezeconfigwidget_h 2 | #define breezeconfigwidget_h 3 | ////////////////////////////////////////////////////////////////////////////// 4 | // breezeconfigurationui.h 5 | // ------------------- 6 | // 7 | // Copyright (c) 2009 Hugo Pereira Da Costa 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to 11 | // deal in the Software without restriction, including without limitation the 12 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | // sell copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 | // IN THE SOFTWARE. 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | #include "ui_breezeconfigurationui.h" 29 | #include "breezeexceptionlistwidget.h" 30 | #include "breezesettings.h" 31 | #include "breeze.h" 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | 39 | namespace Breeze 40 | { 41 | 42 | //_____________________________________________ 43 | class ConfigWidget: public KCModule 44 | { 45 | 46 | Q_OBJECT 47 | 48 | public: 49 | 50 | //* constructor 51 | explicit ConfigWidget( QWidget*, const QVariantList& ); 52 | 53 | //* destructor 54 | virtual ~ConfigWidget() = default; 55 | 56 | //* default 57 | void defaults() override; 58 | 59 | //* load configuration 60 | void load() override; 61 | 62 | //* save configuration 63 | void save() override; 64 | 65 | protected Q_SLOTS: 66 | 67 | //* update changed state 68 | virtual void updateChanged(); 69 | 70 | protected: 71 | 72 | //* set changed state 73 | void setChanged( bool ); 74 | 75 | private: 76 | 77 | //* ui 78 | Ui_BreezeConfigurationUI m_ui; 79 | 80 | //* kconfiguration object 81 | KSharedConfig::Ptr m_configuration; 82 | 83 | //* internal exception 84 | InternalSettingsPtr m_internalSettings; 85 | 86 | //* changed state 87 | bool m_changed; 88 | 89 | }; 90 | 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /config/breezedecorationconfig.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Exec=kcmshell5 breezedecorationconfig 3 | Icon=preferences-system-windows 4 | Type=Service 5 | X-KDE-ServiceTypes=KCModule 6 | 7 | X-KDE-Library=org.kde.kdecoration2/breezedecoration 8 | X-KDE-PluginKeyword=kcmodule 9 | X-KDE-ParentApp=kcontrol 10 | X-KDE-Weight=60 11 | 12 | Name=Breeze Window Decoration 13 | Name[ca]=Decoració de les finestres Brisa 14 | Name[ca@valencia]=Decoració de les finestres Brisa 15 | Name[cs]=Dekorace oken Breeze 16 | Name[da]=Breeze vinduesdekoration 17 | Name[de]=Breeze-Fensterdekoration 18 | Name[el]=Διακοσμήσεις παραθύρου Breeze 19 | Name[en_GB]=Breeze Window Decoration 20 | Name[es]=Decoración de ventanas Brisa 21 | Name[eu]=Breeze leihoen apaindura 22 | Name[fi]=Breeze-ikkunankehys 23 | Name[fr]=Décoration de fenêtre Brise 24 | Name[gl]=Decoración de xanela de Breeze 25 | Name[hu]=Breeze ablakdekoráció 26 | Name[ia]=Decoration de fenestra Breeze 27 | Name[id]=Dekorasi Jendela Breeze 28 | Name[it]=Decorazione delle finestre di Brezza 29 | Name[ko]=Breeze 창 장식 30 | Name[nl]=Breeze vensterdecoratie 31 | Name[nn]=Breeze-vindaugsdekorasjon 32 | Name[pl]=Wygląd okien Bryzy 33 | Name[pt]=Decoração de Janelas Brisa 34 | Name[pt_BR]=Decorações da janela Breeze 35 | Name[ru]=Оформление окон Breeze 36 | Name[sk]=Dekorácie okien Breeze 37 | Name[sl]=Okraski oken Sapica 38 | Name[sr]=Поветарчева декорација прозора 39 | Name[sr@ijekavian]=Поветарчева декорација прозора 40 | Name[sr@ijekavianlatin]=Povetarčeva dekoracija prozora 41 | Name[sr@latin]=Povetarčeva dekoracija prozora 42 | Name[sv]=Breeze fönsterdekoration 43 | Name[tr]=Breeze Pencere Dekorasyonu 44 | Name[uk]=Декорації вікон Breeze 45 | Name[x-test]=xxBreeze Window Decorationxx 46 | Name[zh_CN]=微风窗口装饰 47 | Name[zh_TW]=Breeze 視窗裝飾 48 | Comment=Modify the appearance of window decorations 49 | Comment[ar]=عدّل مظهر زخرفات النّوافذ 50 | Comment[ca]=Modifica l'aparença de les decoracions de les finestres 51 | Comment[ca@valencia]=Modifica l'aparença de les decoracions de les finestres 52 | Comment[cs]=Změnit vzhled dekorace oken 53 | Comment[da]=Ændr vinduesdekorationers udseende 54 | Comment[de]=Das Erscheinungsbild der Fensterdekorationen ändern 55 | Comment[el]=Τροποποίηση εμφάνισης της διακόσμησης παραθύρου 56 | Comment[en_GB]=Modify the appearance of window decorations 57 | Comment[es]=Modificar el aspecto de las decoraciones de las ventanas 58 | Comment[et]=Akna dekoratsioonide välimuse muutmine 59 | Comment[eu]=Aldatu leiho apainduren itxura 60 | Comment[fi]=Muuta ikkunoiden kehysten ulkoasua 61 | Comment[fr]=Modifier l'apparence des décorations des fenêtres 62 | Comment[gl]=Modifica a aparencia da decoración da xanela 63 | Comment[he]=התאם את מראה מסגרות החלונות 64 | Comment[hu]=Az ablakdekorációk megjelenésének módosítása 65 | Comment[ia]=Modifica le apparentia de decorationes de fenestra 66 | Comment[id]=Memodofikasi penampilan dekorasi jendela 67 | Comment[it]=Modifica l'aspetto delle decorazioni delle finestre 68 | Comment[ko]=창 장식의 모습을 수정합니다 69 | Comment[lt]=Keisti lango dekoracijų išvaizdą 70 | Comment[nb]=Endre utseende for vindusdekorasjoner 71 | Comment[nl]=Wijzig het uiterlijk van vensterdecoraties 72 | Comment[nn]=Endra utsjånad på vindaugspynt 73 | Comment[pl]=Zmień wygląd i wystrój okien 74 | Comment[pt]=Modificar a aparência das decorações das janelas 75 | Comment[pt_BR]=Modifica a aparência das decorações da janela 76 | Comment[ro]=Modifică aspectul decorațiilor pentru ferestre 77 | Comment[ru]=Настройка заголовков окон в стиле Breeze 78 | Comment[sk]=Zmena vzhľadu dekorácie okien 79 | Comment[sl]=Spremenite videz okraskov oken 80 | Comment[sr]=Измените изглед декорација прозора 81 | Comment[sr@ijekavian]=Измијените изглед декорација прозора 82 | Comment[sr@ijekavianlatin]=Izmijenite izgled dekoracija prozora 83 | Comment[sr@latin]=Izmenite izgled dekoracija prozora 84 | Comment[sv]=Ändra utseendet hos fönsterdekorationer 85 | Comment[tr]=Pencere dekorasyonlarının görünümünü değiştir 86 | Comment[uk]=Зміна вигляду декорацій вікон 87 | Comment[x-test]=xxModify the appearance of window decorationsxx 88 | Comment[zh_CN]=修改窗口装饰外观 89 | Comment[zh_TW]=變更視窗裝飾外觀 90 | X-KDE-Keywords=breeze,decoration 91 | X-KDE-Keywords[ar]=نسيم,زخرفة 92 | X-KDE-Keywords[ca]=breeze,brisa,decoració 93 | X-KDE-Keywords[ca@valencia]=breeze,brisa,decoració 94 | X-KDE-Keywords[cs]=breeze,dekorace 95 | X-KDE-Keywords[da]=breeze,dekoration 96 | X-KDE-Keywords[de]=Breeze-Dekoration 97 | X-KDE-Keywords[el]=breeze,διακόσμηση 98 | X-KDE-Keywords[en_GB]=breeze,decoration 99 | X-KDE-Keywords[es]=breeze,brisa,decoración 100 | X-KDE-Keywords[et]=breeze,dekoratsioon 101 | X-KDE-Keywords[eu]=breeze,apainketa,apaindura 102 | X-KDE-Keywords[fi]=breeze,decoration,kehys,koriste,koristus,ikkunakehys 103 | X-KDE-Keywords[fr]=breeze,décoration 104 | X-KDE-Keywords[gl]=breeze,decoración 105 | X-KDE-Keywords[he]=breeze,decoration,מסגרת 106 | X-KDE-Keywords[hu]=breeze,dekoráció 107 | X-KDE-Keywords[ia]=breeze,decoration 108 | X-KDE-Keywords[id]=breeze,dekorasi 109 | X-KDE-Keywords[it]=brezza,decorazione 110 | X-KDE-Keywords[ko]=breeze,decoration,장식 111 | X-KDE-Keywords[lt]=breeze,kekoracija 112 | X-KDE-Keywords[nb]=beeze,dekorasjon 113 | X-KDE-Keywords[nl]=breeze,decoratie 114 | X-KDE-Keywords[nn]=breeze,dekorasjonar,pynt 115 | X-KDE-Keywords[pl]=breeze,dekoracja,bryza,wystrój 116 | X-KDE-Keywords[pt]=brisa,decoração 117 | X-KDE-Keywords[pt_BR]=breeze,decoração 118 | X-KDE-Keywords[ro]=briză,breeze,decorare,decorație 119 | X-KDE-Keywords[ru]=breeze,бриз,decoration,декорации окон,оформление окон 120 | X-KDE-Keywords[sk]=breeze,dekorácia 121 | X-KDE-Keywords[sl]=sapica,okraski 122 | X-KDE-Keywords[sr]=breeze,decoration,Поветарац,декорација 123 | X-KDE-Keywords[sr@ijekavian]=breeze,decoration,Поветарац,декорација 124 | X-KDE-Keywords[sr@ijekavianlatin]=breeze,decoration,Povetarac,dekoracija 125 | X-KDE-Keywords[sr@latin]=breeze,decoration,Povetarac,dekoracija 126 | X-KDE-Keywords[sv]=breeze,dekoration 127 | X-KDE-Keywords[tr]=esinti,dekorasyon 128 | X-KDE-Keywords[uk]=breeze,decoration,бриз,декорації,декорація,обрамлення 129 | X-KDE-Keywords[x-test]=xxbreezexx,xxdecorationxx 130 | X-KDE-Keywords[zh_CN]=breeze,decoration,微风,装饰 131 | X-KDE-Keywords[zh_TW]=breeze,decoration 132 | -------------------------------------------------------------------------------- /config/breezedetectwidget.cpp: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////////// 3 | // breezedetectwidget.cpp 4 | // Note: this class is a stripped down version of 5 | // /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.cpp 6 | // Copyright (c) 2004 Lubos Lunak 7 | // ------------------- 8 | // 9 | // Copyright (c) 2009 Hugo Pereira Da Costa 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to 13 | // deal in the Software without restriction, including without limitation the 14 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 15 | // sell copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 27 | // IN THE SOFTWARE. 28 | ////////////////////////////////////////////////////////////////////////////// 29 | 30 | #include "breezedetectwidget.h" 31 | 32 | #include "breeze.h" 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #if BREEZE_HAVE_X11 40 | #include 41 | #include 42 | #endif 43 | 44 | namespace Breeze 45 | { 46 | 47 | //_________________________________________________________ 48 | DetectDialog::DetectDialog( QWidget* parent ): 49 | QDialog( parent ) 50 | { 51 | 52 | // setup 53 | m_ui.setupUi( this ); 54 | 55 | connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) ); 56 | m_ui.windowClassCheckBox->setChecked( true ); 57 | 58 | #if BREEZE_HAVE_X11 59 | if (QX11Info::isPlatformX11()) { 60 | // create atom 61 | xcb_connection_t* connection( QX11Info::connection() ); 62 | const QString atomName( QStringLiteral( "WM_STATE" ) ); 63 | xcb_intern_atom_cookie_t cookie( xcb_intern_atom( connection, false, atomName.size(), qPrintable( atomName ) ) ); 64 | QScopedPointer reply( xcb_intern_atom_reply( connection, cookie, nullptr) ); 65 | m_wmStateAtom = reply ? reply->atom : 0; 66 | } 67 | #endif 68 | 69 | } 70 | 71 | //_________________________________________________________ 72 | void DetectDialog::detect( WId window ) 73 | { 74 | if( window == 0 ) selectWindow(); 75 | else readWindow( window ); 76 | } 77 | 78 | //_________________________________________________________ 79 | void DetectDialog::readWindow( WId window ) 80 | { 81 | 82 | if( window == 0 ) 83 | { 84 | emit detectionDone( false ); 85 | return; 86 | } 87 | 88 | m_info.reset(new KWindowInfo( window, NET::WMAllProperties, NET::WM2AllProperties )); 89 | if( !m_info->valid()) 90 | { 91 | emit detectionDone( false ); 92 | return; 93 | } 94 | 95 | const QString wmClassClass( QString::fromUtf8( m_info->windowClassClass() ) ); 96 | const QString wmClassName( QString::fromUtf8( m_info->windowClassName() ) ); 97 | 98 | m_ui.windowClass->setText( QStringLiteral( "%1 (%2 %3)" ).arg( wmClassClass ).arg( wmClassName ).arg( wmClassClass ) ); 99 | m_ui.windowTitle->setText( m_info->name() ); 100 | emit detectionDone( exec() == QDialog::Accepted ); 101 | 102 | } 103 | 104 | //_________________________________________________________ 105 | void DetectDialog::selectWindow() 106 | { 107 | 108 | // use a dialog, so that all user input is blocked 109 | // use WX11BypassWM and moving away so that it's not actually visible 110 | // grab only mouse, so that keyboard can be used e.g. for switching windows 111 | m_grabber = new QDialog( nullptr, Qt::X11BypassWindowManagerHint ); 112 | m_grabber->move( -1000, -1000 ); 113 | m_grabber->setModal( true ); 114 | m_grabber->show(); 115 | 116 | // need to explicitly override cursor for Qt5 117 | qApp->setOverrideCursor( Qt::CrossCursor ); 118 | m_grabber->grabMouse( Qt::CrossCursor ); 119 | m_grabber->installEventFilter( this ); 120 | 121 | } 122 | 123 | //_________________________________________________________ 124 | bool DetectDialog::eventFilter( QObject* o, QEvent* e ) 125 | { 126 | // check object and event type 127 | if( o != m_grabber ) return false; 128 | if( e->type() != QEvent::MouseButtonRelease ) return false; 129 | 130 | // need to explicitely release cursor for Qt5 131 | qApp->restoreOverrideCursor(); 132 | 133 | // delete old m_grabber 134 | delete m_grabber; 135 | m_grabber = nullptr; 136 | 137 | // check button 138 | if( static_cast< QMouseEvent* >( e )->button() != Qt::LeftButton ) return true; 139 | 140 | // read window information 141 | readWindow( findWindow() ); 142 | 143 | return true; 144 | } 145 | 146 | //_________________________________________________________ 147 | WId DetectDialog::findWindow() 148 | { 149 | 150 | #if BREEZE_HAVE_X11 151 | if (!QX11Info::isPlatformX11()) { 152 | return 0; 153 | } 154 | // check atom 155 | if( !m_wmStateAtom ) return 0; 156 | 157 | xcb_connection_t* connection( QX11Info::connection() ); 158 | xcb_window_t parent( QX11Info::appRootWindow() ); 159 | 160 | // why is there a loop of only 10 here 161 | for( int i = 0; i < 10; ++i ) 162 | { 163 | 164 | // query pointer 165 | xcb_query_pointer_cookie_t pointerCookie( xcb_query_pointer( connection, parent ) ); 166 | QScopedPointer pointerReply( xcb_query_pointer_reply( connection, pointerCookie, nullptr ) ); 167 | if( !( pointerReply && pointerReply->child ) ) return 0; 168 | 169 | const xcb_window_t child( pointerReply->child ); 170 | xcb_get_property_cookie_t cookie( xcb_get_property( connection, 0, child, m_wmStateAtom, XCB_GET_PROPERTY_TYPE_ANY, 0, 0 ) ); 171 | QScopedPointer reply( xcb_get_property_reply( connection, cookie, nullptr ) ); 172 | if( reply && reply->type ) return child; 173 | else parent = child; 174 | 175 | } 176 | #endif 177 | 178 | return 0; 179 | 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /config/breezedetectwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef breezedetectwidget_h 2 | #define breezedetectwidget_h 3 | 4 | ////////////////////////////////////////////////////////////////////////////// 5 | // breezedetectwidget.h 6 | // Note: this class is a stripped down version of 7 | // /kdebase/workspace/kwin/kcmkwin/kwinrules/detectwidget.h 8 | // Copyright (c) 2004 Lubos Lunak 9 | 10 | // ------------------- 11 | // 12 | // Copyright (c) 2009 Hugo Pereira Da Costa 13 | // 14 | // Permission is hereby granted, free of charge, to any person obtaining a copy 15 | // of this software and associated documentation files (the "Software"), to 16 | // deal in the Software without restriction, including without limitation the 17 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 18 | // sell copies of the Software, and to permit persons to whom the Software is 19 | // furnished to do so, subject to the following conditions: 20 | // 21 | // The above copyright notice and this permission notice shall be included in 22 | // all copies or substantial portions of the Software. 23 | // 24 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 29 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 30 | // IN THE SOFTWARE. 31 | ////////////////////////////////////////////////////////////////////////////// 32 | 33 | #include "breezesettings.h" 34 | #include "ui_breezedetectwidget.h" 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | 44 | namespace Breeze 45 | { 46 | 47 | class DetectDialog : public QDialog 48 | { 49 | 50 | Q_OBJECT 51 | 52 | public: 53 | 54 | //* constructor 55 | explicit DetectDialog( QWidget* ); 56 | 57 | //* read window properties or select one from mouse grab 58 | void detect( WId window ); 59 | 60 | //* selected class 61 | QByteArray selectedClass() const; 62 | 63 | //* window information 64 | const KWindowInfo& windowInfo() const 65 | { return *(m_info.data()); } 66 | 67 | //* exception type 68 | InternalSettings::EnumExceptionType exceptionType() const 69 | { 70 | if( m_ui.windowClassCheckBox->isChecked() ) return InternalSettings::ExceptionWindowClassName; 71 | else if( m_ui.windowTitleCheckBox->isChecked() ) return InternalSettings::ExceptionWindowTitle; 72 | else return InternalSettings::ExceptionWindowClassName; 73 | } 74 | 75 | Q_SIGNALS: 76 | 77 | void detectionDone( bool ); 78 | 79 | protected: 80 | 81 | bool eventFilter( QObject* o, QEvent* e ) override; 82 | 83 | private: 84 | 85 | //* select window from grab 86 | void selectWindow(); 87 | 88 | //* read window properties 89 | void readWindow( WId window ); 90 | 91 | //* find window under cursor 92 | WId findWindow(); 93 | 94 | //* execute 95 | void executeDialog(); 96 | 97 | //* ui 98 | Ui::BreezeDetectWidget m_ui; 99 | 100 | //* invisible dialog used to grab mouse 101 | QDialog* m_grabber = nullptr; 102 | 103 | //* current window information 104 | QScopedPointer m_info; 105 | 106 | //* wm state atom 107 | quint32 m_wmStateAtom = 0; 108 | 109 | }; 110 | 111 | } // namespace 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /config/breezeexceptiondialog.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // breezeexceptiondialog.cpp 3 | // ------------------- 4 | // 5 | // Copyright (c) 2009 Hugo Pereira Da Costa 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to 9 | // deal in the Software without restriction, including without limitation the 10 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | // sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | // IN THE SOFTWARE. 24 | ////////////////////////////////////////////////////////////////////////////// 25 | 26 | #include "breezeexceptiondialog.h" 27 | #include "breezedetectwidget.h" 28 | #include "config-breeze.h" 29 | 30 | #if BREEZE_HAVE_X11 31 | #include 32 | #endif 33 | 34 | namespace Breeze 35 | { 36 | 37 | //___________________________________________ 38 | ExceptionDialog::ExceptionDialog( QWidget* parent ): 39 | QDialog( parent ) 40 | { 41 | 42 | m_ui.setupUi( this ); 43 | 44 | connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), SIGNAL(clicked()), this, SLOT(close()) ); 45 | 46 | // store checkboxes from ui into list 47 | m_checkboxes.insert( BorderSize, m_ui.borderSizeCheckBox ); 48 | 49 | // detect window properties 50 | connect( m_ui.detectDialogButton, SIGNAL(clicked()), SLOT(selectWindowProperties()) ); 51 | 52 | // connections 53 | connect( m_ui.exceptionType, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 54 | connect( m_ui.exceptionEditor, SIGNAL(textChanged(QString)), SLOT(updateChanged()) ); 55 | connect( m_ui.borderSizeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 56 | 57 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 58 | { connect( iter.value(), SIGNAL(clicked()), SLOT(updateChanged()) ); } 59 | 60 | connect( m_ui.hideTitleBar, SIGNAL(clicked()), SLOT(updateChanged()) ); 61 | connect( m_ui.opaqueTitleBar, SIGNAL(clicked()), SLOT(updateChanged()) ); 62 | m_ui.opacityOverrideLabelSpinBox->setSpecialValueText(tr("None")); 63 | connect( m_ui.opacityOverrideLabelSpinBox, QOverload::of(&QSpinBox::valueChanged), [=](int /*i*/){updateChanged();} ); 64 | connect( m_ui.isDialog, SIGNAL(clicked()), SLOT(updateChanged()) ); 65 | 66 | // hide detection dialog on non X11 platforms 67 | #if BREEZE_HAVE_X11 68 | if( !QX11Info::isPlatformX11() ) m_ui.detectDialogButton->hide(); 69 | #else 70 | m_ui.detectDialogButton->hide(); 71 | #endif 72 | } 73 | 74 | //___________________________________________ 75 | void ExceptionDialog::setException( InternalSettingsPtr exception ) 76 | { 77 | 78 | // store exception internally 79 | m_exception = exception; 80 | 81 | // type 82 | m_ui.exceptionType->setCurrentIndex(m_exception->exceptionType() ); 83 | m_ui.exceptionEditor->setText( m_exception->exceptionPattern() ); 84 | m_ui.borderSizeComboBox->setCurrentIndex( m_exception->borderSize() ); 85 | m_ui.hideTitleBar->setChecked( m_exception->hideTitleBar() ); 86 | m_ui.opaqueTitleBar->setChecked( m_exception->opaqueTitleBar() ); 87 | m_ui.opacityOverrideLabelSpinBox->setValue( m_exception->opacityOverride() ); 88 | m_ui.isDialog->setChecked( m_exception->isDialog() ); 89 | 90 | // mask 91 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 92 | { iter.value()->setChecked( m_exception->mask() & iter.key() ); } 93 | 94 | setChanged( false ); 95 | 96 | } 97 | 98 | //___________________________________________ 99 | void ExceptionDialog::save() 100 | { 101 | m_exception->setExceptionType( m_ui.exceptionType->currentIndex() ); 102 | m_exception->setExceptionPattern( m_ui.exceptionEditor->text() ); 103 | m_exception->setBorderSize( m_ui.borderSizeComboBox->currentIndex() ); 104 | m_exception->setHideTitleBar( m_ui.hideTitleBar->isChecked() ); 105 | m_exception->setOpaqueTitleBar( m_ui.opaqueTitleBar->isChecked() ); 106 | m_exception->setOpacityOverride( m_ui.opacityOverrideLabelSpinBox->value() ); 107 | m_exception->setIsDialog( m_ui.isDialog->isChecked() ); 108 | 109 | // mask 110 | unsigned int mask = None; 111 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 112 | { if( iter.value()->isChecked() ) mask |= iter.key(); } 113 | 114 | m_exception->setMask( mask ); 115 | 116 | setChanged( false ); 117 | 118 | } 119 | 120 | //___________________________________________ 121 | void ExceptionDialog::updateChanged() 122 | { 123 | bool modified( false ); 124 | if( m_exception->exceptionType() != m_ui.exceptionType->currentIndex() ) modified = true; 125 | else if( m_exception->exceptionPattern() != m_ui.exceptionEditor->text() ) modified = true; 126 | else if( m_exception->borderSize() != m_ui.borderSizeComboBox->currentIndex() ) modified = true; 127 | else if( m_exception->hideTitleBar() != m_ui.hideTitleBar->isChecked() ) modified = true; 128 | else if( m_exception->opaqueTitleBar() != m_ui.opaqueTitleBar->isChecked() ) modified = true; 129 | else if( m_exception->opacityOverride() != m_ui.opacityOverrideLabelSpinBox->value() ) modified = true; 130 | else if( m_exception->isDialog() != m_ui.isDialog->isChecked() ) modified = true; 131 | else 132 | { 133 | // check mask 134 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 135 | { 136 | if( iter.value()->isChecked() != (bool)( m_exception->mask() & iter.key() ) ) 137 | { 138 | modified = true; 139 | break; 140 | } 141 | } 142 | } 143 | 144 | setChanged( modified ); 145 | 146 | } 147 | 148 | //___________________________________________ 149 | void ExceptionDialog::selectWindowProperties() 150 | { 151 | 152 | // create widget 153 | if( !m_detectDialog ) 154 | { 155 | m_detectDialog = new DetectDialog( this ); 156 | connect( m_detectDialog, SIGNAL(detectionDone(bool)), SLOT(readWindowProperties(bool)) ); 157 | } 158 | 159 | m_detectDialog->detect(0); 160 | 161 | } 162 | 163 | //___________________________________________ 164 | void ExceptionDialog::readWindowProperties( bool valid ) 165 | { 166 | Q_CHECK_PTR( m_detectDialog ); 167 | if( valid ) 168 | { 169 | 170 | // type 171 | m_ui.exceptionType->setCurrentIndex( m_detectDialog->exceptionType() ); 172 | 173 | // window info 174 | const KWindowInfo& info( m_detectDialog->windowInfo() ); 175 | 176 | switch( m_detectDialog->exceptionType() ) 177 | { 178 | 179 | default: 180 | case InternalSettings::ExceptionWindowClassName: 181 | m_ui.exceptionEditor->setText( QString::fromUtf8( info.windowClassClass() ) ); 182 | break; 183 | 184 | case InternalSettings::ExceptionWindowTitle: 185 | m_ui.exceptionEditor->setText( info.name() ); 186 | break; 187 | 188 | } 189 | 190 | } 191 | 192 | delete m_detectDialog; 193 | m_detectDialog = nullptr; 194 | 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /config/breezeexceptiondialog.h: -------------------------------------------------------------------------------- 1 | #ifndef breezeexceptiondialog_h 2 | #define breezeexceptiondialog_h 3 | ////////////////////////////////////////////////////////////////////////////// 4 | // breezeexceptiondialog.h 5 | // ------------------- 6 | // 7 | // Copyright (c) 2009 Hugo Pereira Da Costa 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to 11 | // deal in the Software without restriction, including without limitation the 12 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | // sell copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 | // IN THE SOFTWARE. 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | #include "ui_breezeexceptiondialog.h" 29 | #include "breeze.h" 30 | 31 | #include 32 | #include 33 | 34 | namespace Breeze 35 | { 36 | 37 | class DetectDialog; 38 | 39 | //* breeze exceptions list 40 | class ExceptionDialog: public QDialog 41 | { 42 | 43 | Q_OBJECT 44 | 45 | public: 46 | 47 | //* constructor 48 | explicit ExceptionDialog( QWidget* parent ); 49 | 50 | //* destructor 51 | virtual ~ExceptionDialog() 52 | {} 53 | 54 | //* set exception 55 | void setException( InternalSettingsPtr ); 56 | 57 | //* save exception 58 | void save(); 59 | 60 | //* true if changed 61 | virtual bool isChanged() const 62 | { return m_changed; } 63 | 64 | Q_SIGNALS: 65 | 66 | //* emmited when changed 67 | void changed( bool ); 68 | 69 | protected: 70 | 71 | //* set changed state 72 | virtual void setChanged( bool value ) 73 | { 74 | m_changed = value; 75 | emit changed( value ); 76 | } 77 | 78 | protected Q_SLOTS: 79 | 80 | //* check whether configuration is changed and emit appropriate signal if yes 81 | virtual void updateChanged(); 82 | 83 | private Q_SLOTS: 84 | 85 | //* select window properties from grabbed pointers 86 | void selectWindowProperties(); 87 | 88 | //* read properties of selected window 89 | void readWindowProperties( bool ); 90 | 91 | private: 92 | 93 | //* map mask and checkbox 94 | using CheckBoxMap=QMap< ExceptionMask, QCheckBox*>; 95 | 96 | Ui::BreezeExceptionDialog m_ui; 97 | 98 | //* map mask and checkbox 99 | CheckBoxMap m_checkboxes; 100 | 101 | //* internal exception 102 | InternalSettingsPtr m_exception; 103 | 104 | //* detection dialog 105 | DetectDialog* m_detectDialog = nullptr; 106 | 107 | //* changed state 108 | bool m_changed = false; 109 | 110 | }; 111 | 112 | } 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /config/breezeexceptionlistwidget.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // breezeexceptionlistwidget.cpp 3 | // ------------------- 4 | // 5 | // Copyright (c) 2009 Hugo Pereira Da Costa 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to 9 | // deal in the Software without restriction, including without limitation the 10 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | // sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | // IN THE SOFTWARE. 24 | ////////////////////////////////////////////////////////////////////////////// 25 | 26 | #include "breezeexceptionlistwidget.h" 27 | #include "breezeexceptiondialog.h" 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | //__________________________________________________________ 36 | namespace Breeze 37 | { 38 | 39 | //__________________________________________________________ 40 | ExceptionListWidget::ExceptionListWidget( QWidget* parent ): 41 | QWidget( parent ) 42 | { 43 | 44 | // ui 45 | m_ui.setupUi( this ); 46 | 47 | // list 48 | m_ui.exceptionListView->setAllColumnsShowFocus( true ); 49 | m_ui.exceptionListView->setRootIsDecorated( false ); 50 | m_ui.exceptionListView->setSortingEnabled( false ); 51 | m_ui.exceptionListView->setModel( &model() ); 52 | m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType ); 53 | m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) ); 54 | 55 | m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) ); 56 | m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) ); 57 | m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) ); 58 | m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) ); 59 | m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) ); 60 | 61 | connect( m_ui.addButton, SIGNAL(clicked()), SLOT(add()) ); 62 | connect( m_ui.editButton, SIGNAL(clicked()), SLOT(edit()) ); 63 | connect( m_ui.removeButton, SIGNAL(clicked()), SLOT(remove()) ); 64 | connect( m_ui.moveUpButton, SIGNAL(clicked()), SLOT(up()) ); 65 | connect( m_ui.moveDownButton, SIGNAL(clicked()), SLOT(down()) ); 66 | 67 | connect( m_ui.exceptionListView, SIGNAL(activated(QModelIndex)), SLOT(edit()) ); 68 | connect( m_ui.exceptionListView, SIGNAL(clicked(QModelIndex)), SLOT(toggle(QModelIndex)) ); 69 | connect( m_ui.exceptionListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateButtons()) ); 70 | 71 | updateButtons(); 72 | resizeColumns(); 73 | 74 | 75 | } 76 | 77 | //__________________________________________________________ 78 | void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions ) 79 | { 80 | model().set( exceptions ); 81 | resizeColumns(); 82 | setChanged( false ); 83 | } 84 | 85 | //__________________________________________________________ 86 | InternalSettingsList ExceptionListWidget::exceptions() 87 | { 88 | return model().get(); 89 | setChanged( false ); 90 | } 91 | 92 | //__________________________________________________________ 93 | void ExceptionListWidget::updateButtons() 94 | { 95 | 96 | bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() ); 97 | m_ui.removeButton->setEnabled( hasSelection ); 98 | m_ui.editButton->setEnabled( hasSelection ); 99 | 100 | m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) ); 101 | m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) ); 102 | 103 | } 104 | 105 | 106 | //_______________________________________________________ 107 | void ExceptionListWidget::add() 108 | { 109 | 110 | 111 | QPointer dialog = new ExceptionDialog( this ); 112 | dialog->setWindowTitle( i18n( "New Exception - Breeze Settings" ) ); 113 | InternalSettingsPtr exception( new InternalSettings() ); 114 | 115 | exception->load(); 116 | 117 | dialog->setException( exception ); 118 | 119 | // run dialog and check existence 120 | if( !dialog->exec() ) 121 | { 122 | delete dialog; 123 | return; 124 | } 125 | 126 | dialog->save(); 127 | delete dialog; 128 | 129 | // check exceptions 130 | if( !checkException( exception ) ) return; 131 | 132 | // create new item 133 | model().add( exception ); 134 | setChanged( true ); 135 | 136 | // make sure item is selected 137 | QModelIndex index( model().index( exception ) ); 138 | if( index != m_ui.exceptionListView->selectionModel()->currentIndex() ) 139 | { 140 | m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 141 | m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows ); 142 | } 143 | 144 | resizeColumns(); 145 | 146 | } 147 | 148 | //_______________________________________________________ 149 | void ExceptionListWidget::edit() 150 | { 151 | 152 | // retrieve selection 153 | QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() ); 154 | if( ! model().contains( current ) ) return; 155 | 156 | InternalSettingsPtr exception( model().get( current ) ); 157 | 158 | // create dialog 159 | QPointer dialog( new ExceptionDialog( this ) ); 160 | dialog->setWindowTitle( i18n( "Edit Exception - Breeze Settings" ) ); 161 | dialog->setException( exception ); 162 | 163 | // map dialog 164 | if( !dialog->exec() ) 165 | { 166 | delete dialog; 167 | return; 168 | } 169 | 170 | // check modifications 171 | if( !dialog->isChanged() ) return; 172 | 173 | // retrieve exception 174 | dialog->save(); 175 | delete dialog; 176 | 177 | // check new exception validity 178 | checkException( exception ); 179 | resizeColumns(); 180 | 181 | setChanged( true ); 182 | 183 | } 184 | 185 | //_______________________________________________________ 186 | void ExceptionListWidget::remove() 187 | { 188 | 189 | // confirmation dialog 190 | { 191 | QMessageBox messageBox( QMessageBox::Question, i18n("Question - Breeze Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel ); 192 | messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") ); 193 | messageBox.setDefaultButton( QMessageBox::Cancel ); 194 | if( messageBox.exec() == QMessageBox::Cancel ) return; 195 | } 196 | 197 | // remove 198 | model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 199 | resizeColumns(); 200 | updateButtons(); 201 | 202 | setChanged( true ); 203 | 204 | } 205 | 206 | //_______________________________________________________ 207 | void ExceptionListWidget::toggle( const QModelIndex& index ) 208 | { 209 | 210 | if( !model().contains( index ) ) return; 211 | if( index.column() != ExceptionModel::ColumnEnabled ) return; 212 | 213 | // get matching exception 214 | InternalSettingsPtr exception( model().get( index ) ); 215 | exception->setEnabled( !exception->enabled() ); 216 | setChanged( true ); 217 | 218 | } 219 | 220 | //_______________________________________________________ 221 | void ExceptionListWidget::up() 222 | { 223 | 224 | InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 225 | if( selection.empty() ) { return; } 226 | 227 | // retrieve selected indexes in list and store in model 228 | QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() ); 229 | InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); 230 | 231 | InternalSettingsList currentException( model().get() ); 232 | InternalSettingsList newExceptions; 233 | 234 | for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter ) 235 | { 236 | 237 | // check if new list is not empty, current index is selected and last index is not. 238 | // if yes, move. 239 | if( 240 | !( newExceptions.empty() || 241 | selectedIndices.indexOf( model().index( *iter ) ) == -1 || 242 | selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1 243 | ) ) 244 | { 245 | InternalSettingsPtr last( newExceptions.back() ); 246 | newExceptions.removeLast(); 247 | newExceptions.append( *iter ); 248 | newExceptions.append( last ); 249 | } else newExceptions.append( *iter ); 250 | 251 | } 252 | 253 | model().set( newExceptions ); 254 | 255 | // restore selection 256 | m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 257 | for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) 258 | { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } 259 | 260 | setChanged( true ); 261 | 262 | } 263 | 264 | //_______________________________________________________ 265 | void ExceptionListWidget::down() 266 | { 267 | 268 | InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 269 | if( selection.empty() ) 270 | { return; } 271 | 272 | // retrieve selected indexes in list and store in model 273 | QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() ); 274 | InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); 275 | 276 | InternalSettingsList currentExceptions( model().get() ); 277 | InternalSettingsList newExceptions; 278 | 279 | InternalSettingsListIterator iter( currentExceptions ); 280 | iter.toBack(); 281 | while( iter.hasPrevious() ) 282 | { 283 | 284 | InternalSettingsPtr current( iter.previous() ); 285 | 286 | // check if new list is not empty, current index is selected and last index is not. 287 | // if yes, move. 288 | if( 289 | !( newExceptions.empty() || 290 | selectedIndices.indexOf( model().index( current ) ) == -1 || 291 | selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1 292 | ) ) 293 | { 294 | 295 | InternalSettingsPtr first( newExceptions.front() ); 296 | newExceptions.removeFirst(); 297 | newExceptions.prepend( current ); 298 | newExceptions.prepend( first ); 299 | 300 | } else newExceptions.prepend( current ); 301 | } 302 | 303 | model().set( newExceptions ); 304 | 305 | // restore selection 306 | m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 307 | for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) 308 | { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } 309 | 310 | setChanged( true ); 311 | 312 | } 313 | 314 | //_______________________________________________________ 315 | void ExceptionListWidget::resizeColumns() const 316 | { 317 | m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled ); 318 | m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType ); 319 | m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp ); 320 | } 321 | 322 | //_______________________________________________________ 323 | bool ExceptionListWidget::checkException( InternalSettingsPtr exception ) 324 | { 325 | 326 | while( exception->exceptionPattern().isEmpty() || !QRegExp( exception->exceptionPattern() ).isValid() ) 327 | { 328 | 329 | QMessageBox::warning( this, i18n( "Warning - Breeze Settings" ), i18n("Regular Expression syntax is incorrect") ); 330 | QPointer dialog( new ExceptionDialog( this ) ); 331 | dialog->setException( exception ); 332 | if( dialog->exec() == QDialog::Rejected ) 333 | { 334 | delete dialog; 335 | return false; 336 | } 337 | 338 | dialog->save(); 339 | delete dialog; 340 | } 341 | 342 | return true; 343 | } 344 | 345 | } 346 | -------------------------------------------------------------------------------- /config/breezeexceptionlistwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef breezeexceptionlistwidget_h 2 | #define breezeexceptionlistwidget_h 3 | ////////////////////////////////////////////////////////////////////////////// 4 | // breezeexceptionlistwidget.h 5 | // ------------------- 6 | // 7 | // Copyright (c) 2009 Hugo Pereira Da Costa 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to 11 | // deal in the Software without restriction, including without limitation the 12 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | // sell copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 | // IN THE SOFTWARE. 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | #include "ui_breezeexceptionlistwidget.h" 29 | #include "breezeexceptionmodel.h" 30 | 31 | //* QDialog used to commit selected files 32 | namespace Breeze 33 | { 34 | 35 | class ExceptionListWidget: public QWidget 36 | { 37 | 38 | //* Qt meta object 39 | Q_OBJECT 40 | 41 | public: 42 | 43 | //* constructor 44 | explicit ExceptionListWidget( QWidget* = nullptr ); 45 | 46 | //* set exceptions 47 | void setExceptions( const InternalSettingsList& ); 48 | 49 | //* get exceptions 50 | InternalSettingsList exceptions(); 51 | 52 | //* true if changed 53 | virtual bool isChanged() const 54 | { return m_changed; } 55 | 56 | Q_SIGNALS: 57 | 58 | //* emitted when changed 59 | void changed( bool ); 60 | 61 | protected: 62 | 63 | //* model 64 | const ExceptionModel& model() const 65 | { return m_model; } 66 | 67 | //* model 68 | ExceptionModel& model() 69 | { return m_model; } 70 | 71 | protected Q_SLOTS: 72 | 73 | //* update button states 74 | virtual void updateButtons(); 75 | 76 | //* add 77 | virtual void add(); 78 | 79 | //* edit 80 | virtual void edit(); 81 | 82 | //* remove 83 | virtual void remove(); 84 | 85 | //* toggle 86 | virtual void toggle( const QModelIndex& ); 87 | 88 | //* move up 89 | virtual void up(); 90 | 91 | //* move down 92 | virtual void down(); 93 | 94 | protected: 95 | 96 | //* resize columns 97 | void resizeColumns() const; 98 | 99 | //* check exception 100 | bool checkException( InternalSettingsPtr ); 101 | 102 | //* set changed state 103 | virtual void setChanged( bool value ) 104 | { 105 | m_changed = value; 106 | emit changed( value ); 107 | } 108 | 109 | private: 110 | 111 | //* model 112 | ExceptionModel m_model; 113 | 114 | //* ui 115 | Ui_BreezeExceptionListWidget m_ui; 116 | 117 | //* changed state 118 | bool m_changed = false; 119 | 120 | }; 121 | 122 | } 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /config/breezeexceptionmodel.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // breezeexceptionmodel.cpp 3 | // ------------------- 4 | // 5 | // Copyright (c) 2009 Hugo Pereira Da Costa 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to 9 | // deal in the Software without restriction, including without limitation the 10 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | // sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | // IN THE SOFTWARE. 24 | ////////////////////////////////////////////////////////////////////////////// 25 | 26 | #include "breezeexceptionmodel.h" 27 | 28 | #include 29 | 30 | namespace Breeze 31 | { 32 | 33 | //_______________________________________________ 34 | const QString ExceptionModel::m_columnTitles[ ExceptionModel::nColumns ] = 35 | { 36 | QStringLiteral( "" ), 37 | i18n("Exception Type"), 38 | i18n("Regular Expression") 39 | }; 40 | 41 | //__________________________________________________________________ 42 | QVariant ExceptionModel::data( const QModelIndex& index, int role ) const 43 | { 44 | 45 | // check index, role and column 46 | if( !index.isValid() ) return QVariant(); 47 | 48 | // retrieve associated file info 49 | const InternalSettingsPtr& configuration( get(index) ); 50 | 51 | // return text associated to file and column 52 | if( role == Qt::DisplayRole ) 53 | { 54 | 55 | switch( index.column() ) 56 | { 57 | case ColumnType: 58 | { 59 | switch( configuration->exceptionType() ) 60 | { 61 | 62 | case InternalSettings::ExceptionWindowTitle: 63 | return i18n( "Window Title" ); 64 | 65 | default: 66 | case InternalSettings::ExceptionWindowClassName: 67 | return i18n( "Window Class Name" ); 68 | } 69 | 70 | } 71 | 72 | case ColumnRegExp: return configuration->exceptionPattern(); 73 | default: return QVariant(); 74 | break; 75 | } 76 | 77 | } else if( role == Qt::CheckStateRole && index.column() == ColumnEnabled ) { 78 | 79 | return configuration->enabled() ? Qt::Checked : Qt::Unchecked; 80 | 81 | } else if( role == Qt::ToolTipRole && index.column() == ColumnEnabled ) { 82 | 83 | return i18n("Enable/disable this exception"); 84 | 85 | } 86 | 87 | 88 | return QVariant(); 89 | } 90 | 91 | //__________________________________________________________________ 92 | QVariant ExceptionModel::headerData(int section, Qt::Orientation orientation, int role) const 93 | { 94 | 95 | if( 96 | orientation == Qt::Horizontal && 97 | role == Qt::DisplayRole && 98 | section >= 0 && 99 | section < nColumns ) 100 | { return m_columnTitles[section]; } 101 | 102 | // return empty 103 | return QVariant(); 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /config/breezeexceptionmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef breezeexceptionmodel_h 2 | #define breezeexceptionmodel_h 3 | ////////////////////////////////////////////////////////////////////////////// 4 | // breezeexceptionmodel.h 5 | // ------------------- 6 | // 7 | // Copyright (c) 2009 Hugo Pereira Da Costa 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to 11 | // deal in the Software without restriction, including without limitation the 12 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | // sell copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 | // IN THE SOFTWARE. 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | #include "breezelistmodel.h" 29 | #include "breezesettings.h" 30 | #include "breeze.h" 31 | 32 | namespace Breeze 33 | { 34 | 35 | //* qlistview for object counters 36 | class ExceptionModel: public ListModel 37 | { 38 | 39 | public: 40 | 41 | //* number of columns 42 | enum { nColumns = 3 }; 43 | 44 | //* column type enumeration 45 | enum ColumnType { 46 | ColumnEnabled, 47 | ColumnType, 48 | ColumnRegExp 49 | }; 50 | 51 | 52 | //*@name methods reimplemented from base class 53 | //@{ 54 | 55 | //* return data for a given index 56 | QVariant data(const QModelIndex &index, int role) const override; 57 | 58 | //* header data 59 | QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 60 | 61 | //* number of columns for a given index 62 | int columnCount(const QModelIndex& ) const override 63 | { return nColumns; } 64 | 65 | //@} 66 | 67 | protected: 68 | 69 | //* sort 70 | void privateSort( int, Qt::SortOrder ) override 71 | {} 72 | 73 | private: 74 | 75 | //* column titles 76 | static const QString m_columnTitles[ nColumns ]; 77 | 78 | }; 79 | 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /config/breezeitemmodel.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // itemmodel.cpp 3 | // ------------------- 4 | // 5 | // Copyright (c) 2009-2010 Hugo Pereira Da Costa 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to 9 | // deal in the Software without restriction, including without limitation the 10 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | // sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | // IN THE SOFTWARE. 24 | ////////////////////////////////////////////////////////////////////////////// 25 | 26 | #include "breezeitemmodel.h" 27 | 28 | namespace Breeze 29 | { 30 | 31 | //_______________________________________________________________ 32 | ItemModel::ItemModel( QObject* parent ): 33 | QAbstractItemModel( parent ) 34 | {} 35 | 36 | //____________________________________________________________ 37 | void ItemModel::sort( int column, Qt::SortOrder order ) 38 | { 39 | 40 | // store column and order 41 | m_sortColumn = column; 42 | m_sortOrder = order; 43 | 44 | // emit signals and call private methods 45 | emit layoutAboutToBeChanged(); 46 | privateSort( column, order ); 47 | emit layoutChanged(); 48 | 49 | } 50 | 51 | //____________________________________________________________ 52 | QModelIndexList ItemModel::indexes( int column, const QModelIndex& parent ) const 53 | { 54 | QModelIndexList out; 55 | int rows( rowCount( parent ) ); 56 | for( int row = 0; row < rows; row++ ) 57 | { 58 | QModelIndex index( this->index( row, column, parent ) ); 59 | if( !index.isValid() ) continue; 60 | out.append( index ); 61 | out += indexes( column, index ); 62 | } 63 | 64 | return out; 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /config/breezeitemmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef ItemModel_h 2 | #define ItemModel_h 3 | 4 | ////////////////////////////////////////////////////////////////////////////// 5 | // itemmodel.h 6 | // ------------------- 7 | // 8 | // Copyright (c) 2009-2010 Hugo Pereira Da Costa 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to 12 | // deal in the Software without restriction, including without limitation the 13 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 14 | // sell copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 26 | // IN THE SOFTWARE. 27 | ////////////////////////////////////////////////////////////////////////////// 28 | 29 | #include 30 | 31 | namespace Breeze 32 | { 33 | 34 | //* Job model. Stores job information for display in lists 35 | class ItemModel : public QAbstractItemModel 36 | { 37 | 38 | public: 39 | 40 | //* constructor 41 | explicit ItemModel(QObject *parent = nullptr); 42 | 43 | //* destructor 44 | virtual ~ItemModel() 45 | {} 46 | 47 | //* return all indexes in model starting from parent [recursive] 48 | QModelIndexList indexes( int column = 0, const QModelIndex& parent = QModelIndex() ) const; 49 | 50 | //*@name sorting 51 | //@{ 52 | 53 | //* sort 54 | virtual void sort() 55 | { sort( sortColumn(), sortOrder() ); } 56 | 57 | //* sort 58 | void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override; 59 | 60 | //* current sorting column 61 | const int& sortColumn() const 62 | { return m_sortColumn; } 63 | 64 | //* current sort order 65 | const Qt::SortOrder& sortOrder() const 66 | { return m_sortOrder; } 67 | 68 | //@} 69 | 70 | protected: 71 | 72 | //* this sort columns without calling the layout changed callbacks 73 | void privateSort() 74 | { privateSort( m_sortColumn, m_sortOrder ); } 75 | 76 | //* private sort, with no signals emmitted 77 | virtual void privateSort( int column, Qt::SortOrder order ) = 0; 78 | 79 | //* used to sort items in list 80 | class SortFTor 81 | { 82 | 83 | public: 84 | 85 | //* constructor 86 | explicit SortFTor( const int& type, Qt::SortOrder order = Qt::AscendingOrder ): 87 | _type( type ), 88 | _order( order ) 89 | {} 90 | 91 | protected: 92 | 93 | //* column 94 | int _type; 95 | 96 | //* order 97 | Qt::SortOrder _order; 98 | 99 | }; 100 | 101 | private: 102 | 103 | //* sorting column 104 | int m_sortColumn = 0; 105 | 106 | //* sorting order 107 | Qt::SortOrder m_sortOrder = Qt::AscendingOrder; 108 | 109 | }; 110 | 111 | } 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /config/breezelistmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef ListModel_h 2 | #define ListModel_h 3 | ////////////////////////////////////////////////////////////////////////////// 4 | // listmodel.h 5 | // ------------------- 6 | // 7 | // Copyright (c) 2009 Hugo Pereira Da Costa 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to 11 | // deal in the Software without restriction, including without limitation the 12 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | // sell copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 | // IN THE SOFTWARE. 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | #include "breezeitemmodel.h" 29 | 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | namespace Breeze 36 | { 37 | //! Job model. Stores job information for display in lists 38 | template class ListModel : public ItemModel 39 | { 40 | 41 | public: 42 | 43 | //! value type 44 | typedef T ValueType; 45 | 46 | //! reference 47 | typedef T& Reference; 48 | 49 | //! pointer 50 | typedef T* Pointer; 51 | 52 | //! value list and iterators 53 | typedef QList List; 54 | typedef QListIterator ListIterator; 55 | typedef QMutableListIterator MutableListIterator; 56 | 57 | //! list of vector 58 | // typedef QSet Set; 59 | 60 | //! constructor 61 | ListModel(QObject *parent = nullptr): 62 | ItemModel( parent ) 63 | {} 64 | 65 | //! destructor 66 | virtual ~ListModel() 67 | {} 68 | 69 | //!@name methods reimplemented from base class 70 | //@{ 71 | 72 | //! flags 73 | Qt::ItemFlags flags(const QModelIndex &index) const override 74 | { 75 | if (!index.isValid()) return nullptr; 76 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 77 | } 78 | 79 | //! unique index for given row, column and parent index 80 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override 81 | { 82 | 83 | // check if index is valid 84 | if( !hasIndex( row, column, parent ) ) return QModelIndex(); 85 | 86 | // return invalid index if parent is valid 87 | if( parent.isValid() ) return QModelIndex(); 88 | 89 | // check against _values 90 | return ( row < (int) _values.size() ) ? createIndex( row, column ):QModelIndex(); 91 | 92 | } 93 | 94 | //! index of parent 95 | QModelIndex parent(const QModelIndex &) const override 96 | { return QModelIndex(); } 97 | 98 | //! number of rows below given index 99 | int rowCount(const QModelIndex &parent = QModelIndex()) const override 100 | { return parent.isValid() ? 0:_values.size(); } 101 | 102 | //@} 103 | 104 | //!@name selection 105 | //@{ 106 | 107 | //! clear internal list selected items 108 | virtual void clearSelectedIndexes() 109 | { _selection.clear(); } 110 | 111 | //! store index internal selection state 112 | virtual void setIndexSelected( const QModelIndex& index, bool value ) 113 | { 114 | if( value ) _selection.push_back( get(index) ); 115 | else _selection.erase( std::remove( _selection.begin(), _selection.end(), get(index) ), _selection.end() ); 116 | } 117 | 118 | //! get list of internal selected items 119 | virtual QModelIndexList selectedIndexes() const 120 | { 121 | 122 | QModelIndexList out; 123 | for( typename List::const_iterator iter = _selection.begin(); iter != _selection.end(); iter++ ) 124 | { 125 | QModelIndex index( ListModel::index( *iter ) ); 126 | if( index.isValid() ) out.push_back( index ); 127 | } 128 | return out; 129 | 130 | } 131 | 132 | //@} 133 | 134 | //!@name interface 135 | //@{ 136 | 137 | //! add value 138 | virtual void add( const ValueType& value ) 139 | { 140 | 141 | emit layoutAboutToBeChanged(); 142 | _add( value ); 143 | privateSort(); 144 | emit layoutChanged(); 145 | 146 | } 147 | 148 | //! add values 149 | virtual void add( const List& values ) 150 | { 151 | 152 | // check if not empty 153 | // this avoids sending useless signals 154 | if( values.empty() ) return; 155 | 156 | emit layoutAboutToBeChanged(); 157 | 158 | for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ ) 159 | { _add( *iter ); } 160 | 161 | privateSort(); 162 | emit layoutChanged(); 163 | 164 | } 165 | 166 | 167 | //! insert values 168 | virtual void insert( const QModelIndex& index, const ValueType& value ) 169 | { 170 | emit layoutAboutToBeChanged(); 171 | _insert( index, value ); 172 | emit layoutChanged(); 173 | } 174 | 175 | //! insert values 176 | virtual void insert( const QModelIndex& index, const List& values ) 177 | { 178 | emit layoutAboutToBeChanged(); 179 | 180 | // need to loop in reverse order so that the "values" ordering is preserved 181 | ListIterator iter( values ); 182 | iter.toBack(); 183 | while( iter.hasPrevious() ) 184 | { _insert( index, iter.previous() ); } 185 | 186 | emit layoutChanged(); 187 | 188 | } 189 | 190 | //! insert values 191 | virtual void replace( const QModelIndex& index, const ValueType& value ) 192 | { 193 | if( !index.isValid() ) add( value ); 194 | else { 195 | emit layoutAboutToBeChanged(); 196 | setIndexSelected( index, false ); 197 | _values[index.row()] = value; 198 | setIndexSelected( index, true ); 199 | emit layoutChanged(); 200 | } 201 | } 202 | 203 | //! remove 204 | virtual void remove( const ValueType& value ) 205 | { 206 | 207 | emit layoutAboutToBeChanged(); 208 | _remove( value ); 209 | emit layoutChanged(); 210 | 211 | } 212 | 213 | //! remove 214 | virtual void remove( const List& values ) 215 | { 216 | 217 | // check if not empty 218 | // this avoids sending useless signals 219 | if( values.empty() ) return; 220 | 221 | emit layoutAboutToBeChanged(); 222 | for( typename List::const_iterator iter = values.begin(); iter != values.end(); iter++ ) 223 | { _remove( *iter ); } 224 | emit layoutChanged(); 225 | 226 | } 227 | 228 | //! clear 229 | virtual void clear() 230 | { set( List() ); } 231 | 232 | //! update values from list 233 | /*! 234 | values that are not found in current are removed 235 | new values are set to the end. 236 | This is slower than the "set" method, but the selection is not cleared in the process 237 | */ 238 | virtual void update( List values ) 239 | { 240 | 241 | emit layoutAboutToBeChanged(); 242 | 243 | // store values to be removed 244 | List removed_values; 245 | 246 | // update values that are common to both lists 247 | for( typename List::iterator iter = _values.begin(); iter != _values.end(); iter++ ) 248 | { 249 | 250 | // see if iterator is in list 251 | typename List::iterator found_iter( std::find( values.begin(), values.end(), *iter ) ); 252 | if( found_iter == values.end() ) removed_values.push_back( *iter ); 253 | else { 254 | *iter = *found_iter; 255 | values.erase( found_iter ); 256 | } 257 | 258 | } 259 | 260 | // remove values that have not been found in new list 261 | for( typename List::const_iterator iter = removed_values.constBegin(); iter != removed_values.constEnd(); iter++ ) 262 | { _remove( *iter ); } 263 | 264 | // add remaining values 265 | for( typename List::const_iterator iter = values.constBegin(); iter != values.constEnd(); iter++ ) 266 | { _add( *iter ); } 267 | 268 | privateSort(); 269 | emit layoutChanged(); 270 | 271 | } 272 | 273 | //! set all values 274 | virtual void set( const List& values ) 275 | { 276 | 277 | emit layoutAboutToBeChanged(); 278 | _values = values; 279 | _selection.clear(); 280 | privateSort(); 281 | emit layoutChanged(); 282 | } 283 | 284 | //! return all values 285 | const List& get() const 286 | { return _values; } 287 | 288 | //! return value for given index 289 | virtual ValueType get( const QModelIndex& index ) const 290 | { return (index.isValid() && index.row() < int(_values.size()) ) ? _values[index.row()]:ValueType(); } 291 | 292 | //! return value for given index 293 | virtual ValueType& get( const QModelIndex& index ) 294 | { 295 | Q_ASSERT( index.isValid() && index.row() < int( _values.size() ) ); 296 | return _values[index.row()]; 297 | } 298 | 299 | //! return all values 300 | List get( const QModelIndexList& indexes ) const 301 | { 302 | List out; 303 | for( QModelIndexList::const_iterator iter = indexes.begin(); iter != indexes.end(); iter++ ) 304 | { if( iter->isValid() && iter->row() < int(_values.size()) ) out.push_back( get( *iter ) ); } 305 | return out; 306 | } 307 | 308 | //! return index associated to a given value 309 | virtual QModelIndex index( const ValueType& value, int column = 0 ) const 310 | { 311 | for( int row = 0; row < _values.size(); ++row ) 312 | { if( value == _values[row] ) return index( row, column ); } 313 | return QModelIndex(); 314 | } 315 | 316 | //@} 317 | 318 | //! return true if model contains given index 319 | virtual bool contains( const QModelIndex& index ) const 320 | { return index.isValid() && index.row() < _values.size(); } 321 | 322 | protected: 323 | 324 | //! return all values 325 | List& _get() 326 | { return _values; } 327 | 328 | //! add, without update 329 | virtual void _add( const ValueType& value ) 330 | { 331 | typename List::iterator iter = std::find( _values.begin(), _values.end(), value ); 332 | if( iter == _values.end() ) _values.push_back( value ); 333 | else *iter = value; 334 | } 335 | 336 | //! add, without update 337 | virtual void _insert( const QModelIndex& index, const ValueType& value ) 338 | { 339 | if( !index.isValid() ) add( value ); 340 | int row = 0; 341 | typename List::iterator iter( _values.begin() ); 342 | for( ;iter != _values.end() && row != index.row(); iter++, row++ ) 343 | {} 344 | 345 | _values.insert( iter, value ); 346 | } 347 | 348 | //! remove, without update 349 | virtual void _remove( const ValueType& value ) 350 | { 351 | _values.erase( std::remove( _values.begin(), _values.end(), value ), _values.end() ); 352 | _selection.erase( std::remove( _selection.begin(), _selection.end(), value ), _selection.end() ); 353 | } 354 | 355 | private: 356 | 357 | //! values 358 | List _values; 359 | 360 | //! selection 361 | List _selection; 362 | 363 | }; 364 | } 365 | #endif 366 | -------------------------------------------------------------------------------- /config/ui/breezeconfigurationui.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | BreezeConfigurationUI 4 | 5 | 6 | 7 | 0 8 | 0 9 | 428 10 | 418 11 | 12 | 13 | 14 | 15 | 0 16 | 17 | 18 | 19 | 20 | 0 21 | 22 | 23 | 24 | General 25 | 26 | 27 | 28 | 29 | 30 | Tit&le alignment: 31 | 32 | 33 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 34 | 35 | 36 | titleAlignment 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Left 45 | 46 | 47 | 48 | 49 | Center 50 | 51 | 52 | 53 | 54 | Center (Full Width) 55 | 56 | 57 | 58 | 59 | Right 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Qt::Horizontal 68 | 69 | 70 | 71 | 40 72 | 20 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | B&utton size: 81 | 82 | 83 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 84 | 85 | 86 | buttonSize 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | Tiny 95 | 96 | 97 | 98 | 99 | Small 100 | 101 | 102 | 103 | 104 | Medium 105 | 106 | 107 | 108 | 109 | Large 110 | 111 | 112 | 113 | 114 | Very Large 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | Allow resizing maximized windows from window edges 123 | 124 | 125 | 126 | 127 | 128 | 129 | Add handle to resize windows with no border 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | Opacity: 139 | 140 | 141 | 142 | 143 | 144 | 145 | % 146 | 147 | 148 | 100 149 | 150 | 151 | 152 | 153 | 154 | 155 | Qt::Horizontal 156 | 157 | 158 | 159 | 5 160 | 5 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | Font: 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 5 178 | 179 | 180 | 50 181 | 182 | 183 | 184 | 185 | 186 | 187 | Size: 188 | 189 | 190 | 191 | 192 | 193 | 194 | Qt::Horizontal 195 | 196 | 197 | 198 | 5 199 | 5 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | Weight: 208 | 209 | 210 | 211 | 212 | 213 | 214 | 0 215 | 216 | 217 | 218 | Normal 219 | 220 | 221 | 222 | 223 | Medium 224 | 225 | 226 | 227 | 228 | DemiBold 229 | 230 | 231 | 232 | 233 | Bold 234 | 235 | 236 | 237 | 238 | ExtraBold 239 | 240 | 241 | 242 | 243 | Black 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | Italic 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | Qt::Horizontal 262 | 263 | 264 | 265 | 5 266 | 5 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | Qt::Vertical 277 | 278 | 279 | 280 | 20 281 | 40 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | Animations 291 | 292 | 293 | 294 | 295 | 296 | false 297 | 298 | 299 | Anima&tions duration: 300 | 301 | 302 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 303 | 304 | 305 | animationsDuration 306 | 307 | 308 | 309 | 310 | 311 | 312 | false 313 | 314 | 315 | ms 316 | 317 | 318 | 500 319 | 320 | 321 | 322 | 323 | 324 | 325 | Qt::Horizontal 326 | 327 | 328 | 329 | 40 330 | 20 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | Enable animations 339 | 340 | 341 | 342 | 343 | 344 | 345 | Qt::Vertical 346 | 347 | 348 | 349 | 20 350 | 40 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | Shadows 360 | 361 | 362 | 363 | 364 | 365 | Si&ze: 366 | 367 | 368 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 369 | 370 | 371 | shadowSize 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | None 380 | 381 | 382 | 383 | 384 | Small 385 | 386 | 387 | 388 | 389 | Medium 390 | 391 | 392 | 393 | 394 | Large 395 | 396 | 397 | 398 | 399 | Very Large 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | S&trength: 408 | 409 | 410 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 411 | 412 | 413 | shadowStrength 414 | 415 | 416 | 417 | 418 | 419 | 420 | % 421 | 422 | 423 | 10 424 | 425 | 426 | 100 427 | 428 | 429 | 430 | 431 | 432 | 433 | Qt::Horizontal 434 | 435 | 436 | 437 | 40 438 | 20 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | Color: 447 | 448 | 449 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | Qt::Vertical 460 | 461 | 462 | 463 | 20 464 | 40 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | Window-Specific Overrides 474 | 475 | 476 | 477 | 478 | 479 | 480 | 0 481 | 0 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | KColorButton 495 | QPushButton 496 |
kcolorbutton.h
497 |
498 | 499 | Breeze::ExceptionListWidget 500 | QWidget 501 |
config/breezeexceptionlistwidget.h
502 | 1 503 |
504 |
505 | 506 | tabWidget 507 | titleAlignment 508 | buttonSize 509 | drawBorderOnMaximizedWindows 510 | drawSizeGrip 511 | animationsEnabled 512 | animationsDuration 513 | shadowSize 514 | shadowStrength 515 | shadowColor 516 | 517 | 518 | 519 | 520 | animationsEnabled 521 | toggled(bool) 522 | animationsDurationLabel 523 | setEnabled(bool) 524 | 525 | 526 | 34 527 | 194 528 | 529 | 530 | 84 531 | 221 532 | 533 | 534 | 535 | 536 | animationsEnabled 537 | toggled(bool) 538 | animationsDuration 539 | setEnabled(bool) 540 | 541 | 542 | 108 543 | 194 544 | 545 | 546 | 141 547 | 229 548 | 549 | 550 | 551 | 552 |
553 | -------------------------------------------------------------------------------- /config/ui/breezedetectwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | BreezeDetectWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 239 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | Information about Selected Window 21 | 22 | 23 | 24 | 25 | 26 | Class: 27 | 28 | 29 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 30 | 31 | 32 | 33 | 34 | 35 | 36 | TextLabel 37 | 38 | 39 | 40 | 41 | 42 | 43 | Title: 44 | 45 | 46 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 47 | 48 | 49 | 50 | 51 | 52 | 53 | TextLabel 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Window Property Selection 64 | 65 | 66 | 67 | 68 | 69 | Use window class (whole application) 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Use window title 80 | 81 | 82 | 83 | 84 | 85 | 86 | Qt::Vertical 87 | 88 | 89 | 90 | 20 91 | 40 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Qt::Horizontal 103 | 104 | 105 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | buttonBox 115 | accepted() 116 | BreezeDetectWidget 117 | accept() 118 | 119 | 120 | 248 121 | 254 122 | 123 | 124 | 157 125 | 274 126 | 127 | 128 | 129 | 130 | buttonBox 131 | rejected() 132 | BreezeDetectWidget 133 | reject() 134 | 135 | 136 | 316 137 | 260 138 | 139 | 140 | 286 141 | 274 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /config/ui/breezeexceptiondialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | BreezeExceptionDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 362 10 | 321 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | Window Identification 21 | 22 | 23 | 24 | 25 | 26 | &Matching window property: 27 | 28 | 29 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 30 | 31 | 32 | exceptionType 33 | 34 | 35 | 36 | 37 | 38 | 39 | Regular expression &to match: 40 | 41 | 42 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 43 | 44 | 45 | exceptionEditor 46 | 47 | 48 | 49 | 50 | 51 | 52 | Detect Window Properties 53 | 54 | 55 | 56 | 57 | 58 | 59 | true 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Window Class Name 68 | 69 | 70 | 71 | 72 | Window Title 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Decoration Options 84 | 85 | 86 | 87 | 88 | 89 | Border size: 90 | 91 | 92 | 93 | 94 | 95 | 96 | false 97 | 98 | 99 | 100 | No Border 101 | 102 | 103 | 104 | 105 | No Side Borders 106 | 107 | 108 | 109 | 110 | Tiny 111 | 112 | 113 | 114 | 115 | Normal 116 | 117 | 118 | 119 | 120 | Large 121 | 122 | 123 | 124 | 125 | Very Large 126 | 127 | 128 | 129 | 130 | Huge 131 | 132 | 133 | 134 | 135 | Very Huge 136 | 137 | 138 | 139 | 140 | Oversized 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | Only for dialogs 149 | 150 | 151 | 152 | 153 | 154 | 155 | Qt::Vertical 156 | 157 | 158 | 159 | 20 160 | 40 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | Hide window title bar 169 | 170 | 171 | 172 | 173 | 174 | 175 | Opaque title bar 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | Qt::Horizontal 185 | 186 | 187 | QSizePolicy::Fixed 188 | 189 | 190 | 191 | 16 192 | 5 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | Override opacity: 201 | 202 | 203 | 204 | 205 | 206 | 207 | % 208 | 209 | 210 | -1 211 | 212 | 213 | 100 214 | 215 | 216 | -1 217 | 218 | 219 | 220 | 221 | 222 | 223 | Qt::Horizontal 224 | 225 | 226 | 227 | 40 228 | 20 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | Qt::Horizontal 242 | 243 | 244 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | buttonBox 254 | accepted() 255 | BreezeExceptionDialog 256 | accept() 257 | 258 | 259 | 252 260 | 342 261 | 262 | 263 | 157 264 | 274 265 | 266 | 267 | 268 | 269 | buttonBox 270 | rejected() 271 | BreezeExceptionDialog 272 | reject() 273 | 274 | 275 | 320 276 | 342 277 | 278 | 279 | 286 280 | 274 281 | 282 | 283 | 284 | 285 | borderSizeCheckBox 286 | toggled(bool) 287 | borderSizeComboBox 288 | setEnabled(bool) 289 | 290 | 291 | 125 292 | 162 293 | 294 | 295 | 316 296 | 163 297 | 298 | 299 | 300 | 301 | opaqueTitleBar 302 | toggled(bool) 303 | opacityOverrideLabel 304 | setDisabled(bool) 305 | 306 | 307 | 104 308 | 202 309 | 310 | 311 | 82 312 | 229 313 | 314 | 315 | 316 | 317 | opaqueTitleBar 318 | toggled(bool) 319 | opacityOverrideLabelSpinBox 320 | setDisabled(bool) 321 | 322 | 323 | 104 324 | 202 325 | 326 | 327 | 166 328 | 229 329 | 330 | 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /config/ui/breezeexceptionlistwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | BreezeExceptionListWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 473 10 | 182 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 0 22 | 0 23 | 24 | 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 0 37 | 38 | 39 | 40 | 41 | 42 | 0 43 | 0 44 | 45 | 46 | 47 | 48 | 100 49 | 100 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Qt::Vertical 58 | 59 | 60 | 61 | 20 62 | 1 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Move Up 71 | 72 | 73 | 74 | 75 | 76 | 77 | Move Down 78 | 79 | 80 | 81 | 82 | 83 | 84 | Add 85 | 86 | 87 | 88 | 89 | 90 | 91 | Remove 92 | 93 | 94 | 95 | 96 | 97 | 98 | Edit 99 | 100 | 101 | 102 | 103 | 104 | 105 | exceptionListView 106 | moveUpButton 107 | moveDownButton 108 | addButton 109 | removeButton 110 | editButton 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /libbreezecommon/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ################# dependencies ################# 2 | 3 | ### Qt/KDE 4 | find_package(Qt5 REQUIRED CONFIG COMPONENTS Widgets) 5 | 6 | ################# configuration ################# 7 | configure_file(config-breezecommon.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-breezecommon.h ) 8 | 9 | ################# breezestyle target ################# 10 | set(breeze10common_LIB_SRCS 11 | breezeboxshadowrenderer.cpp 12 | ) 13 | 14 | add_library(breeze10common5 ${breeze10common_LIB_SRCS}) 15 | 16 | generate_export_header(breeze10common5 17 | BASE_NAME breezecommon 18 | EXPORT_FILE_NAME breezecommon_export.h) 19 | 20 | target_link_libraries(breeze10common5 21 | PUBLIC 22 | Qt5::Core 23 | Qt5::Gui) 24 | 25 | set_target_properties(breeze10common5 PROPERTIES 26 | VERSION ${PROJECT_VERSION} 27 | SOVERSION ${PROJECT_VERSION_MAJOR}) 28 | 29 | install(TARGETS breeze10common5 ${INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) 30 | -------------------------------------------------------------------------------- /libbreezecommon/breezeboxshadowrenderer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Vlad Zagorodniy 3 | * 4 | * The box blur implementation is based on AlphaBoxBlur from Firefox. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | // own 22 | #include "breezeboxshadowrenderer.h" 23 | 24 | // auto-generated 25 | #include "config-breezecommon.h" 26 | 27 | // Qt 28 | #include 29 | 30 | #include 31 | 32 | namespace Breeze 33 | { 34 | 35 | static inline int calculateBlurRadius(qreal stdDev) 36 | { 37 | // See https://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement 38 | const qreal gaussianScaleFactor = (3.0 * qSqrt(2.0 * M_PI) / 4.0) * 1.5; 39 | return qMax(2, qFloor(stdDev * gaussianScaleFactor + 0.5)); 40 | } 41 | 42 | static inline qreal calculateBlurStdDev(int radius) 43 | { 44 | // See https://www.w3.org/TR/css-backgrounds-3/#shadow-blur 45 | return radius * 0.5; 46 | } 47 | 48 | static inline QSize calculateBlurExtent(int radius) 49 | { 50 | const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius)); 51 | return QSize(blurRadius, blurRadius); 52 | } 53 | 54 | struct BoxLobes 55 | { 56 | int left; ///< how many pixels sample to the left 57 | int right; ///< how many pixels sample to the right 58 | }; 59 | 60 | /** 61 | * Compute box filter parameters. 62 | * 63 | * @param radius The blur radius. 64 | * @returns Parameters for three box filters. 65 | **/ 66 | static QVector computeLobes(int radius) 67 | { 68 | const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius)); 69 | const int z = blurRadius / 3; 70 | 71 | int major; 72 | int minor; 73 | int final; 74 | 75 | switch (blurRadius % 3) { 76 | case 0: 77 | major = z; 78 | minor = z; 79 | final = z; 80 | break; 81 | 82 | case 1: 83 | major = z + 1; 84 | minor = z; 85 | final = z; 86 | break; 87 | 88 | case 2: 89 | major = z + 1; 90 | minor = z; 91 | final = z + 1; 92 | break; 93 | 94 | default: 95 | Q_UNREACHABLE(); 96 | break; 97 | } 98 | 99 | Q_ASSERT(major + minor + final == blurRadius); 100 | 101 | return { 102 | {major, minor}, 103 | {minor, major}, 104 | {final, final} 105 | }; 106 | } 107 | 108 | /** 109 | * Process a row with a box filter. 110 | * 111 | * @param src The start of the row. 112 | * @param dst The destination. 113 | * @param width The width of the row, in pixels. 114 | * @param horizontalStride The number of bytes from one alpha value to the 115 | * next alpha value. 116 | * @param verticalStride The number of bytes from one row to the next row. 117 | * @param lobes Params of the box filter. 118 | * @param transposeInput Whether the input is transposed. 119 | * @param transposeOutput Whether the output should be transposed. 120 | **/ 121 | static inline void boxBlurRowAlpha(const uint8_t *src, uint8_t *dst, int width, int horizontalStride, 122 | int verticalStride, const BoxLobes &lobes, bool transposeInput, 123 | bool transposeOutput) 124 | { 125 | const int inputStep = transposeInput ? verticalStride : horizontalStride; 126 | const int outputStep = transposeOutput ? verticalStride : horizontalStride; 127 | 128 | const int boxSize = lobes.left + 1 + lobes.right; 129 | const int reciprocal = (1 << 24) / boxSize; 130 | 131 | uint32_t alphaSum = (boxSize + 1) / 2; 132 | 133 | const uint8_t *left = src; 134 | const uint8_t *right = src; 135 | uint8_t *out = dst; 136 | 137 | const uint8_t firstValue = src[0]; 138 | const uint8_t lastValue = src[(width - 1) * inputStep]; 139 | 140 | alphaSum += firstValue * lobes.left; 141 | 142 | const uint8_t *initEnd = src + (boxSize - lobes.left) * inputStep; 143 | while (right < initEnd) { 144 | alphaSum += *right; 145 | right += inputStep; 146 | } 147 | 148 | const uint8_t *leftEnd = src + boxSize * inputStep; 149 | while (right < leftEnd) { 150 | *out = (alphaSum * reciprocal) >> 24; 151 | alphaSum += *right - firstValue; 152 | right += inputStep; 153 | out += outputStep; 154 | } 155 | 156 | const uint8_t *centerEnd = src + width * inputStep; 157 | while (right < centerEnd) { 158 | *out = (alphaSum * reciprocal) >> 24; 159 | alphaSum += *right - *left; 160 | left += inputStep; 161 | right += inputStep; 162 | out += outputStep; 163 | } 164 | 165 | const uint8_t *rightEnd = dst + width * outputStep; 166 | while (out < rightEnd) { 167 | *out = (alphaSum * reciprocal) >> 24; 168 | alphaSum += lastValue - *left; 169 | left += inputStep; 170 | out += outputStep; 171 | } 172 | } 173 | 174 | /** 175 | * Blur the alpha channel of a given image. 176 | * 177 | * @param image The input image. 178 | * @param radius The blur radius. 179 | * @param rect Specifies what part of the image to blur. If nothing is provided, then 180 | * the whole alpha channel of the input image will be blurred. 181 | **/ 182 | static inline void boxBlurAlpha(QImage &image, int radius, const QRect &rect = {}) 183 | { 184 | if (radius < 2) { 185 | return; 186 | } 187 | 188 | const QVector lobes = computeLobes(radius); 189 | 190 | const QRect blurRect = rect.isNull() ? image.rect() : rect; 191 | 192 | const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3; 193 | const int width = blurRect.width(); 194 | const int height = blurRect.height(); 195 | const int rowStride = image.bytesPerLine(); 196 | const int pixelStride = image.depth() >> 3; 197 | 198 | const int bufferStride = qMax(width, height) * pixelStride; 199 | QScopedPointer > buf(new uint8_t[2 * bufferStride]); 200 | uint8_t *buf1 = buf.data(); 201 | uint8_t *buf2 = buf1 + bufferStride; 202 | 203 | // Blur the image in horizontal direction. 204 | for (int i = 0; i < height; ++i) { 205 | uint8_t *row = image.scanLine(blurRect.y() + i) + blurRect.x() * pixelStride + alphaOffset; 206 | boxBlurRowAlpha(row, buf1, width, pixelStride, rowStride, lobes[0], false, false); 207 | boxBlurRowAlpha(buf1, buf2, width, pixelStride, rowStride, lobes[1], false, false); 208 | boxBlurRowAlpha(buf2, row, width, pixelStride, rowStride, lobes[2], false, false); 209 | } 210 | 211 | // Blur the image in vertical direction. 212 | for (int i = 0; i < width; ++i) { 213 | uint8_t *column = image.scanLine(blurRect.y()) + (blurRect.x() + i) * pixelStride + alphaOffset; 214 | boxBlurRowAlpha(column, buf1, height, pixelStride, rowStride, lobes[0], true, false); 215 | boxBlurRowAlpha(buf1, buf2, height, pixelStride, rowStride, lobes[1], false, false); 216 | boxBlurRowAlpha(buf2, column, height, pixelStride, rowStride, lobes[2], false, true); 217 | } 218 | } 219 | 220 | static inline void mirrorTopLeftQuadrant(QImage &image) 221 | { 222 | const int width = image.width(); 223 | const int height = image.height(); 224 | 225 | const int centerX = qCeil(width * 0.5); 226 | const int centerY = qCeil(height * 0.5); 227 | 228 | const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3; 229 | const int stride = image.depth() >> 3; 230 | 231 | for (int y = 0; y < centerY; ++y) { 232 | uint8_t *in = image.scanLine(y) + alphaOffset; 233 | uint8_t *out = in + (width - 1) * stride; 234 | 235 | for (int x = 0; x < centerX; ++x, in += stride, out -= stride) { 236 | *out = *in; 237 | } 238 | } 239 | 240 | for (int y = 0; y < centerY; ++y) { 241 | const uint8_t *in = image.scanLine(y) + alphaOffset; 242 | uint8_t *out = image.scanLine(width - y - 1) + alphaOffset; 243 | 244 | for (int x = 0; x < width; ++x, in += stride, out += stride) { 245 | *out = *in; 246 | } 247 | } 248 | } 249 | 250 | static void renderShadow(QPainter *painter, const QRect &rect, qreal borderRadius, const QPoint &offset, int radius, const QColor &color) 251 | { 252 | const QSize inflation = calculateBlurExtent(radius); 253 | const QSize size = rect.size() + 2 * inflation; 254 | 255 | const qreal dpr = painter->device()->devicePixelRatioF(); 256 | 257 | QImage shadow(size * dpr, QImage::Format_ARGB32_Premultiplied); 258 | shadow.setDevicePixelRatio(dpr); 259 | shadow.fill(Qt::transparent); 260 | 261 | QRect boxRect(QPoint(0, 0), rect.size()); 262 | boxRect.moveCenter(QRect(QPoint(0, 0), size).center()); 263 | 264 | const qreal xRadius = 2.0 * borderRadius / boxRect.width(); 265 | const qreal yRadius = 2.0 * borderRadius / boxRect.height(); 266 | 267 | QPainter shadowPainter; 268 | shadowPainter.begin(&shadow); 269 | shadowPainter.setRenderHint(QPainter::Antialiasing); 270 | shadowPainter.setPen(Qt::NoPen); 271 | shadowPainter.setBrush(Qt::black); 272 | shadowPainter.drawRoundedRect(boxRect, xRadius, yRadius); 273 | shadowPainter.end(); 274 | 275 | // Because the shadow texture is symmetrical, that's enough to blur 276 | // only the top-left quadrant and then mirror it. 277 | const QRect blurRect(0, 0, qCeil(shadow.width() * 0.5), qCeil(shadow.height() * 0.5)); 278 | const int scaledRadius = qRound(radius * dpr); 279 | boxBlurAlpha(shadow, scaledRadius, blurRect); 280 | mirrorTopLeftQuadrant(shadow); 281 | 282 | // Give the shadow a tint of the desired color. 283 | shadowPainter.begin(&shadow); 284 | shadowPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); 285 | shadowPainter.fillRect(shadow.rect(), color); 286 | shadowPainter.end(); 287 | 288 | // Actually, present the shadow. 289 | QRect shadowRect = shadow.rect(); 290 | shadowRect.setSize(shadowRect.size() / dpr); 291 | shadowRect.moveCenter(rect.center() + offset); 292 | painter->drawImage(shadowRect, shadow); 293 | } 294 | 295 | void BoxShadowRenderer::setBoxSize(const QSize &size) 296 | { 297 | m_boxSize = size; 298 | } 299 | 300 | void BoxShadowRenderer::setBorderRadius(qreal radius) 301 | { 302 | m_borderRadius = radius; 303 | } 304 | 305 | void BoxShadowRenderer::setDevicePixelRatio(qreal dpr) 306 | { 307 | m_dpr = dpr; 308 | } 309 | 310 | void BoxShadowRenderer::addShadow(const QPoint &offset, int radius, const QColor &color) 311 | { 312 | Shadow shadow = {}; 313 | shadow.offset = offset; 314 | shadow.radius = radius; 315 | shadow.color = color; 316 | m_shadows.append(shadow); 317 | } 318 | 319 | QImage BoxShadowRenderer::render() const 320 | { 321 | if (m_shadows.isEmpty()) { 322 | return {}; 323 | } 324 | 325 | QSize canvasSize; 326 | for (const Shadow &shadow : qAsConst(m_shadows)) { 327 | canvasSize = canvasSize.expandedTo( 328 | calculateMinimumShadowTextureSize(m_boxSize, shadow.radius, shadow.offset)); 329 | } 330 | 331 | QImage canvas(canvasSize * m_dpr, QImage::Format_ARGB32_Premultiplied); 332 | canvas.setDevicePixelRatio(m_dpr); 333 | canvas.fill(Qt::transparent); 334 | 335 | QRect boxRect(QPoint(0, 0), m_boxSize); 336 | boxRect.moveCenter(QRect(QPoint(0, 0), canvasSize).center()); 337 | 338 | QPainter painter(&canvas); 339 | for (const Shadow &shadow : qAsConst(m_shadows)) { 340 | renderShadow(&painter, boxRect, m_borderRadius, shadow.offset, shadow.radius, shadow.color); 341 | } 342 | painter.end(); 343 | 344 | return canvas; 345 | } 346 | 347 | QSize BoxShadowRenderer::calculateMinimumBoxSize(int radius) 348 | { 349 | const QSize blurExtent = calculateBlurExtent(radius); 350 | return 2 * blurExtent + QSize(1, 1); 351 | } 352 | 353 | QSize BoxShadowRenderer::calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset) 354 | { 355 | return boxSize + 2 * calculateBlurExtent(radius) + QSize(qAbs(offset.x()), qAbs(offset.y())); 356 | } 357 | 358 | } // namespace Breeze 359 | -------------------------------------------------------------------------------- /libbreezecommon/breezeboxshadowrenderer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Vlad Zagorodniy 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | 21 | // own 22 | #include "breezecommon_export.h" 23 | 24 | // Qt 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace Breeze 31 | { 32 | 33 | class BREEZECOMMON_EXPORT BoxShadowRenderer 34 | { 35 | public: 36 | // Compiler generated constructors & destructor are fine. 37 | 38 | /** 39 | * Set the size of the box. 40 | * @param size The size of the box. 41 | **/ 42 | void setBoxSize(const QSize &size); 43 | 44 | /** 45 | * Set the radius of box' corners. 46 | * @param radius The border radius, in pixels. 47 | **/ 48 | void setBorderRadius(qreal radius); 49 | 50 | /** 51 | * Set the device pixel ratio of the resulting shadow texture. 52 | * @param dpr The device pixel ratio. 53 | **/ 54 | void setDevicePixelRatio(qreal dpr); 55 | 56 | /** 57 | * Add a shadow. 58 | * @param offset The offset of the shadow. 59 | * @param radius The blur radius. 60 | * @param color The color of the shadow. 61 | **/ 62 | void addShadow(const QPoint &offset, int radius, const QColor &color); 63 | 64 | /** 65 | * Render the shadow. 66 | **/ 67 | QImage render() const; 68 | 69 | /** 70 | * Calculate the minimum size of the box. 71 | * 72 | * This helper computes the minimum size of the box so the shadow behind it has 73 | * full its strength. 74 | * 75 | * @param radius The blur radius of the shadow. 76 | **/ 77 | static QSize calculateMinimumBoxSize(int radius); 78 | 79 | /** 80 | * Calculate the minimum size of the shadow texture. 81 | * 82 | * This helper computes the minimum size of the resulting texture so the shadow 83 | * is not clipped. 84 | * 85 | * @param boxSize The size of the box. 86 | * @param radius The blur radius. 87 | * @param offset The offset of the shadow. 88 | **/ 89 | static QSize calculateMinimumShadowTextureSize(const QSize &boxSize, int radius, const QPoint &offset); 90 | 91 | private: 92 | QSize m_boxSize; 93 | qreal m_borderRadius = 0.0; 94 | qreal m_dpr = 1.0; 95 | 96 | struct Shadow { 97 | QPoint offset; 98 | int radius; 99 | QColor color; 100 | }; 101 | 102 | QVector m_shadows; 103 | }; 104 | 105 | } // namespace Breeze 106 | -------------------------------------------------------------------------------- /libbreezecommon/config-breezecommon.h.cmake: -------------------------------------------------------------------------------- 1 | /* config-breezecommon.h. Generated by cmake from config-breezecommon.h.cmake */ 2 | 3 | /************************************************************************* 4 | * Copyright (C) 2014 by Hugo Pereira Da Costa * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the * 18 | * Free Software Foundation, Inc., * 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 20 | *************************************************************************/ 21 | 22 | #ifndef config_breeze_common_h 23 | #define config_breeze_common_h 24 | 25 | /* Define to 1 if breeze is compiled against KDE4 */ 26 | #cmakedefine01 BREEZE_COMMON_USE_KDE4 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /screenshots/Desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sp1ritCS/Breeze10/d7424b87a9d6139b232c1a54f2462a572988a1f2/screenshots/Desktop.png -------------------------------------------------------------------------------- /screenshots/Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sp1ritCS/Breeze10/d7424b87a9d6139b232c1a54f2462a572988a1f2/screenshots/Settings.png --------------------------------------------------------------------------------