Changeset View
Changeset View
Standalone View
Standalone View
kstyle/breezehelper.cpp
Show All 20 Lines | |||||
21 | 21 | | |||
22 | #include "breeze.h" | 22 | #include "breeze.h" | ||
23 | #include "breezestyleconfigdata.h" | 23 | #include "breezestyleconfigdata.h" | ||
24 | 24 | | |||
25 | #include <KColorUtils> | 25 | #include <KColorUtils> | ||
26 | #include <KWindowSystem> | 26 | #include <KWindowSystem> | ||
27 | 27 | | |||
28 | #include <QApplication> | 28 | #include <QApplication> | ||
29 | #include <QDBusConnection> | ||||
30 | #include <QFileInfo> | ||||
29 | #include <QPainter> | 31 | #include <QPainter> | ||
32 | #include <QMainWindow> | ||||
33 | #include <QMenuBar> | ||||
34 | #include <QMdiArea> | ||||
35 | #include <QDockWidget> | ||||
36 | #include <QWindow> | ||||
30 | 37 | | |||
31 | #if BREEZE_HAVE_X11 | 38 | #if BREEZE_HAVE_X11 | ||
32 | #include <QX11Info> | 39 | #include <QX11Info> | ||
33 | #endif | 40 | #endif | ||
34 | 41 | | |||
35 | #include <algorithm> | 42 | #include <algorithm> | ||
36 | 43 | | |||
37 | namespace Breeze | 44 | namespace Breeze | ||
38 | { | 45 | { | ||
39 | 46 | | |||
40 | //* contrast for arrow and treeline rendering | 47 | //* contrast for arrow and treeline rendering | ||
41 | static const qreal arrowShade = 0.15; | 48 | static const qreal arrowShade = 0.15; | ||
42 | 49 | | |||
43 | //____________________________________________________________________ | 50 | //____________________________________________________________________ | ||
44 | Helper::Helper( KSharedConfig::Ptr config ): | 51 | Helper::Helper( KSharedConfig::Ptr config, QObject *parent ) : | ||
45 | _config( std::move( config ) ) | 52 | _config( std::move( config ) ), | ||
46 | {} | 53 | _kwinConfig( KSharedConfig::openConfig("kwinrc") ), | ||
54 | _decorationConfig( new InternalSettings() ), | ||||
55 | QObject ( parent ) | ||||
56 | { | ||||
57 | if (qApp) { | ||||
58 | connect(qApp, &QApplication::paletteChanged, this, [=]() { | ||||
59 | if (qApp->property("KDE_COLOR_SCHEME_PATH").isValid()) { | ||||
60 | const auto path = qApp->property("KDE_COLOR_SCHEME_PATH").toString(); | ||||
61 | KConfig config(path, KConfig::SimpleConfig); | ||||
62 | KConfigGroup group( config.group("WM") ); | ||||
63 | const QPalette palette( QApplication::palette() ); | ||||
64 | _activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ); | ||||
65 | _activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ); | ||||
66 | _inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ); | ||||
67 | _inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ); | ||||
68 | } | ||||
69 | }); | ||||
70 | } | ||||
71 | } | ||||
47 | 72 | | |||
48 | //____________________________________________________________________ | 73 | //____________________________________________________________________ | ||
49 | KSharedConfig::Ptr Helper::config() const | 74 | KSharedConfig::Ptr Helper::config() const | ||
50 | { return _config; } | 75 | { return _config; } | ||
51 | 76 | | |||
77 | | ||||
78 | //____________________________________________________________________ | ||||
79 | QSharedPointer<InternalSettings> Helper::decorationConfig() const | ||||
80 | { return _decorationConfig; } | ||||
81 | | ||||
52 | //____________________________________________________________________ | 82 | //____________________________________________________________________ | ||
53 | void Helper::loadConfig() | 83 | void Helper::loadConfig() | ||
54 | { | 84 | { | ||
55 | _viewFocusBrush = KStatefulBrush( KColorScheme::View, KColorScheme::FocusColor ); | 85 | _viewFocusBrush = KStatefulBrush( KColorScheme::View, KColorScheme::FocusColor ); | ||
56 | _viewHoverBrush = KStatefulBrush( KColorScheme::View, KColorScheme::HoverColor ); | 86 | _viewHoverBrush = KStatefulBrush( KColorScheme::View, KColorScheme::HoverColor ); | ||
57 | _viewNegativeTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NegativeText ); | 87 | _viewNegativeTextBrush = KStatefulBrush( KColorScheme::View, KColorScheme::NegativeText ); | ||
58 | 88 | | |||
59 | const QPalette palette( QApplication::palette() ); | 89 | const QPalette palette( QApplication::palette() ); | ||
60 | const KConfigGroup group( _config->group( "WM" ) ); | 90 | _config->reparseConfiguration(); | ||
61 | _activeTitleBarColor = group.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ); | 91 | _kwinConfig->reparseConfiguration(); | ||
62 | _activeTitleBarTextColor = group.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ); | 92 | _cachedAutoValid = false; | ||
63 | _inactiveTitleBarColor = group.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ); | 93 | _decorationConfig->load(); | ||
64 | _inactiveTitleBarTextColor = group.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ); | 94 | KConfig config(qApp->property("KDE_COLOR_SCHEME_PATH").toString(), KConfig::SimpleConfig); | ||
95 | KConfigGroup appGroup( config.group("WM") ); | ||||
96 | KConfigGroup globalGroup( _config->group("WM") ); | ||||
97 | _activeTitleBarColor = appGroup.readEntry( "activeBackground", globalGroup.readEntry( "activeBackground", palette.color( QPalette::Active, QPalette::Highlight ) ) ); | ||||
98 | _activeTitleBarTextColor = appGroup.readEntry( "activeForeground", globalGroup.readEntry( "activeForeground", palette.color( QPalette::Active, QPalette::HighlightedText ) ) ); | ||||
99 | _inactiveTitleBarColor = appGroup.readEntry( "inactiveBackground", globalGroup.readEntry( "inactiveBackground", palette.color( QPalette::Disabled, QPalette::Highlight ) ) ); | ||||
100 | _inactiveTitleBarTextColor = appGroup.readEntry( "inactiveForeground", globalGroup.readEntry( "inactiveForeground", palette.color( QPalette::Disabled, QPalette::HighlightedText ) ) ); | ||||
65 | } | 101 | } | ||
66 | 102 | | |||
67 | //____________________________________________________________________ | 103 | //____________________________________________________________________ | ||
68 | QColor Helper::frameOutlineColor( const QPalette& palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode ) const | 104 | QColor Helper::frameOutlineColor( const QPalette& palette, bool mouseOver, bool hasFocus, qreal opacity, AnimationMode mode ) const | ||
69 | { | 105 | { | ||
70 | 106 | | |||
71 | QColor outline( KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.25 ) ); | 107 | QColor outline( KColorUtils::mix( palette.color( QPalette::Window ), palette.color( QPalette::WindowText ), 0.25 ) ); | ||
72 | 108 | | |||
▲ Show 20 Lines • Show All 1517 Lines • ▼ Show 20 Line(s) | 1363 | } | |||
1590 | { return compositingActive() && widget && widget->testAttribute( Qt::WA_TranslucentBackground ); } | 1626 | { return compositingActive() && widget && widget->testAttribute( Qt::WA_TranslucentBackground ); } | ||
1591 | 1627 | | |||
1592 | //______________________________________________________________________________________ | 1628 | //______________________________________________________________________________________ | ||
1593 | qreal Helper::devicePixelRatio( const QPixmap& pixmap ) const | 1629 | qreal Helper::devicePixelRatio( const QPixmap& pixmap ) const | ||
1594 | { | 1630 | { | ||
1595 | return pixmap.devicePixelRatio(); | 1631 | return pixmap.devicePixelRatio(); | ||
1596 | } | 1632 | } | ||
1597 | 1633 | | |||
1634 | bool Helper::isInToolsArea(const QWidget* widget) const | ||||
1635 | { | ||||
1636 | if (!shouldDrawToolsArea(widget)) return false; | ||||
1637 | | ||||
1638 | auto grabMainWindow = [](const QWidget *widget) { | ||||
1639 | auto window = qobject_cast<QMainWindow*>(widget->window()); | ||||
1640 | return window; | ||||
1641 | }; | ||||
1642 | auto checkToolbarInToolsArea = [this, grabMainWindow](const QWidget* widget) { | ||||
1643 | auto toolbar = qobject_cast<const QToolBar*>(widget); | ||||
1644 | if (!toolbar) return false; | ||||
1645 | | ||||
1646 | QMainWindow* window = grabMainWindow(widget); | ||||
1647 | if (window) { | ||||
1648 | auto rect = toolsAreaToolbarsRect(widget); | ||||
1649 | if (widget->parentWidget() != widget->window()) return false; | ||||
1650 | if (toolbar->isFloating()) return false; | ||||
1651 | if (toolbar->orientation() == Qt::Vertical) return false; | ||||
1652 | if (window->toolBarArea(const_cast<QToolBar*>(toolbar)) != Qt::TopToolBarArea) return false; | ||||
1653 | if (window->width() != rect.width()) return false; | ||||
1654 | } | ||||
1655 | | ||||
1656 | return true; | ||||
1657 | }; | ||||
1658 | auto checkMenubarInToolsArea = [grabMainWindow](const QWidget *widget) { | ||||
1659 | QMainWindow* window = grabMainWindow(widget); | ||||
1660 | if (window) { | ||||
1661 | if (window->menuWidget() == widget) { | ||||
1662 | return true; | ||||
1663 | } | ||||
1664 | } | ||||
1665 | | ||||
1666 | return false; | ||||
1667 | }; | ||||
1668 | | ||||
1669 | if (!widget) return false; | ||||
1670 | | ||||
1671 | if (!widget->isVisible()) { | ||||
1672 | return false; | ||||
1673 | } | ||||
1674 | if (widget->window()->windowType() == Qt::Dialog) { | ||||
1675 | return false; | ||||
1676 | } | ||||
1677 | | ||||
1678 | auto parent = widget; | ||||
1679 | while (parent != nullptr) { | ||||
1680 | if (qobject_cast<const QMdiArea*>(parent) || qobject_cast<const QDockWidget*>(parent)) { | ||||
1681 | return false; | ||||
1682 | } | ||||
1683 | if (checkToolbarInToolsArea(parent)) { | ||||
1684 | return true; | ||||
1685 | } | ||||
1686 | if (checkMenubarInToolsArea(parent)) { | ||||
1687 | return true; | ||||
1688 | } | ||||
1689 | parent = parent->parentWidget(); | ||||
1690 | } | ||||
1691 | | ||||
1692 | return false; | ||||
1693 | } | ||||
1694 | | ||||
1695 | QRect Helper::toolsAreaToolbarsRect (const QWidget* widget) const { | ||||
1696 | auto window = qobject_cast<QMainWindow*>(widget->window()); | ||||
1697 | if (!window) return QRect(); | ||||
1698 | | ||||
1699 | auto handle = window->windowHandle(); | ||||
1700 | if (handle) { | ||||
1701 | if (_invalidateCachedRects) { | ||||
1702 | _cachedRects.clear(); | ||||
1703 | _invalidateCachedRects = false; | ||||
1704 | } | ||||
1705 | auto key = _cachedRects.constFind(handle); | ||||
1706 | if (key != _cachedRects.constEnd()) { | ||||
1707 | return *key; | ||||
1708 | } | ||||
1709 | } | ||||
1710 | | ||||
1711 | QList<QToolBar*> widgets = window->findChildren<QToolBar*>(QString(), Qt::FindDirectChildrenOnly); | ||||
1712 | QRect rect = QRect(); | ||||
1713 | for (auto toolbar : widgets) { | ||||
1714 | auto isInSubWindow = false; | ||||
1715 | QWidget* parent = toolbar->parentWidget(); | ||||
1716 | while (parent != nullptr) { | ||||
1717 | if (qobject_cast<QMdiArea*>(parent) || qobject_cast<QDockWidget*>(parent)) { | ||||
1718 | isInSubWindow = true; | ||||
1719 | break; | ||||
1720 | } | ||||
1721 | parent = parent->parentWidget(); | ||||
1722 | } | ||||
1723 | if (!isInSubWindow) { | ||||
1724 | if (window->toolBarArea(toolbar) == Qt::TopToolBarArea) { | ||||
1725 | rect = rect.united(toolbar->geometry()); | ||||
1726 | } | ||||
1727 | } | ||||
1728 | } | ||||
1729 | QList<QMenuBar*> menuWidgets = window->findChildren<QMenuBar*>(QString(), Qt::FindDirectChildrenOnly); | ||||
1730 | for (auto menubar : menuWidgets) { | ||||
1731 | rect = rect.united(menubar->geometry()); | ||||
1732 | } | ||||
1733 | | ||||
1734 | if (handle) { | ||||
1735 | _cachedRects.insert(handle, rect); | ||||
1736 | } | ||||
1737 | return rect; | ||||
1738 | } | ||||
1739 | | ||||
1740 | bool Helper::toolsAreaHasToolBar (const QWidget* widget) const { | ||||
1741 | if (!shouldDrawToolsArea(widget)) return false; | ||||
1742 | | ||||
1743 | auto mainWindow = qobject_cast<QMainWindow*>(widget->window()); | ||||
1744 | if (mainWindow == nullptr) { | ||||
1745 | return false; | ||||
1746 | } | ||||
1747 | | ||||
1748 | QList<QToolBar*> widgets = mainWindow->findChildren<QToolBar*>(QString(), Qt::FindDirectChildrenOnly); | ||||
1749 | for (auto widget : widgets) { | ||||
1750 | if (isInToolsArea(widget) == true) { | ||||
1751 | return true; | ||||
1752 | } | ||||
1753 | } | ||||
1754 | | ||||
1755 | return false; | ||||
1756 | } | ||||
1757 | | ||||
1758 | QToolBar* Helper::grabToolBarForToolsArea(const QWidget *widget) const { | ||||
1759 | auto mainWindow = qobject_cast<QMainWindow*>(widget->window()); | ||||
1760 | if (mainWindow == nullptr) { | ||||
1761 | return nullptr; | ||||
1762 | } | ||||
1763 | | ||||
1764 | QList<QToolBar*> widgets = mainWindow->findChildren<QToolBar*>(QString(), Qt::FindDirectChildrenOnly); | ||||
1765 | for (auto widget : widgets) { | ||||
1766 | if (isInToolsArea(widget)) { | ||||
1767 | return widget; | ||||
1768 | } | ||||
1769 | } | ||||
1770 | | ||||
1771 | return nullptr; | ||||
1772 | } | ||||
1773 | | ||||
1774 | bool Helper::shouldDrawToolsArea(const QWidget* widget) const { | ||||
1775 | if (!widget) return false; | ||||
1776 | if (!_toolsAreaEnabled) return false; | ||||
1777 | static bool isAuto; | ||||
1778 | static QString borderSize; | ||||
1779 | if (!_cachedAutoValid) { | ||||
1780 | KConfigGroup kdecorationGroup(_kwinConfig->group("org.kde.kdecoration2")); | ||||
1781 | isAuto = kdecorationGroup.readEntry("BorderSizeAuto", true); | ||||
1782 | borderSize = kdecorationGroup.readEntry("BorderSize", "Normal"); | ||||
1783 | _cachedAutoValid = true; | ||||
1784 | } | ||||
1785 | if (isAuto) { | ||||
1786 | auto window = widget->window(); | ||||
1787 | if (window) { | ||||
1788 | auto handle = window->windowHandle(); | ||||
1789 | if (handle) { | ||||
1790 | if (handle->frameGeometry().width() != toolsAreaToolbarsRect(widget).width()) { | ||||
1791 | return false; | ||||
1792 | } else { | ||||
1793 | auto toolbar = qobject_cast<const QToolBar*>(widget); | ||||
1794 | if (toolbar) { | ||||
1795 | if (toolbar->isFloating()) { | ||||
1796 | return false; | ||||
1797 | } | ||||
1798 | } | ||||
1799 | return true; | ||||
1800 | } | ||||
1801 | } | ||||
1802 | } else { | ||||
1803 | return false; | ||||
1804 | } | ||||
1805 | } | ||||
1806 | if (borderSize != "None" && borderSize != "NoSides") { | ||||
1807 | return false; | ||||
1808 | } | ||||
1809 | auto toolbar = qobject_cast<const QToolBar*>(widget); | ||||
1810 | if (toolbar) { | ||||
1811 | if (toolbar->isFloating()) { | ||||
1812 | return false; | ||||
1813 | } | ||||
1814 | } | ||||
1815 | return true; | ||||
1816 | } | ||||
1817 | | ||||
1818 | bool Helper::toolsAreaHasContents(const QWidget* widget) const { | ||||
1819 | QList<QWidget*> widgets = widget->window()->findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly); | ||||
1820 | for (auto widget : widgets) { | ||||
1821 | if (isInToolsArea(widget)) { | ||||
1822 | return true; | ||||
1823 | } | ||||
1824 | } | ||||
1825 | return false; | ||||
1826 | } | ||||
1827 | | ||||
1828 | QColor Helper::toolsAreaBorderColor(const QWidget* widget) const { | ||||
1829 | QColor border( | ||||
1830 | KColorUtils::mix( | ||||
1831 | titleBarColor(widget->isActiveWindow()), | ||||
1832 | titleBarTextColor(widget->isActiveWindow()), | ||||
1833 | 0.2 | ||||
1834 | ) | ||||
1835 | ); | ||||
1836 | border.setAlpha(255); | ||||
1837 | return border; | ||||
1838 | } | ||||
1598 | } | 1839 | } |