mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
feat(dependencies): gate ddcutil via DependencyService across settings etc
This commit is contained in:
@@ -1464,7 +1464,8 @@
|
||||
},
|
||||
"ddcutil": {
|
||||
"label": "DDC/CI (ddcutil)",
|
||||
"description": "Control external monitor brightness via DDC/CI"
|
||||
"description": "Control external monitor brightness via DDC/CI",
|
||||
"requires-ddcutil": "Install ddcutil to enable DDC/CI brightness control"
|
||||
},
|
||||
"night-light": {
|
||||
"label": "Night Light",
|
||||
|
||||
@@ -578,8 +578,8 @@ void Application::initServices() {
|
||||
}
|
||||
|
||||
try {
|
||||
m_brightnessService =
|
||||
std::make_unique<BrightnessService>(m_systemBus.get(), m_wayland, m_configService.config().brightness);
|
||||
m_brightnessService = std::make_unique<BrightnessService>(
|
||||
m_systemBus.get(), m_wayland, m_configService.config().brightness, &m_dependencyService);
|
||||
m_brightnessService->setChangeCallback([this, shouldRefreshControlCenter]() {
|
||||
m_brightnessOsd.onBrightnessChanged(*m_brightnessService);
|
||||
m_bar.refresh();
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "shell/control_center/control_center_panel.h"
|
||||
|
||||
#include "config/config_service.h"
|
||||
#include "i18n/i18n.h"
|
||||
#include "notification/notification_manager.h"
|
||||
#include "render/core/renderer.h"
|
||||
#include "render/scene/input_area.h"
|
||||
#include "shell/panel/panel_manager.h"
|
||||
#include "system/brightness_service.h"
|
||||
#include "system/dependency_service.h"
|
||||
#include "ui/controls/button.h"
|
||||
#include "ui/controls/flex.h"
|
||||
@@ -22,6 +24,8 @@ ControlCenterPanel::ControlCenterPanel(
|
||||
SystemMonitorService* sysmon, NightLightManager* nightLight, noctalia::theme::ThemeService* theme,
|
||||
IdleInhibitor* idleInhibitor, DependencyService* dependencies, WaylandConnection* wayland, Wallpaper* wallpaper) {
|
||||
(void)upower;
|
||||
m_config = config;
|
||||
m_brightness = brightness;
|
||||
m_notificationManager = notifications;
|
||||
m_dependencies = dependencies;
|
||||
m_tabs[tabIndex(TabId::Overview)] =
|
||||
@@ -243,6 +247,9 @@ void ControlCenterPanel::onOpen(std::string_view context) {
|
||||
if (m_dependencies != nullptr) {
|
||||
m_dependencies->rescan();
|
||||
}
|
||||
if (m_brightness != nullptr && m_config != nullptr) {
|
||||
m_brightness->reload(m_config->config().brightness);
|
||||
}
|
||||
selectTab(tabFromContext(context));
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,8 @@ private:
|
||||
std::array<Flex*, kTabCount> m_tabContainers{};
|
||||
std::array<Flex*, kTabCount> m_tabHeaderActions{};
|
||||
TabId m_activeTab = TabId::Overview;
|
||||
ConfigService* m_config = nullptr;
|
||||
BrightnessService* m_brightness = nullptr;
|
||||
NotificationManager* m_notificationManager = nullptr;
|
||||
DependencyService* m_dependencies = nullptr;
|
||||
};
|
||||
|
||||
@@ -620,8 +620,11 @@ namespace settings {
|
||||
{"shell", "mpris", "blacklist"}, ListSetting{.items = cfg.shell.mpris.blacklist},
|
||||
"mpris media player dbus session blacklist"));
|
||||
entries.push_back(makeEntry("services", "brightness", tr("settings.schema.services.ddcutil.label"),
|
||||
tr("settings.schema.services.ddcutil.description"), {"brightness", "enable_ddcutil"},
|
||||
ToggleSetting{cfg.brightness.enableDdcutil}, "monitor ddcutil"));
|
||||
env.ddcutilAvailable ? tr("settings.schema.services.ddcutil.description")
|
||||
: tr("settings.schema.services.ddcutil.requires-ddcutil"),
|
||||
{"brightness", "enable_ddcutil"},
|
||||
ToggleSetting{.checked = cfg.brightness.enableDdcutil, .enabled = env.ddcutilAvailable},
|
||||
"monitor ddcutil"));
|
||||
if (!env.wlsunsetAvailable) {
|
||||
// Show only the master toggle in a disabled state so users can discover the feature
|
||||
// and learn the dependency requirement. The remaining settings are hidden until wlsunset is installed.
|
||||
|
||||
@@ -111,6 +111,7 @@ namespace settings {
|
||||
// Runtime conditions that gate optional sections (e.g. compositor-specific features).
|
||||
struct RegistryEnvironment {
|
||||
bool niriBackdropSupported = false; // hide the [backdrop] section when false
|
||||
bool ddcutilAvailable = false; // disable ddcutil toggle when ddcutil is not on PATH
|
||||
bool wlsunsetAvailable = false; // hide night-light entries when wlsunset is not on PATH
|
||||
std::vector<SelectOption> availableOutputs; // monitor selectors available on this machine
|
||||
std::vector<SelectOption> communityPalettes;
|
||||
|
||||
@@ -948,6 +948,7 @@ void SettingsWindow::buildScene(std::uint32_t width, std::uint32_t height) {
|
||||
}
|
||||
settings::RegistryEnvironment env;
|
||||
env.niriBackdropSupported = (m_wayland != nullptr && compositors::isNiri());
|
||||
env.ddcutilAvailable = (m_dependencies != nullptr && m_dependencies->hasDdcutil());
|
||||
env.wlsunsetAvailable = (m_dependencies != nullptr && m_dependencies->hasWlsunset());
|
||||
for (const auto& paletteInfo : noctalia::theme::availableCommunityPalettes()) {
|
||||
env.communityPalettes.push_back(settings::SelectOption{paletteInfo.name, paletteInfo.name});
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
#include "config/config_service.h"
|
||||
#include "core/log.h"
|
||||
#include "core/process.h"
|
||||
#include "core/timer_manager.h"
|
||||
#include "dbus/system_bus.h"
|
||||
#include "ipc/ipc_arg_parse.h"
|
||||
#include "ipc/ipc_service.h"
|
||||
#include "system/dependency_service.h"
|
||||
#include "wayland/wayland_connection.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -586,6 +586,7 @@ namespace {
|
||||
struct BrightnessService::Impl {
|
||||
SystemBus* bus = nullptr;
|
||||
WaylandConnection& wayland;
|
||||
DependencyService* dependencies = nullptr;
|
||||
BrightnessConfig activeConfig;
|
||||
ChangeCallback changeCallback;
|
||||
|
||||
@@ -613,8 +614,8 @@ struct BrightnessService::Impl {
|
||||
std::unordered_map<std::string, DdcJob> pendingRefreshes;
|
||||
std::queue<WorkerCompletion> completions;
|
||||
|
||||
Impl(SystemBus* systemBus, WaylandConnection& wl, const BrightnessConfig& config)
|
||||
: bus(systemBus), wayland(wl), activeConfig(config) {
|
||||
Impl(SystemBus* systemBus, WaylandConnection& wl, const BrightnessConfig& config, DependencyService* deps)
|
||||
: bus(systemBus), wayland(wl), dependencies(deps), activeConfig(config) {
|
||||
setupPollFds();
|
||||
workerThread = std::thread([this]() { workerLoop(); });
|
||||
}
|
||||
@@ -816,7 +817,7 @@ struct BrightnessService::Impl {
|
||||
if (!activeConfig.enableDdcutil) {
|
||||
return;
|
||||
}
|
||||
if (!process::commandExists("ddcutil")) {
|
||||
if (dependencies != nullptr && !dependencies->hasDdcutil()) {
|
||||
if (!warnedMissingDdcutil) {
|
||||
kLog.warn("brightness.enable_ddcutil is set but ddcutil is not installed");
|
||||
warnedMissingDdcutil = true;
|
||||
@@ -1307,8 +1308,9 @@ struct BrightnessService::Impl {
|
||||
}
|
||||
};
|
||||
|
||||
BrightnessService::BrightnessService(SystemBus* bus, WaylandConnection& wayland, const BrightnessConfig& config)
|
||||
: m_impl(new Impl(bus, wayland, config)) {
|
||||
BrightnessService::BrightnessService(SystemBus* bus, WaylandConnection& wayland, const BrightnessConfig& config,
|
||||
DependencyService* dependencies)
|
||||
: m_impl(new Impl(bus, wayland, config, dependencies)) {
|
||||
m_impl->rebuildState(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
|
||||
class IpcService;
|
||||
class DependencyService;
|
||||
class SystemBus;
|
||||
class WaylandConnection;
|
||||
struct BrightnessConfig;
|
||||
@@ -29,7 +30,8 @@ class BrightnessService {
|
||||
public:
|
||||
using ChangeCallback = std::function<void()>;
|
||||
|
||||
BrightnessService(SystemBus* bus, WaylandConnection& wayland, const BrightnessConfig& config);
|
||||
BrightnessService(SystemBus* bus, WaylandConnection& wayland, const BrightnessConfig& config,
|
||||
DependencyService* dependencies = nullptr);
|
||||
~BrightnessService();
|
||||
|
||||
BrightnessService(const BrightnessService&) = delete;
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace {
|
||||
constexpr Logger kLog("dependencies");
|
||||
|
||||
// Optional CLI tools the shell knows about. Adding a new tracked tool is one line.
|
||||
constexpr std::array<const char*, 1> kTrackedTools = {
|
||||
constexpr std::array<const char*, 2> kTrackedTools = {
|
||||
"ddcutil",
|
||||
"wlsunset",
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ public:
|
||||
DependencyService();
|
||||
|
||||
[[nodiscard]] bool has(std::string_view name) const;
|
||||
[[nodiscard]] bool hasDdcutil() const { return has("ddcutil"); }
|
||||
[[nodiscard]] bool hasWlsunset() const { return has("wlsunset"); }
|
||||
|
||||
void rescan();
|
||||
|
||||
Reference in New Issue
Block a user