mirror of
https://github.com/hyprwm/hyprland-qt-support.git
synced 2025-05-12 21:20:35 +01:00
style: allow configuration via hyprlang
This commit is contained in:
parent
c63f0e7c9b
commit
8564f0488e
7 changed files with 183 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
@ -15,6 +15,9 @@ string(STRIP ${VER_RAW} VER)
|
|||
project(hyprland-qt-support VERSION ${VER} LANGUAGES CXX)
|
||||
|
||||
find_package(Qt6 6.6 REQUIRED COMPONENTS Qml Quick QuickControls2)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(hyprlang REQUIRED IMPORTED_TARGET hyprlang>=0.6.0)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.6)
|
||||
set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
cmake,
|
||||
ninja,
|
||||
qt6,
|
||||
pkg-config,
|
||||
hyprlang,
|
||||
version ? "0",
|
||||
}: let
|
||||
inherit (lib.strings) makeBinPath;
|
||||
|
@ -26,6 +28,8 @@ in stdenv.mkDerivation {
|
|||
qt6.qtdeclarative
|
||||
qt6.qtsvg
|
||||
qt6.qtwayland
|
||||
pkg-config
|
||||
hyprlang
|
||||
];
|
||||
|
||||
cmakeFlags = [
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
set_source_files_properties(HyprlandStyle.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
|
||||
|
||||
qt_add_library(hyprland-quick-style-impl SHARED checkdelegate.cpp)
|
||||
qt_add_library(hyprland-quick-style-impl SHARED
|
||||
hyprlandstyle.cpp
|
||||
checkdelegate.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(hyprland-quick-style-impl
|
||||
URI org.hyprland.style.impl
|
||||
|
@ -10,6 +13,6 @@ qt_add_qml_module(hyprland-quick-style-impl
|
|||
MotionBehavior.qml
|
||||
)
|
||||
|
||||
target_link_libraries(hyprland-quick-style-impl PRIVATE Qt::Quick)
|
||||
target_link_libraries(hyprland-quick-style-impl PRIVATE Qt::Quick hyprlang)
|
||||
|
||||
install_qml_module(hyprland-quick-style-impl)
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
pragma Singleton
|
||||
import QtQuick
|
||||
|
||||
QtObject {
|
||||
HyprlandStyleBase {
|
||||
id: root
|
||||
|
||||
property int roundness: 1
|
||||
property int borderWidth: 1
|
||||
property bool reduceMotion: false
|
||||
|
||||
function flat(color: color, flat: bool): color {
|
||||
return flat ? root.transparent(color) : color;
|
||||
}
|
||||
|
|
112
src/style/impl/hyprlandstyle.cpp
Normal file
112
src/style/impl/hyprlandstyle.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
#include "hyprlandstyle.hpp"
|
||||
#include <hyprlang.hpp>
|
||||
#include <any>
|
||||
#include <qfileinfo.h>
|
||||
#include <qfilesystemwatcher.h>
|
||||
#include <qlist.h>
|
||||
#include <qdir.h>
|
||||
#include <qobject.h>
|
||||
#include <qtenvironmentvariables.h>
|
||||
#include <qlogging.h>
|
||||
#include <qloggingcategory.h>
|
||||
|
||||
namespace {
|
||||
Q_LOGGING_CATEGORY(logStyle, "hyprland.style", QtWarningMsg);
|
||||
}
|
||||
|
||||
namespace hyprqml::style {
|
||||
HyprlandStyleBase::HyprlandStyleBase() {
|
||||
QObject::connect(&this->configWatcher, &QFileSystemWatcher::fileChanged, this,
|
||||
&HyprlandStyleBase::fileChanged);
|
||||
QObject::connect(&this->configWatcher, &QFileSystemWatcher::directoryChanged, this,
|
||||
&HyprlandStyleBase::directoryChanged);
|
||||
|
||||
auto basePaths = QList<QString>();
|
||||
auto home = qEnvironmentVariable("XDG_CONFIG_HOME");
|
||||
auto configDirs = qEnvironmentVariable("XDG_CONFIG_DIRS");
|
||||
|
||||
if (home.isEmpty())
|
||||
basePaths << qEnvironmentVariable("HOME") % "/.config";
|
||||
else
|
||||
basePaths << home;
|
||||
|
||||
if (configDirs.isEmpty())
|
||||
basePaths << "/etc/xdg";
|
||||
else
|
||||
basePaths << configDirs.split(':');
|
||||
|
||||
qCDebug(logStyle) << "Hyprland style configuration paths:" << basePaths;
|
||||
|
||||
this->configPath = basePaths.first() % "/hypr/application-style.conf";
|
||||
for (const auto& basePath : basePaths) {
|
||||
auto path = basePath % "/hypr/application-style.conf";
|
||||
|
||||
if (QFileInfo(path).isFile()) {
|
||||
this->configPath = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->configWatcher.addPath(this->configPath);
|
||||
this->configWatcher.addPath(QFileInfo(this->configPath).dir().path());
|
||||
this->loadConfig();
|
||||
}
|
||||
|
||||
void HyprlandStyleBase::loadConfig() {
|
||||
qCDebug(logStyle) << "Reloading configuration from" << this->configPath;
|
||||
|
||||
Hyprlang::INT roundness = 1;
|
||||
Hyprlang::INT borderWidth = 1;
|
||||
Hyprlang::INT reduceMotion = 0;
|
||||
|
||||
try {
|
||||
auto config = Hyprlang::CConfig(this->configPath.toStdString().c_str(), {});
|
||||
|
||||
config.addConfigValue("roundness", roundness);
|
||||
config.addConfigValue("border_width", borderWidth);
|
||||
config.addConfigValue("reduce_motion", reduceMotion);
|
||||
|
||||
config.commence();
|
||||
config.parse();
|
||||
|
||||
roundness = std::any_cast<Hyprlang::INT>(config.getConfigValue("roundness"));
|
||||
borderWidth = std::any_cast<Hyprlang::INT>(config.getConfigValue("border_width"));
|
||||
reduceMotion = std::any_cast<Hyprlang::INT>(config.getConfigValue("reduce_motion"));
|
||||
} catch (...) { return; }
|
||||
|
||||
if (roundness < 0 || roundness > 3) {
|
||||
qCWarning(logStyle) << "Invalid value" << roundness
|
||||
<< "for roundness. Must be in range 0-3.";
|
||||
roundness = 1;
|
||||
}
|
||||
|
||||
if (borderWidth < 0 || borderWidth > 3) {
|
||||
qCWarning(logStyle) << "Invalid value" << borderWidth
|
||||
<< "for border_width. Must be in range 0-3.";
|
||||
borderWidth = 1;
|
||||
}
|
||||
|
||||
this->bRoundness = static_cast<int>(roundness);
|
||||
this->bBorderWidth = static_cast<int>(borderWidth);
|
||||
this->bReduceMotion = reduceMotion;
|
||||
}
|
||||
|
||||
void HyprlandStyleBase::fileChanged() {
|
||||
if (!this->configWatcher.files().contains(this->configPath)) {
|
||||
this->configWatcher.addPath(this->configPath);
|
||||
return;
|
||||
}
|
||||
|
||||
this->loadConfig();
|
||||
}
|
||||
|
||||
void HyprlandStyleBase::directoryChanged() {
|
||||
if (!this->configWatcher.files().contains(this->configPath) &&
|
||||
QFileInfo(this->configPath).isFile()) {
|
||||
this->configWatcher.addPath(this->configPath);
|
||||
this->loadConfig();
|
||||
}
|
||||
|
||||
// if the directory was deleted we stop watching
|
||||
}
|
||||
}
|
56
src/style/impl/hyprlandstyle.hpp
Normal file
56
src/style/impl/hyprlandstyle.hpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qproperty.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qfilesystemwatcher.h>
|
||||
|
||||
namespace hyprqml::style {
|
||||
class HyprlandStyleBase : public QObject {
|
||||
Q_OBJECT;
|
||||
QML_ELEMENT;
|
||||
// writes are mostly intended for tester
|
||||
Q_PROPERTY(int roundness READ default WRITE default BINDABLE bindableRoundness NOTIFY
|
||||
roundnessChanged);
|
||||
Q_PROPERTY(int borderWidth READ default WRITE default BINDABLE bindableBorderWidth NOTIFY
|
||||
borderWidthChanged);
|
||||
Q_PROPERTY(bool reduceMotion READ default WRITE default BINDABLE bindableReduceMotion NOTIFY
|
||||
reduceMotionChanged);
|
||||
|
||||
public:
|
||||
explicit HyprlandStyleBase();
|
||||
|
||||
[[nodiscard]] QBindable<int> bindableRoundness() {
|
||||
return &this->bRoundness;
|
||||
}
|
||||
[[nodiscard]] QBindable<int> bindableBorderWidth() {
|
||||
return &this->bBorderWidth;
|
||||
}
|
||||
[[nodiscard]] QBindable<bool> bindableReduceMotion() {
|
||||
return &this->bReduceMotion;
|
||||
}
|
||||
|
||||
signals:
|
||||
void roundnessChanged();
|
||||
void borderWidthChanged();
|
||||
void reduceMotionChanged();
|
||||
|
||||
private slots:
|
||||
void fileChanged();
|
||||
void directoryChanged();
|
||||
|
||||
private:
|
||||
void loadConfig();
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(HyprlandStyleBase, int, bRoundness,
|
||||
&HyprlandStyleBase::roundnessChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(HyprlandStyleBase, int, bBorderWidth,
|
||||
&HyprlandStyleBase::borderWidthChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(HyprlandStyleBase, bool, bReduceMotion,
|
||||
&HyprlandStyleBase::reduceMotionChanged);
|
||||
|
||||
QString configPath;
|
||||
QFileSystemWatcher configWatcher;
|
||||
};
|
||||
}
|
|
@ -152,7 +152,7 @@ ApplicationWindow {
|
|||
TestField { text: "Normal" }
|
||||
TestField { text: "Disabled"; enabled: false }
|
||||
TestField { placeholderText: "Placeholder" }
|
||||
TestField { placeholderText: "Placeholder"; enabled: false }
|
||||
TestField { placeholderText: "Disabled Placeholder"; enabled: false }
|
||||
Item { Layout.fillHeight: true }
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue