Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ add_subdirectory(treeland-screensaver)
set(BIN_NAME treeland)

qt_add_executable(${BIN_NAME}
deepintheme.cpp
deepintheme.h
main.cpp
)

Expand Down
222 changes: 222 additions & 0 deletions src/deepintheme.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// Copyright (C) 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "deepintheme.h"

#include "seat/helper.h"
#include "seatuserconfig.hpp"

Check warning on line 7 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "seatuserconfig.hpp" not found.
#include "treelanduserconfig.hpp"

Check warning on line 8 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "treelanduserconfig.hpp" not found.

#include <DGuiApplicationHelper>

Check warning on line 10 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DGuiApplicationHelper> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <QCoreApplication>

Check warning on line 12 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QCoreApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QGuiApplication>

Check warning on line 13 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QGuiApplication> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QSizeF>

Check warning on line 14 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QSizeF> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QStyleHints>

Check warning on line 15 in src/deepintheme.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QStyleHints> not found. Please note: Cppcheck does not need standard library headers to get proper results.

DCORE_USE_NAMESPACE;
DGUI_USE_NAMESPACE;

QDeepinTheme::QDeepinTheme() = default;

QDeepinTheme::~QDeepinTheme()
{
disconnectConfig();
disconnectSeatConfig();
}

const QPalette *QDeepinTheme::palette(QPlatformTheme::Palette type) const
{
if (type != QPlatformTheme::SystemPalette) {
return QGenericUnixTheme::palette(type);
}
static QPalette palette;
Comment thread
deepin-wm marked this conversation as resolved.
palette = DGuiApplicationHelper::instance()->applicationPalette();
return &palette;
}

QVariant QDeepinTheme::themeHint(ThemeHint hint) const
{
if (!m_config)
return QGenericUnixTheme::themeHint(hint);

switch (hint) {
case CursorFlashTime:
return m_config->cursorBlink() ? m_config->cursorBlinkTime() : 0;
case MouseDoubleClickInterval:
return m_config->doubleClickTime();
case MouseDoubleClickDistance:
return m_config->doubleClickDistance();
case StartDragDistance:
return m_config->dndDragThreshold();
case MouseCursorTheme:
return m_config->cursorThemeName();
case MouseCursorSize:
return QSizeF(m_config->cursorSize(), m_config->cursorSize());
case KeyboardAutoRepeatRate:
return m_seatConfig ? m_seatConfig->keyboardRate() : QGenericUnixTheme::themeHint(hint);
case KeyboardInputInterval:
return m_seatConfig ? m_seatConfig->keyboardDelay() : QGenericUnixTheme::themeHint(hint);
default:
break;
}
return QGenericUnixTheme::themeHint(hint);
}

const QFont *QDeepinTheme::font(Font type) const
{
if (!m_config)
return QGenericUnixTheme::font(type);

switch (type) {
case SystemFont: {
static QFont f;
f.setFamily(m_config->font());
f.setPointSize(m_config->fontSize() / 10.0);
return &f;
}
case FixedFont: {
static QFont f;
f.setFamily(m_config->monoFont());
f.setPointSize(m_config->fontSize() / 10.0);
return &f;
}
default:
break;
}
return QGenericUnixTheme::font(type);
}

void QDeepinTheme::bindConfig(TreelandUserConfig *config)
{
if (m_config == config)
return;

disconnectConfig();
m_config = config;
if (!m_config)
return;

auto addConnection = [this](const QMetaObject::Connection &conn) {
m_connections.push_back(conn);
};

addConnection(QObject::connect(m_config, &TreelandUserConfig::cursorBlinkChanged, m_config, [this]() { applyCursorSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::cursorBlinkTimeChanged, m_config, [this]() { applyCursorSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::doubleClickTimeChanged, m_config, [this]() { applyStyleHintSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::doubleClickDistanceChanged, m_config, [this]() { applyThemeSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::dndDragThresholdChanged, m_config, [this]() { applyStyleHintSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::fontChanged, m_config, [this]() { applyFontSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::monoFontChanged, m_config, [this]() { applyFontSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::fontSizeChanged, m_config, [this]() { applyFontSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::iconThemeNameChanged, m_config, [this]() { applyThemeSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::themeNameChanged, m_config, [this]() { applyThemeSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::preferDarkChanged, m_config, [this]() { applyStyleHintSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::cursorThemeNameChanged, m_config, [this]() { applyThemeSettings(); }));
addConnection(QObject::connect(m_config, &TreelandUserConfig::cursorSizeChanged, m_config, [this]() { applyThemeSettings(); }));

applyAllSettings();
}

void QDeepinTheme::applyAllSettings()
{
applyCursorSettings();
applyStyleHintSettings();
applyFontSettings();
applyThemeSettings();
applyKeyboardSettings();
}

void QDeepinTheme::applyCursorSettings()
{
if (!m_config)
return;

int flashTime = m_config->cursorBlink() ? m_config->cursorBlinkTime() : 0;
QGuiApplication::styleHints()->setCursorFlashTime(flashTime);
}

void QDeepinTheme::applyFontSettings()
{
if (!m_config)
return;

QFont systemFont;
systemFont.setFamily(m_config->font());
systemFont.setPointSize(m_config->fontSize() / 10.0);
QGuiApplication::setFont(systemFont);
}

void QDeepinTheme::applyThemeSettings()
{
if (!m_config)
return;

QCoreApplication::postEvent(qGuiApp, new QEvent(QEvent::ThemeChange));
}

void QDeepinTheme::applyStyleHintSettings()
{
if (!m_config)
return;

auto *hints = QGuiApplication::styleHints();
hints->setMouseDoubleClickInterval(m_config->doubleClickTime());
hints->setStartDragDistance(m_config->dndDragThreshold());

if (m_config->preferDark()) {
hints->setColorScheme(Qt::ColorScheme::Dark);
} else {
hints->setColorScheme(Qt::ColorScheme::Light);
}
}

void QDeepinTheme::disconnectConfig()
{
for (const auto &conn : std::as_const(m_connections)) {
QObject::disconnect(conn);
}
m_connections.clear();
m_config = nullptr;
}

void QDeepinTheme::bindSeatConfig(SeatUserDConfig *config)
{
if (m_seatConfig == config)
return;

disconnectSeatConfig();
m_seatConfig = config;
if (!m_seatConfig)
return;

auto addConnection = [this](const QMetaObject::Connection &conn) {
m_seatConnections.push_back(conn);
};

addConnection(QObject::connect(m_seatConfig, &SeatUserDConfig::keyboardRateChanged,
m_seatConfig, [this]() { applyKeyboardSettings(); }));
addConnection(QObject::connect(m_seatConfig, &SeatUserDConfig::keyboardDelayChanged,
m_seatConfig, [this]() { applyKeyboardSettings(); }));

applyKeyboardSettings();
}

void QDeepinTheme::applyKeyboardSettings()
{
if (!m_seatConfig)
return;

auto *hints = QGuiApplication::styleHints();
hints->setKeyboardAutoRepeatRate(m_seatConfig->keyboardRate());
hints->setKeyboardInputInterval(m_seatConfig->keyboardDelay());
}

void QDeepinTheme::disconnectSeatConfig()
{
for (const auto &conn : std::as_const(m_seatConnections)) {
QObject::disconnect(conn);
}
m_seatConnections.clear();
m_seatConfig = nullptr;
}
49 changes: 49 additions & 0 deletions src/deepintheme.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#pragma once

#include <QFont>

Check warning on line 6 in src/deepintheme.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QFont> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QPalette>

Check warning on line 7 in src/deepintheme.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QPalette> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QPointer>

Check warning on line 8 in src/deepintheme.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QPointer> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
# include <private/qgenericunixtheme_p.h>
#else
# include <private/qgenericunixthemes_p.h>
#endif

#include <vector>

class SeatUserDConfig;
class TreelandUserConfig;

class QDeepinTheme : public QGenericUnixTheme
{
public:
QDeepinTheme();
~QDeepinTheme() override;

const QPalette *palette(QPlatformTheme::Palette type) const override;
QVariant themeHint(ThemeHint hint) const override;
const QFont *font(Font type) const override;

void bindConfig(TreelandUserConfig *config);
void bindSeatConfig(SeatUserDConfig *config);

private:
void applyAllSettings();
void applyCursorSettings();
void applyFontSettings();
void applyThemeSettings();
void applyStyleHintSettings();
void applyKeyboardSettings();

void disconnectConfig();
void disconnectSeatConfig();

QPointer<TreelandUserConfig> m_config;
QPointer<SeatUserDConfig> m_seatConfig;
std::vector<QMetaObject::Connection> m_connections;
std::vector<QMetaObject::Connection> m_seatConnections;
};
2 changes: 2 additions & 0 deletions src/input/inputmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ void InputManager::setupSeatUserConfig(const QString &userName)
"org.deepin.dde.treeland",
"/" + userName);

Q_EMIT seatConfigChanged(m_seatDConfig);

#if SEATUSERDCONFIG_DCONFIG_FILE_VERSION_MINOR > 0
if (m_seatDConfig->isInitializeSucceeded()) {
#else
Expand Down
3 changes: 3 additions & 0 deletions src/input/inputmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public Q_SLOTS:
void onMousePointerConfigCreated(PointerDeviceConfigurationV1 *config);
void onTouchpadPointerConfigCreated(PointerDeviceConfigurationV1 *config);

Q_SIGNALS:
void seatConfigChanged(SeatUserDConfig *config);

private Q_SLOTS:
void handleMousePointerConfigApplied(PointerDeviceConfigurationV1::ChangeFlags changes);
void handleTouchpadPointerConfigApplied(PointerDeviceConfigurationV1::ChangeFlags changes);
Expand Down
40 changes: 19 additions & 21 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "core/treeland.h"
#include "deepintheme.h"
#include "input/inputmanager.h"
#include "seat/helper.h"
#include "utils/cmdline.h"

#include <wrenderhelper.h>
Expand All @@ -14,13 +17,6 @@

#include <QGuiApplication>
#include <QMetaType>
#include <QPalette>

#if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0)
# include <private/qgenericunixtheme_p.h>
#else
# include <private/qgenericunixthemes_p.h>
#endif

#include <wserver.h>

Expand All @@ -29,19 +25,16 @@
WAYLIB_SERVER_USE_NAMESPACE
DCORE_USE_NAMESPACE;

class QDeepinTheme : public QGenericUnixTheme
static QDeepinTheme *g_theme = nullptr;

static void bindThemeConfig()
{
public:
const QPalette *palette(QPlatformTheme::Palette type) const override
{
if (type != QPlatformTheme::SystemPalette) {
return QGenericUnixTheme::palette(type);
}
static QPalette palette;
palette = Dtk::Gui::DGuiApplicationHelper::instance()->applicationPalette();
return &palette;
}
};
auto *helper = Helper::instance();
if (!helper || !g_theme)
return;

g_theme->bindConfig(helper->config());
}

int main(int argc, char *argv[])
{
Expand All @@ -50,9 +43,9 @@ int main(int argc, char *argv[])
DTK_GUI_NAMESPACE::DGuiApplicationHelper::DontSaveApplicationTheme,
true);
WServer::initializeQPA({}, [](const QString &) {
return static_cast<QPlatformTheme *>(new QDeepinTheme());
g_theme = new QDeepinTheme();
return static_cast<QPlatformTheme *>(g_theme);
});
// QQuickStyle::setStyle("Material");

QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
Expand Down Expand Up @@ -86,6 +79,11 @@ int main(int argc, char *argv[])
{
Treeland::Treeland treeland;

bindThemeConfig();
QObject::connect(Helper::instance(), &Helper::configChanged, &bindThemeConfig);
QObject::connect(Helper::instance()->inputManager(), &InputManager::seatConfigChanged,
[](SeatUserDConfig *config) { g_theme->bindSeatConfig(config); });

quitCode = app.exec();
}

Expand Down
1 change: 1 addition & 0 deletions src/seat/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ class Helper : public WSeatEventFilter

RootSurfaceContainer *rootContainer() const { return m_rootSurfaceContainer; }
inline WBackend *backend() const { return m_backend; }
InputManager *inputManager() const { return m_inputManager; }
public Q_SLOTS:
void activateSurface(SurfaceWrapper *wrapper, Qt::FocusReason reason = Qt::OtherFocusReason);
void forceActivateSurface(SurfaceWrapper *wrapper,
Expand Down
Loading