├── .gitignore ├── screenshots ├── ActiveButtons.gif ├── SBE_settings.png ├── symbol-style.gif └── InactiveButtons.gif ├── breezesettings.kcfgc ├── Messages.sh ├── config ├── kcm_sierrabreezeenhanceddecoration.cpp ├── sierrabreezeenhancedconfig.desktop ├── CMakeLists.txt ├── breezedetectwidget.h ├── breezeitemmodel.cpp ├── breezeexceptionmodel.h ├── breezeconfigwidget.h ├── breezedetectwidget.cpp ├── ui │ ├── breezeexceptionlistwidget.ui │ └── breezeexceptiondialog.ui ├── breezeexceptiondialog.h ├── breezeitemmodel.h ├── breezeexceptionlistwidget.h ├── breezeexceptionmodel.cpp ├── kcm_sierrabreezeenhanceddecoration.json ├── breezeexceptiondialog.cpp ├── breezelistmodel.h ├── breezeexceptionlistwidget.cpp └── breezeconfigwidget.cpp ├── install.sh ├── sierrabreezeenhanced.json ├── libbreezecommon ├── CMakeLists.txt ├── config-breezecommon.h.cmake ├── breezeboxshadowrenderer.h └── breezeboxshadowrenderer.cpp ├── uninstall.sh ├── config-breeze.h.cmake ├── breezesettingsprovider.h ├── breeze.h ├── breezeexceptionlist.h ├── breezesizegrip.h ├── breezesettingsprovider.cpp ├── README.md ├── CMakeLists.txt ├── breezebutton.h ├── breezeexceptionlist.cpp ├── breezesettingsdata.kcfg ├── breezedecoration.h ├── ChangeLog └── breezesizegrip.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .vscode 3 | .cache 4 | .clang-format 5 | -------------------------------------------------------------------------------- /screenshots/ActiveButtons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kupiqu/SierraBreezeEnhanced/HEAD/screenshots/ActiveButtons.gif -------------------------------------------------------------------------------- /screenshots/SBE_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kupiqu/SierraBreezeEnhanced/HEAD/screenshots/SBE_settings.png -------------------------------------------------------------------------------- /screenshots/symbol-style.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kupiqu/SierraBreezeEnhanced/HEAD/screenshots/symbol-style.gif -------------------------------------------------------------------------------- /screenshots/InactiveButtons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kupiqu/SierraBreezeEnhanced/HEAD/screenshots/InactiveButtons.gif -------------------------------------------------------------------------------- /breezesettings.kcfgc: -------------------------------------------------------------------------------- 1 | File=breezesettingsdata.kcfg 2 | ClassName=InternalSettings 3 | NameSpace=Breeze 4 | Singleton=false 5 | Mutators=true 6 | GlobalEnums=true 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/kcm_sierrabreezeenhanceddecoration.cpp: -------------------------------------------------------------------------------- 1 | #include "breezeconfigwidget.h" 2 | #include 3 | 4 | K_PLUGIN_CLASS_WITH_JSON(Breeze::ConfigWidget, "kcm_sierrabreezeenhanceddecoration.json") 5 | 6 | #include "kcm_sierrabreezeenhanceddecoration.moc" 7 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # - Recreate build 4 | # - Build 5 | # - Install 6 | 7 | ORIGINAL_DIR=$(pwd) 8 | 9 | rm -rf build 10 | mkdir build 11 | cd build 12 | cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DKDE_INSTALL_USE_QT_SYS_PATHS=ON 13 | make 14 | sudo make install 15 | 16 | cd $ORIGINAL_DIR 17 | -------------------------------------------------------------------------------- /config/sierrabreezeenhancedconfig.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Exec=kcmshell5 sierrabreezeenhancedconfig 3 | Icon=preferences-system-windows 4 | Type=Service 5 | X-KDE-ServiceTypes=KCModule 6 | 7 | X-KDE-Library=org.kde.kdecoration3/sierrabreezeenhanced 8 | X-KDE-PluginKeyword=kcmodule 9 | X-KDE-ParentApp=kcontrol 10 | X-KDE-Weight=60 11 | X-KDE-PluginInfo-Name=Sierra Breeze Enhanced 12 | 13 | Name=Sierra Breeze Enhanced 14 | Comment=Modify the appearance of window decorations 15 | X-KDE-Keywords=sierrabreezeenhanced,decoration 16 | -------------------------------------------------------------------------------- /sierrabreezeenhanced.json: -------------------------------------------------------------------------------- 1 | { 2 | "KPlugin": { 3 | "Description": "Window decoration based on SierraBreeze and BreezeEnhanced styles for the Plasma Desktop", 4 | "EnabledByDefault": true, 5 | "Id": "org.kde.sierrabreezeenhanced", 6 | "Name": "Sierra Breeze Enhanced", 7 | "ServiceTypes": [ 8 | "org.kde.kdecoration3" 9 | ] 10 | }, 11 | "X-KDE-ConfigModule": "kcm_sierrabreezeenhanceddecoration", 12 | "org.kde.kdecoration3": { 13 | "defaultTheme": "Sierra Breeze Enhanced", 14 | "recommendedBorderSize": "Tiny" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libbreezecommon/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ################ dependencies ################# 2 | # Qt/KDE 3 | find_package(Qt6 REQUIRED CONFIG COMPONENTS Widgets) 4 | 5 | # ################ configuration ################# 6 | configure_file(config-breezecommon.h.cmake 7 | ${CMAKE_CURRENT_BINARY_DIR}/config-breezecommon.h) 8 | 9 | # ################ breezestyle target ################# 10 | set(sierrabreezeenhancedcommon_LIB_SRCS breezeboxshadowrenderer.cpp) 11 | 12 | add_library(sierrabreezeenhancedcommon6 ${sierrabreezeenhancedcommon_LIB_SRCS}) 13 | 14 | generate_export_header(sierrabreezeenhancedcommon6 BASE_NAME breezecommon 15 | EXPORT_FILE_NAME breezecommon_export.h) 16 | 17 | target_link_libraries(sierrabreezeenhancedcommon6 PUBLIC Qt6::Core Qt6::Gui) 18 | 19 | set_target_properties( 20 | sierrabreezeenhancedcommon6 PROPERTIES VERSION ${PROJECT_VERSION} 21 | SOVERSION ${PROJECT_VERSION_MAJOR}) 22 | 23 | install(TARGETS sierrabreezeenhancedcommon6 ${INSTALL_TARGETS_DEFAULT_ARGS} 24 | LIBRARY NAMELINK_SKIP) 25 | -------------------------------------------------------------------------------- /config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(breezedecoration_config_SRCS 2 | ../breezeexceptionlist.cpp 3 | breezeconfigwidget.cpp 4 | breezedetectwidget.cpp 5 | breezeexceptiondialog.cpp 6 | breezeexceptionlistwidget.cpp 7 | breezeexceptionmodel.cpp 8 | breezeitemmodel.cpp) 9 | ki18n_wrap_ui( 10 | breezedecoration_config_SRCS ui/breezeconfigurationui.ui 11 | ui/breezeexceptiondialog.ui ui/breezeexceptionlistwidget.ui) 12 | 13 | kcoreaddons_add_plugin( 14 | kcm_sierrabreezeenhanceddecoration SOURCES kcm_sierrabreezeenhanceddecoration 15 | ${breezedecoration_config_SRCS} INSTALL_NAMESPACE 16 | "${KDECORATION_KCM_PLUGIN_DIR}") 17 | kconfig_add_kcfg_files(kcm_sierrabreezeenhanceddecoration 18 | ../breezesettings.kcfgc) 19 | target_include_directories(kcm_sierrabreezeenhanceddecoration 20 | PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/) 21 | target_link_libraries( 22 | kcm_sierrabreezeenhanceddecoration 23 | PUBLIC Qt6::Core Qt6::Gui Qt6::DBus Qt6::Core5Compat Qt6::GuiPrivate 24 | PRIVATE KF6::ConfigCore KF6::CoreAddons KF6::GuiAddons KF6::I18n 25 | KF6::KCMUtils KF6::WindowSystem) 26 | if(BREEZE_HAVE_X11) 27 | target_link_libraries(kcm_sierrabreezeenhanceddecoration 28 | PUBLIC Qt6::GuiPrivate XCB::XCB) 29 | endif() 30 | kcmutils_generate_desktop_file(kcm_sierrabreezeenhanceddecoration) 31 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ORIGINAL_DIR=$(pwd) 4 | 5 | confirm() { 6 | # call with a prompt string or use a default 7 | read -r -p "${1:-Are you sure? [y/N]} " response 8 | case "$response" in 9 | [yY][eE][sS]|[yY]) 10 | true 11 | ;; 12 | *) 13 | false 14 | ;; 15 | esac 16 | } 17 | 18 | uninstall() { 19 | sudo make uninstall && echo "Uninstalled successfully!" 20 | } 21 | 22 | # Recreate install manifest and uninstall 23 | install_and_uninstall() { 24 | sh install.sh && 25 | cd build && 26 | uninstall 27 | echo It is possible that some files left over at the following locations 28 | echo Please remove any files containing sierrabreezeenhanced in their name 29 | echo - /usr/lib/qt/plugins/org.kde.kdecoration3/ 30 | echo - /usr/share/kservices5/ 31 | echo - /usr/lib/ 32 | } 33 | 34 | if [ ! -d "build" ]; then 35 | # If no build folder is found 36 | confirm "No installation found, (re)install and uninstall? [y/n]" && install_and_uninstall 37 | else 38 | if test -f "$ORIGINAL_DIR/build/install_manifest.txt"; then 39 | # Remove normally 40 | echo Found $ORIGINAL_DIR/build/install_manifest.txt 41 | cd build && 42 | uninstall 43 | else 44 | # If no install manifest found 45 | echo Did not find $ORIGINAL_DIR/build/install_manifest.txt 46 | confirm "(re)install and uninstall? [y/n]" && install_and_uninstall 47 | fi 48 | fi 49 | 50 | cd $ORIGINAL_DIR 51 | 52 | # Clean up 53 | rm -rf build 54 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | //* constructor 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 | -------------------------------------------------------------------------------- /libbreezecommon/breezeboxshadowrenderer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2018 Vlad Zahorodnii 3 | * 4 | * SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | 7 | #pragma once 8 | // own 9 | #include "breezecommon_export.h" 10 | // Qt 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace Breeze 17 | { 18 | class BREEZECOMMON_EXPORT BoxShadowRenderer 19 | { 20 | public: 21 | // Compiler generated constructors & destructor are fine. 22 | 23 | /** 24 | * Set the size of the box. 25 | * @param size The size of the box. 26 | **/ 27 | void setBoxSize(const QSizeF &size); 28 | 29 | /** 30 | * Set the radius of box' corners. 31 | * @param radius The border radius, in pixels. 32 | **/ 33 | void setBorderRadius(qreal radius); 34 | 35 | /** 36 | * Add a shadow. 37 | * @param offset The offset of the shadow. 38 | * @param radius The blur radius. 39 | * @param color The color of the shadow. 40 | **/ 41 | void addShadow(const QPointF &offset, double radius, const QColor &color); 42 | 43 | /** 44 | * Render the shadow. 45 | **/ 46 | QImage render() const; 47 | 48 | /** 49 | * Calculate the minimum size of the box. 50 | * 51 | * This helper computes the minimum size of the box so the shadow behind it has 52 | * full its strength. 53 | * 54 | * @param radius The blur radius of the shadow. 55 | **/ 56 | static QSize calculateMinimumBoxSize(int radius); 57 | 58 | /** 59 | * Calculate the minimum size of the shadow texture. 60 | * 61 | * This helper computes the minimum size of the resulting texture so the shadow 62 | * is not clipped. 63 | * 64 | * @param boxSize The size of the box. 65 | * @param radius The blur radius. 66 | * @param offset The offset of the shadow. 67 | **/ 68 | static QSizeF calculateMinimumShadowTextureSize(const QSizeF &boxSize, double radius, const QPointF &offset); 69 | 70 | private: 71 | QSizeF m_boxSize; 72 | qreal m_borderRadius = 0.0; 73 | 74 | struct Shadow { 75 | QPointF offset; 76 | double radius; 77 | QColor color; 78 | }; 79 | 80 | QVector m_shadows; 81 | }; 82 | 83 | } // namespace Breeze -------------------------------------------------------------------------------- /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 34 | #include 35 | 36 | namespace Breeze 37 | { 38 | 39 | class DetectDialog : public QObject 40 | { 41 | 42 | Q_OBJECT 43 | 44 | public: 45 | 46 | //* constructor 47 | explicit DetectDialog( QObject *parent = nullptr ); 48 | 49 | //* read window properties or select one from mouse grab 50 | void detect(); 51 | 52 | //* window properties 53 | QVariantMap properties() const; 54 | 55 | Q_SIGNALS: 56 | 57 | void detectionDone( bool ); 58 | 59 | private: 60 | 61 | //* properties 62 | QVariantMap m_properties; 63 | }; 64 | 65 | } // namespace 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /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 | //* corner radius (pixels) 41 | Frame_FrameRadius = 0, 42 | 43 | //* titlebar metrics, in units of small spacing 44 | // defaulting now to small spacing 45 | TitleBar_TopMargin = 1, // 2, 46 | TitleBar_BottomMargin = 1, // 2, 47 | TitleBar_SideMargin = 1, // 2, 48 | TitleBar_ButtonSpacing = 1, // 2, 49 | 50 | // shadow dimensions (pixels) 51 | Shadow_Overlap = 3, 52 | 53 | }; 54 | 55 | //* standard pen widths 56 | namespace PenWidth 57 | { 58 | /* Using 1 instead of slightly more than 1 causes symbols drawn with 59 | * pen strokes to look skewed. The exact amount added does not matter 60 | * as long as it isn't too visible. 61 | */ 62 | // The standard pen stroke width for symbols. 63 | static constexpr qreal Symbol = 1.01; 64 | } 65 | 66 | //* exception 67 | enum ExceptionMask 68 | { 69 | None = 0, 70 | BorderSize = 1<<4 71 | }; 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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( QObject *parent, const KPluginMetaData &data, 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 | private: 71 | 72 | //* ui 73 | Ui_BreezeConfigurationUI m_ui; 74 | 75 | //* kconfiguration object 76 | KSharedConfig::Ptr m_configuration; 77 | 78 | //* internal exception 79 | InternalSettingsPtr m_internalSettings; 80 | 81 | //* changed state 82 | bool m_changed; 83 | 84 | }; 85 | 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 33 | #include 34 | #include 35 | #include 36 | 37 | namespace Breeze 38 | { 39 | 40 | //_________________________________________________________ 41 | DetectDialog::DetectDialog( QObject* parent ): 42 | QObject( parent ) 43 | { 44 | } 45 | 46 | //_________________________________________________________ 47 | void DetectDialog::detect() 48 | { 49 | QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"), 50 | QStringLiteral("/KWin"), 51 | QStringLiteral("org.kde.KWin"), 52 | QStringLiteral("queryWindowInfo")); 53 | 54 | QDBusPendingReply asyncReply = QDBusConnection::sessionBus().asyncCall(message); 55 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncReply, this); 56 | connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) { 57 | QDBusPendingReply reply = *self; 58 | self->deleteLater(); 59 | if (!reply.isValid()) { 60 | Q_EMIT detectionDone(false); 61 | return; 62 | } 63 | m_properties = reply.value(); 64 | Q_EMIT detectionDone(true); 65 | }); 66 | } 67 | 68 | //_________________________________________________________ 69 | QVariantMap DetectDialog::properties() const 70 | { 71 | return m_properties; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | //* emitted 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/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 emitted 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/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 | -------------------------------------------------------------------------------- /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 | #include 27 | 28 | namespace Breeze 29 | { 30 | 31 | SettingsProvider *SettingsProvider::s_self = nullptr; 32 | 33 | //__________________________________________________________________ 34 | SettingsProvider::SettingsProvider(): 35 | m_config( KSharedConfig::openConfig( QStringLiteral("sierrabreezeenhancedrc") ) ) 36 | { reconfigure(); } 37 | 38 | //__________________________________________________________________ 39 | SettingsProvider::~SettingsProvider() 40 | { s_self = nullptr; } 41 | 42 | //__________________________________________________________________ 43 | SettingsProvider *SettingsProvider::self() 44 | { 45 | // TODO: this is not thread safe! 46 | if (!s_self) 47 | { s_self = new SettingsProvider(); } 48 | 49 | return s_self; 50 | } 51 | 52 | //__________________________________________________________________ 53 | void SettingsProvider::reconfigure() 54 | { 55 | if( !m_defaultSettings ) 56 | { 57 | m_defaultSettings = InternalSettingsPtr(new InternalSettings()); 58 | m_defaultSettings->setCurrentGroup( QStringLiteral("Windeco") ); 59 | } 60 | 61 | m_defaultSettings->load(); 62 | 63 | ExceptionList exceptions; 64 | exceptions.readConfig( m_config ); 65 | m_exceptions = exceptions.get(); 66 | 67 | } 68 | 69 | //__________________________________________________________________ 70 | InternalSettingsPtr SettingsProvider::internalSettings( Decoration *decoration ) const 71 | { 72 | 73 | QString windowTitle; 74 | QString windowClass; 75 | 76 | // get the client 77 | const auto client = decoration->window(); 78 | 79 | foreach( auto internalSettings, m_exceptions ) 80 | { 81 | 82 | // discard disabled exceptions 83 | if( !internalSettings->enabled() ) continue; 84 | 85 | // discard exceptions with empty exception pattern 86 | if( internalSettings->exceptionPattern().isEmpty() ) continue; 87 | 88 | // if (internalSettings->isDialog()) 89 | // { 90 | // KWindowInfo info(client->windowId(), NET::WMWindowType); 91 | // if (info.valid() && info.windowType(NET::NormalMask | NET::DialogMask) != NET::Dialog) { 92 | // continue; 93 | // } 94 | // } 95 | 96 | /* 97 | decide which value is to be compared 98 | to the regular expression, based on exception type 99 | */ 100 | QString value; 101 | switch( internalSettings->exceptionType() ) 102 | { 103 | case InternalSettings::ExceptionWindowTitle: 104 | { 105 | value = windowTitle.isEmpty() ? (windowTitle = client->caption()):windowTitle; 106 | break; 107 | } 108 | 109 | default: 110 | case InternalSettings::ExceptionWindowClassName: 111 | { 112 | value = windowClass.isEmpty() ? (windowClass = client->windowClass()) : windowClass; 113 | break; 114 | } 115 | 116 | } 117 | 118 | // check matching 119 | QRegularExpression rx( internalSettings->exceptionPattern() ); 120 | if( rx.match( value ).hasMatch() ) 121 | { return internalSettings; } 122 | 123 | } 124 | 125 | return m_defaultSettings; 126 | 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sierra Breeze Enhanced 2 | 3 | **Ported to Plasma 6 (community mantained)** 4 | 5 | Be aware that this README file needs an update. 6 | 7 | ## Overview 8 | 9 | Sierra Breeze Enhanced started as a fork of Breeze Enhanced decoration. It has the following main features: 10 | 11 | * Button style options: Plasma / Gnome / macOS Sierra / macOS Dark Aurorae / SBE Sierra themes / SBE Dark Aurorae themes / Color Symbols themes / Monochrome Symbols themes (Note: the application menu button is considered special and does not change). 12 | * Button spacing and padding Options. 13 | * Button hovering animation. 14 | * Option to make all button symbols to appear at unison on hovering (Note: it does not apply to symbol themes). 15 | * Titlebar style options: SBE own style of Line Separation between Titlebar and Window / Match Titlebar color to Window color / Hide Titlebar under certain circumstances (Never/Maximization/Any Maximization (including H/V)/Always) / Gradient Adjustments / Opacity Adjustments. 16 | * Specific Shadow settings for inactive windows 17 | 18 | 19 | ### Screenshot of SBE Sierra theme (or How it All started...) 20 | 21 | 22 | ![Active Buttons](screenshots/ActiveButtons.gif?raw=true "Active Buttons") 23 | ![Inactive Buttons](screenshots/InactiveButtons.gif?raw=true "Inactive Buttons") 24 | 25 | 26 | ### Screenshot of Settings 27 | 28 | 29 | ![SBE Settings](screenshots/SBE_settings.png?raw=true "SBE Settings") 30 | 31 | 32 | ## Installation 33 | 34 | Please note that after installing, you need to restart KWin by executing either `kwin_x11 --replace` or `kwin_wayland --replace` in krunner (depending on whether your session runs upon X11 or Wayland). Alternatively, restarting the KDE session is obviously also an option. Then, Sierra Breeze Enhanced will appear in *System Settings → Application Style → Window Decorations*. 35 | 36 | ### Method 1: Install prebuilt packages 37 | - Ubuntu: 38 | ```sh 39 | sudo add-apt-repository ppa:krisives/sierrabreezeenhanced 40 | sudo apt update 41 | sudo apt install sierrabreezeenhanced 42 | ``` 43 | - openSUSE: 44 | ```sh 45 | sudo zypper ar obs://home:trmdi trmdi 46 | sudo zypper in SierraBreezeEnhanced 47 | ``` 48 | - Arch Linux: 49 | ``` 50 | git clone https://aur.archlinux.org/kwin-decoration-sierra-breeze-enhanced-git.git 51 | cd kwin-decoration-sierra-breeze-enhanced-git 52 | makepkg -si 53 | cd .. 54 | rm -rf kwin-decoration-sierra-breeze-enhanced-git 55 | ``` 56 | 57 | - Alpine Linux: 58 | ``` shell 59 | sudo echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories 60 | sudo apk update 61 | sudo apk add sierrabreezeenhanced 62 | ``` 63 | 64 | ### Method 2: Compile from source code 65 | *Compilation should NOT be done against versions of Plasma < 6.3\* 66 | 67 | #### Step 1: Build dependencies 68 | 69 | - Ubuntu 70 | ``` shell 71 | sudo apt install build-essential libkf6config-dev libkdecorations2-dev qtdeclarative6-dev extra-cmake-modules libkf6guiaddons-dev libkf6configwidgets-dev libkf6windowsystem-dev libkf6coreaddons-dev libkf6iconthemes-dev gettext cmake 72 | ``` 73 | - Arch Linux 74 | ``` shell 75 | sudo pacman -S base-devel # Required development packages 76 | sudo pacman -S kdecoration qt6-declarative # Decoration 77 | sudo pacman -S cmake extra-cmake-modules # Installation 78 | ``` 79 | - Fedora 80 | ``` shell 81 | sudo dnf install cmake extra-cmake-modules kf6-kiconthemes-devel 82 | sudo dnf install "cmake(Qt6Core)" "cmake(Qt6Gui)" "cmake(Qt6DBus)" "cmake(KF6GuiAddons)" "cmake(KF6WindowSystem)" "cmake(KF6I18n)" "cmake(KDecoration3)" "cmake(KF6CoreAddons)" "cmake(KF6ConfigWidgets)" 83 | sudo dnf install qt6-qt5compat-devel kf6-kcmutils-devel qt6-qtbase-private-devel 84 | ``` 85 | 86 | - Alpine Linux 87 | ``` shell 88 | sudo apk add extra-cmake-modules qt6-qtbase-dev qt6-qt5compat-dev kcmutils-dev kdecoration-dev kcoreaddons-dev kguiaddons-dev kconfigwidgets-dev kwindowsystem-dev ki18n-dev kiconthemes-dev 89 | ``` 90 | 91 | #### Step 2: Then compile and install 92 | - Install from script: 93 | ```sh 94 | chmod +x install.sh 95 | ./install.sh 96 | ``` 97 | - Or more manually: 98 | Open a terminal inside the source directory and do: 99 | ```sh 100 | mkdir build && cd build 101 | cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DKDE_INSTALL_LIBDIR=lib -DBUILD_TESTING=OFF -DKDE_INSTALL_USE_QT_SYS_PATHS=ON 102 | make 103 | sudo make install 104 | ``` 105 | 106 | 107 | ## Uninstall 108 | 109 | - Method 1: Use your Package manager 110 | - Method 2: Run the uninstall script 111 | ```sh 112 | chmod +x uninstall.sh 113 | ./uninstall.sh 114 | ``` 115 | - Method 3: or manually if previously ran the install script 116 | ```sh 117 | cd build 118 | sudo make uninstall 119 | ``` 120 | 121 | 122 | ## Credits 123 | Breeze, Sierra Breeze and Breeze Enhanced for obvious reasons :) 124 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(sierrabreezeenhanced) 2 | set(PROJECT_VERSION "2.1.1") 3 | set(PROJECT_VERSION_MAJOR 0) 4 | 5 | cmake_minimum_required(VERSION 3.5.0 FATAL_ERROR) 6 | 7 | include(WriteBasicConfigVersionFile) 8 | include(FeatureSummary) 9 | 10 | set(QT_MAJOR_VERSION 6) 11 | set(QT_MIN_VERSION "6.6.0") 12 | set(KF6_MIN_VERSION "6.0.0") 13 | set(KDE_COMPILERSETTINGS_LEVEL "5.82") 14 | 15 | find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE) 16 | 17 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules") 18 | 19 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} 20 | ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake) 21 | 22 | set(CMAKE_CXX_STANDARD 20) 23 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 24 | 25 | include(ECMInstallIcons) 26 | include(KDEInstallDirs6) 27 | include(KDECMakeSettings) 28 | include(KDECompilerSettings NO_POLICY_SCOPE) 29 | include(GenerateExportHeader) 30 | include(KDEClangFormat) 31 | # include(GtkUpdateIconCache) 32 | 33 | find_package(KDecoration3 REQUIRED) 34 | 35 | if(NOT WIN32 AND NOT APPLE) 36 | find_package(KF6KCMUtils ${KF6_MIN_VERSION}) 37 | set_package_properties( 38 | KF6KCMUtils PROPERTIES 39 | TYPE REQUIRED 40 | DESCRIPTION "Helps create configuration modules" 41 | PURPOSE 42 | "KCMUtils used for the configuration modules or the decoration and Qt Style" 43 | ) 44 | endif() 45 | 46 | # old stuff 47 | add_definitions(-DTRANSLATION_DOMAIN="breeze_kwin_deco") 48 | 49 | find_package( 50 | KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS IconThemes CoreAddons GuiAddons 51 | ConfigWidgets WindowSystem I18n) 52 | find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} CONFIG REQUIRED 53 | COMPONENTS Widgets DBus) 54 | find_package(Qt6 REQUIRED COMPONENTS Core5Compat GuiPrivate) 55 | 56 | # XCB 57 | find_package(XCB COMPONENTS XCB) 58 | set_package_properties( 59 | XCB PROPERTIES 60 | DESCRIPTION "X protocol C-language Binding" 61 | URL "https://xcb.freedesktop.org/" 62 | TYPE OPTIONAL 63 | PURPOSE "Required to pass style properties to native Windows on X11 Platform") 64 | 65 | if(UNIX AND NOT APPLE) 66 | 67 | set(BREEZE_HAVE_X11 ${XCB_XCB_FOUND}) 68 | 69 | else() 70 | 71 | set(BREEZE_HAVE_X11 FALSE) 72 | 73 | endif() 74 | 75 | # ################ configuration ################# 76 | configure_file(config-breeze.h.cmake 77 | ${CMAKE_CURRENT_BINARY_DIR}/config-breeze.h) 78 | 79 | # ################ includes ################# 80 | add_subdirectory(libbreezecommon) 81 | 82 | # ################ newt target ################# 83 | # plugin classes 84 | set(sierrabreezeenhanced_SRCS 85 | breezebutton.cpp breezedecoration.cpp breezeexceptionlist.cpp 86 | breezesettingsprovider.cpp breezesizegrip.cpp) 87 | 88 | kconfig_add_kcfg_files(sierrabreezeenhanced_SRCS breezesettings.kcfgc) 89 | 90 | # config classes they are kept separately because they might move in a separate 91 | # library in the future 92 | set(sierrabreezeenhanced_config_SRCS 93 | config/breezeconfigwidget.cpp config/breezedetectwidget.cpp 94 | config/breezeexceptiondialog.cpp config/breezeexceptionlistwidget.cpp 95 | config/breezeexceptionmodel.cpp config/breezeitemmodel.cpp) 96 | 97 | set(sierrabreezeenhanced_config_PART_FORMS 98 | config/ui/breezeconfigurationui.ui 99 | config/ui/breezeexceptiondialog.ui config/ui/breezeexceptionlistwidget.ui) 100 | 101 | ki18n_wrap_ui(sierrabreezeenhanced_config_PART_FORMS_HEADERS 102 | ${sierrabreezeenhanced_config_PART_FORMS}) 103 | 104 | # build library 105 | add_library( 106 | sierrabreezeenhanced MODULE 107 | ${sierrabreezeenhanced_SRCS} ${sierrabreezeenhanced_config_SRCS} 108 | ${sierrabreezeenhanced_config_PART_FORMS_HEADERS}) 109 | 110 | target_link_libraries( 111 | sierrabreezeenhanced 112 | PUBLIC Qt6::Core Qt6::Gui Qt6::DBus Qt6::Core5Compat 113 | PRIVATE sierrabreezeenhancedcommon6 114 | KDecoration3::KDecoration 115 | KF6::IconThemes 116 | KF6::ConfigCore 117 | KF6::CoreAddons 118 | KF6::ConfigWidgets 119 | KF6::GuiAddons 120 | KF6::I18n 121 | KF6::KCMUtils 122 | KF6::WindowSystem) 123 | 124 | if(BREEZE_HAVE_X11) 125 | target_link_libraries(sierrabreezeenhanced PUBLIC Qt6::GuiPrivate XCB::XCB) 126 | endif() 127 | 128 | install(TARGETS sierrabreezeenhanced 129 | DESTINATION ${KDE_INSTALL_PLUGINDIR}/${KDECORATION_PLUGIN_DIR}) 130 | # install(FILES config/sierrabreezeenhancedconfig.desktop DESTINATION 131 | # ${SERVICES_INSTALL_DIR}) 132 | kcmutils_generate_desktop_file(sierrabreezeenhanced) 133 | 134 | # install(TARGETS breezedecoration DESTINATION 135 | # ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2) install(FILES 136 | # config/breezedecorationconfig.desktop DESTINATION ${SERVICES_INSTALL_DIR}) 137 | 138 | add_subdirectory(config) 139 | -------------------------------------------------------------------------------- /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 | 30 | #include 31 | 32 | class QVariantAnimation; 33 | 34 | namespace Breeze 35 | { 36 | 37 | class Button : public KDecoration3::DecorationButton 38 | { 39 | Q_OBJECT 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(KDecoration3::DecorationButtonType type, KDecoration3::Decoration *decoration, QObject *parent); 51 | 52 | //* render 53 | virtual void paint(QPainter *painter, const QRectF &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(KDecoration3::DecorationButtonType type, Decoration *decoration, QObject *parent = nullptr); 113 | 114 | //* draw button icon 115 | void drawIconPlasma( QPainter *) const; 116 | void drawIconGnome( QPainter *) const; 117 | void drawIconMacSierra( QPainter *) const; 118 | void drawIconMacDarkAurorae( QPainter *) const; 119 | void drawIconSBEsierra( QPainter *) const; 120 | void drawIconSBEdarkAurorae( QPainter *) const; 121 | void drawIconSierraColorSymbols( QPainter *) const; 122 | void drawIconDarkAuroraeColorSymbols( QPainter *) const; 123 | void drawIconSierraMonochromeSymbols( QPainter *) const; 124 | void drawIconDarkAuroraeMonochromeSymbols( QPainter *) const; 125 | 126 | //*@name colors 127 | //@{ 128 | QColor fontColor() const; 129 | QColor foregroundColor() const; 130 | QColor backgroundColor() const; 131 | QColor mixColors(const QColor&, const QColor&, qreal) const; 132 | QColor autoColor( const bool, const bool, const bool, const QColor, const QColor ) const; 133 | //@} 134 | 135 | //*@hover buttons 136 | //@{ 137 | bool hovered() const; 138 | //@} 139 | 140 | //*@button radius 141 | //@{ 142 | qreal buttonRadius() const; 143 | //@} 144 | 145 | Flag m_flag = FlagNone; 146 | 147 | //* active state change animation 148 | QVariantAnimation *m_animation; 149 | 150 | //* vertical offset (for rendering) 151 | QPointF m_offset; 152 | 153 | //* icon size 154 | QSizeF m_iconSize; 155 | 156 | //* active state change opacity 157 | qreal m_opacity = 0; 158 | }; 159 | 160 | } // namespace 161 | 162 | #endif 163 | -------------------------------------------------------------------------------- /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->setDrawTitleBarSeparator( exception.drawTitleBarSeparator() ); 63 | configuration->setOpaqueTitleBar( exception.opaqueTitleBar() ); 64 | configuration->setOpacityOverride( exception.opacityOverride() ); 65 | configuration->setDrawBackgroundGradient( exception.drawBackgroundGradient() ); 66 | configuration->setGradientOverride( exception.gradientOverride() ); 67 | configuration->setMatchColorForTitleBar( exception.matchColorForTitleBar() ); 68 | configuration->setIsDialog( exception.isDialog() ); 69 | 70 | // append to exceptions 71 | _exceptions.append( configuration ); 72 | 73 | } 74 | 75 | } 76 | 77 | //______________________________________________________________ 78 | void ExceptionList::writeConfig( KSharedConfig::Ptr config ) 79 | { 80 | 81 | // remove all existing exceptions 82 | QString groupName; 83 | for( int index = 0; config->hasGroup( groupName = exceptionGroupName( index ) ); ++index ) 84 | { config->deleteGroup( groupName ); } 85 | 86 | // rewrite current exceptions 87 | int index = 0; 88 | foreach( const InternalSettingsPtr& exception, _exceptions ) 89 | { 90 | 91 | writeConfig( exception.data(), config.data(), exceptionGroupName( index ) ); 92 | ++index; 93 | 94 | } 95 | 96 | } 97 | 98 | //_______________________________________________________________________ 99 | QString ExceptionList::exceptionGroupName( int index ) 100 | { return QString( "Windeco Exception %1" ).arg( index ); } 101 | 102 | //______________________________________________________________ 103 | void ExceptionList::writeConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName ) 104 | { 105 | 106 | // list of items to be written 107 | QStringList keys = { "Enabled", "ExceptionPattern", "ExceptionType", "HideTitleBar", "DrawTitleBarSeparator", "IsDialog", "OpaqueTitleBar", "OpacityOverride", "Mask", "BorderSize", "MatchColorForTitleBar", "DrawBackgroundGradient", "GradientOverride"}; 108 | 109 | // write all items 110 | foreach( auto key, keys ) 111 | { 112 | KConfigSkeletonItem* item( skeleton->findItem( key ) ); 113 | if( !item ) continue; 114 | 115 | if( !groupName.isEmpty() ) item->setGroup( groupName ); 116 | KConfigGroup configGroup( config, item->group() ); 117 | configGroup.writeEntry( item->key(), item->property() ); 118 | 119 | } 120 | 121 | } 122 | 123 | //______________________________________________________________ 124 | void ExceptionList::readConfig( KCoreConfigSkeleton* skeleton, KConfig* config, const QString& groupName ) 125 | { 126 | 127 | foreach( KConfigSkeletonItem* item, skeleton->items() ) 128 | { 129 | if( !groupName.isEmpty() ) item->setGroup( groupName ); 130 | item->readConfig( config ); 131 | } 132 | 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /breezesettingsdata.kcfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ShadowLarge 19 | 20 | 21 | 22 | 255 23 | 25 24 | 255 25 | 26 | 27 | 28 | 0, 0, 0 29 | 30 | 31 | 32 | false 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ShadowLargeInactiveWindows 44 | 45 | 46 | 47 | 255 48 | 25 49 | 255 50 | 51 | 52 | 53 | 0, 0, 0 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | BorderTiny 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | AlignCenterFullWidth 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | ButtonDefault 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | macDarkAurorae 122 | 123 | 124 | 125 | 2 126 | 127 | 128 | 129 | 4 130 | 131 | 132 | 133 | 0 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | Never 145 | 146 | 147 | 148 | 149 | false 150 | 151 | 152 | 153 | 154 | false 155 | 156 | 157 | 158 | 159 | true 160 | 161 | 162 | 163 | 164 | false 165 | 166 | 167 | 168 | 169 | 0 170 | 171 | 172 | 173 | 174 | true 175 | 176 | 177 | 178 | 20 179 | 180 | 181 | 182 | -1 183 | 184 | 185 | 186 | 187 | false 188 | 189 | 190 | 191 | 192 | true 193 | 194 | 195 | 196 | 197 | true 198 | 199 | 200 | 201 | 100 202 | 203 | 204 | 205 | -1 206 | 207 | 208 | 209 | 210 | 211 | 212 | true 213 | 214 | 215 | 216 | 150 217 | 218 | 219 | 220 |  221 |  false 222 |  223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | ExceptionWindowClassName 231 | 232 | 233 | 234 | 235 | 236 | true 237 | 238 | 239 | 240 | 0 241 | 242 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /config/kcm_sierrabreezeenhanceddecoration.json: -------------------------------------------------------------------------------- 1 | { 2 | "KPlugin": { 3 | "Description": "Modify the appearance of window decorations", 4 | "Description[ar]": "عدّل مظهر زخرفات النّوافذ", 5 | "Description[bg]": "Промяна на външния вид на декорацията на прозорците", 6 | "Description[ca@valencia]": "Modifica l'aparença de les decoracions de les finestres", 7 | "Description[ca]": "Modifica l'aparença de les decoracions de les finestres", 8 | "Description[cs]": "Změnit vzhled dekorace oken", 9 | "Description[de]": "Das Erscheinungsbild der Fensterdekoration ändern", 10 | "Description[el]": "Τροποποίηση της εμφάνισης των διακοσμητικών στοιχείων των παραθύρων", 11 | "Description[en_GB]": "Modify the appearance of window decorations", 12 | "Description[eo]": "Modifi la aspekton de fenestraĵaj ornamaĵoj", 13 | "Description[es]": "Modificar el aspecto de las decoraciones de ventanas", 14 | "Description[eu]": "Leiho apainduren itxura aldatzea", 15 | "Description[fi]": "Muuta ikkunakoristeiden ulkoasua", 16 | "Description[fr]": "Modifier l'apparence des décorations de fenêtres", 17 | "Description[gl]": "Modifica a aparencia da decoración da xanela.", 18 | "Description[he]": "שינוי מראה עיטורי החלונות", 19 | "Description[hu]": "Az ablakdekorációk megjelenésének módosítása", 20 | "Description[ia]": "Modifica le apparentia de decorationes de fenestra", 21 | "Description[id]": "Ubah tampilan dekorasi jendela", 22 | "Description[is]": "Breyta útliti gluggaskreytinga", 23 | "Description[it]": "Modifica l'aspetto delle decorazioni delle finestre", 24 | "Description[ka]": "ფანჯრის დეკორაციებს გარეგნობის შეცვლა", 25 | "Description[ko]": "창 장식의 모양을 수정합니다", 26 | "Description[lt]": "Modifiktuoti lango dekoracijų išvaizdą", 27 | "Description[lv]": "Pielāgojiet logu noformējumu", 28 | "Description[nl]": "Wijzig het uiterlijk van vensterdecoraties", 29 | "Description[nn]": "Endra utsjånad på vindaugspynt", 30 | "Description[pa]": "ਵਿੰਡੋ ਸਜਾਵਟ ਦੀ ਦਿੱਖ ਨੂੰ ਸੋਧੋ", 31 | "Description[pl]": "Zmień wygląd okien", 32 | "Description[pt]": "Modificar a aparência das decorações das janelas", 33 | "Description[pt_BR]": "Modifica a aparência das decorações da janela", 34 | "Description[ro]": "Modifică aspectul decorațiilor pentru ferestre", 35 | "Description[ru]": "Настройка заголовков окон", 36 | "Description[sk]": "Zmeniť vzhľad dekorácie okien", 37 | "Description[sl]": "Spremeni videz okenskih okraskov", 38 | "Description[sv]": "Ändra utseendet hos fönsterdekorationer", 39 | "Description[tr]": "Pencere dekorasyonlarının görünüşünü değiştirin", 40 | "Description[uk]": "Внесення змін до обрамлення вікон", 41 | "Description[x-test]": "xxModify the appearance of window decorationsxx", 42 | "Description[zh_CN]": "调整窗口装饰外观", 43 | "Description[zh_TW]": "修改視窗裝飾的外觀", 44 | "Icon": "preferences-system-windows", 45 | "Name": "Breeze Window Decoration", 46 | "Name[ar]": "زخرفة نوافذ نسيم", 47 | "Name[bg]": "Декорации на прозорци Breeze", 48 | "Name[ca@valencia]": "Decoració Brisa de les finestres", 49 | "Name[ca]": "Decoració Brisa de les finestres", 50 | "Name[cs]": "Dekorace oken Breeze", 51 | "Name[de]": "Breeze-Fensterdekoration", 52 | "Name[el]": "Breeze διακόσμηση παραθύρου", 53 | "Name[en_GB]": "Breeze Window Decoration", 54 | "Name[eo]": "Breeze-fenestraĵornamoj", 55 | "Name[es]": "Decoración de ventanas Brisa", 56 | "Name[eu]": "Breeze leihoen apaindura", 57 | "Name[fi]": "Breeze-ikkunakoristelu", 58 | "Name[fr]": "Décoration de fenêtre pour Breeze", 59 | "Name[gl]": "Decoración de xanela de Brisa", 60 | "Name[he]": "עיטור חלונות בריזה", 61 | "Name[hu]": "Breeze ablakdekoráció", 62 | "Name[ia]": "Decoration de fenestra Breeze", 63 | "Name[id]": "Dekorasi Jendela Breeze", 64 | "Name[is]": "Breeze gluggaskreytingar", 65 | "Name[it]": "Decorazione delle finestre di Brezza", 66 | "Name[ka]": "Breeze -ის ფანჯრის დეკორაცია", 67 | "Name[ko]": "Breeze 창 장식", 68 | "Name[lt]": "Breeze lango dekoracijos", 69 | "Name[lv]": "„Breeze“ logu noformējums", 70 | "Name[nl]": "Breeze vensterdecoratie", 71 | "Name[nn]": "Breeze-vindaugspynt", 72 | "Name[pa]": "ਬਰੀਜ਼ ਵਿੰਡੋ ਸਜਾਵਟ", 73 | "Name[pl]": "Wygląd okien Bryzy", 74 | "Name[pt]": "Decoração de Janelas Brisa", 75 | "Name[pt_BR]": "Decorações da janela Breeze", 76 | "Name[ro]": "Decorații pentru ferestre Briză", 77 | "Name[ru]": "Оформление окон Breeze", 78 | "Name[sk]": "Dekorácie okien Vánok", 79 | "Name[sl]": "Okraski oken Sapice", 80 | "Name[sv]": "Breeze fönsterdekoration", 81 | "Name[tr]": "Esinti Pencere Dekorasyonu", 82 | "Name[uk]": "Обрамлення вікон Breeze", 83 | "Name[x-test]": "xxBreeze Window Decorationxx", 84 | "Name[zh_CN]": "Breeze 微风窗口装饰", 85 | "Name[zh_TW]": "Breeze 視窗裝飾", 86 | "ServiceTypes": [ 87 | "KCModule" 88 | ] 89 | }, 90 | "X-KDE-Keywords": "breeze,decoration", 91 | "X-KDE-Keywords[ar]": "نسيم,زخرفة", 92 | "X-KDE-Keywords[az]": "breeze,dekorasiya", 93 | "X-KDE-Keywords[bg]": "breeze,декорации", 94 | "X-KDE-Keywords[ca@valencia]": "breeze,brisa,decoració", 95 | "X-KDE-Keywords[ca]": "breeze,brisa,decoració", 96 | "X-KDE-Keywords[cs]": "breeze,dekorace", 97 | "X-KDE-Keywords[da]": "breeze,dekoration", 98 | "X-KDE-Keywords[de]": "Dekoration", 99 | "X-KDE-Keywords[el]": "breeze,διακόσμηση", 100 | "X-KDE-Keywords[en_GB]": "breeze,decoration", 101 | "X-KDE-Keywords[es]": "breeze,brisa,decoración", 102 | "X-KDE-Keywords[et]": "breeze,dekoratsioon", 103 | "X-KDE-Keywords[eu]": "breeze,apainketa,apaindura", 104 | "X-KDE-Keywords[fi]": "breeze,decoration,kehys,koriste,koristus,ikkunakehys", 105 | "X-KDE-Keywords[fr]": "brise,décoration", 106 | "X-KDE-Keywords[gl]": "breeze,decoración", 107 | "X-KDE-Keywords[he]": "breeze,decoration,מסגרת", 108 | "X-KDE-Keywords[hi]": "ब्रीज़, सजावट", 109 | "X-KDE-Keywords[hu]": "breeze,dekoráció", 110 | "X-KDE-Keywords[ia]": "breeze,decoration", 111 | "X-KDE-Keywords[id]": "breeze,dekorasi", 112 | "X-KDE-Keywords[it]": "brezza,decorazione", 113 | "X-KDE-Keywords[ja]": "breeze,decoration", 114 | "X-KDE-Keywords[ko]": "breeze,decoration,장식", 115 | "X-KDE-Keywords[lt]": "breeze,dekoracija", 116 | "X-KDE-Keywords[nb]": "beeze,dekorasjon", 117 | "X-KDE-Keywords[nl]": "breeze,decoratie", 118 | "X-KDE-Keywords[nn]": "breeze,dekorasjonar,pynt", 119 | "X-KDE-Keywords[pa]": "ਬਰੀਜ਼,ਸਜਾਵਟ", 120 | "X-KDE-Keywords[pl]": "breeze,dekoracja,bryza,wystrój", 121 | "X-KDE-Keywords[pt]": "brisa,decoração", 122 | "X-KDE-Keywords[pt_BR]": "breeze,decoração", 123 | "X-KDE-Keywords[ro]": "briză,breeze,decorare,decorație", 124 | "X-KDE-Keywords[ru]": "breeze,бриз,decoration,декорации окон,оформление окон", 125 | "X-KDE-Keywords[sk]": "vánok,dekorácia", 126 | "X-KDE-Keywords[sl]": "sapica,okraski,okrasitev,breeze", 127 | "X-KDE-Keywords[sr@ijekavian]": "breeze,decoration,Поветарац,декорација", 128 | "X-KDE-Keywords[sr@ijekavianlatin]": "breeze,decoration,Povetarac,dekoracija", 129 | "X-KDE-Keywords[sr@latin]": "breeze,decoration,Povetarac,dekoracija", 130 | "X-KDE-Keywords[sr]": "breeze,decoration,Поветарац,декорација", 131 | "X-KDE-Keywords[sv]": "breeze,dekoration", 132 | "X-KDE-Keywords[tg]": "насим,ороиш", 133 | "X-KDE-Keywords[tr]": "esinti,dekorasyon", 134 | "X-KDE-Keywords[uk]": "breeze,decoration,бриз,декорації,декорація,обрамлення", 135 | "X-KDE-Keywords[x-test]": "xxbreezexx,xxdecorationxx", 136 | "X-KDE-Keywords[zh_CN]": "breeze,微风,装饰,修饰", 137 | "X-KDE-Keywords[zh_TW]": "breeze,decoration", 138 | "X-KDE-ParentApp": "kcontrol", 139 | "X-KDE-Weight": 60 140 | } 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 | #include 36 | 37 | class QVariantAnimation; 38 | 39 | namespace KDecoration3 40 | { 41 | class DecorationButton; 42 | class DecorationButtonGroup; 43 | } 44 | 45 | namespace Breeze 46 | { 47 | class SizeGrip; 48 | class Button; 49 | class Decoration : public KDecoration3::Decoration 50 | { 51 | Q_OBJECT 52 | 53 | public: 54 | 55 | //* constructor 56 | explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList()); 57 | 58 | //* destructor 59 | virtual ~Decoration(); 60 | 61 | //* paint 62 | void paint(QPainter *painter, const QRectF &repaintRegion) override; 63 | 64 | //* internal settings 65 | InternalSettingsPtr internalSettings() const 66 | { return m_internalSettings; } 67 | 68 | //* caption height 69 | int captionHeight() const; 70 | 71 | //* button height 72 | int buttonHeight() const; 73 | 74 | //*@name active state change animation 75 | //@{ 76 | void setOpacity( qreal ); 77 | 78 | qreal opacity() const 79 | { return m_opacity; } 80 | 81 | //@} 82 | 83 | //*@name colors 84 | //@{ 85 | QColor titleBarColor() const; 86 | QColor outlineColor() const; 87 | QColor rawTitleBarColor() const; 88 | QColor fontColor() const; 89 | //@} 90 | 91 | //*@name maximization modes 92 | //@{ 93 | inline bool isMaximized() const; 94 | inline bool isMaximizedHorizontally() const; 95 | inline bool isMaximizedVertically() const; 96 | 97 | inline bool isLeftEdge() const; 98 | inline bool isRightEdge() const; 99 | inline bool isTopEdge() const; 100 | inline bool isBottomEdge() const; 101 | 102 | inline bool hideTitleBar() const; 103 | inline int titleBarAlpha() const; 104 | inline bool matchColorForTitleBar() const; 105 | inline bool drawBackgroundGradient() const; 106 | inline bool systemForegroundColor() const; 107 | //@} 108 | 109 | //*@Decoration has a hovered button 110 | //@{ 111 | bool m_buttonHovered = false; 112 | bool buttonHovered() const 113 | { return m_buttonHovered; } 114 | 115 | signals: 116 | void buttonHoveredChanged(); 117 | 118 | public Q_SLOTS: 119 | void setButtonHovered(bool value); 120 | 121 | protected: 122 | void hoverMoveEvent(QHoverEvent *event) override; 123 | //@} 124 | 125 | 126 | public Q_SLOTS: 127 | bool init() override; 128 | 129 | private Q_SLOTS: 130 | void reconfigure(); 131 | void recalculateBorders(); 132 | void updateButtonsGeometry(); 133 | void updateButtonsGeometryDelayed(); 134 | void updateTitleBar(); 135 | void updateAnimationState(); 136 | void updateSizeGripVisibility(); 137 | void updateBlur(); 138 | void createShadow(); 139 | 140 | private: 141 | 142 | //* return the rect in which caption will be drawn 143 | QPair captionRect() const; 144 | 145 | void createButtons(); 146 | void paintTitleBar(QPainter *painter, const QRectF &repaintRegion); 147 | void updateShadow(); 148 | void updateActiveShadow(); 149 | void updateInactiveShadow(); 150 | void calculateWindowAndTitleBarShapes(const bool windowShapeOnly=false); 151 | 152 | //*@name border size 153 | //@{ 154 | int borderSize(bool bottom = false) const; 155 | inline bool hasBorders() const; 156 | inline bool hasNoBorders() const; 157 | inline bool hasNoSideBorders() const; 158 | //@} 159 | 160 | //*@name size grip 161 | //@{ 162 | void createSizeGrip(); 163 | void deleteSizeGrip(); 164 | SizeGrip* sizeGrip() const 165 | { return m_sizeGrip; } 166 | //@} 167 | 168 | InternalSettingsPtr m_internalSettings; 169 | KDecoration3::DecorationButtonGroup *m_leftButtons = nullptr; 170 | KDecoration3::DecorationButtonGroup *m_rightButtons = nullptr; 171 | 172 | //* size grip widget 173 | SizeGrip *m_sizeGrip = nullptr; 174 | 175 | //* active state change animation 176 | QVariantAnimation *m_animation; 177 | 178 | //* active state change opacity 179 | qreal m_opacity = 0; 180 | 181 | //* Rectangular area of titlebar without clipped corners 182 | QRect m_titleRect; 183 | 184 | //* Exact titlebar path, with clipped rounded corners 185 | std::shared_ptr m_titleBarPath = std::make_shared(); 186 | //* Exact window path, with clipped rounded corners 187 | std::shared_ptr m_windowPath = std::make_shared(); 188 | }; 189 | 190 | bool Decoration::hasBorders() const 191 | { 192 | if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() > InternalSettings::BorderNoSides; 193 | else return settings()->borderSize() > KDecoration3::BorderSize::NoSides; 194 | } 195 | 196 | bool Decoration::hasNoBorders() const 197 | { 198 | if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNone; 199 | else return settings()->borderSize() == KDecoration3::BorderSize::None; 200 | } 201 | 202 | bool Decoration::hasNoSideBorders() const 203 | { 204 | if( m_internalSettings && m_internalSettings->mask() & BorderSize ) return m_internalSettings->borderSize() == InternalSettings::BorderNoSides; 205 | else return settings()->borderSize() == KDecoration3::BorderSize::NoSides; 206 | } 207 | 208 | bool Decoration::isMaximized() const 209 | { return window()->isMaximized() && !m_internalSettings->drawBorderOnMaximizedWindows(); } 210 | 211 | bool Decoration::isMaximizedHorizontally() const 212 | { return window()->isMaximizedHorizontally() && !m_internalSettings->drawBorderOnMaximizedWindows(); } 213 | 214 | bool Decoration::isMaximizedVertically() const 215 | { return window()->isMaximizedVertically() && !m_internalSettings->drawBorderOnMaximizedWindows(); } 216 | 217 | bool Decoration::isLeftEdge() const 218 | { return (window()->isMaximizedHorizontally() || window()->adjacentScreenEdges().testFlag( Qt::LeftEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 219 | 220 | bool Decoration::isRightEdge() const 221 | { return (window()->isMaximizedHorizontally() || window()->adjacentScreenEdges().testFlag( Qt::RightEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 222 | 223 | bool Decoration::isTopEdge() const 224 | { return (window()->isMaximizedVertically() || window()->adjacentScreenEdges().testFlag( Qt::TopEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 225 | 226 | bool Decoration::isBottomEdge() const 227 | { return (window()->isMaximizedVertically() || window()->adjacentScreenEdges().testFlag( Qt::BottomEdge ) ) && !m_internalSettings->drawBorderOnMaximizedWindows(); } 228 | 229 | bool Decoration::hideTitleBar() const 230 | { return m_internalSettings->hideTitleBar() == 3 || ( m_internalSettings->hideTitleBar() == 1 && window()->isMaximized() ) || ( m_internalSettings->hideTitleBar() == 2 && ( window()->isMaximized() || window()->isMaximizedVertically() || window()->isMaximizedHorizontally()) ); } 231 | 232 | int Decoration::titleBarAlpha() const 233 | { 234 | if (m_internalSettings->opaqueTitleBar()) 235 | return 255; 236 | int a = m_internalSettings->opacityOverride() > -1 ? m_internalSettings->opacityOverride() : m_internalSettings->backgroundOpacity(); 237 | a = qBound(0, a, 100); 238 | return qRound(static_cast(a) * static_cast(2.55)); 239 | } 240 | 241 | bool Decoration::matchColorForTitleBar() const 242 | { return m_internalSettings->matchColorForTitleBar(); } 243 | 244 | bool Decoration::drawBackgroundGradient() const 245 | { return m_internalSettings->drawBackgroundGradient(); } 246 | 247 | bool Decoration::systemForegroundColor() const 248 | { return m_internalSettings->systemForegroundColor(); } 249 | } 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /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 | namespace Breeze 31 | { 32 | 33 | //___________________________________________ 34 | ExceptionDialog::ExceptionDialog( QWidget* parent ): 35 | QDialog( parent ) 36 | { 37 | 38 | m_ui.setupUi( this ); 39 | 40 | connect( m_ui.buttonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QWidget::close ); 41 | 42 | // store checkboxes from ui into list 43 | m_checkboxes.insert( BorderSize, m_ui.borderSizeCheckBox ); 44 | 45 | // detect window properties 46 | connect( m_ui.detectDialogButton, &QAbstractButton::clicked, this, &ExceptionDialog::selectWindowProperties ); 47 | 48 | // connections 49 | connect( m_ui.exceptionType, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 50 | connect( m_ui.exceptionEditor, &QLineEdit::textChanged, this, &ExceptionDialog::updateChanged ); 51 | connect( m_ui.borderSizeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 52 | 53 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 54 | { connect( iter.value(), &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); } 55 | 56 | connect( m_ui.hideTitleBar, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 57 | connect( m_ui.matchColorForTitleBar, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); 58 | connect( m_ui.systemForegroundColor, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); 59 | connect( m_ui.drawTitleBarSeparator, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); 60 | connect( m_ui.drawBackgroundGradient, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); 61 | m_ui.gradientOverrideLabelSpinBox->setSpecialValueText(tr("None")); 62 | connect( m_ui.gradientOverrideLabelSpinBox, QOverload::of(&QSpinBox::valueChanged), [this](int /*i*/){updateChanged();} ); 63 | connect( m_ui.opaqueTitleBar, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); 64 | m_ui.opacityOverrideLabelSpinBox->setSpecialValueText(tr("None")); 65 | connect( m_ui.opacityOverrideLabelSpinBox, QOverload::of(&QSpinBox::valueChanged), [this](int /*i*/){updateChanged();} ); 66 | connect( m_ui.isDialog, &QAbstractButton::clicked, this, &ExceptionDialog::updateChanged ); 67 | } 68 | 69 | //___________________________________________ 70 | void ExceptionDialog::setException( InternalSettingsPtr exception ) 71 | { 72 | 73 | // store exception internally 74 | m_exception = exception; 75 | 76 | // type 77 | m_ui.exceptionType->setCurrentIndex(m_exception->exceptionType() ); 78 | m_ui.exceptionEditor->setText( m_exception->exceptionPattern() ); 79 | m_ui.borderSizeComboBox->setCurrentIndex( m_exception->borderSize() ); 80 | m_ui.hideTitleBar->setCurrentIndex( m_exception->hideTitleBar() ); 81 | m_ui.matchColorForTitleBar->setChecked( m_exception->matchColorForTitleBar() ); 82 | m_ui.systemForegroundColor->setChecked( m_exception->systemForegroundColor() ); 83 | m_ui.drawTitleBarSeparator->setChecked( m_exception->drawTitleBarSeparator() ); 84 | m_ui.drawBackgroundGradient->setChecked( m_exception->drawBackgroundGradient() ); 85 | m_ui.gradientOverrideLabelSpinBox->setValue( m_exception->gradientOverride() ); 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->currentIndex() ); 105 | m_exception->setMatchColorForTitleBar( m_ui.matchColorForTitleBar->isChecked() ); 106 | m_exception->setSystemForegroundColor( m_ui.systemForegroundColor->isChecked() ); 107 | m_exception->setDrawTitleBarSeparator( m_ui.drawTitleBarSeparator->isChecked() ); 108 | m_exception->setDrawBackgroundGradient( m_ui.drawBackgroundGradient->isChecked() ); 109 | m_exception->setGradientOverride( m_ui.gradientOverrideLabelSpinBox->value() ); 110 | m_exception->setOpaqueTitleBar( m_ui.opaqueTitleBar->isChecked() ); 111 | m_exception->setOpacityOverride( m_ui.opacityOverrideLabelSpinBox->value() ); 112 | m_exception->setIsDialog( m_ui.isDialog->isChecked() ); 113 | 114 | // mask 115 | unsigned int mask = None; 116 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 117 | { if( iter.value()->isChecked() ) mask |= iter.key(); } 118 | 119 | m_exception->setMask( mask ); 120 | 121 | setChanged( false ); 122 | 123 | } 124 | 125 | //___________________________________________ 126 | void ExceptionDialog::updateChanged() 127 | { 128 | bool modified( false ); 129 | if( m_exception->exceptionType() != m_ui.exceptionType->currentIndex() ) modified = true; 130 | else if( m_exception->exceptionPattern() != m_ui.exceptionEditor->text() ) modified = true; 131 | else if( m_exception->borderSize() != m_ui.borderSizeComboBox->currentIndex() ) modified = true; 132 | else if( m_exception->hideTitleBar() != m_ui.hideTitleBar->currentIndex() ) modified = true; 133 | else if( m_exception->matchColorForTitleBar() != m_ui.matchColorForTitleBar->isChecked() ) modified = true; 134 | else if( m_exception->systemForegroundColor() != m_ui.systemForegroundColor->isChecked() ) modified = true; 135 | else if( m_exception->drawTitleBarSeparator() != m_ui.drawTitleBarSeparator->isChecked() ) modified = true; 136 | else if( m_exception->drawBackgroundGradient() != m_ui.drawBackgroundGradient->isChecked() ) modified = true; 137 | else if( m_exception->gradientOverride() != m_ui.gradientOverrideLabelSpinBox->value() ) modified = true; 138 | else if( m_exception->opaqueTitleBar() != m_ui.opaqueTitleBar->isChecked() ) modified = true; 139 | else if( m_exception->opacityOverride() != m_ui.opacityOverrideLabelSpinBox->value() ) modified = true; 140 | else if( m_exception->isDialog() != m_ui.isDialog->isChecked() ) modified = true; 141 | else 142 | { 143 | // check mask 144 | for( CheckBoxMap::iterator iter = m_checkboxes.begin(); iter != m_checkboxes.end(); ++iter ) 145 | { 146 | if( iter.value()->isChecked() != (bool)( m_exception->mask() & iter.key() ) ) 147 | { 148 | modified = true; 149 | break; 150 | } 151 | } 152 | } 153 | 154 | setChanged( modified ); 155 | 156 | } 157 | 158 | //___________________________________________ 159 | void ExceptionDialog::selectWindowProperties() 160 | { 161 | 162 | // create widget 163 | if( !m_detectDialog ) 164 | { 165 | m_detectDialog = new DetectDialog( this ); 166 | connect( m_detectDialog, &DetectDialog::detectionDone, this, &ExceptionDialog::readWindowProperties ); 167 | } 168 | 169 | m_detectDialog->detect(); 170 | 171 | } 172 | 173 | //___________________________________________ 174 | void ExceptionDialog::readWindowProperties( bool valid ) 175 | { 176 | Q_CHECK_PTR( m_detectDialog ); 177 | if( valid ) 178 | { 179 | 180 | // window info 181 | const QVariantMap properties = m_detectDialog->properties(); 182 | 183 | switch(m_ui.exceptionType->currentIndex()) 184 | { 185 | 186 | default: 187 | case InternalSettings::ExceptionWindowClassName: 188 | m_ui.exceptionEditor->setText(properties.value(QStringLiteral("resourceClass")).toString()); 189 | break; 190 | 191 | case InternalSettings::ExceptionWindowTitle: 192 | m_ui.exceptionEditor->setText(properties.value(QStringLiteral("caption")).toString()); 193 | break; 194 | 195 | } 196 | 197 | } 198 | 199 | delete m_detectDialog; 200 | m_detectDialog = nullptr; 201 | 202 | } 203 | 204 | } 205 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | V2.1.1 2 | -------- 3 | 4 | * Fixed CMakeLists Version 5 | 6 | V2.1.0 7 | -------- 8 | 9 | * Ported to Plasma 6.3 (thanks @rodevasia for the PR) 10 | 11 | 12 | V2.0.1 13 | -------- 14 | 15 | * Update README and ChangeLog 16 | * Fixed CMakeLists Version 17 | 18 | 19 | V2.0.0 20 | -------- 21 | 22 | * Ported to Plasma 6 (big thanks to @chiyuki0325 and @A1ca7raz) 23 | 24 | V1.3.3 25 | --------- 26 | 27 | * Restore gradients 28 | 29 | V1.3.2 30 | --------- 31 | 32 | * Fix issue #111 33 | 34 | V1.3.1 35 | --------- 36 | 37 | * Horizontal offset refinement 38 | 39 | V1.3.0 40 | --------- 41 | 42 | * fixes issues #89, #84, #85, #63 and further refinements 43 | 44 | V1.2.0 45 | --------- 46 | 47 | * Fixes issue #108 48 | 49 | V1.1.0 50 | --------- 51 | 52 | * Fixes blur for Plasma 5.25 53 | * Fixes settings window not showing 54 | * Fixes issues #104, #105 and #106 55 | 56 | Thanks @a-parhom for the pull request! 57 | 58 | V1.0.3 59 | --------- 60 | 61 | * fixes issue #101 62 | 63 | V1.0.2 64 | --------- 65 | 66 | * SBE detached from BE to increase Contributors visibility 67 | 68 | V1.0.1 69 | --------- 70 | 71 | * Match new Breeze upstream behavior introduced with Plasma 5.23+ (fixes issue #98; contributed by @DiabeticCrab, thanks!) 72 | 73 | V1.0.0 74 | --------- 75 | 76 | * Rename config file to avoid interference with upstream breezerc file (fixes issue #90) 77 | 78 | V0.9.5 79 | --------- 80 | 81 | * Upstream sync: Port away from deprecated Qt::MidButton 82 | * Upstream sync: use linear animations 83 | 84 | V0.9.4 85 | --------- 86 | 87 | * Upstream sync: color icons in titlebar if possible 88 | 89 | V0.9.3 90 | --------- 91 | 92 | * Symmetric and more subtle lighter/darker button outline 93 | 94 | V0.9.2 95 | --------- 96 | 97 | * Symmetric behavior of darker/ligther coloring 98 | 99 | V0.9.1 100 | --------- 101 | 102 | * More minimalistic title bar separator 103 | 104 | V0.9.0 105 | --------- 106 | 107 | * Extended resizing area now applies to the top border as well 108 | 109 | V0.9RC 110 | --------- 111 | 112 | * Added option for button horizontal offset 113 | 114 | * Enhanced resizing area now applies to SBE's tiny border, i.e., the 1 px outline border 115 | 116 | * Grip option now applies to to SBE's tiny border, i.e., the 1 px outline border 117 | 118 | V0.8.12 119 | --------- 120 | 121 | * Fixed regression in exception dialog 122 | 123 | V0.8.11 124 | --------- 125 | 126 | * Changes to be in sync with upstream Breeze 127 | 128 | V0.8.10 129 | --------- 130 | 131 | * fix ui warning 132 | 133 | V0.8.9 134 | --------- 135 | 136 | * added upstream updates from Breeze theme 137 | 138 | V0.8.8 139 | --------- 140 | 141 | * fix issue #62 142 | 143 | V0.8.7 144 | --------- 145 | 146 | * minor unison hovering adjustments 147 | 148 | V0.8.6 149 | --------- 150 | 151 | * fixes #59 152 | 153 | V0.8.5 154 | --------- 155 | 156 | * removed redundant font settings (see issue #57) 157 | * improved unison hovering communication with window buttons applet (contributed by @trmdi, thanks!) 158 | 159 | V0.8.4 160 | --------- 161 | 162 | * improved unison hovering (contributed by @trmdi, thanks!) 163 | * minor shadow adjustments 164 | * minor ui fix 165 | 166 | V0.8.3 167 | --------- 168 | 169 | * Further minor tweak of Dark Aurorae macOS and SBE themes under indirect unison hovering when animation is enabled 170 | 171 | V0.8.3 172 | --------- 173 | 174 | * Further minor tweak of Dark Aurorae macOS and SBE themes under indirect unison hovering when animation is enabled 175 | 176 | V0.8.2 177 | --------- 178 | 179 | * Readjustment of corner radius setting 180 | 181 | V0.8.1 182 | --------- 183 | 184 | * Minor tweak of Dark Aurorae macOS and SBE themes under indirect unison hovering when animation is enabled 185 | 186 | V0.8.0 187 | --------- 188 | 189 | * Better scaling for disabled animation 190 | 191 | V0.7.8 192 | --------- 193 | 194 | * Restyled Gnome Theme (Fixes #21) 195 | 196 | V0.7.7 197 | --------- 198 | 199 | * README update 200 | * SierraBreezeEnhanced renamed to Sierra Breeze Enhanced 201 | * Gradients apply to inactive windows but slightlier than to active windows 202 | * Resize of some Dark Aurorae symbols 203 | * mac renamed to macOS 204 | * Some cleaning 205 | 206 | V0.7.6 207 | --------- 208 | 209 | * Fix issue #49 210 | * Fix issue #50 211 | 212 | V0.7.5 213 | --------- 214 | 215 | * Unison Hovering option 216 | 217 | V0.7.4 218 | --------- 219 | 220 | * Reverting fix for glitches (issue #47) as it does not work consistently 221 | 222 | V0.7.3 223 | --------- 224 | 225 | * Hovering symbols at unison (mac Sierra style only for now) 226 | * Fixed window outline adjustment 227 | * Better support when alpha is disabled 228 | * Tentative fix for glitches (issue #47) 229 | 230 | V0.7.2 231 | --------- 232 | 233 | * Further improvement of TitleBar Gradient and Line Separation 234 | * Added line separation override 235 | * Button padding applies both horizontally and vertically (nice method to adjust title bar height) 236 | * Tiny border reduces now to window outline, all other borders move accordingly, normal is prev tiny, big is prev normal, etc. 237 | * Added hide title bar option under any maximization, including V/H 238 | 239 | V0.7.1 240 | --------- 241 | 242 | * Improved Behavior of TitleBar Gradient and Line Separation 243 | 244 | V0.7.0 245 | --------- 246 | 247 | * Rearranged button styles 248 | * Added macOS styles (Sierra and Dark Aurorae symbols) 249 | * macOS Dark Aurorae is new default 250 | * Adapted traffic colors (more similar to macOS Catalina) 251 | * Thinner ring borders (more similar to macOS Catalina) 252 | * Added Dark Aurorae symbol styles (color and monochrome) 253 | * Checked buttons now occupy all available space (including that of animation) 254 | * Many minor fixes and improved consistency 255 | 256 | V0.6.3 257 | --------- 258 | 259 | * Three options for hiding window title bars (never, always and only for maximized windows) 260 | 261 | V0.6.2 262 | --------- 263 | 264 | * Fine-tuning of one-by-one outer rings 265 | 266 | V0.6.1 267 | --------- 268 | 269 | * Softer outer ring on dark themes 270 | 271 | V0.6.0 272 | --------- 273 | 274 | * Enabled option to hide title bar 275 | * Nicer hide title bar behavior (it actually keeps a title bar as minimalistic as it can be to save vertical space; thought for laptops using window appMenu and window buttons in a latte panel) 276 | * Fixed issue in Symbol Style Minimal 277 | * Improved outer ring contrast 278 | * Fixed issue with titlebar color (issue #36) 279 | 280 | V0.5.3 281 | --------- 282 | 283 | * Better ring outlines 284 | 285 | V0.5.2 286 | --------- 287 | 288 | * Many fixes to border lines 289 | 290 | V0.5.1 291 | --------- 292 | 293 | * Fixes broken Corner Radius from added border lines 294 | 295 | V0.5.0 296 | --------- 297 | 298 | * Arguably better switch between light and dark colors 299 | * Added border lines (fixes issue 12) 300 | * Added outline to filled rings (fixes issue 23) 301 | * Added new Symbol Style Minimal (monocolor; fixes issue 28) 302 | * Some minor improvements to Gnome Style 303 | 304 | V0.4.10 305 | --------- 306 | 307 | Full consistency between buttons and foreground text colors 308 | * Particularly useful when using kwin auto titlebars colors https://github.com/ArturGaspar/kwin_auto_titlebar_colours 309 | 310 | V0.4.9 311 | --------- 312 | 313 | Reverting the "blur" setting in breeze.json to true 314 | 315 | V0.4.8 316 | --------- 317 | 318 | Changing "blur" to false in breeze.json as explained in pull request #32 319 | 320 | V0.4.7 321 | --------- 322 | 323 | * Added a new style 324 | * Added `Button horizontal padding` in the settings: when using "high" value of corner radius it may be useful to move the buttons a little bit more toward the inside. 325 | * Aligned a few items in the General tab of the Settings 326 | 327 | V0.4.6 328 | --------- 329 | 330 | * Changes to be in sync with upstream Breeze 331 | * Added the checkbox "Only for dialogs" to the exception dialog to support separate settings for dialogs (Ported from BreezeEnhanced). 332 | 333 | V0.4.5 334 | --------- 335 | 336 | * Scale icon size to resemble buttons size 337 | * Shadow intrinsics as in vanilla breeze 338 | * Automatic gradient direction and smoother appearance 339 | * Added a new restore symbol 340 | * Added (actually recovered) vanilla breeze button style 341 | * Added button style similar to adwaita/materia 342 | * Added Dark-Aurorae button style (with new checked alldesktop symbol) 343 | * Exchange colors between keepabove and shade 344 | 345 | 346 | V0.4.4 347 | --------- 348 | 349 | * Defaulting now to small spacing 350 | 351 | V0.4.3 352 | --------- 353 | 354 | * Added option to adjust corner radius 355 | 356 | V0.4.2 357 | --------- 358 | 359 | * Dim buttons of inactive windows under matchTitleBar option for further consistency 360 | 361 | V0.4.1 362 | --------- 363 | 364 | * Dim inactive window to make them less salient under certain circumstances (issue #11): 365 | - Dim title of inactive windows under matchTitleBar option 366 | - Dim buttons of inactive windows under (inactive button style && matchTitleBar) options 367 | 368 | V0.4 369 | --------- 370 | 371 | * Option to override matchTitleBar behavior for specific applications (especially useful for applications such as konsole and qView) 372 | * Option to override gradients for specific applications 373 | * Specific shadow properties for inactive windows 374 | 375 | V0.3.2 376 | --------- 377 | 378 | * Borders opacity further improvement. 379 | 380 | V0.3.1 381 | --------- 382 | 383 | * Fixed borders opacity. 384 | * Better description of shadows setting on inactive windows: "Small shadows on inactive windows". 385 | 386 | V0.3 387 | --------- 388 | 389 | * Added option to display small shadows for inactive windows as a way to make the active window more salient wrt others (issue #4). 390 | * Ported Match Title Bar Color from Sierra Breeze. It matches the "BackgroundNormal" color under "Windows" section of the color scheme. Title Bar Text Color is manipulated to guarantee visibility (issue #5). 391 | * Ported Font Weight Combobox from Breeze Enhanced. 392 | * Other minor fixes and code clean-up. 393 | 394 | V0.2 395 | --------- 396 | 397 | * Added settings option for decoration style: 398 | - distinct decoration for active and inactive windows (default). 399 | - use the active decoration also for inactive windows. 400 | - use the inactive decoration also for the active window. 401 | 402 | V0.1.2 403 | --------- 404 | 405 | * Fixed version numbering. 406 | 407 | V0.1.1 408 | --------- 409 | 410 | * Symbol properties (line colors and width) now apply to the menu button. 411 | 412 | V0.1 413 | --------- 414 | * First version of the fork (arguably more minimalistic and informative behavior): 415 | - non-gray colors do not change. 416 | - active window: show symbol on hovering. 417 | - inactive window: always show symbol, show ring color on hovering. 418 | - application menu button is considered special and stays as in vanilla breeze. 419 | - no more option for non macOS-like buttons as it doesn't apply anymore. 420 | -------------------------------------------------------------------------------- /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->window(); 66 | connect( c, &KDecoration3::DecoratedWindow::widthChanged, this, &SizeGrip::updatePosition ); 67 | connect( c, &KDecoration3::DecoratedWindow::heightChanged, this, &SizeGrip::updatePosition ); 68 | connect( c, &KDecoration3::DecoratedWindow::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()->window(); 103 | 104 | // xcb_window_t windowId = QX11Info::appRootWindow(); //FIXME: looking for client but don't know how 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, &QWidget::show); 166 | break; 167 | } 168 | 169 | case Qt::MiddleButton: 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()->window(); 195 | QPoint position( 196 | c->width() - static_cast(GripSize) - static_cast(Offset), 197 | c->height() - static_cast(GripSize) - static_cast(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()->window(); // FIXME: need to find a way to get windowId 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(); // FIXME: need to find a way to get 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 | -------------------------------------------------------------------------------- /libbreezecommon/breezeboxshadowrenderer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2018 Vlad Zahorodnii 3 | * 4 | * The box blur implementation is based on AlphaBoxBlur from Firefox. 5 | * 6 | * SPDX-License-Identifier: GPL-2.0-or-later 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16 | */ 17 | 18 | // own 19 | #include "breezeboxshadowrenderer.h" 20 | 21 | // Qt 22 | #include 23 | #include 24 | 25 | namespace Breeze 26 | { 27 | static inline int calculateBlurRadius(qreal stdDev) 28 | { 29 | // See https://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement 30 | const qreal gaussianScaleFactor = (3.0 * qSqrt(2.0 * M_PI) / 4.0) * 1.5; 31 | return qMax(2, qFloor(stdDev * gaussianScaleFactor + 0.5)); 32 | } 33 | 34 | static inline qreal calculateBlurStdDev(int radius) 35 | { 36 | // See https://www.w3.org/TR/css-backgrounds-3/#shadow-blur 37 | return radius * 0.5; 38 | } 39 | 40 | static inline QSize calculateBlurExtent(int radius) 41 | { 42 | const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius)); 43 | return QSize(blurRadius, blurRadius); 44 | } 45 | 46 | struct BoxLobes { 47 | int left; ///< how many pixels sample to the left 48 | int right; ///< how many pixels sample to the right 49 | }; 50 | 51 | /** 52 | * Compute box filter parameters. 53 | * 54 | * @param radius The blur radius. 55 | * @returns Parameters for three box filters. 56 | **/ 57 | static QVector computeLobes(int radius) 58 | { 59 | const int blurRadius = calculateBlurRadius(calculateBlurStdDev(radius)); 60 | const int z = blurRadius / 3; 61 | 62 | int major; 63 | int minor; 64 | int final; 65 | 66 | switch (blurRadius % 3) { 67 | case 0: 68 | major = z; 69 | minor = z; 70 | final = z; 71 | break; 72 | 73 | case 1: 74 | major = z + 1; 75 | minor = z; 76 | final = z; 77 | break; 78 | 79 | case 2: 80 | major = z + 1; 81 | minor = z; 82 | final = z + 1; 83 | break; 84 | 85 | default: 86 | Q_UNREACHABLE(); 87 | } 88 | 89 | Q_ASSERT(major + minor + final == blurRadius); 90 | 91 | return {{major, minor}, {minor, major}, {final, final}}; 92 | } 93 | 94 | /** 95 | * Process a row with a box filter. 96 | * 97 | * @param src The start of the row. 98 | * @param dst The destination. 99 | * @param width The width of the row, in pixels. 100 | * @param horizontalStride The number of bytes from one alpha value to the 101 | * next alpha value. 102 | * @param verticalStride The number of bytes from one row to the next row. 103 | * @param lobes Params of the box filter. 104 | * @param transposeInput Whether the input is transposed. 105 | * @param transposeOutput Whether the output should be transposed. 106 | **/ 107 | static inline void boxBlurRowAlpha(const uint8_t *src, 108 | uint8_t *dst, 109 | int width, 110 | int horizontalStride, 111 | int verticalStride, 112 | const BoxLobes &lobes, 113 | bool transposeInput, 114 | bool transposeOutput) 115 | { 116 | const int inputStep = transposeInput ? verticalStride : horizontalStride; 117 | const int outputStep = transposeOutput ? verticalStride : horizontalStride; 118 | 119 | const int boxSize = lobes.left + 1 + lobes.right; 120 | const int reciprocal = (1 << 24) / boxSize; 121 | 122 | uint32_t alphaSum = (boxSize + 1) / 2; 123 | 124 | const uint8_t *left = src; 125 | const uint8_t *right = src; 126 | uint8_t *out = dst; 127 | 128 | const uint8_t firstValue = src[0]; 129 | const uint8_t lastValue = src[(width - 1) * inputStep]; 130 | 131 | alphaSum += firstValue * lobes.left; 132 | 133 | const uint8_t *initEnd = src + (boxSize - lobes.left) * inputStep; 134 | while (right < initEnd) { 135 | alphaSum += *right; 136 | right += inputStep; 137 | } 138 | 139 | const uint8_t *leftEnd = src + boxSize * inputStep; 140 | while (right < leftEnd) { 141 | *out = (alphaSum * reciprocal) >> 24; 142 | alphaSum += *right - firstValue; 143 | right += inputStep; 144 | out += outputStep; 145 | } 146 | 147 | const uint8_t *centerEnd = src + width * inputStep; 148 | while (right < centerEnd) { 149 | *out = (alphaSum * reciprocal) >> 24; 150 | alphaSum += *right - *left; 151 | left += inputStep; 152 | right += inputStep; 153 | out += outputStep; 154 | } 155 | 156 | const uint8_t *rightEnd = dst + width * outputStep; 157 | while (out < rightEnd) { 158 | *out = (alphaSum * reciprocal) >> 24; 159 | alphaSum += lastValue - *left; 160 | left += inputStep; 161 | out += outputStep; 162 | } 163 | } 164 | 165 | /** 166 | * Blur the alpha channel of a given image. 167 | * 168 | * @param image The input image. 169 | * @param radius The blur radius. 170 | * @param rect Specifies what part of the image to blur. If nothing is provided, then 171 | * the whole alpha channel of the input image will be blurred. 172 | **/ 173 | static inline void boxBlurAlpha(QImage &image, int radius, const QRect &rect = {}) 174 | { 175 | if (radius < 2) { 176 | return; 177 | } 178 | 179 | const QVector lobes = computeLobes(radius); 180 | 181 | const QRect blurRect = rect.isNull() ? image.rect() : rect; 182 | 183 | const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3; 184 | const int width = blurRect.width(); 185 | const int height = blurRect.height(); 186 | const int rowStride = image.bytesPerLine(); 187 | const int pixelStride = image.depth() >> 3; 188 | 189 | const int bufferStride = qMax(width, height) * pixelStride; 190 | QScopedPointer> buf(new uint8_t[2 * bufferStride]); 191 | uint8_t *buf1 = buf.data(); 192 | uint8_t *buf2 = buf1 + bufferStride; 193 | 194 | // Blur the image in horizontal direction. 195 | for (int i = 0; i < height; ++i) { 196 | uint8_t *row = image.scanLine(blurRect.y() + i) + blurRect.x() * pixelStride + alphaOffset; 197 | boxBlurRowAlpha(row, buf1, width, pixelStride, rowStride, lobes[0], false, false); 198 | boxBlurRowAlpha(buf1, buf2, width, pixelStride, rowStride, lobes[1], false, false); 199 | boxBlurRowAlpha(buf2, row, width, pixelStride, rowStride, lobes[2], false, false); 200 | } 201 | 202 | // Blur the image in vertical direction. 203 | for (int i = 0; i < width; ++i) { 204 | uint8_t *column = image.scanLine(blurRect.y()) + (blurRect.x() + i) * pixelStride + alphaOffset; 205 | boxBlurRowAlpha(column, buf1, height, pixelStride, rowStride, lobes[0], true, false); 206 | boxBlurRowAlpha(buf1, buf2, height, pixelStride, rowStride, lobes[1], false, false); 207 | boxBlurRowAlpha(buf2, column, height, pixelStride, rowStride, lobes[2], false, true); 208 | } 209 | } 210 | 211 | static inline void mirrorTopLeftQuadrant(QImage &image) 212 | { 213 | const int width = image.width(); 214 | const int height = image.height(); 215 | 216 | const int centerX = qCeil(width * 0.5); 217 | const int centerY = qCeil(height * 0.5); 218 | 219 | const int alphaOffset = QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3; 220 | const int stride = image.depth() >> 3; 221 | 222 | for (int y = 0; y < centerY; ++y) { 223 | uint8_t *in = image.scanLine(y) + alphaOffset; 224 | uint8_t *out = in + (width - 1) * stride; 225 | 226 | for (int x = 0; x < centerX; ++x, in += stride, out -= stride) { 227 | *out = *in; 228 | } 229 | } 230 | 231 | for (int y = 0; y < centerY; ++y) { 232 | const uint8_t *in = image.scanLine(y) + alphaOffset; 233 | uint8_t *out = image.scanLine(width - y - 1) + alphaOffset; 234 | 235 | for (int x = 0; x < width; ++x, in += stride, out += stride) { 236 | *out = *in; 237 | } 238 | } 239 | } 240 | 241 | static void renderShadow(QPainter *painter, const QRectF &rect, qreal borderRadius, const QPointF &offset, double radius, const QColor &color) 242 | { 243 | const qreal dpr = painter->device()->devicePixelRatioF(); 244 | const QSize inflation = calculateBlurExtent(radius); 245 | const QSize pixelSize = ((rect.size() + 2 * inflation) * dpr).toSize(); 246 | const QSizeF size = QSizeF(pixelSize) / dpr; 247 | 248 | QImage shadow(pixelSize, QImage::Format_ARGB32_Premultiplied); 249 | shadow.setDevicePixelRatio(dpr); 250 | shadow.fill(Qt::transparent); 251 | 252 | QRectF boxRect(QPoint(0, 0), rect.size()); 253 | boxRect.moveCenter(QRectF(QPoint(0, 0), size).center()); 254 | 255 | const qreal xRadius = 2.0 * borderRadius / boxRect.width(); 256 | const qreal yRadius = 2.0 * borderRadius / boxRect.height(); 257 | 258 | QPainter shadowPainter; 259 | shadowPainter.begin(&shadow); 260 | shadowPainter.setRenderHint(QPainter::Antialiasing); 261 | shadowPainter.setPen(Qt::NoPen); 262 | shadowPainter.setBrush(Qt::black); 263 | shadowPainter.drawRoundedRect(boxRect, xRadius, yRadius); 264 | shadowPainter.end(); 265 | 266 | // Because the shadow texture is symmetrical, that's enough to blur 267 | // only the top-left quadrant and then mirror it. 268 | const QRect blurRect(0, 0, std::ceil(shadow.width() * 0.5), std::ceil(shadow.height() * 0.5)); 269 | const int scaledRadius = std::round(radius * dpr); 270 | boxBlurAlpha(shadow, scaledRadius, blurRect); 271 | mirrorTopLeftQuadrant(shadow); 272 | 273 | // Give the shadow a tint of the desired color. 274 | shadowPainter.begin(&shadow); 275 | shadowPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); 276 | shadowPainter.fillRect(shadow.rect(), color); 277 | shadowPainter.end(); 278 | 279 | // Actually, present the shadow. 280 | QRectF shadowRect = shadow.rect(); 281 | shadowRect.setSize(shadowRect.size() / dpr); 282 | shadowRect.moveCenter(rect.center() + offset); 283 | painter->drawImage(shadowRect, shadow); 284 | } 285 | 286 | void BoxShadowRenderer::setBoxSize(const QSizeF &size) 287 | { 288 | m_boxSize = size; 289 | } 290 | 291 | void BoxShadowRenderer::setBorderRadius(qreal radius) 292 | { 293 | m_borderRadius = radius; 294 | } 295 | 296 | void BoxShadowRenderer::addShadow(const QPointF &offset, double radius, const QColor &color) 297 | { 298 | Shadow shadow = {}; 299 | shadow.offset = offset; 300 | shadow.radius = radius; 301 | shadow.color = color; 302 | m_shadows.append(shadow); 303 | } 304 | 305 | QImage BoxShadowRenderer::render() const 306 | { 307 | if (m_shadows.isEmpty()) { 308 | return {}; 309 | } 310 | 311 | QSizeF canvasSize; 312 | for (const Shadow &shadow : std::as_const(m_shadows)) { 313 | canvasSize = canvasSize.expandedTo(calculateMinimumShadowTextureSize(m_boxSize, shadow.radius, shadow.offset)); 314 | } 315 | 316 | QImage canvas(canvasSize.toSize(), QImage::Format_ARGB32_Premultiplied); 317 | canvas.fill(Qt::transparent); 318 | 319 | QRectF boxRect(QPoint(0, 0), m_boxSize); 320 | boxRect.moveCenter(QRect(QPoint(0, 0), canvas.size()).center()); 321 | 322 | QPainter painter(&canvas); 323 | for (const Shadow &shadow : std::as_const(m_shadows)) { 324 | renderShadow(&painter, boxRect, m_borderRadius, shadow.offset, shadow.radius, shadow.color); 325 | } 326 | painter.end(); 327 | 328 | return canvas; 329 | } 330 | 331 | QSize BoxShadowRenderer::calculateMinimumBoxSize(int radius) 332 | { 333 | const QSize blurExtent = calculateBlurExtent(radius); 334 | return 2 * blurExtent + QSize(1, 1); 335 | } 336 | 337 | QSizeF BoxShadowRenderer::calculateMinimumShadowTextureSize(const QSizeF &boxSize, double radius, const QPointF &offset) 338 | { 339 | return boxSize + 2 * calculateBlurExtent(radius) + QSizeF(std::abs(offset.x()), std::abs(offset.y())); 340 | } 341 | 342 | } // namespace Breeze -------------------------------------------------------------------------------- /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 Qt::NoItemFlags; 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( void ) 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/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 | #include 35 | 36 | //__________________________________________________________ 37 | namespace Breeze 38 | { 39 | 40 | //__________________________________________________________ 41 | ExceptionListWidget::ExceptionListWidget( QWidget* parent ): 42 | QWidget( parent ) 43 | { 44 | 45 | // ui 46 | m_ui.setupUi( this ); 47 | 48 | // list 49 | m_ui.exceptionListView->setAllColumnsShowFocus( true ); 50 | m_ui.exceptionListView->setRootIsDecorated( false ); 51 | m_ui.exceptionListView->setSortingEnabled( false ); 52 | m_ui.exceptionListView->setModel( &model() ); 53 | m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType, Qt::AscendingOrder ); 54 | m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) ); 55 | 56 | m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) ); 57 | m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) ); 58 | m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) ); 59 | m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) ); 60 | m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) ); 61 | 62 | connect( m_ui.addButton, &QAbstractButton::clicked, this, &ExceptionListWidget::add ); 63 | connect( m_ui.editButton, &QAbstractButton::clicked, this, &ExceptionListWidget::edit ); 64 | connect( m_ui.removeButton, &QAbstractButton::clicked, this, &ExceptionListWidget::remove ); 65 | connect( m_ui.moveUpButton, &QAbstractButton::clicked, this, &ExceptionListWidget::up ); 66 | connect( m_ui.moveDownButton, &QAbstractButton::clicked, this, &ExceptionListWidget::down ); 67 | 68 | connect( m_ui.exceptionListView, &QAbstractItemView::activated, this, &ExceptionListWidget::edit ); 69 | connect( m_ui.exceptionListView, &QAbstractItemView::clicked, this, &ExceptionListWidget::toggle ); 70 | connect( m_ui.exceptionListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ExceptionListWidget::updateButtons ); 71 | 72 | updateButtons(); 73 | resizeColumns(); 74 | 75 | 76 | } 77 | 78 | //__________________________________________________________ 79 | void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions ) 80 | { 81 | model().set( exceptions ); 82 | resizeColumns(); 83 | setChanged( false ); 84 | } 85 | 86 | //__________________________________________________________ 87 | InternalSettingsList ExceptionListWidget::exceptions() 88 | { 89 | return model().get(); 90 | setChanged( false ); 91 | } 92 | 93 | //__________________________________________________________ 94 | void ExceptionListWidget::updateButtons() 95 | { 96 | 97 | bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() ); 98 | m_ui.removeButton->setEnabled( hasSelection ); 99 | m_ui.editButton->setEnabled( hasSelection ); 100 | 101 | m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) ); 102 | m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) ); 103 | 104 | } 105 | 106 | 107 | //_______________________________________________________ 108 | void ExceptionListWidget::add() 109 | { 110 | 111 | 112 | QPointer dialog = new ExceptionDialog( this ); 113 | dialog->setWindowTitle( i18n( "New Exception - Breeze Settings" ) ); 114 | InternalSettingsPtr exception( new InternalSettings() ); 115 | 116 | exception->load(); 117 | 118 | dialog->setException( exception ); 119 | 120 | // run dialog and check existence 121 | if( !dialog->exec() ) 122 | { 123 | delete dialog; 124 | return; 125 | } 126 | 127 | dialog->save(); 128 | delete dialog; 129 | 130 | // check exceptions 131 | if( !checkException( exception ) ) return; 132 | 133 | // create new item 134 | model().add( exception ); 135 | setChanged( true ); 136 | 137 | // make sure item is selected 138 | QModelIndex index( model().index( exception ) ); 139 | if( index != m_ui.exceptionListView->selectionModel()->currentIndex() ) 140 | { 141 | m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 142 | m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows ); 143 | } 144 | 145 | resizeColumns(); 146 | 147 | } 148 | 149 | //_______________________________________________________ 150 | void ExceptionListWidget::edit() 151 | { 152 | 153 | // retrieve selection 154 | QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() ); 155 | if( ! model().contains( current ) ) return; 156 | 157 | InternalSettingsPtr exception( model().get( current ) ); 158 | 159 | // create dialog 160 | QPointer dialog( new ExceptionDialog( this ) ); 161 | dialog->setWindowTitle( i18n( "Edit Exception - Breeze Settings" ) ); 162 | dialog->setException( exception ); 163 | 164 | // map dialog 165 | if( !dialog->exec() ) 166 | { 167 | delete dialog; 168 | return; 169 | } 170 | 171 | // check modifications 172 | if( !dialog->isChanged() ) return; 173 | 174 | // retrieve exception 175 | dialog->save(); 176 | delete dialog; 177 | 178 | // check new exception validity 179 | checkException( exception ); 180 | resizeColumns(); 181 | 182 | setChanged( true ); 183 | 184 | } 185 | 186 | //_______________________________________________________ 187 | void ExceptionListWidget::remove() 188 | { 189 | 190 | // confirmation dialog 191 | { 192 | QMessageBox messageBox( QMessageBox::Question, i18n("Question - Breeze Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel ); 193 | messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") ); 194 | messageBox.setDefaultButton( QMessageBox::Cancel ); 195 | if( messageBox.exec() == QMessageBox::Cancel ) return; 196 | } 197 | 198 | // remove 199 | model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 200 | resizeColumns(); 201 | updateButtons(); 202 | 203 | setChanged( true ); 204 | 205 | } 206 | 207 | //_______________________________________________________ 208 | void ExceptionListWidget::toggle( const QModelIndex& index ) 209 | { 210 | 211 | if( !model().contains( index ) ) return; 212 | if( index.column() != ExceptionModel::ColumnEnabled ) return; 213 | 214 | // get matching exception 215 | InternalSettingsPtr exception( model().get( index ) ); 216 | exception->setEnabled( !exception->enabled() ); 217 | setChanged( true ); 218 | 219 | } 220 | 221 | //_______________________________________________________ 222 | void ExceptionListWidget::up() 223 | { 224 | 225 | InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 226 | if( selection.empty() ) { return; } 227 | 228 | // retrieve selected indexes in list and store in model 229 | QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() ); 230 | InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); 231 | 232 | InternalSettingsList currentException( model().get() ); 233 | InternalSettingsList newExceptions; 234 | 235 | for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter ) 236 | { 237 | 238 | // check if new list is not empty, current index is selected and last index is not. 239 | // if yes, move. 240 | if( 241 | !( newExceptions.empty() || 242 | selectedIndices.indexOf( model().index( *iter ) ) == -1 || 243 | selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1 244 | ) ) 245 | { 246 | InternalSettingsPtr last( newExceptions.back() ); 247 | newExceptions.removeLast(); 248 | newExceptions.append( *iter ); 249 | newExceptions.append( last ); 250 | } else newExceptions.append( *iter ); 251 | 252 | } 253 | 254 | model().set( newExceptions ); 255 | 256 | // restore selection 257 | m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 258 | for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) 259 | { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } 260 | 261 | setChanged( true ); 262 | 263 | } 264 | 265 | //_______________________________________________________ 266 | void ExceptionListWidget::down() 267 | { 268 | 269 | InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 270 | if( selection.empty() ) 271 | { return; } 272 | 273 | // retrieve selected indexes in list and store in model 274 | QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() ); 275 | InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); 276 | 277 | InternalSettingsList currentExceptions( model().get() ); 278 | InternalSettingsList newExceptions; 279 | 280 | InternalSettingsListIterator iter( currentExceptions ); 281 | iter.toBack(); 282 | while( iter.hasPrevious() ) 283 | { 284 | 285 | InternalSettingsPtr current( iter.previous() ); 286 | 287 | // check if new list is not empty, current index is selected and last index is not. 288 | // if yes, move. 289 | if( 290 | !( newExceptions.empty() || 291 | selectedIndices.indexOf( model().index( current ) ) == -1 || 292 | selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1 293 | ) ) 294 | { 295 | 296 | InternalSettingsPtr first( newExceptions.front() ); 297 | newExceptions.removeFirst(); 298 | newExceptions.prepend( current ); 299 | newExceptions.prepend( first ); 300 | 301 | } else newExceptions.prepend( current ); 302 | } 303 | 304 | model().set( newExceptions ); 305 | 306 | // restore selection 307 | m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 308 | for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) 309 | { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } 310 | 311 | setChanged( true ); 312 | 313 | } 314 | 315 | //_______________________________________________________ 316 | void ExceptionListWidget::resizeColumns() const 317 | { 318 | m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled ); 319 | m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType ); 320 | m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp ); 321 | } 322 | 323 | //_______________________________________________________ 324 | bool ExceptionListWidget::checkException( InternalSettingsPtr exception ) 325 | { 326 | 327 | while( exception->exceptionPattern().isEmpty() || !QRegExp( exception->exceptionPattern() ).isValid() ) 328 | { 329 | 330 | QMessageBox::warning( this, i18n( "Warning - Breeze Settings" ), i18n("Regular Expression syntax is incorrect") ); 331 | QPointer dialog( new ExceptionDialog( this ) ); 332 | dialog->setException( exception ); 333 | if( dialog->exec() == QDialog::Rejected ) 334 | { 335 | delete dialog; 336 | return false; 337 | } 338 | 339 | dialog->save(); 340 | delete dialog; 341 | } 342 | 343 | return true; 344 | } 345 | 346 | } 347 | -------------------------------------------------------------------------------- /config/ui/breezeexceptiondialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | BreezeExceptionDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 553 10 | 572 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 | Hide window title bar: 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | Never 157 | 158 | 159 | 160 | 161 | Maximized Windows 162 | 163 | 164 | 165 | 166 | Any Maximization 167 | 168 | 169 | 170 | 171 | Always 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | Match Title Bar's and Window's color 180 | 181 | 182 | 183 | 184 | 185 | 186 | Use System Foreground Colors 187 | 188 | 189 | 190 | 191 | 192 | 193 | Draw window background gradient 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | Qt::Horizontal 203 | 204 | 205 | QSizePolicy::Fixed 206 | 207 | 208 | 209 | 16 210 | 5 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | false 219 | 220 | 221 | Override gradient: 222 | 223 | 224 | 225 | 226 | 227 | 228 | false 229 | 230 | 231 | % 232 | 233 | 234 | -1 235 | 236 | 237 | 100 238 | 239 | 240 | -1 241 | 242 | 243 | 244 | 245 | 246 | 247 | Qt::Horizontal 248 | 249 | 250 | 251 | 40 252 | 20 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | Draw separator between Title Bar and Window 263 | 264 | 265 | 266 | 267 | 268 | 269 | Opaque title bar 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | Qt::Horizontal 279 | 280 | 281 | QSizePolicy::Fixed 282 | 283 | 284 | 285 | 16 286 | 5 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | Override opacity: 295 | 296 | 297 | 298 | 299 | 300 | 301 | % 302 | 303 | 304 | -1 305 | 306 | 307 | 100 308 | 309 | 310 | -1 311 | 312 | 313 | 314 | 315 | 316 | 317 | Qt::Horizontal 318 | 319 | 320 | 321 | 40 322 | 20 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | Only for dialogs 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | Qt::Horizontal 343 | 344 | 345 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | buttonBox 355 | accepted() 356 | BreezeExceptionDialog 357 | accept() 358 | 359 | 360 | 252 361 | 342 362 | 363 | 364 | 157 365 | 274 366 | 367 | 368 | 369 | 370 | buttonBox 371 | rejected() 372 | BreezeExceptionDialog 373 | reject() 374 | 375 | 376 | 320 377 | 342 378 | 379 | 380 | 286 381 | 274 382 | 383 | 384 | 385 | 386 | borderSizeCheckBox 387 | toggled(bool) 388 | borderSizeComboBox 389 | setEnabled(bool) 390 | 391 | 392 | 125 393 | 162 394 | 395 | 396 | 316 397 | 163 398 | 399 | 400 | 401 | 402 | drawBackgroundGradient 403 | toggled(bool) 404 | gradientOverrideLabel 405 | setEnabled(bool) 406 | 407 | 408 | 20 409 | 20 410 | 411 | 412 | 20 413 | 20 414 | 415 | 416 | 417 | 418 | drawBackgroundGradient 419 | toggled(bool) 420 | gradientOverrideLabelSpinBox 421 | setEnabled(bool) 422 | 423 | 424 | 20 425 | 20 426 | 427 | 428 | 20 429 | 20 430 | 431 | 432 | 433 | 434 | opaqueTitleBar 435 | toggled(bool) 436 | opacityOverrideLabel 437 | setDisabled(bool) 438 | 439 | 440 | 104 441 | 202 442 | 443 | 444 | 82 445 | 229 446 | 447 | 448 | 449 | 450 | opaqueTitleBar 451 | toggled(bool) 452 | opacityOverrideLabelSpinBox 453 | setDisabled(bool) 454 | 455 | 456 | 104 457 | 202 458 | 459 | 460 | 166 461 | 229 462 | 463 | 464 | 465 | 466 | 467 | -------------------------------------------------------------------------------- /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( QObject *parent, const KPluginMetaData &data, const QVariantList & /*args*/ ): 40 | KCModule(parent, data), 41 | m_configuration( KSharedConfig::openConfig( QStringLiteral( "sierrabreezeenhancedrc" ) ) ), 42 | m_changed( false ) 43 | { 44 | 45 | // configuration 46 | m_ui.setupUi( widget() ); 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.buttonSpacing, QOverload::of(&QSpinBox::valueChanged), [this](int /*i*/){updateChanged();} ); 52 | connect( m_ui.buttonPadding, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 53 | connect( m_ui.hOffset, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 54 | connect( m_ui.unisonHovering, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 55 | connect( m_ui.cornerRadiusSpinBox, QOverload::of(&QSpinBox::valueChanged), [this](int /*i*/){updateChanged();} ); 56 | connect( m_ui.drawBorderOnMaximizedWindows, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 57 | connect( m_ui.drawSizeGrip, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 58 | connect( m_ui.opaqueTitleBar, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 59 | connect( m_ui.drawBackgroundGradient, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 60 | connect( m_ui.buttonStyle, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 61 | connect( m_ui.opacitySpinBox, QOverload::of(&QSpinBox::valueChanged), [this](int /*i*/){updateChanged();} ); 62 | connect( m_ui.gradientSpinBox, QOverload::of(&QSpinBox::valueChanged), [this](int /*i*/){updateChanged();} ); 63 | connect( m_ui.drawTitleBarSeparator, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 64 | connect( m_ui.hideTitleBar, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 65 | connect( m_ui.matchColorForTitleBar, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 66 | connect( m_ui.systemForegroundColor, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 67 | 68 | // track animations changes 69 | connect( m_ui.animationsEnabled, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 70 | connect( m_ui.animationsDuration, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 71 | 72 | // track shadows changes 73 | connect( m_ui.shadowSize, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 74 | connect( m_ui.shadowStrength, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 75 | connect( m_ui.shadowColor, &KColorButton::changed, this, &ConfigWidget::updateChanged ); 76 | connect( m_ui.specificShadowsInactiveWindows, &QAbstractButton::clicked, this, &ConfigWidget::updateChanged ); 77 | connect( m_ui.shadowSizeInactiveWindows, SIGNAL(currentIndexChanged(int)), SLOT(updateChanged()) ); 78 | connect( m_ui.shadowStrengthInactiveWindows, SIGNAL(valueChanged(int)), SLOT(updateChanged()) ); 79 | connect( m_ui.shadowColorInactiveWindows, &KColorButton::changed, this, &ConfigWidget::updateChanged ); 80 | 81 | // track exception changes 82 | connect( m_ui.exceptions, &ExceptionListWidget::changed, this, &ConfigWidget::updateChanged ); 83 | 84 | } 85 | 86 | //_________________________________________________________ 87 | void ConfigWidget::load() 88 | { 89 | 90 | // create internal settings and load from rc files 91 | m_internalSettings = InternalSettingsPtr( new InternalSettings() ); 92 | m_internalSettings->load(); 93 | 94 | // assign to ui 95 | m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); 96 | m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); 97 | m_ui.buttonSpacing->setValue( m_internalSettings->buttonSpacing() ); 98 | m_ui.buttonPadding->setValue( m_internalSettings->buttonPadding() ); 99 | m_ui.hOffset->setValue( m_internalSettings->hOffset() ); 100 | m_ui.unisonHovering->setChecked( m_internalSettings->unisonHovering() ); 101 | m_ui.cornerRadiusSpinBox->setValue( m_internalSettings->cornerRadius() ); 102 | m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); 103 | m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); 104 | m_ui.opaqueTitleBar->setChecked( m_internalSettings->opaqueTitleBar() ); 105 | m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() ); 106 | m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); 107 | m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); 108 | m_ui.buttonStyle->setCurrentIndex ( m_internalSettings->buttonStyle() ); 109 | m_ui.opacitySpinBox->setValue( m_internalSettings->backgroundOpacity() ); 110 | m_ui.gradientSpinBox->setValue( m_internalSettings->backgroundGradientIntensity() ); 111 | m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() ); 112 | m_ui.hideTitleBar->setCurrentIndex( m_internalSettings->hideTitleBar() ); 113 | m_ui.matchColorForTitleBar->setChecked( m_internalSettings->matchColorForTitleBar() ); 114 | m_ui.systemForegroundColor->setChecked( m_internalSettings->systemForegroundColor() ); 115 | 116 | // load shadows 117 | if( m_internalSettings->shadowSize() <= InternalSettings::ShadowVeryLarge ) m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); 118 | else m_ui.shadowSize->setCurrentIndex( InternalSettings::ShadowLarge ); 119 | m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); 120 | m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); 121 | 122 | m_ui.specificShadowsInactiveWindows->setChecked( m_internalSettings->specificShadowsInactiveWindows() ); 123 | 124 | if( m_internalSettings->shadowSizeInactiveWindows() <= InternalSettings::ShadowVeryLargeInactiveWindows ) m_ui.shadowSizeInactiveWindows->setCurrentIndex( m_internalSettings->shadowSizeInactiveWindows() ); 125 | else m_ui.shadowSizeInactiveWindows->setCurrentIndex( InternalSettings::ShadowLargeInactiveWindows ); 126 | m_ui.shadowStrengthInactiveWindows->setValue( qRound(qreal(m_internalSettings->shadowStrengthInactiveWindows()*100)/255 ) ); 127 | m_ui.shadowColorInactiveWindows->setColor( m_internalSettings->shadowColorInactiveWindows() ); 128 | 129 | // load exceptions 130 | ExceptionList exceptions; 131 | exceptions.readConfig( m_configuration ); 132 | m_ui.exceptions->setExceptions( exceptions.get() ); 133 | setNeedsSave( false ); 134 | 135 | } 136 | 137 | //_________________________________________________________ 138 | void ConfigWidget::save() 139 | { 140 | 141 | // create internal settings and load from rc files 142 | m_internalSettings = InternalSettingsPtr( new InternalSettings() ); 143 | m_internalSettings->load(); 144 | 145 | // apply modifications from ui 146 | m_internalSettings->setTitleAlignment( m_ui.titleAlignment->currentIndex() ); 147 | m_internalSettings->setButtonSize( m_ui.buttonSize->currentIndex() ); 148 | m_internalSettings->setButtonSpacing( m_ui.buttonSpacing->value() ); 149 | m_internalSettings->setButtonPadding( m_ui.buttonPadding->value() ); 150 | m_internalSettings->setHOffset( m_ui.hOffset->value() ); 151 | m_internalSettings->setUnisonHovering( m_ui.unisonHovering->isChecked() ); 152 | m_internalSettings->setCornerRadius( m_ui.cornerRadiusSpinBox->value() ); 153 | m_internalSettings->setDrawBorderOnMaximizedWindows( m_ui.drawBorderOnMaximizedWindows->isChecked() ); 154 | m_internalSettings->setDrawSizeGrip( m_ui.drawSizeGrip->isChecked() ); 155 | m_internalSettings->setOpaqueTitleBar( m_ui.opaqueTitleBar->isChecked() ); 156 | m_internalSettings->setDrawBackgroundGradient( m_ui.drawBackgroundGradient->isChecked() ); 157 | m_internalSettings->setAnimationsEnabled( m_ui.animationsEnabled->isChecked() ); 158 | m_internalSettings->setAnimationsDuration( m_ui.animationsDuration->value() ); 159 | m_internalSettings->setButtonStyle( m_ui.buttonStyle->currentIndex() ); 160 | m_internalSettings->setBackgroundOpacity(m_ui.opacitySpinBox->value()); 161 | m_internalSettings->setBackgroundGradientIntensity(m_ui.gradientSpinBox->value()); 162 | m_internalSettings->setDrawTitleBarSeparator(m_ui.drawTitleBarSeparator->isChecked()); 163 | m_internalSettings->setHideTitleBar( m_ui.hideTitleBar->currentIndex() ); 164 | m_internalSettings->setMatchColorForTitleBar( m_ui.matchColorForTitleBar->isChecked() ); 165 | m_internalSettings->setSystemForegroundColor( m_ui.systemForegroundColor->isChecked() ); 166 | 167 | m_internalSettings->setShadowSize( m_ui.shadowSize->currentIndex() ); 168 | m_internalSettings->setShadowStrength( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) ); 169 | m_internalSettings->setShadowColor( m_ui.shadowColor->color() ); 170 | 171 | m_internalSettings->setSpecificShadowsInactiveWindows( m_ui.specificShadowsInactiveWindows->isChecked() ); 172 | 173 | m_internalSettings->setShadowSizeInactiveWindows( m_ui.shadowSizeInactiveWindows->currentIndex() ); 174 | m_internalSettings->setShadowStrengthInactiveWindows( qRound( qreal(m_ui.shadowStrengthInactiveWindows->value()*255)/100 ) ); 175 | m_internalSettings->setShadowColorInactiveWindows( m_ui.shadowColorInactiveWindows->color() ); 176 | 177 | // save configuration 178 | m_internalSettings->save(); 179 | 180 | // get list of exceptions and write 181 | InternalSettingsList exceptions( m_ui.exceptions->exceptions() ); 182 | ExceptionList( exceptions ).writeConfig( m_configuration ); 183 | 184 | // sync configuration 185 | m_configuration->sync(); 186 | setNeedsSave( false ); 187 | 188 | // needed to tell kwin to reload when running from external kcmshell 189 | { 190 | QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig"); 191 | QDBusConnection::sessionBus().send(message); 192 | } 193 | 194 | // needed for breeze style to reload shadows 195 | { 196 | QDBusMessage message( QDBusMessage::createSignal("/BreezeDecoration", "org.kde.Breeze.Style", "reparseConfiguration") ); 197 | QDBusConnection::sessionBus().send(message); 198 | } 199 | 200 | } 201 | 202 | //_________________________________________________________ 203 | void ConfigWidget::defaults() 204 | { 205 | 206 | // create internal settings and load from rc files 207 | m_internalSettings = InternalSettingsPtr( new InternalSettings() ); 208 | m_internalSettings->setDefaults(); 209 | 210 | // assign to ui 211 | m_ui.titleAlignment->setCurrentIndex( m_internalSettings->titleAlignment() ); 212 | m_ui.buttonSize->setCurrentIndex( m_internalSettings->buttonSize() ); 213 | m_ui.buttonSpacing->setValue( m_internalSettings->buttonSpacing() ); 214 | m_ui.buttonPadding->setValue( m_internalSettings->buttonPadding() ); 215 | m_ui.hOffset->setValue( m_internalSettings->hOffset() ); 216 | m_ui.unisonHovering->setChecked( m_internalSettings->unisonHovering() ); 217 | m_ui.cornerRadiusSpinBox->setValue( m_internalSettings->cornerRadius() ); 218 | m_ui.drawBorderOnMaximizedWindows->setChecked( m_internalSettings->drawBorderOnMaximizedWindows() ); 219 | m_ui.drawSizeGrip->setChecked( m_internalSettings->drawSizeGrip() ); 220 | m_ui.opaqueTitleBar->setChecked( m_internalSettings->opaqueTitleBar() ); 221 | m_ui.drawBackgroundGradient->setChecked( m_internalSettings->drawBackgroundGradient() ); 222 | m_ui.drawTitleBarSeparator->setChecked( m_internalSettings->drawTitleBarSeparator() ); 223 | m_ui.hideTitleBar->setCurrentIndex( m_internalSettings->hideTitleBar() ); 224 | m_ui.matchColorForTitleBar->setChecked( m_internalSettings->matchColorForTitleBar() ); 225 | m_ui.systemForegroundColor->setChecked( m_internalSettings->systemForegroundColor() ); 226 | 227 | m_ui.animationsEnabled->setChecked( m_internalSettings->animationsEnabled() ); 228 | m_ui.animationsDuration->setValue( m_internalSettings->animationsDuration() ); 229 | m_ui.buttonStyle->setCurrentIndex( m_internalSettings->buttonStyle() ); 230 | m_ui.opacitySpinBox->setValue( m_internalSettings->backgroundOpacity() ); 231 | m_ui.gradientSpinBox->setValue( m_internalSettings->backgroundGradientIntensity() ); 232 | 233 | m_ui.shadowSize->setCurrentIndex( m_internalSettings->shadowSize() ); 234 | m_ui.shadowStrength->setValue( qRound(qreal(m_internalSettings->shadowStrength()*100)/255 ) ); 235 | m_ui.shadowColor->setColor( m_internalSettings->shadowColor() ); 236 | 237 | m_ui.specificShadowsInactiveWindows->setChecked( m_internalSettings->specificShadowsInactiveWindows() ); 238 | 239 | m_ui.shadowSizeInactiveWindows->setCurrentIndex( m_internalSettings->shadowSizeInactiveWindows() ); 240 | m_ui.shadowStrengthInactiveWindows->setValue( qRound(qreal(m_internalSettings->shadowStrengthInactiveWindows()*100)/255 ) ); 241 | m_ui.shadowColorInactiveWindows->setColor( m_internalSettings->shadowColorInactiveWindows() ); 242 | 243 | } 244 | 245 | //_______________________________________________ 246 | void ConfigWidget::updateChanged() 247 | { 248 | 249 | // check configuration 250 | if( !m_internalSettings ) return; 251 | 252 | // track modifications 253 | bool modified( false ); 254 | 255 | if( m_ui.titleAlignment->currentIndex() != m_internalSettings->titleAlignment() ) modified = true; 256 | else if( m_ui.buttonSize->currentIndex() != m_internalSettings->buttonSize() ) modified = true; 257 | else if( m_ui.buttonSpacing->value() != m_internalSettings->buttonSpacing() ) modified = true; 258 | else if ( m_ui.buttonPadding->value() != m_internalSettings->buttonPadding() ) modified = true; 259 | else if ( m_ui.hOffset->value() != m_internalSettings->hOffset() ) modified = true; 260 | else if( m_ui.unisonHovering->isChecked() != m_internalSettings->unisonHovering() ) modified = true; 261 | else if( m_ui.cornerRadiusSpinBox->value() != m_internalSettings->cornerRadius() ) modified = true; 262 | else if( m_ui.drawBorderOnMaximizedWindows->isChecked() != m_internalSettings->drawBorderOnMaximizedWindows() ) modified = true; 263 | else if( m_ui.drawSizeGrip->isChecked() != m_internalSettings->drawSizeGrip() ) modified = true; 264 | else if( m_ui.opaqueTitleBar->isChecked() != m_internalSettings->opaqueTitleBar() ) modified = true; 265 | else if( m_ui.drawBackgroundGradient->isChecked() != m_internalSettings->drawBackgroundGradient() ) modified = true; 266 | else if( m_ui.buttonStyle->currentIndex() != m_internalSettings->buttonStyle() ) modified = true; 267 | else if( m_ui.opacitySpinBox->value() != m_internalSettings->backgroundOpacity() ) modified = true; 268 | else if( m_ui.gradientSpinBox->value() != m_internalSettings->backgroundGradientIntensity() ) modified = true; 269 | else if (m_ui.drawTitleBarSeparator->isChecked() != m_internalSettings->drawTitleBarSeparator()) modified = true; 270 | else if ( m_ui.hideTitleBar->currentIndex() != m_internalSettings->hideTitleBar() ) modified = true; 271 | else if ( m_ui.matchColorForTitleBar->isChecked() != m_internalSettings->matchColorForTitleBar() ) modified = true; 272 | else if ( m_ui.systemForegroundColor->isChecked() != m_internalSettings->systemForegroundColor() ) modified = true; 273 | 274 | // animations 275 | else if( m_ui.animationsEnabled->isChecked() != m_internalSettings->animationsEnabled() ) modified = true; 276 | else if( m_ui.animationsDuration->value() != m_internalSettings->animationsDuration() ) modified = true; 277 | 278 | // shadows 279 | else if( m_ui.shadowSize->currentIndex() != m_internalSettings->shadowSize() ) modified = true; 280 | else if( qRound( qreal(m_ui.shadowStrength->value()*255)/100 ) != m_internalSettings->shadowStrength() ) modified = true; 281 | else if( m_ui.shadowColor->color() != m_internalSettings->shadowColor() ) modified = true; 282 | 283 | else if( m_ui.specificShadowsInactiveWindows->isChecked() != m_internalSettings->specificShadowsInactiveWindows() ) modified = true; 284 | 285 | else if( m_ui.shadowSizeInactiveWindows->currentIndex() != m_internalSettings->shadowSizeInactiveWindows() ) modified = true; 286 | else if( qRound( qreal(m_ui.shadowStrengthInactiveWindows->value()*255)/100 ) != m_internalSettings->shadowStrengthInactiveWindows() ) modified = true; 287 | else if( m_ui.shadowColorInactiveWindows->color() != m_internalSettings->shadowColorInactiveWindows() ) modified = true; 288 | 289 | // exceptions 290 | else if( m_ui.exceptions->isChanged() ) modified = true; 291 | 292 | 293 | setNeedsSave( modified ); 294 | 295 | } 296 | } 297 | --------------------------------------------------------------------------------