From f50a5d9bb1a1f5ad11662618eca87c0025a8de1f Mon Sep 17 00:00:00 2001 From: Lemmy Date: Mon, 27 Apr 2026 02:08:40 -0400 Subject: [PATCH] feat(bar): control center button --- example.toml | 2 +- meson.build | 1 + src/config/config_service.h | 2 +- src/shell/bar/widget_factory.cpp | 12 ++++++ .../bar/widgets/control_center_widget.cpp | 42 +++++++++++++++++++ src/shell/bar/widgets/control_center_widget.h | 22 ++++++++++ 6 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/shell/bar/widgets/control_center_widget.cpp create mode 100644 src/shell/bar/widgets/control_center_widget.h diff --git a/example.toml b/example.toml index 8d901e50f..3f4b4301c 100644 --- a/example.toml +++ b/example.toml @@ -170,7 +170,7 @@ capsule = false start = ["launcher", "wallpaper", "workspaces"] center = ["clock"] -end = ["media", "tray", "notifications", "network", "bluetooth", "volume", "brightness", "battery", "session"] +end = ["media", "tray", "notifications", "network", "bluetooth", "volume", "brightness", "battery", "control-center", "session"] # Per-monitor override example — only the fields you list are overridden: # [bar.main.monitor.dp1] diff --git a/meson.build b/meson.build index 080880346..b055e8030 100644 --- a/meson.build +++ b/meson.build @@ -449,6 +449,7 @@ _noctalia_sources = files( 'src/shell/bar/widgets/audio_visualizer_widget.cpp', 'src/shell/bar/widgets/battery_widget.cpp', 'src/shell/bar/widgets/bluetooth_widget.cpp', + 'src/shell/bar/widgets/control_center_widget.cpp', 'src/shell/bar/widgets/clock_widget.cpp', 'src/shell/bar/widgets/idle_inhibitor_widget.cpp', 'src/shell/bar/widgets/keyboard_layout_widget.cpp', diff --git a/src/config/config_service.h b/src/config/config_service.h index 04f3357da..75e539e02 100644 --- a/src/config/config_service.h +++ b/src/config/config_service.h @@ -78,7 +78,7 @@ struct BarConfig { std::vector startWidgets = {"launcher", "wallpaper", "workspaces"}; std::vector centerWidgets = {"clock"}; std::vector endWidgets = {"media", "tray", "notifications", "network", "bluetooth", - "volume", "brightness", "battery", "session"}; + "volume", "brightness", "battery", "control-center", "session"}; // When true, widgets on this bar use a capsule unless `[widget.*] capsule = false`. bool widgetCapsuleDefault = false; ThemeColor widgetCapsuleFill = roleColor(ColorRole::SurfaceVariant); diff --git a/src/shell/bar/widget_factory.cpp b/src/shell/bar/widget_factory.cpp index d9983b66c..3cb62f10c 100644 --- a/src/shell/bar/widget_factory.cpp +++ b/src/shell/bar/widget_factory.cpp @@ -15,6 +15,7 @@ #include "shell/bar/widgets/bluetooth_widget.h" #include "shell/bar/widgets/brightness_widget.h" #include "shell/bar/widgets/clock_widget.h" +#include "shell/bar/widgets/control_center_widget.h" #include "shell/bar/widgets/idle_inhibitor_widget.h" #include "shell/bar/widgets/keyboard_layout_widget.h" #include "shell/bar/widgets/launcher_widget.h" @@ -124,6 +125,17 @@ std::unique_ptr WidgetFactory::create(const std::string& name, wl_output return widget; } + if (type == "control-center") { + auto barGlyph = wc != nullptr ? wc->getString("glyph", "noctalia") : std::string{"noctalia"}; + if (barGlyph.empty()) { + barGlyph = "search"; + } + auto widget = std::make_unique(output, std::move(barGlyph)); + widget->setContentScale(contentScale); + return widget; + } + + if (type == "idle_inhibitor") { auto widget = std::make_unique(m_idleInhibitor); widget->setContentScale(contentScale); diff --git a/src/shell/bar/widgets/control_center_widget.cpp b/src/shell/bar/widgets/control_center_widget.cpp new file mode 100644 index 000000000..f98e69ec6 --- /dev/null +++ b/src/shell/bar/widgets/control_center_widget.cpp @@ -0,0 +1,42 @@ +#include "shell/bar/widgets/control_center_widget.h" + +#include "render/scene/input_area.h" +#include "render/scene/node.h" +#include "shell/panel/panel_manager.h" +#include "ui/controls/glyph.h" +#include "ui/palette.h" +#include "ui/style.h" + +#include + +ControlCenterWidget::ControlCenterWidget(wl_output* output, std::string barGlyphId) + : m_output(output), m_barGlyphId(std::move(barGlyphId)) {} + +void ControlCenterWidget::create() { + auto area = std::make_unique(); + area->setOnClick([this](const InputArea::PointerData& /*data*/) { + PanelManager::instance().togglePanel("control-center", m_output, 0.0f, 0.0f, "overview"); + }); + + auto glyph = std::make_unique(); + glyph->setGlyph(m_barGlyphId.empty() ? "search" : m_barGlyphId); + glyph->setGlyphSize(Style::fontSizeBody * m_contentScale); + glyph->setColor(widgetForegroundOr(roleColor(ColorRole::OnSurface))); + m_glyph = glyph.get(); + area->addChild(std::move(glyph)); + + setRoot(std::move(area)); +} + +void ControlCenterWidget::doLayout(Renderer& renderer, float /*containerWidth*/, float /*containerHeight*/) { + if (m_glyph == nullptr) { + return; + } + m_glyph->setGlyphSize(Style::fontSizeBody * m_contentScale); + m_glyph->setColor(widgetForegroundOr(roleColor(ColorRole::OnSurface))); + m_glyph->measure(renderer); + auto* node = root(); + if (node != nullptr) { + node->setSize(m_glyph->width(), m_glyph->height()); + } +} diff --git a/src/shell/bar/widgets/control_center_widget.h b/src/shell/bar/widgets/control_center_widget.h new file mode 100644 index 000000000..547643c61 --- /dev/null +++ b/src/shell/bar/widgets/control_center_widget.h @@ -0,0 +1,22 @@ +#pragma once + +#include "shell/bar/widget.h" + +#include +#include + +class Glyph; +struct wl_output; + +class ControlCenterWidget : public Widget { +public: + ControlCenterWidget(wl_output* output, std::string barGlyphId); + + void create() override; + +private: + void doLayout(Renderer& renderer, float containerWidth, float containerHeight) override; + wl_output* m_output; + std::string m_barGlyphId; + Glyph* m_glyph = nullptr; +};