From 5674e34608b00691280291e97d9bdc867293d18b Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sun, 31 Oct 2021 20:16:41 +0900 Subject: [PATCH] compositor: Add a new OVERLAY layer, specifically for toasts --- apps/compositor.c | 89 ++++++++++++++++++-------- apps/toastd.c | 2 + base/usr/include/toaru/yutani-server.h | 1 + base/usr/include/toaru/yutani.h | 7 +- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/apps/compositor.c b/apps/compositor.c index d1abf148..e3e62fc6 100644 --- a/apps/compositor.c +++ b/apps/compositor.c @@ -227,11 +227,17 @@ static void unorder_window(yutani_globals_t * yg, yutani_server_window_t * w) { yg->top_z = NULL; return; } - - node_t * n = list_find(yg->mid_zs, w); - if (!n) return; - list_delete(yg->mid_zs, n); - free(n); + if (index == YUTANI_ZORDER_OVERLAY) { + node_t * n = list_find(yg->overlay_zs, w); + if (!n) return; + list_delete(yg->overlay_zs, n); + free(n); + } else { + node_t * n = list_find(yg->mid_zs, w); + if (!n) return; + list_delete(yg->mid_zs, n); + free(n); + } } /** @@ -247,7 +253,11 @@ static void reorder_window(yutani_globals_t * yg, yutani_server_window_t * windo window->z = new_zed; if (new_zed != YUTANI_ZORDER_TOP && new_zed != YUTANI_ZORDER_BOTTOM) { - list_insert(yg->mid_zs, window); + if (new_zed == YUTANI_ZORDER_OVERLAY) { + list_insert(yg->overlay_zs, window); + } else { + list_insert(yg->mid_zs, window); + } return; } @@ -276,6 +286,7 @@ static void make_top(yutani_globals_t * yg, yutani_server_window_t * w) { if (index == YUTANI_ZORDER_BOTTOM) return; if (index == YUTANI_ZORDER_TOP) return; + if (index == YUTANI_ZORDER_OVERLAY) return; node_t * n = list_find(yg->mid_zs, w); if (!n) return; /* wat */ @@ -581,6 +592,10 @@ static yutani_server_window_t * check_top_at(yutani_globals_t * yg, yutani_serve */ static yutani_server_window_t * top_at(yutani_globals_t * yg, uint16_t x, uint16_t y) { if (check_top_at(yg, yg->top_z, x, y)) return yg->top_z; + foreachr(node, yg->overlay_zs) { + yutani_server_window_t * w = node->value; + if (check_top_at(yg, w, x, y)) return w; + } foreachr(node, yg->mid_zs) { yutani_server_window_t * w = node->value; if (check_top_at(yg, w, x, y)) return w; @@ -768,29 +783,39 @@ static void yutani_post_vbox_rects(yutani_globals_t * yg) { char tmp[4096]; uint32_t * count = (uint32_t *)tmp; *count = 0; - int32_t * magic = (int32_t *)tmp; - magic++; + + struct Rect { + int32_t x; + int32_t y; + int32_t xe; + int32_t ye; + } __attribute__((packed)); + + + struct Rect * rects = (struct Rect *)(tmp+sizeof(int32_t)); + +#define DO_WINDOW(win) if (win && !win->hidden && *count < 255 ) { \ + rects->x = (win)->x; \ + rects->y = (win)->y; \ + rects->xe = (win)->x + (win)->width; \ + rects->ye = (win)->y + (win)->height; \ + rects++; \ + (*count)++; \ +} /* Add top window if it exists */ - if (yg->top_z) { - *magic = yg->top_z->x; magic++; - *magic = yg->top_z->y; magic++; - *magic = yg->top_z->x + yg->top_z->width; magic++; - *magic = yg->top_z->y + yg->top_z->height; magic++; - (*count)++; - } + DO_WINDOW(yg->top_z); /* Add regular windows */ foreach (node, yg->mid_zs) { yutani_server_window_t * w = node->value; - if (w) { - *magic = w->x; magic++; - *magic = w->y; magic++; - *magic = w->x + w->width; magic++; - *magic = w->y + w->height; magic++; - (*count)++; - if (*count == 254) break; - } + DO_WINDOW(w); + } + + /* Add overlay windows */ + foreach (node, yg->overlay_zs) { + yutani_server_window_t * w = node->value; + DO_WINDOW(w); } /* @@ -799,10 +824,10 @@ static void yutani_post_vbox_rects(yutani_globals_t * yg) { */ if (*count == 0) { *count = 1; - *magic = 0; magic++; - *magic = 0; magic++; - *magic = yg->width; magic++; - *magic = yg->height; magic++; + rects->x = 0; + rects->y = 0; + rects->xe = yg->width; + rects->ye = yg->height; } /* Post rectangle data to driver */ @@ -823,6 +848,10 @@ static void yutani_blit_windows(yutani_globals_t * yg) { yutani_server_window_t * w = node->value; if (w) yutani_blit_window(yg, w, w->x, w->y); } + foreach (node, yg->overlay_zs) { + yutani_server_window_t * w = node->value; + if (w) yutani_blit_window(yg, w, w->x, w->y); + } if (yg->top_z) yutani_blit_window(yg, yg->top_z, yg->top_z->x, yg->top_z->y); } @@ -959,6 +988,10 @@ static void redraw_windows(yutani_globals_t * yg) { yutani_server_window_t * w = node->value; if (w && w->anim_mode) mark_window(yg, w); } + foreach (node, yg->overlay_zs) { + yutani_server_window_t * w = node->value; + if (w && w->anim_mode) mark_window(yg, w); + } /* Calculate damage regions from currently queued updates */ while (yg->update_list->length) { @@ -2123,6 +2156,7 @@ int main(int argc, char * argv[]) { yg->key_binds = hashmap_create_int(10); yg->clients_to_windows = hashmap_create_int(10); yg->mid_zs = list_create(); + yg->overlay_zs = list_create(); yg->windows_to_remove = list_create(); yg->window_subscribers = list_create(); @@ -2489,6 +2523,7 @@ int main(int argc, char * argv[]) { foreach (node, yg->mid_zs) { yutani_query_result(yg, p->source, node->value); } + /* Exclude overlay windows? */ yutani_query_result(yg, p->source, yg->top_z); yutani_msg_buildx_window_advertise_alloc(response, 0); yutani_msg_buildx_window_advertise(response,0, 0, NULL, 0, NULL); diff --git a/apps/toastd.c b/apps/toastd.c index 75e0663f..480c51ef 100644 --- a/apps/toastd.c +++ b/apps/toastd.c @@ -62,6 +62,8 @@ static void handle_msg(JSON_Value * msg) { background_sprite.height, YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS | YUTANI_WINDOW_FLAG_ALT_ANIMATION); + yutani_set_stack(yctx, win, YUTANI_ZORDER_OVERLAY); + /* TODO: We need to figure out how to place this... */ yutani_window_move(yctx, win, yctx->display_width - background_sprite.width - PAD_RIGHT, PAD_TOP + background_sprite.height * windows->length); diff --git a/base/usr/include/toaru/yutani-server.h b/base/usr/include/toaru/yutani-server.h index cbe459fe..63cd0f9b 100644 --- a/base/usr/include/toaru/yutani-server.h +++ b/base/usr/include/toaru/yutani-server.h @@ -203,6 +203,7 @@ typedef struct YutaniGlobals { */ yutani_server_window_t * bottom_z; list_t * mid_zs; + list_t * overlay_zs; yutani_server_window_t * top_z; /* Damage region list */ diff --git a/base/usr/include/toaru/yutani.h b/base/usr/include/toaru/yutani.h index 43409f3a..edea02c7 100644 --- a/base/usr/include/toaru/yutani.h +++ b/base/usr/include/toaru/yutani.h @@ -313,9 +313,10 @@ struct yutani_msg_clipboard { * * Specifies which stack set a window should appear in. */ -#define YUTANI_ZORDER_MAX 0xFFFF -#define YUTANI_ZORDER_TOP 0xFFFF -#define YUTANI_ZORDER_BOTTOM 0x0000 +#define YUTANI_ZORDER_MAX 0xFFFF +#define YUTANI_ZORDER_TOP 0xFFFF +#define YUTANI_ZORDER_OVERLAY 0xFFFE +#define YUTANI_ZORDER_BOTTOM 0x0000 /* * YUTANI_MOUSE_BUTTON