Files
subhobhai943andClaude Opus 4.8 c9dfa6a1aa feat(gui): Sorry -- an apology app with a live parametric heart
A new desktop app whose whole point is to say sorry, and to look like
saying it took effort. Nothing in it is a static bitmap.

The heart is the classic parametric heart curve, x = 16sin^3(t) and
y = 13cos(t) - 5cos(2t) - 2cos(3t) - cos(4t), precomputed as a 96-point
integer polygon normalised to a half-width of 1000 and scanline-filled at
whatever size the beat currently has it at. Even-odd crossing counting is
what keeps the notch between the lobes open. The beat is a two-thump
cardiac envelope -- a strong systolic beat and a softer echo -- and the
fill carries a vertical gradient, a soft specular highlight on the upper
lobe, and a six-layer glow. The kernel is built -mno-sse with no floating
point, so every curve, gradient, easing and physics step is integer-only
and needs no trigonometry at runtime.

Around it: three apology letters that type themselves out a character at
a time, and a slow drift of small hearts using the same fill routine.
Answering "I forgive you" brightens the heart and bursts the drift
outward; answering "Not yet" dims it, slows the beat, and starts an
honest count of how long it has been waiting. Neither answer is an exit.

Supporting changes, all of them general rather than app-specific:

  - gui_desktop_request_animation_frame(), so an app can opt into
    full-rate recompositing instead of the ~10 Hz live-content
    heartbeat. It is renewed per paint, so it lapses by itself when the
    app stops animating or its window closes.
  - gui_button_styled() and gui_hitzone() in SUB-WT, letting an app with
    its own palette keep the toolkit's click handling. gui_button_colored
    is now a thin wrapper over the former.
  - A heart glyph in the icon set.

The glow layers skip whatever the heart body is about to cover, which
cuts their blended-pixel cost by roughly 3.5x and pays for the extra
layers that turn contour rings into a smooth halo.

Verified in QEMU on x86_64: all three states driven by real clicks --
hover, forgiveness (brighter heart, burst, live typewriter) and waiting
(dimmed heart, slower beat, running counter). Builds clean on x86_64,
aarch64 and armv8i.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
2026-08-26 18:21:22 +05:30

54 lines
1.9 KiB
C

#ifndef _GUI_DESKTOP_H
#define _GUI_DESKTOP_H
#include <stdint.h>
#include <stdbool.h>
#define GUI_TASKBAR_HEIGHT 32
#define GUI_DESKTOP_ICON_W 72
#define GUI_DESKTOP_ICON_H 64
void gui_desktop_init(void);
void gui_desktop_render_background(void);
// Drop the cached wallpaper so the next background render repaints it. Needed
// when the resolution changes or the framebuffer is handed to another owner.
void gui_desktop_invalidate_background(void);
void gui_desktop_render_icons(void);
void gui_desktop_render_taskbar(void);
void gui_desktop_render_start_menu(void);
void gui_desktop_render_context_menu(void);
void gui_desktop_toggle_start_menu(void);
bool gui_desktop_is_start_menu_open(void);
void gui_desktop_open_context_menu(int mx, int my);
void gui_desktop_close_menus(void);
// Returns true if the click was consumed by desktop chrome (taskbar, menus,
// icons) rather than falling through to the window manager.
bool gui_desktop_handle_click(int mx, int my);
// Height of the area windows may occupy (screen minus taskbar).
int gui_desktop_workarea_height(void);
// An app that animates continuously calls this from its paint routine to ask
// for a full-rate recomposite instead of the ~10 Hz live-content heartbeat.
// The request covers only the next frame, so it has to be renewed on every
// paint; it therefore lapses by itself when the app stops animating or its
// window closes, and the compositor goes straight back to idling cheaply.
void gui_desktop_request_animation_frame(void);
// Wallpaper grid overlay (also toggled from the desktop context menu).
void gui_desktop_set_grid(bool on);
bool gui_desktop_get_grid(void);
// Taskbar clock: show seconds (HH:MM:SS) instead of HH:MM.
void gui_desktop_set_clock_seconds(bool on);
bool gui_desktop_get_clock_seconds(void);
void gui_desktop_request_exit(void);
int gui_desktop_run(void);
#endif // _GUI_DESKTOP_H