From 96943116f87fc2351ef2f4ef6a39477dc61c1b5e Mon Sep 17 00:00:00 2001 From: Daniel Hammer Date: Sun, 24 May 2026 21:29:59 +0200 Subject: [PATCH] feat: respect accent colors in more places in desktop --- GNUmakefile | 2 +- programs/include/gui/mtk/theme.hpp | 20 +++++++++++++++- programs/include/gui/mtk/widgets.hpp | 2 +- programs/src/bluetooth/main.cpp | 3 +-- .../src/desktop/apps/filemanager/render.cpp | 10 +++++--- programs/src/desktop/compose.cpp | 3 ++- programs/src/desktop/launcher.cpp | 23 +++++++++++++++---- programs/src/desktop/panel.cpp | 3 ++- programs/src/dialogs/filedialog.cpp | 15 ++++++++---- programs/src/screenshot/Makefile | 3 +++ programs/src/texteditor/main.cpp | 3 ++- programs/src/wordprocessor/render.cpp | 3 ++- 12 files changed, 70 insertions(+), 20 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 9f9da94..a23668e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -6,7 +6,7 @@ MAKEFLAGS += -rR ARCH := x86_64 # Default user QEMU flags. These are appended to the QEMU command calls. -QEMUFLAGS := -smp 32 -m 2G -d int -D qemu.log -no-reboot +QEMUFLAGS := -smp 4 -m 2G -d int -D qemu.log -no-reboot override IMAGE_NAME := montauk-$(ARCH) diff --git a/programs/include/gui/mtk/theme.hpp b/programs/include/gui/mtk/theme.hpp index ea7a90e..95c3638 100644 --- a/programs/include/gui/mtk/theme.hpp +++ b/programs/include/gui/mtk/theme.hpp @@ -7,6 +7,7 @@ #pragma once #include "gui/gui.hpp" +#include "gui/mtk/settings.hpp" namespace gui::mtk { @@ -28,6 +29,16 @@ inline Color darken(Color c, uint8_t amount) { return mix(c, colors::BLACK, amount); } +// Light selection/hover tint derived from the desktop accent. Returns the +// canonical MENU_HOVER for the default blue accent so existing visuals are +// preserved exactly; otherwise tints white with ~11% of the accent. +inline Color accent_hover_tint(Color accent) { + if (accent.r == colors::ACCENT.r && accent.g == colors::ACCENT.g + && accent.b == colors::ACCENT.b) + return colors::MENU_HOVER; + return mix(colors::WHITE, accent, 28); +} + struct Theme { Color window_bg; Color surface; @@ -69,7 +80,7 @@ struct Theme { int gap_lg; }; -inline Theme make_theme(Color accent = colors::ACCENT) { +inline Theme make_theme(Color accent) { Theme theme {}; theme.window_bg = colors::WINDOW_BG; theme.surface = Color::from_rgb(0xF5, 0xF5, 0xF5); @@ -112,4 +123,11 @@ inline Theme make_theme(Color accent = colors::ACCENT) { return theme; } +// Zero-arg overload pulls the accent from the desktop appearance settings, so +// MTK widgets (buttons, menus, etc.) automatically pick up the user's chosen +// accent without each caller having to plumb it through. +inline Theme make_theme() { + return make_theme(load_system_accent()); +} + } // namespace gui::mtk diff --git a/programs/include/gui/mtk/widgets.hpp b/programs/include/gui/mtk/widgets.hpp index 6899ccf..498f739 100644 --- a/programs/include/gui/mtk/widgets.hpp +++ b/programs/include/gui/mtk/widgets.hpp @@ -221,7 +221,7 @@ inline void draw_context_menu(Canvas& c, Rect item = {menu.x + 2, menu.y + CONTEXT_MENU_PAD_Y + i * item_h, menu.w - 4, item_h}; if (state.hover == i) - c.fill_rect(item.x, item.y, item.w, item.h, colors::MENU_HOVER); + c.fill_rect(item.x, item.y, item.w, item.h, accent_hover_tint(theme.accent)); Color label_color = items[i].enabled ? theme.text : theme.text_muted; context_menu_draw_label(c, menu.x + 12, item.y + (item.h - fh) / 2, diff --git a/programs/src/bluetooth/main.cpp b/programs/src/bluetooth/main.cpp index 16fbf6d..4750032 100644 --- a/programs/src/bluetooth/main.cpp +++ b/programs/src/bluetooth/main.cpp @@ -94,7 +94,7 @@ static uint64_t g_status_time = 0; // ============================================================================ static mtk::Theme bt_theme() { - mtk::Theme theme = mtk::make_theme(ACCENT); + mtk::Theme theme = mtk::make_theme(); theme.window_bg = BG_COLOR; theme.surface = Color::from_rgb(0xF5, 0xF5, 0xF5); theme.surface_alt = Color::from_rgb(0xF8, 0xF8, 0xF8); @@ -103,7 +103,6 @@ static mtk::Theme bt_theme() { theme.text = TEXT_COLOR; theme.text_muted = Color::from_rgb(0x88, 0x88, 0x88); theme.text_subtle = DIM_TEXT; - theme.selection = ACCENT; theme.accent_soft = ROW_HOVER; theme.danger = RED; theme.danger_hover = mtk::darken(RED, 18); diff --git a/programs/src/desktop/apps/filemanager/render.cpp b/programs/src/desktop/apps/filemanager/render.cpp index 06d04fc..c0aebba 100644 --- a/programs/src/desktop/apps/filemanager/render.cpp +++ b/programs/src/desktop/apps/filemanager/render.cpp @@ -8,6 +8,10 @@ namespace filemanager { +static Color selection_highlight(const DesktopState* ds) { + return gui::mtk::accent_hover_tint(ds ? ds->settings.accent_color : colors::ACCENT); +} + static bool label_break_char(char ch) { return ch == ' ' || ch == '-' || ch == '_' || ch == '/'; } @@ -308,7 +312,7 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) { int sh = gui_min(cell_y + row_h, c.h) - sy; int sw = gui_min(FM_GRID_CELL_W, c.w - FM_SCROLLBAR_W - cell_x); if (sh > 0 && sw > 0) - c.fill_rect(cell_x, sy, sw, sh, colors::MENU_HOVER); + c.fill_rect(cell_x, sy, sw, sh, selection_highlight(ds)); } // Large icon centered horizontally @@ -441,7 +445,7 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) { int sy = gui_max(iy, list_y); int sh = gui_min(iy + FM_ITEM_H, c.h) - sy; if (sh > 0) - c.fill_rect(0, sy, c.w - FM_SCROLLBAR_W, sh, colors::MENU_HOVER); + c.fill_rect(0, sy, c.w - FM_SCROLLBAR_W, sh, selection_highlight(fm->desktop)); } // Icon (skip if it would bleed above the list area) @@ -582,7 +586,7 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) { // ---- Context menu overlay ---- if (fm->ctx_open && fm->ctx_item_count > 0) { - mtk::Theme theme = mtk::make_theme(colors::ACCENT); + mtk::Theme theme = mtk::make_theme(fm->desktop ? fm->desktop->settings.accent_color : colors::ACCENT); theme.border = colors::BORDER; theme.text = colors::TEXT_COLOR; diff --git a/programs/src/desktop/compose.cpp b/programs/src/desktop/compose.cpp index 176e52d..2d9dacf 100644 --- a/programs/src/desktop/compose.cpp +++ b/programs/src/desktop/compose.cpp @@ -5,6 +5,7 @@ */ #include "desktop_internal.hpp" +#include // ============================================================================ // Lock Screen Drawing @@ -304,7 +305,7 @@ void gui::desktop_compose(DesktopState* ds) { Rect item_r = {cmx + 4, iy, CTX_MENU_W - 8, CTX_ITEM_H}; if (item_r.contains(mmx, mmy)) { - fill_rounded_rect(fb, item_r.x, item_r.y, item_r.w, item_r.h, 4, colors::MENU_HOVER); + fill_rounded_rect(fb, item_r.x, item_r.y, item_r.w, item_r.h, 4, gui::mtk::accent_hover_tint(ds->settings.accent_color)); } int icon_x = item_r.x + 8; diff --git a/programs/src/desktop/launcher.cpp b/programs/src/desktop/launcher.cpp index 174a45e..cfa9f8f 100644 --- a/programs/src/desktop/launcher.cpp +++ b/programs/src/desktop/launcher.cpp @@ -5,6 +5,7 @@ */ #include "desktop_internal.hpp" +#include static constexpr int LAUNCHER_W = 560; static constexpr int LAUNCHER_SEARCH_H = 52; @@ -17,8 +18,22 @@ static constexpr int LAUNCHER_SPECIAL_FOLDER_COUNT = 6; static constexpr Color LAUNCHER_BORDER = Color::from_rgb(0xD4, 0xDB, 0xE4); static constexpr Color LAUNCHER_FIELD_BG = Color::from_rgb(0xFF, 0xFF, 0xFF); -static constexpr Color LAUNCHER_SELECTED_BG = Color::from_rgb(0xDA, 0xE7, 0xFD); -static constexpr Color LAUNCHER_HOVER_BG = Color::from_rgb(0xEC, 0xF3, 0xFE); +static constexpr Color LAUNCHER_SELECTED_BG_DEFAULT = Color::from_rgb(0xDA, 0xE7, 0xFD); +static constexpr Color LAUNCHER_HOVER_BG_DEFAULT = Color::from_rgb(0xEC, 0xF3, 0xFE); + +static Color launcher_selected_bg(Color accent) { + if (accent.r == colors::ACCENT.r && accent.g == colors::ACCENT.g + && accent.b == colors::ACCENT.b) + return LAUNCHER_SELECTED_BG_DEFAULT; + return gui::mtk::mix(colors::WHITE, accent, 47); +} + +static Color launcher_hover_bg(Color accent) { + if (accent.r == colors::ACCENT.r && accent.g == colors::ACCENT.g + && accent.b == colors::ACCENT.b) + return LAUNCHER_HOVER_BG_DEFAULT; + return gui::mtk::mix(colors::WHITE, accent, 20); +} static constexpr Color LAUNCHER_MUTED = Color::from_rgb(0x6F, 0x7B, 0x89); static constexpr Color LAUNCHER_PLACEHOLDER = Color::from_rgb(0x98, 0xA1, 0xAD); @@ -589,9 +604,9 @@ void desktop_draw_launcher(DesktopState* ds) { bool selected = (result_idx == ds->launcher_selected); bool hovered = row.contains(ds->mouse.x, ds->mouse.y); if (selected) { - fill_rounded_rect(fb, row.x, row.y, row.w, row.h, 8, LAUNCHER_SELECTED_BG); + fill_rounded_rect(fb, row.x, row.y, row.w, row.h, 8, launcher_selected_bg(ds->settings.accent_color)); } else if (hovered) { - fill_rounded_rect(fb, row.x, row.y, row.w, row.h, 8, LAUNCHER_HOVER_BG); + fill_rounded_rect(fb, row.x, row.y, row.w, row.h, 8, launcher_hover_bg(ds->settings.accent_color)); } if (i > 0) { diff --git a/programs/src/desktop/panel.cpp b/programs/src/desktop/panel.cpp index 636e0f0..f765bfc 100644 --- a/programs/src/desktop/panel.cpp +++ b/programs/src/desktop/panel.cpp @@ -5,6 +5,7 @@ */ #include "desktop_internal.hpp" +#include void gui::desktop_draw_panel(DesktopState* ds) { Framebuffer& fb = ds->fb; @@ -229,7 +230,7 @@ void desktop_draw_app_menu(DesktopState* ds) { // Hover highlight if (item_rect.contains(mx, my)) { - fill_rounded_rect(fb, item_rect.x, item_rect.y, item_rect.w, item_rect.h, 4, colors::MENU_HOVER); + fill_rounded_rect(fb, item_rect.x, item_rect.y, item_rect.w, item_rect.h, 4, gui::mtk::accent_hover_tint(ds->settings.accent_color)); } // Icon diff --git a/programs/src/dialogs/filedialog.cpp b/programs/src/dialogs/filedialog.cpp index f966c39..b8d9b25 100644 --- a/programs/src/dialogs/filedialog.cpp +++ b/programs/src/dialogs/filedialog.cpp @@ -8,6 +8,8 @@ #include "main.hpp" #include #include +#include +#include #include extern "C" { @@ -256,13 +258,14 @@ void draw_input(Canvas& c, const Rect& rect, const char* text, bool focused, int } void draw_action_button(Canvas& c, const Rect& rect, const char* label, bool enabled, bool hovered, bool primary) { - Color bg = primary ? colors::ACCENT : Color::from_rgb(0xE8, 0xE8, 0xE8); + Color accent = gui::mtk::load_system_accent(); + Color bg = primary ? accent : Color::from_rgb(0xE8, 0xE8, 0xE8); Color fg = primary ? colors::WHITE : colors::TEXT_COLOR; if (!enabled) { bg = Color::from_rgb(0xF0, 0xF0, 0xF0); fg = Color::from_rgb(0x9A, 0x9A, 0x9A); } else if (hovered) { - bg = primary ? Color::from_rgb(0x2B, 0x6B, 0xE0) : Color::from_rgb(0xDC, 0xDC, 0xDC); + bg = primary ? gui::mtk::darken(accent, 32) : Color::from_rgb(0xDC, 0xDC, 0xDC); } c.fill_rounded_rect(rect.x, rect.y, rect.w, rect.h, 4, bg); int tx = rect.x + (rect.w - text_width(label)) / 2; @@ -827,6 +830,8 @@ void draw_grid_entries(Canvas& c, FileDialogState* st, const FileDialogLayout& l st->scrollbar.content_height = content_h; st->scrollbar.view_height = lo.content_rect.h; + Color sel_bg = gui::mtk::accent_hover_tint(gui::mtk::load_system_accent()); + for (int i = 0; i < st->entry_count; i++) { int col = i % cols; int row = i / cols; @@ -838,7 +843,7 @@ void draw_grid_entries(Canvas& c, FileDialogState* st, const FileDialogLayout& l int sy = gui_max(cell_y, lo.content_rect.y); int sh = gui_min(cell_y + GRID_CELL_H, lo.content_rect.y + lo.content_rect.h) - sy; int sw = gui_min(GRID_CELL_W, c.w - SCROLLBAR_W - cell_x); - if (sh > 0 && sw > 0) c.fill_rect(cell_x, sy, sw, sh, colors::MENU_HOVER); + if (sh > 0 && sw > 0) c.fill_rect(cell_x, sy, sw, sh, sel_bg); } int icon_x = cell_x + (GRID_CELL_W - GRID_ICON) / 2; @@ -888,11 +893,13 @@ void draw_list_entries(Canvas& c, FileDialogState* st, const FileDialogLayout& l st->scrollbar.content_height = st->entry_count * ITEM_H; st->scrollbar.view_height = rows_h; + Color sel_bg = gui::mtk::accent_hover_tint(gui::mtk::load_system_accent()); + for (int i = 0; i < st->entry_count; i++) { int y = rows_y + i * ITEM_H - st->scrollbar.scroll_offset; if (y + ITEM_H <= rows_y || y >= rows_y + rows_h) continue; - if (i == st->selected) c.fill_rect(0, y, c.w - SCROLLBAR_W, ITEM_H, colors::MENU_HOVER); + if (i == st->selected) c.fill_rect(0, y, c.w - SCROLLBAR_W, ITEM_H, sel_bg); int sfi = -1; if (st->entry_types[i] == ENTRY_SPECIAL) sfi = st->drive_indices[i]; diff --git a/programs/src/screenshot/Makefile b/programs/src/screenshot/Makefile index 66b1943..4017c0b 100644 --- a/programs/src/screenshot/Makefile +++ b/programs/src/screenshot/Makefile @@ -49,6 +49,7 @@ CXXFLAGS := \ -msse2 \ -mno-red-zone \ -mcmodel=small \ + -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -isystem $(PROJECT_ROOT)/kernel/freestnd-c-hdrs/x86_64/include \ @@ -90,5 +91,7 @@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) $(CXX) $(CXXFLAGS) -c $< -o $@ +-include $(OBJS:.o=.d) + clean: rm -rf $(OBJDIR) $(TARGET) diff --git a/programs/src/texteditor/main.cpp b/programs/src/texteditor/main.cpp index 691fa1d..66fe195 100644 --- a/programs/src/texteditor/main.cpp +++ b/programs/src/texteditor/main.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include extern "C" { @@ -692,7 +693,7 @@ static void draw_context_menu(uint32_t* pixels, int W, int H) { if (!g_ctx_menu.open) return; Canvas c(pixels, W, H); - mtk::Theme theme = mtk::make_theme(ACCENT); + mtk::Theme theme = mtk::make_theme(mtk::load_system_accent(ACCENT)); theme.border = BORDER_COLOR; theme.text = TEXT_COLOR; diff --git a/programs/src/wordprocessor/render.cpp b/programs/src/wordprocessor/render.cpp index 4062feb..ec05c3e 100644 --- a/programs/src/wordprocessor/render.cpp +++ b/programs/src/wordprocessor/render.cpp @@ -5,6 +5,7 @@ */ #include "wordprocessor.hpp" +#include static int wp_ui_line_height() { if (g_ui_font && g_ui_font->valid) @@ -38,7 +39,7 @@ static void wp_draw_ui_icon_button(Canvas& c, int x, int y, int w, int h, static void wp_draw_context_menu(Canvas& c, WordProcessorState* wp) { if (!wp || !wp->context_menu.open) return; - mtk::Theme theme = mtk::make_theme(colors::ACCENT); + mtk::Theme theme = mtk::make_theme(mtk::load_system_accent()); theme.border = colors::BORDER; theme.text = colors::TEXT_COLOR;