Patch KDE to force serverside decoraations and full window frame
This commit is contained in:
parent
ddbf16133e
commit
6722c0fbb4
3 changed files with 267 additions and 99 deletions
|
|
@ -863,7 +863,7 @@ in
|
|||
kfinal: kprev: {
|
||||
kwin = kprev.kwin.overrideAttrs (old: {
|
||||
patches = (old.patches or [ ]) ++ [
|
||||
../patches/kde-decoration.patch
|
||||
../patches/vmsilo-decorations-combined-v6.5.5.patch
|
||||
];
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
From 9c102e0fa2e268dad187f0a882f8b2db5feb1967 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Dav=C3=AD=C3=B0=20Steinn=20Geirsson?= <david@dsg.is>
|
||||
Date: Sun, 8 Feb 2026 23:31:28 +0000
|
||||
Subject: [PATCH] decorations: support vmsilo security context color override
|
||||
|
||||
Add support for changing window decoration colors based on Wayland
|
||||
security context. When a window's security context has the format
|
||||
"vmsilo:<vmname>:<color>", the decoration uses the specified color
|
||||
for the frame and titlebar, with automatic contrast adjustment for
|
||||
foreground text.
|
||||
|
||||
Windows without a security context or with non-vmsilo contexts
|
||||
continue to use standard palette behavior.
|
||||
|
||||
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
||||
---
|
||||
src/decorations/decoratedwindow.cpp | 49 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 48 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/decorations/decoratedwindow.cpp b/src/decorations/decoratedwindow.cpp
|
||||
index 74f799daa8..1cf52c647d 100644
|
||||
--- a/src/decorations/decoratedwindow.cpp
|
||||
+++ b/src/decorations/decoratedwindow.cpp
|
||||
@@ -17,11 +17,32 @@
|
||||
#include <KDecoration3/DecoratedWindow>
|
||||
#include <KDecoration3/Decoration>
|
||||
|
||||
+#include "wayland/clientconnection.h"
|
||||
+#include "wayland/surface.h"
|
||||
+
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QStyle>
|
||||
#include <QToolTip>
|
||||
|
||||
+namespace {
|
||||
+QColor parseVmsiloColor(const QString &securityContextAppId)
|
||||
+{
|
||||
+ if (securityContextAppId.isEmpty() ||
|
||||
+ !securityContextAppId.startsWith(QLatin1String("vmsilo:"))) {
|
||||
+ return QColor();
|
||||
+ }
|
||||
+
|
||||
+ const QStringList parts = securityContextAppId.split(QLatin1Char(':'));
|
||||
+ if (parts.size() != 3) {
|
||||
+ return QColor();
|
||||
+ }
|
||||
+
|
||||
+ // parts[0] = "vmsilo", parts[1] = vmname, parts[2] = color
|
||||
+ return QColor(parts[2]);
|
||||
+}
|
||||
+} // anonymous namespace
|
||||
+
|
||||
namespace KWin
|
||||
{
|
||||
namespace Decoration
|
||||
@@ -192,11 +213,37 @@ void DecoratedWindowImpl::requestClose()
|
||||
|
||||
QColor DecoratedWindowImpl::color(KDecoration3::ColorGroup group, KDecoration3::ColorRole role) const
|
||||
{
|
||||
+ // Check for vmsilo security context color override
|
||||
+ if (SurfaceInterface *surf = m_window->surface()) {
|
||||
+ if (ClientConnection *client = surf->client()) {
|
||||
+ const QColor vmsiloColor = parseVmsiloColor(client->securityContextAppId());
|
||||
+ if (vmsiloColor.isValid()) {
|
||||
+ switch (role) {
|
||||
+ case KDecoration3::ColorRole::Frame:
|
||||
+ case KDecoration3::ColorRole::TitleBar:
|
||||
+ if (group == KDecoration3::ColorGroup::Inactive) {
|
||||
+ return vmsiloColor.darker(120);
|
||||
+ }
|
||||
+ return vmsiloColor;
|
||||
+ case KDecoration3::ColorRole::Foreground: {
|
||||
+ // Calculate contrasting foreground color
|
||||
+ const qreal luminance = 0.299 * vmsiloColor.redF()
|
||||
+ + 0.587 * vmsiloColor.greenF()
|
||||
+ + 0.114 * vmsiloColor.blueF();
|
||||
+ return (luminance > 0.5) ? Qt::black : Qt::white;
|
||||
+ }
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Fall back to standard palette behavior
|
||||
auto dp = m_window->decorationPalette();
|
||||
if (dp) {
|
||||
return dp->color(group, role);
|
||||
}
|
||||
-
|
||||
return QColor();
|
||||
}
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
266
patches/vmsilo-decorations-combined-v6.5.5.patch
Normal file
266
patches/vmsilo-decorations-combined-v6.5.5.patch
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
diff --git a/src/decorations/decoratedwindow.cpp b/src/decorations/decoratedwindow.cpp
|
||||
index ff1a4ad245..300dd996cb 100644
|
||||
--- a/src/decorations/decoratedwindow.cpp
|
||||
+++ b/src/decorations/decoratedwindow.cpp
|
||||
@@ -17,11 +17,32 @@
|
||||
#include <KDecoration3/DecoratedWindow>
|
||||
#include <KDecoration3/Decoration>
|
||||
|
||||
+#include "wayland/clientconnection.h"
|
||||
+#include "wayland/surface.h"
|
||||
+
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QStyle>
|
||||
#include <QToolTip>
|
||||
|
||||
+namespace {
|
||||
+QColor parseVmsiloColor(const QString &securityContextAppId)
|
||||
+{
|
||||
+ if (securityContextAppId.isEmpty() ||
|
||||
+ !securityContextAppId.startsWith(QLatin1String("vmsilo:"))) {
|
||||
+ return QColor();
|
||||
+ }
|
||||
+
|
||||
+ const QStringList parts = securityContextAppId.split(QLatin1Char(':'));
|
||||
+ if (parts.size() != 3) {
|
||||
+ return QColor();
|
||||
+ }
|
||||
+
|
||||
+ // parts[0] = "vmsilo", parts[1] = vmname, parts[2] = color
|
||||
+ return QColor(parts[2]);
|
||||
+}
|
||||
+} // anonymous namespace
|
||||
+
|
||||
namespace KWin
|
||||
{
|
||||
namespace Decoration
|
||||
@@ -187,11 +208,37 @@ void DecoratedWindowImpl::requestClose()
|
||||
|
||||
QColor DecoratedWindowImpl::color(KDecoration3::ColorGroup group, KDecoration3::ColorRole role) const
|
||||
{
|
||||
+ // Check for vmsilo security context color override
|
||||
+ if (SurfaceInterface *surf = m_window->surface()) {
|
||||
+ if (ClientConnection *client = surf->client()) {
|
||||
+ const QColor vmsiloColor = parseVmsiloColor(client->securityContextAppId());
|
||||
+ if (vmsiloColor.isValid()) {
|
||||
+ switch (role) {
|
||||
+ case KDecoration3::ColorRole::Frame:
|
||||
+ case KDecoration3::ColorRole::TitleBar:
|
||||
+ if (group == KDecoration3::ColorGroup::Inactive) {
|
||||
+ return vmsiloColor.darker(120);
|
||||
+ }
|
||||
+ return vmsiloColor;
|
||||
+ case KDecoration3::ColorRole::Foreground: {
|
||||
+ // Calculate contrasting foreground color
|
||||
+ const qreal luminance = 0.299 * vmsiloColor.redF()
|
||||
+ + 0.587 * vmsiloColor.greenF()
|
||||
+ + 0.114 * vmsiloColor.blueF();
|
||||
+ return (luminance > 0.5) ? Qt::black : Qt::white;
|
||||
+ }
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Fall back to standard palette behavior
|
||||
auto dp = m_window->decorationPalette();
|
||||
if (dp) {
|
||||
return dp->color(group, role);
|
||||
}
|
||||
-
|
||||
return QColor();
|
||||
}
|
||||
|
||||
diff --git a/src/decorations/decorationbridge.cpp b/src/decorations/decorationbridge.cpp
|
||||
index bde1d82b06..48726d0fc2 100644
|
||||
--- a/src/decorations/decorationbridge.cpp
|
||||
+++ b/src/decorations/decorationbridge.cpp
|
||||
@@ -89,6 +89,10 @@ void DecorationBridge::init()
|
||||
}
|
||||
m_settings = std::make_shared<KDecoration3::DecorationSettings>(this);
|
||||
|
||||
+ m_pendingBorderSizeOverride = KDecoration3::BorderSize::Tiny;
|
||||
+ m_vmsiloSettings = std::make_shared<KDecoration3::DecorationSettings>(this);
|
||||
+ m_pendingBorderSizeOverride.reset();
|
||||
+
|
||||
const QString pluginId = readPlugin();
|
||||
if (!initPlugin(pluginId)) {
|
||||
if (s_defaultPlugin != pluginId) {
|
||||
@@ -144,6 +148,7 @@ void DecorationBridge::reconfigure()
|
||||
m_plugin = QString();
|
||||
m_factory.reset();
|
||||
m_settings.reset();
|
||||
+ m_vmsiloSettings.reset();
|
||||
} else {
|
||||
// decorations enabled now
|
||||
init();
|
||||
@@ -212,7 +217,7 @@ std::unique_ptr<KDecoration3::DecoratedWindowPrivate> DecorationBridge::createCl
|
||||
|
||||
std::unique_ptr<KDecoration3::DecorationSettingsPrivate> DecorationBridge::settings(KDecoration3::DecorationSettings *parent)
|
||||
{
|
||||
- return std::unique_ptr<SettingsImpl>(new SettingsImpl(parent));
|
||||
+ return std::make_unique<SettingsImpl>(parent, m_pendingBorderSizeOverride);
|
||||
}
|
||||
|
||||
KDecoration3::Decoration *DecorationBridge::createDecoration(Window *window)
|
||||
@@ -229,7 +234,11 @@ KDecoration3::Decoration *DecorationBridge::createDecoration(Window *window)
|
||||
args.insert(QStringLiteral("theme"), m_theme);
|
||||
}
|
||||
auto deco = m_factory->create<KDecoration3::Decoration>(window, QVariantList{args});
|
||||
- deco->setSettings(m_settings);
|
||||
+ if (window->hasVmsiloSecurityContext()) {
|
||||
+ deco->setSettings(m_vmsiloSettings);
|
||||
+ } else {
|
||||
+ deco->setSettings(m_settings);
|
||||
+ }
|
||||
deco->create();
|
||||
deco->init();
|
||||
return deco;
|
||||
diff --git a/src/decorations/decorationbridge.h b/src/decorations/decorationbridge.h
|
||||
index e06a131134..51c96dcd27 100644
|
||||
--- a/src/decorations/decorationbridge.h
|
||||
+++ b/src/decorations/decorationbridge.h
|
||||
@@ -10,7 +10,9 @@
|
||||
|
||||
#include "kwin_export.h"
|
||||
#include <KDecoration3/Private/DecorationBridge>
|
||||
+#include <KDecoration3/DecorationSettings>
|
||||
#include <QObject>
|
||||
+#include <optional>
|
||||
|
||||
class KPluginFactory;
|
||||
namespace KDecoration3
|
||||
@@ -76,6 +78,8 @@ private:
|
||||
QString m_defaultTheme;
|
||||
QString m_theme;
|
||||
std::shared_ptr<KDecoration3::DecorationSettings> m_settings;
|
||||
+ std::shared_ptr<KDecoration3::DecorationSettings> m_vmsiloSettings;
|
||||
+ std::optional<KDecoration3::BorderSize> m_pendingBorderSizeOverride;
|
||||
bool m_noPlugin;
|
||||
};
|
||||
} // Decoration
|
||||
diff --git a/src/decorations/settings.cpp b/src/decorations/settings.cpp
|
||||
index 21b5bbf5cf..70f313d636 100644
|
||||
--- a/src/decorations/settings.cpp
|
||||
+++ b/src/decorations/settings.cpp
|
||||
@@ -22,10 +22,12 @@ namespace KWin
|
||||
{
|
||||
namespace Decoration
|
||||
{
|
||||
-SettingsImpl::SettingsImpl(KDecoration3::DecorationSettings *parent)
|
||||
+SettingsImpl::SettingsImpl(KDecoration3::DecorationSettings *parent,
|
||||
+ std::optional<KDecoration3::BorderSize> borderSizeOverride)
|
||||
: QObject()
|
||||
, DecorationSettingsPrivate(parent)
|
||||
, m_borderSize(KDecoration3::BorderSize::Normal)
|
||||
+ , m_borderSizeOverride(borderSizeOverride)
|
||||
{
|
||||
readSettings();
|
||||
|
||||
diff --git a/src/decorations/settings.h b/src/decorations/settings.h
|
||||
index 128bead161..e6e4e83b60 100644
|
||||
--- a/src/decorations/settings.h
|
||||
+++ b/src/decorations/settings.h
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <KDecoration3/Private/DecorationSettingsPrivate>
|
||||
|
||||
#include <QObject>
|
||||
+#include <optional>
|
||||
|
||||
class KConfigGroup;
|
||||
|
||||
@@ -23,14 +24,15 @@ class SettingsImpl : public QObject, public KDecoration3::DecorationSettingsPriv
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
- explicit SettingsImpl(KDecoration3::DecorationSettings *parent);
|
||||
+ explicit SettingsImpl(KDecoration3::DecorationSettings *parent,
|
||||
+ std::optional<KDecoration3::BorderSize> borderSizeOverride = std::nullopt);
|
||||
~SettingsImpl() override;
|
||||
bool isAlphaChannelSupported() const override;
|
||||
bool isOnAllDesktopsAvailable() const override;
|
||||
bool isCloseOnDoubleClickOnMenu() const override;
|
||||
KDecoration3::BorderSize borderSize() const override
|
||||
{
|
||||
- return m_borderSize;
|
||||
+ return m_borderSizeOverride.value_or(m_borderSize);
|
||||
}
|
||||
QList<KDecoration3::DecorationButtonType> decorationButtonsLeft() const override
|
||||
{
|
||||
@@ -53,6 +55,7 @@ private:
|
||||
QList<KDecoration3::DecorationButtonType> m_leftButtons;
|
||||
QList<KDecoration3::DecorationButtonType> m_rightButtons;
|
||||
KDecoration3::BorderSize m_borderSize;
|
||||
+ std::optional<KDecoration3::BorderSize> m_borderSizeOverride;
|
||||
bool m_autoBorderSize = true;
|
||||
bool m_closeDoubleClickMenu = false;
|
||||
QFont m_font;
|
||||
diff --git a/src/window.cpp b/src/window.cpp
|
||||
index c4dd92c06f..e8f1901252 100644
|
||||
--- a/src/window.cpp
|
||||
+++ b/src/window.cpp
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "useractions.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "wayland/output.h"
|
||||
+#include "wayland/clientconnection.h"
|
||||
#include "wayland/plasmawindowmanagement.h"
|
||||
#include "wayland/surface.h"
|
||||
#include "wayland_server.h"
|
||||
@@ -4336,6 +4337,16 @@ bool Window::userCanSetNoBorder() const
|
||||
return false;
|
||||
}
|
||||
|
||||
+bool Window::hasVmsiloSecurityContext() const
|
||||
+{
|
||||
+ if (SurfaceInterface *surf = surface()) {
|
||||
+ if (ClientConnection *client = surf->client()) {
|
||||
+ return client->securityContextAppId().startsWith(QLatin1String("vmsilo:"));
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
void Window::setNoBorder(bool set)
|
||||
{
|
||||
qCWarning(KWIN_CORE, "%s doesn't support setting decorations", metaObject()->className());
|
||||
diff --git a/src/window.h b/src/window.h
|
||||
index 2b11fa365c..fcf37d32bb 100644
|
||||
--- a/src/window.h
|
||||
+++ b/src/window.h
|
||||
@@ -844,6 +844,8 @@ public:
|
||||
SurfaceInterface *surface() const;
|
||||
void setSurface(SurfaceInterface *surface);
|
||||
|
||||
+ bool hasVmsiloSecurityContext() const;
|
||||
+
|
||||
/**
|
||||
* @returns Transformation to map from global to window coordinates.
|
||||
*/
|
||||
diff --git a/src/xdgshellwindow.cpp b/src/xdgshellwindow.cpp
|
||||
index 092c284b8c..0439025636 100644
|
||||
--- a/src/xdgshellwindow.cpp
|
||||
+++ b/src/xdgshellwindow.cpp
|
||||
@@ -694,6 +694,9 @@ bool XdgToplevelWindow::isTransient() const
|
||||
|
||||
bool XdgToplevelWindow::userCanSetNoBorder() const
|
||||
{
|
||||
+ if (hasVmsiloSecurityContext()) {
|
||||
+ return false;
|
||||
+ }
|
||||
return (m_serverDecoration || m_xdgDecoration) && !isFullScreen();
|
||||
}
|
||||
|
||||
@@ -704,6 +707,9 @@ bool XdgToplevelWindow::noBorder() const
|
||||
|
||||
void XdgToplevelWindow::setNoBorder(bool set)
|
||||
{
|
||||
+ if (hasVmsiloSecurityContext()) {
|
||||
+ set = false;
|
||||
+ }
|
||||
set = rules()->checkNoBorder(set);
|
||||
if (m_userNoBorder == set) {
|
||||
return;
|
||||
Loading…
Add table
Add a link
Reference in a new issue