diff --git a/atoms.cpp b/atoms.cpp index b42d05a35a..cacea099b1 100644 --- a/atoms.cpp +++ b/atoms.cpp @@ -56,6 +56,7 @@ Atoms::Atoms() , net_wm_opaque_region(QByteArrayLiteral("_NET_WM_OPAQUE_REGION")) , kde_net_wm_tab_group(QByteArrayLiteral("_KDE_NET_WM_TAB_GROUP")) , kde_first_in_window_list(QByteArrayLiteral("_KDE_FIRST_IN_WINDOWLIST")) + , kde_color_sheme(QByteArrayLiteral("_KDE_NET_WM_COLOR_SCHEME")) , m_dtSmWindowInfo(QByteArrayLiteral("_DT_SM_WINDOW_INFO")) , m_motifSupport(QByteArrayLiteral("_MOTIF_WM_INFO")) , m_helpersRetrieved(false) diff --git a/atoms.h b/atoms.h index 500705507d..83191f80e5 100644 --- a/atoms.h +++ b/atoms.h @@ -65,6 +65,7 @@ public: Xcb::Atom net_wm_opaque_region; Xcb::Atom kde_net_wm_tab_group; Xcb::Atom kde_first_in_window_list; + Xcb::Atom kde_color_sheme; /** * @internal diff --git a/client.cpp b/client.cpp index 3bef84affe..fe317b8433 100644 --- a/client.cpp +++ b/client.cpp @@ -45,6 +45,7 @@ along with this program. If not, see . // KDE #include #include +#include // Qt #include #include @@ -141,6 +142,7 @@ Client::Client() #endif , m_decoInputExtent() , m_focusOutTimer(nullptr) + , m_palette(QApplication::palette()) { // TODO: Do all as initialization syncRequest.counter = syncRequest.alarm = XCB_NONE; @@ -2441,6 +2443,29 @@ void Client::updateFirstInTabBox() } } +void Client::updateColorScheme() +{ + // TODO: move into KWindowInfo + xcb_connection_t *c = connection(); + const auto cookie = xcb_get_property_unchecked(c, false, m_client, atoms->kde_color_sheme, + XCB_ATOM_STRING, 0, 10000); + ScopedCPointer prop(xcb_get_property_reply(c, cookie, nullptr)); + auto resetToDefault = [this]() { + m_palette = QApplication::palette(); + }; + if (!prop.isNull() && prop->format == 8 && prop->value_len > 0) { + QString path = QString::fromUtf8(static_cast(xcb_get_property_value(prop.data()))); + if (!path.isNull()) { + m_palette = KColorScheme::createApplicationPalette(KSharedConfig::openConfig(path)); + } else { + resetToDefault(); + } + } else { + resetToDefault(); + } + triggerDecorationRepaint(); +} + bool Client::isClient() const { return true; diff --git a/client.h b/client.h index 9f9adc07ed..1eb4ea474a 100644 --- a/client.h +++ b/client.h @@ -620,6 +620,7 @@ public: m_firstInTabBox = enable; } void updateFirstInTabBox(); + void updateColorScheme(); //sets whether the client should be treated as a SessionInteract window void setSessionInteract(bool needed); @@ -648,6 +649,8 @@ public: void cancelFocusOutTimer(); + QPalette palette() const; + public Q_SLOTS: void closeWindow(); void updateCaption(); @@ -993,6 +996,8 @@ private: QPoint input_offset; QTimer *m_focusOutTimer; + + QPalette m_palette; }; /** @@ -1259,6 +1264,11 @@ inline bool Client::hiddenPreview() const return mapping_state == Kept; } +inline QPalette Client::palette() const +{ + return m_palette; +} + template inline void Client::print(T &stream) const { diff --git a/events.cpp b/events.cpp index b402fee644..6956f3479b 100644 --- a/events.cpp +++ b/events.cpp @@ -800,6 +800,8 @@ void Client::propertyNotifyEvent(xcb_property_notify_event_t *e) updateCompositeBlocking(true); else if (e->atom == atoms->kde_first_in_window_list) updateFirstInTabBox(); + else if (e->atom == atoms->kde_color_sheme) + updateColorScheme(); break; } } diff --git a/manage.cpp b/manage.cpp index 5f38fe1982..deeee4f917 100644 --- a/manage.cpp +++ b/manage.cpp @@ -618,6 +618,7 @@ bool Client::manage(xcb_window_t w, bool isMapped) updateWindowRules(Rules::All); // Was blocked while !isManaged() updateCompositeBlocking(true); + updateColorScheme(); // TODO: there's a small problem here - isManaged() depends on the mapping state, // but this client is not yet in Workspace's client list at this point, will