feat: add window decoration that integrates with tiling

This commit is contained in:
Mikhail Zolotukhin 2022-03-19 14:27:18 +03:00 committed by Genda
parent 38712f6b81
commit 517281e158
6 changed files with 220 additions and 4 deletions

View File

@ -56,8 +56,20 @@ set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS DBus Quick Svg
Test)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED
COMPONENTS I18n KCMUtils Declarative GlobalAccel Config)
find_package(
KF5 ${KF5_MIN_VERSION} REQUIRED
COMPONENTS Config
ConfigWidgets
CoreAddons
Declarative
GlobalAccel
GuiAddons
IconThemes
KCMUtils
WindowSystem
I18n)
find_package(KDecoration2 REQUIRED)
include_directories("${PROJECT_SOURCE_DIR}/external")

View File

@ -1,7 +1,8 @@
# SPDX-FileCopyrightText: 2021 Mikhail Zolotukhin <mail@gikari.com>
# SPDX-FileCopyrightText: 2021-2022 Mikhail Zolotukhin <mail@gikari.com>
# SPDX-License-Identifier: MIT
add_subdirectory(config)
add_subdirectory(core)
add_subdirectory(kcm)
add_subdirectory(kdecoration)
add_subdirectory(kwinscript)
add_subdirectory(config)

View File

@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2022 Mikhail Zolotukhin <mail@gikari.com>
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.16)
project(bismuth-kdecoration)
add_library(bismuth_kdecoration MODULE)
target_sources(bismuth_kdecoration PRIVATE decoration.cpp decoration.hpp)
target_link_libraries(
bismuth_kdecoration
PUBLIC Qt::Core
PRIVATE KDecoration2::KDecoration KF5::ConfigCore KF5::ConfigWidgets)
install(TARGETS bismuth_kdecoration
DESTINATION ${KDE_INSTALL_PLUGINDIR}/org.kde.kdecoration2)

View File

@ -0,0 +1,123 @@
// SPDX-FileCopyrightText: 2022 Mikhail Zolotukhin <mail@gikari.com>
// SPDX-License-Identifier: MIT
#include "decoration.hpp"
#include <QPainter>
#include <KConfigGroup>
#include <KDecoration2/DecoratedClient>
#include <KDecoration2/DecorationSettings>
#include <KPluginFactory>
#include <KSharedConfig>
K_PLUGIN_FACTORY_WITH_JSON(BismuthDecorationFactory, "metadata.json", registerPlugin<Bismuth::Decoration>();)
namespace Bismuth
{
Decoration::Decoration(QObject *parent, const QVariantList &args)
: KDecoration2::Decoration(parent, args)
{
}
void Decoration::init()
{
m_kdeglobalsWatcher = KConfigWatcher::create(KSharedConfig::openConfig("kdeglobals"));
setBorderSizes();
connectEvents();
updateColors();
}
void Decoration::paint(QPainter *painter, const QRect &repaintRegion)
{
paintBorders(*painter);
}
void Decoration::paintBorders(QPainter &p)
{
auto client = this->client().lock();
auto windowRect = rect();
p.save();
p.setPen(Qt::NoPen);
if (client->isActive()) {
p.setBrush(m_activeColor);
} else {
p.setBrush(m_inactiveColor);
}
p.drawRect(windowRect);
p.restore();
}
void Decoration::updateColors()
{
auto colorsConfig = KSharedConfig::openConfig("kdeglobals");
auto group = colorsConfig->group("Colors:Window");
m_activeColor = group.readEntry("DecorationFocus", QColor(255, 0, 0));
m_inactiveColor = group.readEntry("BackgroundNormal", QColor(0, 0, 0));
}
void Decoration::setBorderSizes()
{
const auto client = this->client().lock();
const int left = (settings()->borderSize() == KDecoration2::BorderSize::NoSides) ? 0 : borderSize();
const int top = borderSize();
const int right = (settings()->borderSize() == KDecoration2::BorderSize::NoSides) ? 0 : borderSize();
const int bottom = borderSize();
setBorders(QMargins(left, top, right, bottom));
}
void Decoration::connectEvents()
{
auto clientPtr = this->client().lock().data();
auto settingsPtr = settings().data();
// No idea why regular connection does not work
connect(clientPtr, &KDecoration2::DecoratedClient::activeChanged, this, [&](bool value) {
this->update();
});
connect(settingsPtr, &KDecoration2::DecorationSettings::borderSizeChanged, this, &Decoration::setBorderSizes);
connect(m_kdeglobalsWatcher.data(), &KConfigWatcher::configChanged, [&](const KConfigGroup &group, const QByteArrayList &names) {
if (group.name() == QStringLiteral("General")) {
if (names.contains(QByteArrayLiteral("ColorScheme")) || names.contains(QByteArrayLiteral("AccentColor"))) {
updateColors();
this->update();
}
}
});
}
int Decoration::borderSize() const
{
const int baseSize = settings()->smallSpacing();
switch (settings()->borderSize()) {
case KDecoration2::BorderSize::Oversized:
return baseSize * 10;
case KDecoration2::BorderSize::VeryHuge:
return baseSize * 6;
case KDecoration2::BorderSize::Huge:
return baseSize * 5;
case KDecoration2::BorderSize::VeryLarge:
return baseSize * 4;
case KDecoration2::BorderSize::NoSides:
case KDecoration2::BorderSize::Normal:
return baseSize * 2;
case KDecoration2::BorderSize::Large:
return baseSize * 3;
case KDecoration2::BorderSize::None:
return 0;
case KDecoration2::BorderSize::Tiny:
default:
return baseSize;
}
}
}
#include "decoration.moc"

View File

@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: 2022 Mikhail Zolotukhin <mail@gikari.com>
// SPDX-License-Identifier: MIT
#pragma once
#include <QVariant>
#include <KConfigWatcher>
#include <KDecoration2/Decoration>
namespace Bismuth
{
class Decoration : public KDecoration2::Decoration
{
Q_OBJECT
public:
explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList());
/**
* Provides the rendering.
*
* The painter is set up to paint on an internal QPaintDevice. The painting is implicitly double buffered.
*/
void paint(QPainter *painter, const QRect &repaintRegion) override;
public Q_SLOTS:
/**
* This method gets invoked once the Decoration is created and completely setup.
*
* All initialization must be performed in this method instead of the constructor.
*/
void init() override;
private:
void paintBorders(QPainter &painter);
void updateColors();
void setBorderSizes();
void connectEvents();
int borderSize() const;
QColor m_activeColor;
QColor m_inactiveColor;
KConfigWatcher::Ptr m_kdeglobalsWatcher;
};
}

View File

@ -0,0 +1,13 @@
{
"KPlugin": {
"Id": "org.kde.bismuth.decoration",
"Description": "Window decoration, that integrates with Bismuth Tiling Window extension for the Plasma Desktop",
"Name": "Bismuth",
"ServiceTypes": ["org.kde.kdecoration2"]
},
"org.kde.kdecoration2": {
"blur": false,
"kcmodule": false,
"recommendedBorderSize": "Normal"
}
}