From 302271ce97c80d248d57c00e50a97cd7d81a8d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Mon, 14 Oct 2013 07:17:07 +0200 Subject: [PATCH] [kwin] Client supports an X property for color scheme The X property _KDE_NET_WM_COLOR_SCHEME can be set on a window and specifies the absolute path to a .color file describing the color scheme of the managed client. The Client reads this property and creates a QPalette from it. If the property is not set or the value is incorrect, the Client uses KWin's default palette. The idea behind this property is to allow an application with a custom color scheme to tell KWin which color scheme the window decoration should use. So that the window looks as a solid pattern again. --- atoms.cpp | 1 + atoms.h | 1 + client.cpp | 25 +++++++++++++++++++++++++ client.h | 10 ++++++++++ events.cpp | 2 ++ manage.cpp | 1 + 6 files changed, 40 insertions(+) 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