From 509ff6bc48f4baef7e0965071f9ee5b5a1840474 Mon Sep 17 00:00:00 2001 From: Carson Black Date: Mon, 8 Jun 2020 22:12:07 -0400 Subject: [PATCH] [kstyle] Tools area Summary: There is now a tools area. Test Plan: {F8132249} {F8132260} (no border drawn when titlebar and content colours are the same) {F8132252} {F8132253} Reviewers: #plasma, #breeze, #vdg, hpereiradacosta, davidre, ngraham Reviewed By: #breeze, #vdg, hpereiradacosta, ngraham Subscribers: mart, maartens, abstractdevelop, IlyaBizyaev, davidre, davidedmundson, hpereiradacosta, ngraham, manueljlin, niccolove, ndavis, plasma-devel Tags: #plasma Maniphest Tasks: T10201, T11661 Differential Revision: https://phabricator.kde.org/D27669 --- kstyle/CMakeLists.txt | 2 + kstyle/breezehelper.cpp | 93 +++++++++++- kstyle/breezehelper.h | 27 +++- kstyle/breezemetrics.h | 2 +- kstyle/breezestyle.cpp | 71 ++++++++- kstyle/breezestyle.h | 8 + kstyle/breezetoolsareamanager.cpp | 244 ++++++++++++++++++++++++++++++ kstyle/breezetoolsareamanager.h | 63 ++++++++ 8 files changed, 495 insertions(+), 15 deletions(-) create mode 100644 kstyle/breezetoolsareamanager.cpp create mode 100644 kstyle/breezetoolsareamanager.h diff --git a/kstyle/CMakeLists.txt b/kstyle/CMakeLists.txt index 0abe736b..3c461be5 100644 --- a/kstyle/CMakeLists.txt +++ b/kstyle/CMakeLists.txt @@ -75,8 +75,10 @@ set(breeze_PART_SRCS breezestyleplugin.cpp breezetileset.cpp breezewindowmanager.cpp + breezetoolsareamanager.cpp ) +kconfig_add_kcfg_files(breeze_PART_SRCS ../kdecoration/breezesettings.kcfgc) kconfig_add_kcfg_files(breeze_PART_SRCS breezestyleconfigdata.kcfgc) add_library(breeze MODULE ${breeze_PART_SRCS}) target_link_libraries(breeze Qt5::Core Qt5::Gui Qt5::Widgets Qt5::DBus) diff --git a/kstyle/breezehelper.cpp b/kstyle/breezehelper.cpp index 1bda96d0..d9014990 100644 --- a/kstyle/breezehelper.cpp +++ b/kstyle/breezehelper.cpp @@ -13,13 +13,22 @@ #include #include +#include +#include #include +#include +#include +#include +#include +#include #if BREEZE_HAVE_QTX11EXTRAS #include #endif #include +#include + namespace Breeze { @@ -28,14 +37,37 @@ namespace Breeze static const qreal arrowShade = 0.15; //____________________________________________________________________ - Helper::Helper( KSharedConfig::Ptr config ): - _config( std::move( config ) ) - {} + Helper::Helper( KSharedConfig::Ptr config, QObject *parent ) : + QObject ( parent ), + _config( std::move( config ) ), + _kwinConfig( KSharedConfig::openConfig("kwinrc") ), + _decorationConfig( new InternalSettings() ) + { + if (qApp) { + connect(qApp, &QApplication::paletteChanged, this, [=]() { + if (qApp->property("KDE_COLOR_SCHEME_PATH").isValid()) { + const auto path = qApp->property("KDE_COLOR_SCHEME_PATH").toString(); + KConfig config(path, KConfig::SimpleConfig); + KConfigGroup group( config.group("WM") ); + const QPalette palette( QApplication::palette() ); + _activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ); + _activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ); + _inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ); + _inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ); + } + }); + } + } //____________________________________________________________________ KSharedConfig::Ptr Helper::config() const { return _config; } + + //____________________________________________________________________ + QSharedPointer Helper::decorationConfig() const + { return _decorationConfig; } + //____________________________________________________________________ void Helper::loadConfig() { @@ -47,11 +79,18 @@ namespace Breeze _viewNeutralTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NeutralText ); const QPalette palette( QApplication::palette() ); - const KConfigGroup group( _config->group( "WM" ) ); - _activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ); - _activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ); - _inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ); - _inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ); + _config->reparseConfiguration(); + _kwinConfig->reparseConfiguration(); + _cachedAutoValid = false; + _decorationConfig->load(); + + KConfig config(qApp->property("KDE_COLOR_SCHEME_PATH").toString(), KConfig::SimpleConfig); + KConfigGroup appGroup( config.group("WM") ); + KConfigGroup globalGroup( _config->group("WM") ); + _activeTitleBarColor = appGroup.readEntry( "activeBackground", globalGroup.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ) ); + _activeTitleBarTextColor = appGroup.readEntry( "activeForeground", globalGroup.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ) ); + _inactiveTitleBarColor = appGroup.readEntry( "inactiveBackground", globalGroup.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ) ); + _inactiveTitleBarTextColor = appGroup.readEntry( "inactiveForeground", globalGroup.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ) ); } //____________________________________________________________________ @@ -1602,4 +1641,42 @@ namespace Breeze } return pixmap; } + + bool Helper::shouldDrawToolsArea(const QWidget* widget) const { + if (!widget) { + return false; + } + static bool isAuto = false; + static QString borderSize; + if (!_cachedAutoValid) { + KConfigGroup kdecorationGroup(_kwinConfig->group("org.kde.kdecoration2")); + isAuto = kdecorationGroup.readEntry("BorderSizeAuto", true); + borderSize = kdecorationGroup.readEntry("BorderSize", "Normal"); + _cachedAutoValid = true; + } + if (isAuto) { + auto window = widget->window(); + if (qobject_cast(widget)) { + return true; + } + if (window) { + auto handle = window->windowHandle(); + if (handle) { + auto toolbar = qobject_cast(widget); + if (toolbar) { + if (toolbar->isFloating()) { + return false; + } + } + return true; + } + } else { + return false; + } + } + if (borderSize != "None" && borderSize != "NoSides") { + return false; + } + return true; + } } diff --git a/kstyle/breezehelper.h b/kstyle/breezehelper.h index ec1c7df6..a2728482 100644 --- a/kstyle/breezehelper.h +++ b/kstyle/breezehelper.h @@ -10,11 +10,14 @@ #include "breeze.h" #include "breezemetrics.h" #include "breezeanimationdata.h" +#include "breezesettings.h" #include "config-breeze.h" #include #include +#include +#include #include #include #include @@ -24,12 +27,14 @@ namespace Breeze //* breeze style helper class. /** contains utility functions used at multiple places in both breeze style and breeze window decoration */ - class Helper + class Helper : public QObject { + Q_OBJECT + public: //* constructor - explicit Helper( KSharedConfig::Ptr ); + explicit Helper( KSharedConfig::Ptr, QObject *parent = nullptr ); //* destructor virtual ~Helper() @@ -41,6 +46,9 @@ namespace Breeze //* pointer to shared config KSharedConfig::Ptr config() const; + //* pointer to kdecoration config + QSharedPointer decorationConfig() const; + //*@name color utilities //@{ @@ -81,7 +89,7 @@ namespace Breeze //* titlebar text color const QColor& titleBarTextColor( bool active ) const - { return active ? _activeTitleBarTextColor:_inactiveTitleBarTextColor; } + { return active ? _activeTitleBarTextColor : _inactiveTitleBarTextColor; } //* frame outline color, using animations QColor frameOutlineColor( const QPalette&, bool mouseOver = false, bool hasFocus = false, qreal opacity = AnimationData::OpacityInvalid, AnimationMode = AnimationNone ) const; @@ -263,6 +271,9 @@ namespace Breeze //* returns true if a given widget supports alpha channel bool hasAlphaChannel( const QWidget* ) const; + //* returns true if the tools area should be drawn + bool shouldDrawToolsArea ( const QWidget* ) const; + //@} //* return device pixel ratio for a given pixmap @@ -295,6 +306,12 @@ namespace Breeze //* configuration KSharedConfig::Ptr _config; + //* KWin configuration + KSharedConfig::Ptr _kwinConfig; + + //* decoration configuration + QSharedPointer _decorationConfig; + //*@name brushes //@{ KStatefulBrush _viewFocusBrush; @@ -313,6 +330,10 @@ namespace Breeze QColor _inactiveTitleBarTextColor; //@} + mutable bool _cachedAutoValid = false; + + friend class ToolsAreaManager; + }; } diff --git a/kstyle/breezemetrics.h b/kstyle/breezemetrics.h index 7011558c..742bd4b9 100644 --- a/kstyle/breezemetrics.h +++ b/kstyle/breezemetrics.h @@ -92,7 +92,7 @@ namespace Breeze static constexpr int ScrollBar_DoubleButtonHeight = 2*ScrollBar_Extend; // toolbars - static constexpr int ToolBar_FrameWidth = 2; + static constexpr int ToolBar_FrameWidth = 6; static constexpr int ToolBar_HandleExtent = 10; static constexpr int ToolBar_HandleWidth = 6; static constexpr int ToolBar_SeparatorWidth = 8; diff --git a/kstyle/breezestyle.cpp b/kstyle/breezestyle.cpp index 5d866745..2f6b3bff 100644 --- a/kstyle/breezestyle.cpp +++ b/kstyle/breezestyle.cpp @@ -17,13 +17,17 @@ #include "breezewidgetexplorer.h" #include "breezewindowmanager.h" #include "breezeblurhelper.h" +#include "breezetoolsareamanager.h" #include +#include #include +#include #include #include #include +#include #include #include #include @@ -45,6 +49,7 @@ #include #include #include +#include #if BREEZE_HAVE_QTQUICK #include @@ -190,6 +195,7 @@ namespace Breeze , _frameShadowFactory( new FrameShadowFactory( this ) ) , _mdiWindowShadowFactory( new MdiWindowShadowFactory( this ) ) , _splitterFactory( new SplitterFactory( this ) ) + , _toolsAreaManager ( new ToolsAreaManager( _helper, this ) ) , _widgetExplorer( new WidgetExplorer( this ) ) , _tabBarData( new BreezePrivate::TabBarData( this ) ) #if BREEZE_HAVE_KSTYLE @@ -209,10 +215,17 @@ namespace Breeze QStringLiteral( "/BreezeDecoration" ), QStringLiteral( "org.kde.Breeze.Style" ), QStringLiteral( "reparseConfiguration" ), this, SLOT(configurationChanged()) ); + dbus.connect( QString(), QStringLiteral( "/KGlobalSettings" ), QStringLiteral( "org.kde.KGlobalSettings" ), QStringLiteral( "notifyChange" ), this, SLOT(configurationChanged()) ); + + dbus.connect( QString(), + QStringLiteral( "/KWin" ), + QStringLiteral( "org.kde.KWin" ), + QStringLiteral( "reloadConfig" ), this, SLOT(configurationChanged())); + #if QT_VERSION < 0x050D00 // Check if Qt version < 5.13 this->addEventFilter(qApp); #else @@ -243,6 +256,7 @@ namespace Breeze _mdiWindowShadowFactory->registerWidget( widget ); _shadowHelper->registerWidget( widget ); _splitterFactory->registerWidget( widget ); + _toolsAreaManager->registerWidget ( widget ); // enable mouse over effects for all necessary widgets if( @@ -380,13 +394,20 @@ namespace Breeze setTranslucentBackground( widget ); + } else if ( qobject_cast (widget) || qobject_cast (widget) ) { + widget->setAttribute(Qt::WA_StyledBackground); } - // base class polishing ParentStyleClass::polish( widget ); } + //______________________________________________________________ + void Style::polish( QApplication *application ) + { + _toolsAreaManager->registerApplication(application); + } + //______________________________________________________________ void Style::polishScrollArea( QAbstractScrollArea* scrollArea ) { @@ -469,6 +490,7 @@ namespace Breeze _windowManager->unregisterWidget( widget ); _splitterFactory->unregisterWidget( widget ); _blurHelper->unregisterWidget( widget ); + _toolsAreaManager->unregisterWidget ( widget ); // remove event filter if( qobject_cast( widget ) || @@ -874,6 +896,7 @@ namespace Breeze case PE_FrameTabBarBase: fcn = &Style::drawFrameTabBarBasePrimitive; break; case PE_FrameWindow: fcn = &Style::drawFrameWindowPrimitive; break; case PE_FrameFocusRect: fcn = _frameFocusPrimitive; break; + case PE_Widget: fcn = &Style::drawWidgetPrimitive; break; // fallback default: break; @@ -890,6 +913,43 @@ namespace Breeze } + bool Style::drawWidgetPrimitive( const QStyleOption* option, QPainter* painter, const QWidget* widget ) const { + Q_UNUSED(option) + auto parent = widget; + if (!_helper->shouldDrawToolsArea(widget)) { + return true; + } + if (auto mw = qobject_cast(widget)) { + painter->save(); + + auto rect = _toolsAreaManager->toolsAreaRect(mw); + + if (rect.height() == 0) { + painter->setPen(_helper->separatorColor(_toolsAreaManager->palette())); + painter->drawLine(widget->rect().topLeft(), widget->rect().topRight()); + painter->restore(); + return true; + } + + auto color = _toolsAreaManager->palette().brush(mw->isActiveWindow() ? QPalette::Active : QPalette::Inactive, QPalette::Window); + + painter->setPen(Qt::transparent); + painter->setBrush(color); + painter->drawRect(rect); + + painter->setPen(_helper->separatorColor(_toolsAreaManager->palette())); + painter->drawLine(rect.bottomLeft(), rect.bottomRight()); + + painter->restore(); + } else if (auto dialog = qobject_cast(widget)) { + auto margins = dialog->contentsMargins(); + const_cast(dialog)->setContentsMargins(margins.left(), margins.top(), margins.right(), qMax(margins.bottom(), 1)); + painter->setPen(_helper->separatorColor(_toolsAreaManager->palette())); + painter->drawLine(widget->rect().topLeft(), widget->rect().topRight()); + } + return true; + } + //______________________________________________________________ void Style::drawControl( ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget ) const { @@ -4300,7 +4360,6 @@ namespace Breeze // copy rect and palette const auto& rect = option->rect; - const auto& palette = option->palette; // state const State& state( option->state ); @@ -4425,6 +4484,8 @@ namespace Breeze if( flat ) textRole = ( ((hasFocus&&sunken) || (state & State_Sunken))&&!mouseOver) ? QPalette::HighlightedText: QPalette::WindowText; else if( hasFocus&&!mouseOver ) textRole = QPalette::HighlightedText; + auto palette = option->palette; + painter->setFont(toolButtonOption->font); drawItemText( painter, textRect, textFlags, palette, enabled, toolButtonOption->text, textRole ); @@ -4589,6 +4650,9 @@ namespace Breeze const bool sunken( enabled && (state & State_Sunken) ); const bool useStrongFocus( StyleConfigData::menuItemDrawStrongFocus() ); + painter->save(); + painter->setRenderHints( QPainter::Antialiasing ); + // render hover and focus if( useStrongFocus && ( selected || sunken ) ) { @@ -4667,8 +4731,9 @@ namespace Breeze } - return true; + painter->restore(); + return true; } diff --git a/kstyle/breezestyle.h b/kstyle/breezestyle.h index 75c76106..29dbfd07 100644 --- a/kstyle/breezestyle.h +++ b/kstyle/breezestyle.h @@ -48,6 +48,7 @@ namespace Breeze class WidgetExplorer; class WindowManager; class BlurHelper; + class ToolsAreaManager; //* convenience typedef for base class #if !BREEZE_HAVE_KSTYLE @@ -83,6 +84,9 @@ namespace Breeze //* widget unpolishing void unpolish( QWidget* ) override; + //* application polishing + void polish( QApplication* ) override; + //* polish scrollarea void polishScrollArea( QAbstractScrollArea* ); @@ -267,6 +271,7 @@ namespace Breeze bool drawIndicatorToolBarHandlePrimitive( const QStyleOption*, QPainter*, const QWidget* ) const; bool drawIndicatorToolBarSeparatorPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const; bool drawIndicatorBranchPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const; + bool drawWidgetPrimitive( const QStyleOption*, QPainter*, const QWidget* ) const; //@} @@ -496,6 +501,9 @@ namespace Breeze //* splitter Factory, to extend splitters hit area SplitterFactory* _splitterFactory = nullptr; + //* signal manager for the tools area + ToolsAreaManager* _toolsAreaManager = nullptr; + //* widget explorer WidgetExplorer* _widgetExplorer = nullptr; diff --git a/kstyle/breezetoolsareamanager.cpp b/kstyle/breezetoolsareamanager.cpp new file mode 100644 index 00000000..bd2c5352 --- /dev/null +++ b/kstyle/breezetoolsareamanager.cpp @@ -0,0 +1,244 @@ +#include "breezetoolsareamanager.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +const char* colorProperty = "KDE_COLOR_SCHEME_PATH"; + +namespace Breeze { + ToolsAreaManager::ToolsAreaManager(Helper *helper, QObject *parent) : QObject(parent), _helper(helper) + { + if (qApp && qApp->property(colorProperty).isValid()) { + auto path = qApp->property(colorProperty).toString(); + _config = KSharedConfig::openConfig(path); + } else { + _config = KSharedConfig::openConfig(); + } + _watcher = KConfigWatcher::create(_config); + connect(_watcher.data(), &KConfigWatcher::configChanged, this, &ToolsAreaManager::configUpdated); + configUpdated(); + } + + ToolsAreaManager::~ToolsAreaManager() {} + + template + void appendIfNotAlreadyExists(T1* list, T2 item) { + for (auto listItem : *list) { + if (listItem == item) { + return; + } + } + list->append(item); + } + + void ToolsAreaManager::registerApplication(QApplication *application) + { + _listener = new AppListener; + _listener->manager = this; + if (application->property(colorProperty).isValid()) { + auto path = application->property(colorProperty).toString(); + _config = KSharedConfig::openConfig(path); + _watcher = KConfigWatcher::create(_config); + connect(_watcher.data(), &KConfigWatcher::configChanged, this, &ToolsAreaManager::configUpdated); + } + application->installEventFilter(_listener); + configUpdated(); + } + + QRect ToolsAreaManager::toolsAreaRect(const QMainWindow *window) + { + Q_ASSERT(window); + + int itemHeight = window->menuWidget() ? window->menuWidget()->height() : 0; + for (auto item : _windows[const_cast(window)]) { + if (!item.isNull() && item->isVisible() && window->toolBarArea(item) == Qt::TopToolBarArea) { + itemHeight = qMax(item->mapTo(window, item->rect().bottomLeft()).y(), itemHeight); + } + } + + if (itemHeight == 0) { + auto win = const_cast(window); + win->setContentsMargins(0, 0, 0, 1); + } else { + auto win = const_cast(window); + win->setContentsMargins(0, 0, 0, 0); + } + + return QRect(0, 0, window->width(), itemHeight); + } + + bool ToolsAreaManager::tryRegisterToolBar(QPointer window, QPointer widget) + { + Q_ASSERT(!widget.isNull()); + + QPointer toolbar; + if (!(toolbar = qobject_cast(widget))) return false; + + if (window->toolBarArea(toolbar) == Qt::TopToolBarArea) { + widget->setPalette(palette()); + appendIfNotAlreadyExists(&_windows[window], toolbar); + return true; + } + + return false; + } + + void ToolsAreaManager::tryUnregisterToolBar(QPointer window, QPointer widget) + { + Q_ASSERT(!widget.isNull()); + + QPointer toolbar; + if (!(toolbar = qobject_cast(widget))) return; + + if (window->toolBarArea(toolbar) != Qt::TopToolBarArea) { + widget->setPalette(window->palette()); + _windows[window].removeAll(toolbar); + } + } + + void ToolsAreaManager::configUpdated() + { + auto active = KColorScheme(QPalette::Active, KColorScheme::Header, _config); + auto inactive = KColorScheme(QPalette::Inactive, KColorScheme::Header, _config); + auto disabled = KColorScheme(QPalette::Disabled, KColorScheme::Header, _config); + + _palette = KColorScheme::createApplicationPalette(_config); + + _palette.setBrush(QPalette::Active, QPalette::Window, active.background()); + _palette.setBrush(QPalette::Active, QPalette::WindowText, active.foreground()); + _palette.setBrush(QPalette::Disabled, QPalette::Window, disabled.background()); + _palette.setBrush(QPalette::Disabled, QPalette::WindowText, disabled.foreground()); + _palette.setBrush(QPalette::Inactive, QPalette::Window, inactive.background()); + _palette.setBrush(QPalette::Inactive, QPalette::WindowText, inactive.foreground()); + + for (auto window : _windows) { + for (auto toolbar : window) { + if (!toolbar.isNull()) { + toolbar->setPalette(_palette); + } + } + } + } + + bool AppListener::eventFilter(QObject *watched, QEvent *event) + { + Q_ASSERT(watched); + Q_ASSERT(event); + + if (watched != qApp) { + return false; + } + + if (event->type() == QEvent::DynamicPropertyChange) { + if (watched != qApp) { + return false; + } + auto ev = static_cast(event); + if (ev->propertyName() == colorProperty) { + if (qApp && qApp->property(colorProperty).isValid()) { + auto path = qApp->property(colorProperty).toString(); + manager->_config = KSharedConfig::openConfig(path); + } else { + manager->_config = KSharedConfig::openConfig(); + } + manager->_watcher = KConfigWatcher::create(manager->_config); + connect(manager->_watcher.data(), &KConfigWatcher::configChanged, manager, &ToolsAreaManager::configUpdated); + manager->configUpdated(); + } + } + + return false; + } + + bool ToolsAreaManager::eventFilter(QObject *watched, QEvent *event) + { + Q_ASSERT(watched); + Q_ASSERT(event); + + QPointer parent = watched; + QPointer mainWindow = nullptr; + while (parent != nullptr) { + if (qobject_cast(parent)) { + mainWindow = qobject_cast(parent); + break; + } + parent = parent->parent(); + } + + if (QPointer mw = qobject_cast(watched)) { + QChildEvent *ev = nullptr; + if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) + ev = static_cast(event); + + QPointer tb = qobject_cast(ev->child()); + if (tb.isNull()) + return false; + + if (ev->added()) { + if (mw->toolBarArea(tb) == Qt::TopToolBarArea) + appendIfNotAlreadyExists(&_windows[mw], tb); + } else if (ev->removed()) { + _windows[mw].removeAll(tb); + } + } else if (qobject_cast(watched)) { + if (!mainWindow.isNull()) { + tryUnregisterToolBar(mainWindow, qobject_cast(watched)); + } + } + + return false; + } + + void ToolsAreaManager::registerWidget(QWidget *widget) + { + Q_ASSERT(widget); + auto ptr = QPointer(widget); + + auto parent = ptr; + QPointer mainWindow = nullptr; + while (parent != nullptr) { + if (qobject_cast(parent) || qobject_cast(parent)) { + break; + } + if (qobject_cast(parent)) { + mainWindow = qobject_cast(parent); + } + parent = parent->parentWidget(); + } if (mainWindow == nullptr) { + return; + } + + if (tryRegisterToolBar(mainWindow, widget)) return; + } + + void ToolsAreaManager::unregisterWidget(QWidget *widget) + { + Q_ASSERT(widget); + auto ptr = QPointer(widget); + + if (QPointer window = qobject_cast(ptr)) { + _windows.remove(window); + return; + } else if (QPointer toolbar = qobject_cast(ptr)) { + auto parent = ptr; + QPointer mainWindow = nullptr; + while (parent != nullptr) { + if (qobject_cast(parent)) { + mainWindow = qobject_cast(parent); + break; + } + parent = parent->parentWidget(); + } if (mainWindow == nullptr) { + return; + } + _windows[mainWindow].removeAll(toolbar); + } + } +} diff --git a/kstyle/breezetoolsareamanager.h b/kstyle/breezetoolsareamanager.h new file mode 100644 index 00000000..efb5d051 --- /dev/null +++ b/kstyle/breezetoolsareamanager.h @@ -0,0 +1,63 @@ +#ifndef breezetoolsareamanager_h +#define breezetoolsareamanager_h + +#include +#include +#include +#include +#include "breezestyle.h" +#include "breezehelper.h" + +namespace Breeze { + class ToolsAreaManager; + + // Trying to discriminate QApplication events from events from all QObjects + // belonging to it is impractical with everything going through a single + // eventFilter, so we have this class which provides a second one that allows + // us to filter for the events we want. + class AppListener : public QObject + { + Q_OBJECT + + bool eventFilter(QObject *watched, QEvent *event) override; + + ToolsAreaManager *manager; + friend class ToolsAreaManager; + }; + + class ToolsAreaManager : public QObject + { + Q_OBJECT + + private: + Helper* _helper; + QHash>> _windows; + KSharedConfigPtr _config; + KConfigWatcher::Ptr _watcher; + QPalette _palette = QPalette(); + AppListener* _listener; + + friend class AppListener; + + protected: + bool tryRegisterToolBar(QPointer window, QPointer widget); + void tryUnregisterToolBar(QPointer window, QPointer widget); + void configUpdated(); + + public: + explicit ToolsAreaManager(Helper *helper, QObject *parent = nullptr); + ~ToolsAreaManager(); + + bool eventFilter(QObject *watched, QEvent *event) override; + + const QPalette& palette() const { return _palette; } + + void registerApplication(QApplication *application); + void registerWidget(QWidget *widget); + void unregisterWidget(QWidget *widget); + + QRect toolsAreaRect(const QMainWindow *window); + }; +} + +#endif