feat: show selected window title as header row in preview overlay
Preview menus open with a full-width header naming the active tab's current window (icon plus ellipsized title). Full width keeps menu sizing independent of the selection, so moving the highlight never resizes anything; thumbnail fill-share accounts for the header block within the existing margins. Taps on the header are swallowed.
This commit is contained in:
parent
d47cb4ad03
commit
28d5df8d52
3 changed files with 152 additions and 14 deletions
87
kick.c
87
kick.c
|
|
@ -2673,8 +2673,9 @@ static void overlay_pass_icon_tex(struct wlr_render_pass *pass,
|
|||
|
||||
/* --overlay-previews geometry: thumbnail rows divide the menu, which is
|
||||
content-sized and centered with a 50px top/bottom margin. Each row would
|
||||
fill an equal share of the margined height, but no thumbnail grows past
|
||||
a quarter of the screen height; the menu then wraps the capped rows.
|
||||
fill an equal share of the margined height less the selected-window
|
||||
header block, but no thumbnail grows past a quarter of the screen
|
||||
height; the menu then wraps the header plus the capped rows.
|
||||
Thumbnails keep a fixed 16:9 size; the preview row pads them like a text
|
||||
row pads its font (+8). Pending (windowless) rows share the uniform row
|
||||
height. */
|
||||
|
|
@ -2689,10 +2690,12 @@ static int overlay_title_row_h(void) {
|
|||
A slightly stale snapshot only changes the effective downscale filtering
|
||||
at draw time, which stretches any snapshot to the live thumb box. */
|
||||
static int preview_thumb_w_cached, preview_thumb_h_cached;
|
||||
static int overlay_preview_head_h(void);
|
||||
static void overlay_preview_metrics(int n_rows, int *row_h, int *thumb_w,
|
||||
int *thumb_h) {
|
||||
int boxpad = 6, row_gap = 8;
|
||||
int avail_h = host.height - 2 * OVERLAY_MENU_MARGIN_V;
|
||||
int avail_h = host.height - 2 * OVERLAY_MENU_MARGIN_V -
|
||||
overlay_preview_head_h();
|
||||
int fill = 0;
|
||||
if (n_rows > 0)
|
||||
fill = (avail_h - 2 * boxpad - (n_rows - 1) * row_gap) / n_rows - 8;
|
||||
|
|
@ -3317,7 +3320,8 @@ static int overlay_tab_box(struct overlay_box *box) {
|
|||
if (max_row_w > avail_w) max_row_w = avail_w;
|
||||
|
||||
int bw = max_row_w + 2 * boxpad;
|
||||
int bh = n_rows * row_h + (n_rows - 1) * row_gap + 2 * boxpad;
|
||||
int bh = overlay_preview_head_h() + n_rows * row_h +
|
||||
(n_rows - 1) * row_gap + 2 * boxpad;
|
||||
if (bw > host.width - 2 * margin) bw = host.width - 2 * margin;
|
||||
/* Preview menus are content-sized by construction; the margin clamp is
|
||||
only a safety net for degenerate (tiny) screens. */
|
||||
|
|
@ -3402,8 +3406,62 @@ static void draw_confirm_quit_pass(struct wlr_render_pass *pass,
|
|||
}
|
||||
}
|
||||
|
||||
/* Selected-window header (preview mode): the active tab's current window
|
||||
-- what the highlight sits on -- as a full-width header row at the top
|
||||
of the menu: icon left-anchored, title centered in the remaining width
|
||||
and ellipsized to it. Full width keeps the menu size independent of
|
||||
the selection, so moving the highlight never resizes anything. Reuses
|
||||
the row machinery: tab_row_title for the string (with its pending-tab
|
||||
command fallback), the icon loader, and a budgeted text tile. */
|
||||
static struct kick_window *overlay_selected_window(void) {
|
||||
if (!server.active_tab) return NULL;
|
||||
return tab_current_window(server.active_tab);
|
||||
}
|
||||
|
||||
/* Vertical block the header reserves above the thumbnail rows: the title
|
||||
row plus one standard row gap. Zero outside preview mode. */
|
||||
static int overlay_preview_head_h(void) {
|
||||
if (!opt_overlay_previews) return 0;
|
||||
return overlay_title_row_h() + 8; /* row_gap */
|
||||
}
|
||||
|
||||
static void overlay_pass_selected_header(struct wlr_render_pass *pass,
|
||||
int box_x, int box_y, int boxpad,
|
||||
int row_inner) {
|
||||
struct kick_window *w = overlay_selected_window();
|
||||
if (!w) return;
|
||||
const char *t = tab_row_title(server.active_tab);
|
||||
if (!t) t = "";
|
||||
int icon_sz = OVERLAY_ICON_SZ, icon_gap = 8;
|
||||
int row_h = overlay_title_row_h();
|
||||
int hy = box_y + boxpad;
|
||||
|
||||
overlay_pass_rect(pass, box_x + boxpad - 2, hy - 1, row_inner + 4,
|
||||
row_h, 0.22f, 0.22f, 0.25f, 1.0f);
|
||||
if (overlay_window_icon_needs_load(w))
|
||||
overlay_icon_load_window(w);
|
||||
int ix = box_x + boxpad, iy = hy + (row_h - icon_sz) / 2;
|
||||
if (w->icon_wlr) {
|
||||
overlay_pass_icon_tex(pass, w->icon_wlr, ix, iy, icon_sz, 1.0f);
|
||||
} else {
|
||||
overlay_pass_rect(pass, ix, iy, icon_sz, icon_sz,
|
||||
0.45f, 0.45f, 0.48f, 0.85f);
|
||||
overlay_pass_rect(pass, ix + 3, iy + 3, icon_sz - 6,
|
||||
icon_sz - 6, 0.07f, 0.07f, 0.09f, 1.0f);
|
||||
}
|
||||
int rx = ix + icon_sz + icon_gap;
|
||||
int rw = row_inner - (icon_sz + icon_gap);
|
||||
if (rw < 0) rw = 0;
|
||||
struct overlay_text_entry *te = overlay_text_tile(t, rw);
|
||||
int tw = te ? te->w : 0;
|
||||
int tx = rx + (rw - tw) / 2;
|
||||
if (tx < rx) tx = rx;
|
||||
overlay_pass_text(pass, t, rw, tx,
|
||||
hy + (row_h - host.overlay_font_h) / 2, 1.0f);
|
||||
}
|
||||
|
||||
static void draw_tab_overlay_pass(struct wlr_render_pass *pass,
|
||||
int origin_x, int origin_y) {
|
||||
int origin_x, int origin_y) {
|
||||
if (!host.overlay_visible && !confirm_quit_pending) return;
|
||||
if (confirm_quit_pending) {
|
||||
draw_confirm_quit_pass(pass, origin_x, origin_y);
|
||||
|
|
@ -3441,13 +3499,19 @@ static void draw_tab_overlay_pass(struct wlr_render_pass *pass,
|
|||
overlay_pass_rect(pass, box_x + box_w - bw, box_y, bw, box_h,
|
||||
0.45f, 0.45f, 0.48f, 1.0f);
|
||||
|
||||
/* Selected-window header first (preview mode); thumbnail rows follow
|
||||
below it with the standard gap. */
|
||||
int head_h = overlay_preview_head_h();
|
||||
int row_inner = box_w - 2 * boxpad;
|
||||
if (opt_overlay_previews && head_h > 0)
|
||||
overlay_pass_selected_header(pass, box_x, box_y, boxpad, row_inner);
|
||||
|
||||
int row = 0;
|
||||
wl_list_for_each(tab, &server.tabs, link) {
|
||||
if (!tab_overlay_row(tab)) continue;
|
||||
(void)tab_row_title(tab);
|
||||
int ry = box_y + boxpad + row * (row_h + row_gap);
|
||||
int ry = box_y + boxpad + head_h + row * (row_h + row_gap);
|
||||
bool active = tab == server.active_tab;
|
||||
int row_inner = box_w - 2 * boxpad;
|
||||
|
||||
struct kick_window *wins[32];
|
||||
char tbuf[32][256];
|
||||
|
|
@ -3577,10 +3641,17 @@ static bool overlay_hit_test(double ox, double oy,
|
|||
}
|
||||
struct kick_tab *tab;
|
||||
|
||||
/* The selected-window header is display-only: taps on it change
|
||||
nothing. */
|
||||
int head_h = overlay_preview_head_h();
|
||||
if (head_h > 0 && oy >= box_y + boxpad &&
|
||||
oy < box_y + boxpad + head_h)
|
||||
return false;
|
||||
|
||||
int row = 0;
|
||||
wl_list_for_each(tab, &server.tabs, link) {
|
||||
if (!tab_overlay_row(tab)) continue;
|
||||
int ry = box_y + boxpad + row * (row_h + row_gap);
|
||||
int ry = box_y + boxpad + head_h + row * (row_h + row_gap);
|
||||
int row_inner = box_w - 2 * boxpad;
|
||||
|
||||
struct kick_window *wins[32];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue