mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
Rework the compositor so it stops repainting the whole screen every frame, tripling the frame rate (17 -> 54 FPS at HD) and adding smooth animation. - Scene-dirty skipping (gui/gui_desktop.c): the full scene is recomposited only when something other than the bare pointer changed -- input, an open animation, or a ~10 Hz heartbeat for live content (clock, graphs). Idle and pointer-only frames skip the recomposite entirely. - Cursor save-under (gui/gui_cursor.c): the pointer is an overlay that stashes and restores the pixels beneath it, so moving the mouse never forces a full repaint -- pointer motion runs at the frame cap. - 60 FPS frame pacer: each iteration is timed against the monotonic clock and padded to a 16.666 ms budget with the new ktime_delay_us() (HPET-precise busy-wait), giving consistent pacing instead of a free-running spin. - Window open animation (gui/gui_wm.c): new windows grow from 60% to full size with a cubic ease-out over ~160 ms; gui_wm_update() drives it and reports while any window is still animating so the compositor keeps redrawing. - Default display mode set to 1280x720 (HD) -- the sweet spot where the software compositor sustains a near-60 FPS cursor with headroom for effects. Kernel: kernel/time/ktime.c gains ktime_delay_us(), a precise HPET-based delay (bounded PIT fallback) used by the pacer. Verified live (screenshotted): boots to 1280x720, logs in, tray reads ~54 FPS (green) while the pointer moves, no cursor ghosting, windows render cleanly. Clean build on x86_64/aarch64/armv8i; 0 panics / 0 OOM. Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
124 lines
3.4 KiB
C
124 lines
3.4 KiB
C
#ifndef _GUI_WM_H
|
|
#define _GUI_WM_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <gui/gui_gfx.h>
|
|
#include <gui/gui_theme.h>
|
|
|
|
#define GUI_MAX_WINDOWS 16
|
|
#define GUI_TITLEBAR_HEIGHT 24
|
|
#define GUI_RESIZE_GRIP 12
|
|
#define GUI_MIN_WINDOW_W 160
|
|
#define GUI_MIN_WINDOW_H 100
|
|
|
|
typedef enum {
|
|
GUI_EVENT_MOUSE_MOVE,
|
|
GUI_EVENT_MOUSE_DOWN,
|
|
GUI_EVENT_MOUSE_UP,
|
|
GUI_EVENT_KEY_DOWN,
|
|
GUI_EVENT_FOCUS,
|
|
GUI_EVENT_RESIZE,
|
|
GUI_EVENT_CLOSE
|
|
} gui_event_type_t;
|
|
|
|
typedef struct {
|
|
gui_event_type_t type;
|
|
int mouse_x;
|
|
int mouse_y;
|
|
int rel_x;
|
|
int rel_y;
|
|
bool btn_left;
|
|
bool btn_right;
|
|
uint16_t key;
|
|
} gui_event_t;
|
|
|
|
// Where a window sits relative to the screen edges.
|
|
typedef enum {
|
|
GUI_SNAP_NONE = 0,
|
|
GUI_SNAP_LEFT,
|
|
GUI_SNAP_RIGHT,
|
|
GUI_SNAP_MAXIMIZED
|
|
} gui_snap_t;
|
|
|
|
typedef struct gui_window {
|
|
int id;
|
|
char title[64];
|
|
int x;
|
|
int y;
|
|
int width;
|
|
int height;
|
|
|
|
bool active;
|
|
bool minimized;
|
|
bool visible;
|
|
bool resizable;
|
|
|
|
// Drag / resize interaction state
|
|
bool is_dragging;
|
|
bool is_resizing;
|
|
int drag_off_x;
|
|
int drag_off_y;
|
|
|
|
// Geometry remembered across maximize / snap so restore is exact
|
|
gui_snap_t snap;
|
|
int saved_x;
|
|
int saved_y;
|
|
int saved_width;
|
|
int saved_height;
|
|
|
|
void* user_data;
|
|
|
|
// Open animation: the window grows from a fraction of its final size to
|
|
// full over a short interval. anim_open_ns == 0 means no animation running.
|
|
uint64_t anim_open_ns; // ktime_ns() when the open animation began
|
|
int target_w; // final geometry the animation resolves to
|
|
int target_h;
|
|
int center_x; // fixed centre the growth expands around
|
|
int center_y;
|
|
|
|
void (*paint)(struct gui_window* win);
|
|
void (*handle_event)(struct gui_window* win, const gui_event_t* ev);
|
|
} gui_window_t;
|
|
|
|
void gui_wm_init(void);
|
|
|
|
// The work area excludes the taskbar; windows maximize and snap inside it.
|
|
void gui_wm_set_workarea(int width, int height);
|
|
|
|
gui_window_t* gui_wm_create_window(const char* title, int x, int y, int w, int h);
|
|
|
|
// Advance any running open animations; returns true while at least one window
|
|
// is still animating (so the compositor keeps redrawing during the effect).
|
|
bool gui_wm_update(void);
|
|
void gui_wm_destroy_window(int win_id);
|
|
void gui_wm_focus_window(int win_id);
|
|
gui_window_t* gui_wm_get_window(int win_id);
|
|
gui_window_t* gui_wm_get_active_window(void);
|
|
int gui_wm_get_window_count(void);
|
|
|
|
// Enumerate in z-order, bottom-most first. Returns NULL past the end.
|
|
gui_window_t* gui_wm_get_window_at_index(int index);
|
|
|
|
void gui_wm_minimize_window(int win_id);
|
|
void gui_wm_restore_window(int win_id);
|
|
void gui_wm_toggle_maximize(int win_id);
|
|
void gui_wm_snap_window(int win_id, gui_snap_t snap);
|
|
void gui_wm_close_active(void);
|
|
void gui_wm_cycle_focus(void);
|
|
void gui_wm_cascade_windows(void);
|
|
void gui_wm_tile_windows(void);
|
|
|
|
// Keep the WM's press-edge detector in step when another layer (a menu, a
|
|
// modal dialog) consumed the click instead. Without this the WM still holds
|
|
// the pre-press state and reads the still-held button as a fresh press on the
|
|
// following frame, stealing focus from whatever the click just opened.
|
|
void gui_wm_sync_button_state(bool btn_left);
|
|
|
|
void gui_wm_handle_mouse(int x, int y, bool btn_left, bool btn_right);
|
|
void gui_wm_handle_key(uint16_t key);
|
|
void gui_wm_render(void);
|
|
|
|
#endif // _GUI_WM_H
|