feat: respect accent colors in more places in desktop

This commit is contained in:
2026-05-24 21:29:59 +02:00
parent c731f718e9
commit 96943116f8
12 changed files with 70 additions and 20 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ MAKEFLAGS += -rR
ARCH := x86_64 ARCH := x86_64
# Default user QEMU flags. These are appended to the QEMU command calls. # 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) override IMAGE_NAME := montauk-$(ARCH)
+19 -1
View File
@@ -7,6 +7,7 @@
#pragma once #pragma once
#include "gui/gui.hpp" #include "gui/gui.hpp"
#include "gui/mtk/settings.hpp"
namespace gui::mtk { namespace gui::mtk {
@@ -28,6 +29,16 @@ inline Color darken(Color c, uint8_t amount) {
return mix(c, colors::BLACK, 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 { struct Theme {
Color window_bg; Color window_bg;
Color surface; Color surface;
@@ -69,7 +80,7 @@ struct Theme {
int gap_lg; int gap_lg;
}; };
inline Theme make_theme(Color accent = colors::ACCENT) { inline Theme make_theme(Color accent) {
Theme theme {}; Theme theme {};
theme.window_bg = colors::WINDOW_BG; theme.window_bg = colors::WINDOW_BG;
theme.surface = Color::from_rgb(0xF5, 0xF5, 0xF5); theme.surface = Color::from_rgb(0xF5, 0xF5, 0xF5);
@@ -112,4 +123,11 @@ inline Theme make_theme(Color accent = colors::ACCENT) {
return theme; 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 } // namespace gui::mtk
+1 -1
View File
@@ -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, Rect item = {menu.x + 2, menu.y + CONTEXT_MENU_PAD_Y + i * item_h,
menu.w - 4, item_h}; menu.w - 4, item_h};
if (state.hover == i) 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; 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, context_menu_draw_label(c, menu.x + 12, item.y + (item.h - fh) / 2,
+1 -2
View File
@@ -94,7 +94,7 @@ static uint64_t g_status_time = 0;
// ============================================================================ // ============================================================================
static mtk::Theme bt_theme() { static mtk::Theme bt_theme() {
mtk::Theme theme = mtk::make_theme(ACCENT); mtk::Theme theme = mtk::make_theme();
theme.window_bg = BG_COLOR; theme.window_bg = BG_COLOR;
theme.surface = Color::from_rgb(0xF5, 0xF5, 0xF5); theme.surface = Color::from_rgb(0xF5, 0xF5, 0xF5);
theme.surface_alt = Color::from_rgb(0xF8, 0xF8, 0xF8); theme.surface_alt = Color::from_rgb(0xF8, 0xF8, 0xF8);
@@ -103,7 +103,6 @@ static mtk::Theme bt_theme() {
theme.text = TEXT_COLOR; theme.text = TEXT_COLOR;
theme.text_muted = Color::from_rgb(0x88, 0x88, 0x88); theme.text_muted = Color::from_rgb(0x88, 0x88, 0x88);
theme.text_subtle = DIM_TEXT; theme.text_subtle = DIM_TEXT;
theme.selection = ACCENT;
theme.accent_soft = ROW_HOVER; theme.accent_soft = ROW_HOVER;
theme.danger = RED; theme.danger = RED;
theme.danger_hover = mtk::darken(RED, 18); theme.danger_hover = mtk::darken(RED, 18);
@@ -8,6 +8,10 @@
namespace filemanager { 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) { static bool label_break_char(char ch) {
return ch == ' ' || ch == '-' || ch == '_' || 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 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); int sw = gui_min(FM_GRID_CELL_W, c.w - FM_SCROLLBAR_W - cell_x);
if (sh > 0 && sw > 0) 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 // Large icon centered horizontally
@@ -441,7 +445,7 @@ void filemanager_on_draw(Window* win, Framebuffer& fb) {
int sy = gui_max(iy, list_y); int sy = gui_max(iy, list_y);
int sh = gui_min(iy + FM_ITEM_H, c.h) - sy; int sh = gui_min(iy + FM_ITEM_H, c.h) - sy;
if (sh > 0) 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) // 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 ---- // ---- Context menu overlay ----
if (fm->ctx_open && fm->ctx_item_count > 0) { 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.border = colors::BORDER;
theme.text = colors::TEXT_COLOR; theme.text = colors::TEXT_COLOR;
+2 -1
View File
@@ -5,6 +5,7 @@
*/ */
#include "desktop_internal.hpp" #include "desktop_internal.hpp"
#include <gui/mtk/theme.hpp>
// ============================================================================ // ============================================================================
// Lock Screen Drawing // 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}; Rect item_r = {cmx + 4, iy, CTX_MENU_W - 8, CTX_ITEM_H};
if (item_r.contains(mmx, mmy)) { 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; int icon_x = item_r.x + 8;
+19 -4
View File
@@ -5,6 +5,7 @@
*/ */
#include "desktop_internal.hpp" #include "desktop_internal.hpp"
#include <gui/mtk/theme.hpp>
static constexpr int LAUNCHER_W = 560; static constexpr int LAUNCHER_W = 560;
static constexpr int LAUNCHER_SEARCH_H = 52; 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_BORDER = Color::from_rgb(0xD4, 0xDB, 0xE4);
static constexpr Color LAUNCHER_FIELD_BG = Color::from_rgb(0xFF, 0xFF, 0xFF); 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_SELECTED_BG_DEFAULT = Color::from_rgb(0xDA, 0xE7, 0xFD);
static constexpr Color LAUNCHER_HOVER_BG = Color::from_rgb(0xEC, 0xF3, 0xFE); 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_MUTED = Color::from_rgb(0x6F, 0x7B, 0x89);
static constexpr Color LAUNCHER_PLACEHOLDER = Color::from_rgb(0x98, 0xA1, 0xAD); 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 selected = (result_idx == ds->launcher_selected);
bool hovered = row.contains(ds->mouse.x, ds->mouse.y); bool hovered = row.contains(ds->mouse.x, ds->mouse.y);
if (selected) { 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) { } 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) { if (i > 0) {
+2 -1
View File
@@ -5,6 +5,7 @@
*/ */
#include "desktop_internal.hpp" #include "desktop_internal.hpp"
#include <gui/mtk/theme.hpp>
void gui::desktop_draw_panel(DesktopState* ds) { void gui::desktop_draw_panel(DesktopState* ds) {
Framebuffer& fb = ds->fb; Framebuffer& fb = ds->fb;
@@ -229,7 +230,7 @@ void desktop_draw_app_menu(DesktopState* ds) {
// Hover highlight // Hover highlight
if (item_rect.contains(mx, my)) { 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 // Icon
+11 -4
View File
@@ -8,6 +8,8 @@
#include "main.hpp" #include "main.hpp"
#include <gui/svg.hpp> #include <gui/svg.hpp>
#include <gui/canvas.hpp> #include <gui/canvas.hpp>
#include <gui/mtk/theme.hpp>
#include <gui/mtk/settings.hpp>
#include <montauk/user.h> #include <montauk/user.h>
extern "C" { 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) { 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; Color fg = primary ? colors::WHITE : colors::TEXT_COLOR;
if (!enabled) { if (!enabled) {
bg = Color::from_rgb(0xF0, 0xF0, 0xF0); bg = Color::from_rgb(0xF0, 0xF0, 0xF0);
fg = Color::from_rgb(0x9A, 0x9A, 0x9A); fg = Color::from_rgb(0x9A, 0x9A, 0x9A);
} else if (hovered) { } 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); c.fill_rounded_rect(rect.x, rect.y, rect.w, rect.h, 4, bg);
int tx = rect.x + (rect.w - text_width(label)) / 2; 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.content_height = content_h;
st->scrollbar.view_height = lo.content_rect.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++) { for (int i = 0; i < st->entry_count; i++) {
int col = i % cols; int col = i % cols;
int row = 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 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 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); 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; 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.content_height = st->entry_count * ITEM_H;
st->scrollbar.view_height = rows_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++) { for (int i = 0; i < st->entry_count; i++) {
int y = rows_y + i * ITEM_H - st->scrollbar.scroll_offset; int y = rows_y + i * ITEM_H - st->scrollbar.scroll_offset;
if (y + ITEM_H <= rows_y || y >= rows_y + rows_h) continue; 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; int sfi = -1;
if (st->entry_types[i] == ENTRY_SPECIAL) sfi = st->drive_indices[i]; if (st->entry_types[i] == ENTRY_SPECIAL) sfi = st->drive_indices[i];
+3
View File
@@ -49,6 +49,7 @@ CXXFLAGS := \
-msse2 \ -msse2 \
-mno-red-zone \ -mno-red-zone \
-mcmodel=small \ -mcmodel=small \
-MMD -MP \
-I $(PROG_INC) \ -I $(PROG_INC) \
-isystem $(PROG_INC)/libc \ -isystem $(PROG_INC)/libc \
-isystem $(PROJECT_ROOT)/kernel/freestnd-c-hdrs/x86_64/include \ -isystem $(PROJECT_ROOT)/kernel/freestnd-c-hdrs/x86_64/include \
@@ -90,5 +91,7 @@ $(OBJDIR)/%.o: %.cpp Makefile
mkdir -p $(OBJDIR) mkdir -p $(OBJDIR)
$(CXX) $(CXXFLAGS) -c $< -o $@ $(CXX) $(CXXFLAGS) -c $< -o $@
-include $(OBJS:.o=.d)
clean: clean:
rm -rf $(OBJDIR) $(TARGET) rm -rf $(OBJDIR) $(TARGET)
+2 -1
View File
@@ -15,6 +15,7 @@
#include <gui/dialogs.hpp> #include <gui/dialogs.hpp>
#include <gui/clipboard.hpp> #include <gui/clipboard.hpp>
#include <gui/mtk/widgets.hpp> #include <gui/mtk/widgets.hpp>
#include <gui/mtk/settings.hpp>
#include <gui/stb_math.h> #include <gui/stb_math.h>
extern "C" { extern "C" {
@@ -692,7 +693,7 @@ static void draw_context_menu(uint32_t* pixels, int W, int H) {
if (!g_ctx_menu.open) return; if (!g_ctx_menu.open) return;
Canvas c(pixels, W, H); 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.border = BORDER_COLOR;
theme.text = TEXT_COLOR; theme.text = TEXT_COLOR;
+2 -1
View File
@@ -5,6 +5,7 @@
*/ */
#include "wordprocessor.hpp" #include "wordprocessor.hpp"
#include <gui/mtk/settings.hpp>
static int wp_ui_line_height() { static int wp_ui_line_height() {
if (g_ui_font && g_ui_font->valid) 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) { static void wp_draw_context_menu(Canvas& c, WordProcessorState* wp) {
if (!wp || !wp->context_menu.open) return; 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.border = colors::BORDER;
theme.text = colors::TEXT_COLOR; theme.text = colors::TEXT_COLOR;