mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
render: scrollback indicator: wip: implement 'fixed:percent' indicator
When scrollback indicator has been enabled, and the viewport isn't at the bottom, we now render a *static* indicator with the position in percent. We use the color scheme's blue color as background, and it's white color as foreground. This is subject to change... Should maybe be configurable as well. The Wayland surface + sub-surface are instantiated on-demand, and automatically destroyed when no longer used.
This commit is contained in:
parent
c2362c10f1
commit
67758a7cb7
1 changed files with 100 additions and 10 deletions
110
render.c
110
render.c
|
|
@ -1293,6 +1293,53 @@ render_scrollback_position(struct terminal *term)
|
|||
if (term->conf->scrollback.indicator.style == SCROLLBACK_INDICATOR_STYLE_NONE)
|
||||
return;
|
||||
|
||||
struct wayland *wayl = term->wl;
|
||||
struct wl_window *win = term->window;
|
||||
|
||||
if (term->grid->view == term->grid->offset) {
|
||||
if (win->scrollback_indicator_surface != NULL) {
|
||||
wl_subsurface_destroy(win->scrollback_indicator_sub_surface);
|
||||
wl_surface_destroy(win->scrollback_indicator_surface);
|
||||
|
||||
win->scrollback_indicator_surface = NULL;
|
||||
win->scrollback_indicator_sub_surface = NULL;
|
||||
|
||||
LOG_INFO("destroyed indicator surfaces");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (win->scrollback_indicator_surface == NULL) {
|
||||
win->scrollback_indicator_surface
|
||||
= wl_compositor_create_surface(wayl->compositor);
|
||||
|
||||
if (win->scrollback_indicator_surface == NULL) {
|
||||
LOG_ERR("failed to create scrollback indicator surface");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_surface_set_user_data(win->scrollback_indicator_surface, win);
|
||||
|
||||
term->window->scrollback_indicator_sub_surface
|
||||
= wl_subcompositor_get_subsurface(
|
||||
wayl->sub_compositor,
|
||||
win->scrollback_indicator_surface,
|
||||
win->surface);
|
||||
|
||||
if (win->scrollback_indicator_sub_surface == NULL) {
|
||||
LOG_ERR("failed to create scrollback indicator sub-surface");
|
||||
wl_surface_destroy(win->scrollback_indicator_surface);
|
||||
win->scrollback_indicator_surface = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
wl_subsurface_set_sync(win->scrollback_indicator_sub_surface);
|
||||
LOG_INFO("instantiated indicator surfaces");
|
||||
}
|
||||
|
||||
assert(win->scrollback_indicator_surface != NULL);
|
||||
assert(win->scrollback_indicator_sub_surface != NULL);
|
||||
|
||||
/* Find absolute row number of the scrollback start */
|
||||
int scrollback_start = term->grid->offset + term->rows;
|
||||
while (term->grid->rows[scrollback_start & (term->grid->num_rows - 1)] == NULL)
|
||||
|
|
@ -1309,24 +1356,67 @@ render_scrollback_position(struct terminal *term)
|
|||
* 0% -> at the beginning of the scrollback
|
||||
* 100% -> at the bottom, i.e. where new lines are inserted
|
||||
*/
|
||||
int percentage __attribute__((unused)) =
|
||||
int percentage =
|
||||
rebased_view + term->rows == term->grid->num_rows
|
||||
? 100
|
||||
: 100 * rebased_view / term->grid->num_rows;
|
||||
|
||||
int next_row_no = term->grid->view + term->rows;
|
||||
next_row_no &= term->grid->num_rows - 1;
|
||||
const int scale = term->scale;
|
||||
const int margin = 3 * scale;
|
||||
const int width = 2 * margin + 3 * term->cell_width; /* TODO: this is percent only */
|
||||
const int height = 2 * margin + term->cell_height;
|
||||
|
||||
/* Are we at the end of the scrollback? */
|
||||
bool at_bottom = rebased_view + term->rows == term->grid->num_rows ||
|
||||
term->grid->rows[next_row_no] == NULL;
|
||||
unsigned long cookie = shm_cookie_scrollback_indicator(term);
|
||||
struct buffer *buf = shm_get_buffer(
|
||||
term->wl->shm, width, height, cookie, false, 1);
|
||||
|
||||
LOG_DBG("scrollback position: %d/%d (%d%%), at-bottom: %d",
|
||||
rebased_view, term->grid->num_rows, percentage, at_bottom);
|
||||
pixman_color_t bg = color_hex_to_pixman(term->colors.table[4]);
|
||||
pixman_image_fill_rectangles(
|
||||
PIXMAN_OP_SRC, buf->pix[0], &bg, 1,
|
||||
&(pixman_rectangle16_t){0, 0, width, height});
|
||||
|
||||
if (!at_bottom) {
|
||||
/* TODO: insert rendering code here */
|
||||
struct fcft_font *font = term->fonts[0];
|
||||
pixman_color_t fg = color_hex_to_pixman(term->colors.table[7]);
|
||||
|
||||
wchar_t text[64];
|
||||
swprintf(text, sizeof(text) / sizeof(text[0]), L"%d%%", percentage);
|
||||
|
||||
unsigned x = width - margin - wcslen(text) * term->cell_width;
|
||||
const unsigned y = margin;
|
||||
|
||||
for (size_t i = 0; i < wcslen(text); i++) {
|
||||
const struct fcft_glyph *glyph = fcft_glyph_rasterize(
|
||||
font, text[i], term->font_subpixel);
|
||||
|
||||
if (glyph == NULL)
|
||||
continue;
|
||||
|
||||
pixman_image_t *src = pixman_image_create_solid_fill(&fg);
|
||||
pixman_image_composite32(
|
||||
PIXMAN_OP_OVER, src, glyph->pix, buf->pix[0], 0, 0, 0, 0,
|
||||
x + glyph->x, y + font_baseline(term) - glyph->y,
|
||||
glyph->width, glyph->height);
|
||||
pixman_image_unref(src);
|
||||
|
||||
x += term->cell_width;
|
||||
}
|
||||
|
||||
wl_subsurface_set_position(
|
||||
win->scrollback_indicator_sub_surface,
|
||||
(term->width - term->margins.right - width) / scale,
|
||||
term->margins.top / scale + term->cell_height);
|
||||
wl_surface_attach(win->scrollback_indicator_surface, buf->wl_buf, 0, 0);
|
||||
wl_surface_damage_buffer(win->scrollback_indicator_surface, 0, 0, width, height);
|
||||
wl_surface_set_buffer_scale(win->scrollback_indicator_surface, scale);
|
||||
|
||||
struct wl_region *region = wl_compositor_create_region(wayl->compositor);
|
||||
if (region != NULL) {
|
||||
wl_region_add(region, 0, 0, width, height);
|
||||
wl_surface_set_opaque_region(win->scrollback_indicator_surface, region);
|
||||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
wl_surface_commit(win->scrollback_indicator_surface);
|
||||
}
|
||||
|
||||
static void frame_callback(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue