Icons now update to reflect window activity.
This commit is contained in:
parent
10b49868cd
commit
e453b4d35a
6 changed files with 61 additions and 4 deletions
53
dvx/dvxApp.c
53
dvx/dvxApp.c
|
|
@ -8,7 +8,8 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <dpmi.h>
|
#include <dpmi.h>
|
||||||
|
|
||||||
#define DBLCLICK_THRESHOLD (CLOCKS_PER_SEC / 2)
|
#define DBLCLICK_THRESHOLD (CLOCKS_PER_SEC / 2)
|
||||||
|
#define ICON_REFRESH_INTERVAL 8
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Prototypes
|
// Prototypes
|
||||||
|
|
@ -23,6 +24,7 @@ static void initColorScheme(AppContextT *ctx);
|
||||||
static void initMouse(AppContextT *ctx);
|
static void initMouse(AppContextT *ctx);
|
||||||
static void pollKeyboard(AppContextT *ctx);
|
static void pollKeyboard(AppContextT *ctx);
|
||||||
static void pollMouse(AppContextT *ctx);
|
static void pollMouse(AppContextT *ctx);
|
||||||
|
static void refreshMinimizedIcons(AppContextT *ctx);
|
||||||
static void updateCursorShape(AppContextT *ctx);
|
static void updateCursorShape(AppContextT *ctx);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -495,6 +497,13 @@ bool dvxUpdate(AppContextT *ctx) {
|
||||||
pollKeyboard(ctx);
|
pollKeyboard(ctx);
|
||||||
dispatchEvents(ctx);
|
dispatchEvents(ctx);
|
||||||
|
|
||||||
|
// Periodically refresh one minimized window thumbnail (staggered)
|
||||||
|
ctx->frameCount++;
|
||||||
|
|
||||||
|
if (ctx->frameCount % ICON_REFRESH_INTERVAL == 0) {
|
||||||
|
refreshMinimizedIcons(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->dirty.count > 0) {
|
if (ctx->dirty.count > 0) {
|
||||||
compositeAndFlush(ctx);
|
compositeAndFlush(ctx);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -830,6 +839,48 @@ static void pollMouse(AppContextT *ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// refreshMinimizedIcons
|
||||||
|
// ============================================================
|
||||||
|
//
|
||||||
|
// Dirty the next minimized window icon whose content has changed
|
||||||
|
// since the last refresh. Only considers windows without custom
|
||||||
|
// iconData. Called every ICON_REFRESH_INTERVAL frames to stagger.
|
||||||
|
|
||||||
|
static void refreshMinimizedIcons(AppContextT *ctx) {
|
||||||
|
WindowStackT *ws = &ctx->stack;
|
||||||
|
DisplayT *d = &ctx->display;
|
||||||
|
int32_t count = 0;
|
||||||
|
int32_t iconIdx = 0;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < ws->count; i++) {
|
||||||
|
WindowT *win = ws->windows[i];
|
||||||
|
|
||||||
|
if (!win->visible || !win->minimized) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!win->iconData && win->contentDirty) {
|
||||||
|
if (count >= ctx->iconRefreshIdx) {
|
||||||
|
int32_t ix = ICON_SPACING + iconIdx * (ICON_TOTAL_SIZE + ICON_SPACING);
|
||||||
|
int32_t iy = d->height - ICON_TOTAL_SIZE - ICON_SPACING;
|
||||||
|
dirtyListAdd(&ctx->dirty, ix, iy, ICON_TOTAL_SIZE, ICON_TOTAL_SIZE);
|
||||||
|
win->contentDirty = false;
|
||||||
|
ctx->iconRefreshIdx = count + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
iconIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapped past the end — reset for next cycle
|
||||||
|
ctx->iconRefreshIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// updateCursorShape
|
// updateCursorShape
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ typedef struct AppContextT {
|
||||||
int32_t lastIconClickId; // window ID of last-clicked minimized icon (-1 = none)
|
int32_t lastIconClickId; // window ID of last-clicked minimized icon (-1 = none)
|
||||||
clock_t lastCloseClickTime;
|
clock_t lastCloseClickTime;
|
||||||
int32_t lastCloseClickId; // window ID of last-clicked close gadget (-1 = none)
|
int32_t lastCloseClickId; // window ID of last-clicked close gadget (-1 = none)
|
||||||
|
int32_t iconRefreshIdx; // next minimized icon to refresh (staggered)
|
||||||
|
int32_t frameCount; // frame counter for periodic tasks
|
||||||
} AppContextT;
|
} AppContextT;
|
||||||
|
|
||||||
// Initialize the application (VESA mode, input, etc.)
|
// Initialize the application (VESA mode, input, etc.)
|
||||||
|
|
@ -53,9 +55,7 @@ void dvxRun(AppContextT *ctx);
|
||||||
bool dvxUpdate(AppContextT *ctx);
|
bool dvxUpdate(AppContextT *ctx);
|
||||||
|
|
||||||
// Create a window
|
// Create a window
|
||||||
WindowT *dvxCreateWindow(AppContextT *ctx, const char *title,
|
WindowT *dvxCreateWindow(AppContextT *ctx, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
|
||||||
int32_t x, int32_t y, int32_t w, int32_t h,
|
|
||||||
bool resizable);
|
|
||||||
|
|
||||||
// Destroy a window
|
// Destroy a window
|
||||||
void dvxDestroyWindow(AppContextT *ctx, WindowT *win);
|
void dvxDestroyWindow(AppContextT *ctx, WindowT *win);
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,7 @@ typedef struct WindowT {
|
||||||
bool minimized;
|
bool minimized;
|
||||||
bool maximized;
|
bool maximized;
|
||||||
bool resizable;
|
bool resizable;
|
||||||
|
bool contentDirty; // true when contentBuf has changed since last icon refresh
|
||||||
int32_t maxW; // maximum width (-1 = screen width)
|
int32_t maxW; // maximum width (-1 = screen width)
|
||||||
int32_t maxH; // maximum height (-1 = screen height)
|
int32_t maxH; // maximum height (-1 = screen height)
|
||||||
int32_t preMaxX; // saved position before maximize
|
int32_t preMaxX; // saved position before maximize
|
||||||
|
|
|
||||||
|
|
@ -1102,6 +1102,7 @@ void wmMaximize(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT
|
||||||
if (win->onPaint) {
|
if (win->onPaint) {
|
||||||
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
||||||
win->onPaint(win, &fullRect);
|
win->onPaint(win, &fullRect);
|
||||||
|
win->contentDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark new position dirty
|
// Mark new position dirty
|
||||||
|
|
@ -1461,6 +1462,7 @@ void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_
|
||||||
if (win->onPaint) {
|
if (win->onPaint) {
|
||||||
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
||||||
win->onPaint(win, &fullRect);
|
win->onPaint(win, &fullRect);
|
||||||
|
win->contentDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stack->dragOffX = mouseX;
|
stack->dragOffX = mouseX;
|
||||||
|
|
@ -1502,6 +1504,7 @@ void wmRestore(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *
|
||||||
if (win->onPaint) {
|
if (win->onPaint) {
|
||||||
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
||||||
win->onPaint(win, &fullRect);
|
win->onPaint(win, &fullRect);
|
||||||
|
win->contentDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark restored position dirty
|
// Mark restored position dirty
|
||||||
|
|
|
||||||
|
|
@ -566,5 +566,6 @@ void widgetOnScroll(WindowT *win, ScrollbarOrientE orient, int32_t value) {
|
||||||
if (win->onPaint) {
|
if (win->onPaint) {
|
||||||
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
RectT fullRect = {0, 0, win->contentW, win->contentH};
|
||||||
win->onPaint(win, &fullRect);
|
win->onPaint(win, &fullRect);
|
||||||
|
win->contentDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,7 @@ void wgtInvalidate(WidgetT *w) {
|
||||||
// Repaint
|
// Repaint
|
||||||
RectT fullRect = {0, 0, w->window->contentW, w->window->contentH};
|
RectT fullRect = {0, 0, w->window->contentW, w->window->contentH};
|
||||||
widgetOnPaint(w->window, &fullRect);
|
widgetOnPaint(w->window, &fullRect);
|
||||||
|
w->window->contentDirty = true;
|
||||||
|
|
||||||
// Dirty the window on screen
|
// Dirty the window on screen
|
||||||
dvxInvalidateWindow(ctx, w->window);
|
dvxInvalidateWindow(ctx, w->window);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue