mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-06-05 03:02:17 -04: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)
|
if (term->conf->scrollback.indicator.style == SCROLLBACK_INDICATOR_STYLE_NONE)
|
||||||
return;
|
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 */
|
/* Find absolute row number of the scrollback start */
|
||||||
int scrollback_start = term->grid->offset + term->rows;
|
int scrollback_start = term->grid->offset + term->rows;
|
||||||
while (term->grid->rows[scrollback_start & (term->grid->num_rows - 1)] == NULL)
|
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
|
* 0% -> at the beginning of the scrollback
|
||||||
* 100% -> at the bottom, i.e. where new lines are inserted
|
* 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
|
rebased_view + term->rows == term->grid->num_rows
|
||||||
? 100
|
? 100
|
||||||
: 100 * rebased_view / term->grid->num_rows;
|
: 100 * rebased_view / term->grid->num_rows;
|
||||||
|
|
||||||
int next_row_no = term->grid->view + term->rows;
|
const int scale = term->scale;
|
||||||
next_row_no &= term->grid->num_rows - 1;
|
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? */
|
unsigned long cookie = shm_cookie_scrollback_indicator(term);
|
||||||
bool at_bottom = rebased_view + term->rows == term->grid->num_rows ||
|
struct buffer *buf = shm_get_buffer(
|
||||||
term->grid->rows[next_row_no] == NULL;
|
term->wl->shm, width, height, cookie, false, 1);
|
||||||
|
|
||||||
LOG_DBG("scrollback position: %d/%d (%d%%), at-bottom: %d",
|
pixman_color_t bg = color_hex_to_pixman(term->colors.table[4]);
|
||||||
rebased_view, term->grid->num_rows, percentage, at_bottom);
|
pixman_image_fill_rectangles(
|
||||||
|
PIXMAN_OP_SRC, buf->pix[0], &bg, 1,
|
||||||
|
&(pixman_rectangle16_t){0, 0, width, height});
|
||||||
|
|
||||||
if (!at_bottom) {
|
struct fcft_font *font = term->fonts[0];
|
||||||
/* TODO: insert rendering code here */
|
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(
|
static void frame_callback(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue