[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.
This commit is contained in:
Martin Gräßlin 2013-10-14 07:17:07 +02:00
parent 1ea1fb4fbd
commit 302271ce97
6 changed files with 40 additions and 0 deletions

View file

@ -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)

View file

@ -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

View file

@ -45,6 +45,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// KDE
#include <KDE/KIconLoader>
#include <KDE/KWindowSystem>
#include <KDE/KColorScheme>
// Qt
#include <QApplication>
#include <QDebug>
@ -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<xcb_get_property_reply_t> 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<const char*>(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;

View file

@ -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 <typename T>
inline void Client::print(T &stream) const
{

View file

@ -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;
}
}

View file

@ -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