mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
url-mode: underline URLs using the color from colors.urls
This is implemented by allocating one of the (few!) remaining bits in the cells’ attribute struct to indicate the cell should be “URL highlighted”. render_cell() looks at this bit and draws an underline using the color from colors.urls (defaults to regular3 - i.e. yellow). A new function, url_tag_cells(), iterates the currently detected URLs and sets the new ‘url’ attribute flag on the affected cells. Note: this is done in a separate function to keep urls_collect() free from as many dependencies as possible. urls_reset() is updated to *clear* the ‘url’ flag (and thus implicitly also results in a grid refresh, _if_ there were any URLs). We now exit URL mode on *any* client application input. This needs to be so since we can’t know if the URLs we previously detected are still valid.
This commit is contained in:
parent
6726494f4c
commit
2c10a147ea
6 changed files with 61 additions and 1 deletions
1
input.c
1
input.c
|
|
@ -281,6 +281,7 @@ execute_binding(struct seat *seat, struct terminal *term,
|
|||
: URL_ACTION_LAUNCH;
|
||||
|
||||
urls_collect(term, url_action);
|
||||
urls_tag_cells(term);
|
||||
render_refresh_urls(term);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
9
render.c
9
render.c
|
|
@ -616,6 +616,15 @@ render_cell(struct terminal *term, pixman_image_t *pix,
|
|||
if (cell->attrs.strikethrough)
|
||||
draw_strikeout(term, pix, font, &fg, x, y, cell_cols);
|
||||
|
||||
if (unlikely(cell->attrs.url)) {
|
||||
pixman_color_t url_color = color_hex_to_pixman(
|
||||
term->conf->colors.use_custom.url
|
||||
? term->conf->colors.url
|
||||
: term->colors.table[3]
|
||||
);
|
||||
draw_underline(term, pix, font, &url_color, x, y, cell_cols);
|
||||
}
|
||||
|
||||
draw_cursor:
|
||||
if (has_cursor && (term->cursor_style != CURSOR_BLOCK || !term->kbd_focus))
|
||||
draw_cursor(term, cell, font, pix, &fg, &bg, x, y, cell_cols);
|
||||
|
|
|
|||
|
|
@ -228,6 +228,8 @@ fdm_ptmx(struct fdm *fdm, int fd, int events, void *data)
|
|||
cursor_blink_rearm_timer(term);
|
||||
}
|
||||
|
||||
urls_reset(term);
|
||||
|
||||
uint8_t buf[24 * 1024];
|
||||
ssize_t count = sizeof(buf);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ struct attributes {
|
|||
uint32_t have_fg:1;
|
||||
uint32_t have_bg:1;
|
||||
uint32_t selected:2;
|
||||
uint32_t reserved:3;
|
||||
uint32_t url:1;
|
||||
uint32_t reserved:2;
|
||||
uint32_t bg:24;
|
||||
};
|
||||
static_assert(sizeof(struct attributes) == 8, "bad size");
|
||||
|
|
|
|||
46
url-mode.c
46
url-mode.c
|
|
@ -7,6 +7,7 @@
|
|||
#define LOG_ENABLE_DBG 1
|
||||
#include "log.h"
|
||||
#include "grid.h"
|
||||
#include "render.h"
|
||||
#include "selection.h"
|
||||
#include "spawn.h"
|
||||
#include "terminal.h"
|
||||
|
|
@ -399,6 +400,49 @@ urls_collect(struct terminal *term, enum url_action action)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tag_cells_for_url(struct terminal *term, const struct url *url, bool value)
|
||||
{
|
||||
const struct coord *start = &url->start;
|
||||
const struct coord *end = &url->end;
|
||||
|
||||
size_t end_r = end->row & (term->grid->num_rows - 1);
|
||||
|
||||
size_t r = start->row & (term->grid->num_rows - 1);
|
||||
size_t c = start->col;
|
||||
|
||||
struct row *row = term->grid->rows[r];
|
||||
row->dirty = true;
|
||||
|
||||
while (true) {
|
||||
struct cell *cell = &row->cells[c];
|
||||
cell->attrs.url = value;
|
||||
cell->attrs.clean = 0;
|
||||
|
||||
if (r == end_r && c == end->col)
|
||||
break;
|
||||
|
||||
if (++c >= term->cols) {
|
||||
r = (r + 1) & (term->grid->num_rows - 1);
|
||||
c = 0;
|
||||
|
||||
row = term->grid->rows[r];
|
||||
row->dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
urls_tag_cells(struct terminal *term)
|
||||
{
|
||||
if (unlikely(tll_length(term->urls)) == 0)
|
||||
return;
|
||||
|
||||
tll_foreach(term->urls, it)
|
||||
tag_cells_for_url(term, &it->item, true);
|
||||
render_refresh(term);
|
||||
}
|
||||
|
||||
void
|
||||
urls_reset(struct terminal *term)
|
||||
{
|
||||
|
|
@ -416,10 +460,12 @@ urls_reset(struct terminal *term)
|
|||
}
|
||||
|
||||
tll_foreach(term->urls, it) {
|
||||
tag_cells_for_url(term, &it->item, false);
|
||||
free(it->item.url);
|
||||
free(it->item.text);
|
||||
}
|
||||
tll_free(term->urls);
|
||||
|
||||
memset(term->url_keys, 0, sizeof(term->url_keys));
|
||||
render_refresh(term);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ static inline bool urls_mode_is_active(const struct terminal *term)
|
|||
}
|
||||
|
||||
void urls_collect(struct terminal *term, enum url_action action);
|
||||
void urls_tag_cells(struct terminal *term);
|
||||
void urls_reset(struct terminal *term);
|
||||
|
||||
void urls_input(struct seat *seat, struct terminal *term, uint32_t key,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue