From b1950ac222f525f6763908ad57ff6d6399e061a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 24 Jul 2020 17:51:40 +0200 Subject: [PATCH 01/24] render: add code that calculates current position in scrollback --- render.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/render.c b/render.c index 80611d22..da6c2610 100644 --- a/render.c +++ b/render.c @@ -1287,6 +1287,50 @@ render_csd(struct terminal *term) render_csd_title(term); } +static void +render_scrollback_position(struct terminal *term) +{ +#if 0 + if (!term->conf->show_scrollback_position) + return; +#endif + + /* 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) + scrollback_start++; + + /* Rebase viewport against scrollback start (so that 0 is at + * the beginning of the scrollback) */ + int rebased_view = term->grid->view - scrollback_start + term->grid->num_rows; + rebased_view &= term->grid->num_rows - 1; + + /* + * How far down in the scrollback we are. + * + * 0% -> at the beginning of the scrollback + * 100% -> at the bottom, i.e. where new lines are inserted + */ + int percentage __attribute__((unused)) = + 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; + + /* 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; + + LOG_DBG("scrollback position: %d/%d (%d%%), at-bottom: %d", + rebased_view, term->grid->num_rows, percentage, at_bottom); + + if (!at_bottom) { + /* TODO: insert rendering code here */ + } +} + static void frame_callback( void *data, struct wl_callback *wl_callback, uint32_t callback_data); @@ -1498,6 +1542,8 @@ grid_render(struct terminal *term) term->window->surface, 0, 0, term->width, term->height); } + render_scrollback_position(term); + assert(term->grid->offset >= 0 && term->grid->offset < term->grid->num_rows); assert(term->grid->view >= 0 && term->grid->view < term->grid->num_rows); From 2c6f7adc17832c77b2353338b0c76c8a19f4112b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 24 Jul 2020 18:20:26 +0200 Subject: [PATCH 02/24] config: add 'show-scrollback-position' option to footrc --- config.c | 4 ++++ config.h | 1 + doc/foot.5.scd | 4 ++++ render.c | 2 -- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/config.c b/config.c index 283a72ea..9666da61 100644 --- a/config.c +++ b/config.c @@ -291,6 +291,9 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->scrollback_lines = lines; } + else if (strcmp(key, "show-scrollback-position") == 0) + conf->show_scrollback_position = str_to_bool(value); + else { LOG_ERR("%s:%u: invalid key: %s", path, lineno, key); return false; @@ -918,6 +921,7 @@ config_load(struct config *conf, const char *conf_path) .startup_mode = STARTUP_WINDOWED, .fonts = tll_init(), .scrollback_lines = 1000, + .show_scrollback_position = true, .colors = { .fg = default_foreground, diff --git a/config.h b/config.h index 2b43b806..c21e1160 100644 --- a/config.h +++ b/config.h @@ -40,6 +40,7 @@ struct config { tll(struct config_font) fonts; int scrollback_lines; + bool show_scrollback_position; struct { uint32_t fg; diff --git a/doc/foot.5.scd b/doc/foot.5.scd index 92ac7c01..fd5a5d42 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -68,6 +68,10 @@ in this order: *scrollback* Number of scrollback lines. Default: _1000_. +*show-scrollback-position* + Boolean. Enables a position indicator when the viewport is not at + the bottom of the scrollback history. Default: _yes_. + *workers* Number of threads to use for rendering. Set to 0 to disable multithreading. Default: the number of available logical CPUs diff --git a/render.c b/render.c index da6c2610..6611fbb9 100644 --- a/render.c +++ b/render.c @@ -1290,10 +1290,8 @@ render_csd(struct terminal *term) static void render_scrollback_position(struct terminal *term) { -#if 0 if (!term->conf->show_scrollback_position) return; -#endif /* Find absolute row number of the scrollback start */ int scrollback_start = term->grid->offset + term->rows; From e94506362028b57fa5d2c77f73a152a47cc06768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 24 Jul 2020 18:26:44 +0200 Subject: [PATCH 03/24] config: rename show-scrollback-position to scrollback-indicator --- config.c | 6 +++--- config.h | 2 +- doc/foot.5.scd | 2 +- render.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config.c b/config.c index 9666da61..e7ba74b2 100644 --- a/config.c +++ b/config.c @@ -291,8 +291,8 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->scrollback_lines = lines; } - else if (strcmp(key, "show-scrollback-position") == 0) - conf->show_scrollback_position = str_to_bool(value); + else if (strcmp(key, "scrollback-indicator") == 0) + conf->scrollback_indicator = str_to_bool(value); else { LOG_ERR("%s:%u: invalid key: %s", path, lineno, key); @@ -921,7 +921,7 @@ config_load(struct config *conf, const char *conf_path) .startup_mode = STARTUP_WINDOWED, .fonts = tll_init(), .scrollback_lines = 1000, - .show_scrollback_position = true, + .scrollback_indicator = true, .colors = { .fg = default_foreground, diff --git a/config.h b/config.h index c21e1160..f0f077be 100644 --- a/config.h +++ b/config.h @@ -40,7 +40,7 @@ struct config { tll(struct config_font) fonts; int scrollback_lines; - bool show_scrollback_position; + bool scrollback_indicator; struct { uint32_t fg; diff --git a/doc/foot.5.scd b/doc/foot.5.scd index fd5a5d42..1f71a8d3 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -68,7 +68,7 @@ in this order: *scrollback* Number of scrollback lines. Default: _1000_. -*show-scrollback-position* +*scrollback-indicator* Boolean. Enables a position indicator when the viewport is not at the bottom of the scrollback history. Default: _yes_. diff --git a/render.c b/render.c index 6611fbb9..d5cdb8dc 100644 --- a/render.c +++ b/render.c @@ -1290,7 +1290,7 @@ render_csd(struct terminal *term) static void render_scrollback_position(struct terminal *term) { - if (!term->conf->show_scrollback_position) + if (!term->conf->scrollback_indicator) return; /* Find absolute row number of the scrollback start */ From 5b868fd0c94af61e62a28a80a4bd337f9cbb25b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 24 Jul 2020 18:34:19 +0200 Subject: [PATCH 04/24] config: add 'scrollback-indicator-format' option The value of this option must be either 'percent', or 'line', and determines _how_ we render the scrollback indicator. --- config.c | 14 ++++++++++++++ config.h | 1 + doc/foot.5.scd | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/config.c b/config.c index e7ba74b2..332fd11a 100644 --- a/config.c +++ b/config.c @@ -294,6 +294,19 @@ parse_section_main(const char *key, const char *value, struct config *conf, else if (strcmp(key, "scrollback-indicator") == 0) conf->scrollback_indicator = str_to_bool(value); + else if (strcmp(key, "scrollback-indicator-format") == 0) { + if (strcmp(value, "percent") == 0) + conf->scrollback_indicator_format = SCROLLBACK_INDICATOR_PERCENT; + else if (strcmp(value, "line") == 0) + conf->scrollback_indicator_format = SCROLLBACK_INDICATOR_LINENO; + else { + LOG_ERR("%s:%d: 'scrollback-indicator-format must be one " + "of 'percent' or 'line', not %s", + path, lineno, value); + return false; + } + } + else { LOG_ERR("%s:%u: invalid key: %s", path, lineno, key); return false; @@ -922,6 +935,7 @@ config_load(struct config *conf, const char *conf_path) .fonts = tll_init(), .scrollback_lines = 1000, .scrollback_indicator = true, + .scrollback_indicator_format = SCROLLBACK_INDICATOR_PERCENT, .colors = { .fg = default_foreground, diff --git a/config.h b/config.h index f0f077be..109eecb8 100644 --- a/config.h +++ b/config.h @@ -41,6 +41,7 @@ struct config { int scrollback_lines; bool scrollback_indicator; + enum {SCROLLBACK_INDICATOR_PERCENT, SCROLLBACK_INDICATOR_LINENO} scrollback_indicator_format; struct { uint32_t fg; diff --git a/doc/foot.5.scd b/doc/foot.5.scd index 1f71a8d3..485886fa 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -72,6 +72,11 @@ in this order: Boolean. Enables a position indicator when the viewport is not at the bottom of the scrollback history. Default: _yes_. +*scrollback-indicator-format* + Which format to use when displaying the scrollback position + indicator. Either _percent_ or _line_. This option is ignored if + *scrollback-indicator=no*. Default: _percent_. + *workers* Number of threads to use for rendering. Set to 0 to disable multithreading. Default: the number of available logical CPUs From c4679e474e0546ee8dad6e122c226ece85bdb134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 25 Jul 2020 14:31:45 +0200 Subject: [PATCH 05/24] config: rename scrollback-indicator to scrollback-indicator-style And turn it from a boolean to an enum. It can be set to: * `none` - disables the indicator * `static` - always rendered near the top of the window * `moving` - position reflects the scrollback position --- config.c | 37 ++++++++++++++++++++++++++----------- config.h | 19 ++++++++++++++++--- doc/foot.5.scd | 12 ++++++++---- footrc | 2 ++ render.c | 2 +- terminal.c | 2 +- 6 files changed, 54 insertions(+), 20 deletions(-) diff --git a/config.c b/config.c index 332fd11a..7c4c9d9f 100644 --- a/config.c +++ b/config.c @@ -288,21 +288,33 @@ parse_section_main(const char *key, const char *value, struct config *conf, LOG_ERR("%s:%d: expected an integer: %s", path, lineno, value); return false; } - conf->scrollback_lines = lines; + conf->scrollback.lines = lines; } - else if (strcmp(key, "scrollback-indicator") == 0) - conf->scrollback_indicator = str_to_bool(value); + else if (strcmp(key, "scrollback-indicator") == 0) { + if (strcmp(value, "none") == 0) + conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_NONE; + else if (strcmp(value, "static") == 0) + conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_STATIC; + else if (strcmp(value, "moving") == 0) + conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_MOVING; + else { + LOG_ERR("%s:%d: scrollback-indicator-style must be one of " + "'none', 'static' or 'moving'", + path, lineno); + return false; + } + } else if (strcmp(key, "scrollback-indicator-format") == 0) { if (strcmp(value, "percent") == 0) - conf->scrollback_indicator_format = SCROLLBACK_INDICATOR_PERCENT; + conf->scrollback.indicator.format = SCROLLBACK_INDICATOR_FORMAT_PERCENT; else if (strcmp(value, "line") == 0) - conf->scrollback_indicator_format = SCROLLBACK_INDICATOR_LINENO; + conf->scrollback.indicator.format = SCROLLBACK_INDICATOR_FORMAT_LINENO; else { LOG_ERR("%s:%d: 'scrollback-indicator-format must be one " - "of 'percent' or 'line', not %s", - path, lineno, value); + "of 'percent' or 'line'", + path, lineno); return false; } } @@ -933,10 +945,13 @@ config_load(struct config *conf, const char *conf_path) .pad_y = 2, .startup_mode = STARTUP_WINDOWED, .fonts = tll_init(), - .scrollback_lines = 1000, - .scrollback_indicator = true, - .scrollback_indicator_format = SCROLLBACK_INDICATOR_PERCENT, - + .scrollback = { + .lines = 1000, + .indicator = { + .style = SCROLLBACK_INDICATOR_STYLE_MOVING, + .format = SCROLLBACK_INDICATOR_FORMAT_PERCENT, + }, + }, .colors = { .fg = default_foreground, .bg = default_background, diff --git a/config.h b/config.h index 109eecb8..9ff83b77 100644 --- a/config.h +++ b/config.h @@ -39,9 +39,22 @@ struct config { tll(struct config_font) fonts; - int scrollback_lines; - bool scrollback_indicator; - enum {SCROLLBACK_INDICATOR_PERCENT, SCROLLBACK_INDICATOR_LINENO} scrollback_indicator_format; + struct { + int lines; + + struct { + enum { + SCROLLBACK_INDICATOR_STYLE_NONE, + SCROLLBACK_INDICATOR_STYLE_STATIC, + SCROLLBACK_INDICATOR_STYLE_MOVING + } style; + + enum { + SCROLLBACK_INDICATOR_FORMAT_PERCENT, + SCROLLBACK_INDICATOR_FORMAT_LINENO + } format; + } indicator; + } scrollback; struct { uint32_t fg; diff --git a/doc/foot.5.scd b/doc/foot.5.scd index 485886fa..9813741c 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -68,14 +68,18 @@ in this order: *scrollback* Number of scrollback lines. Default: _1000_. -*scrollback-indicator* - Boolean. Enables a position indicator when the viewport is not at - the bottom of the scrollback history. Default: _yes_. +*scrollback-indicator-style* + Configures the style of the scrollback position indicator. One of + *none*, *static* or *moving*. *none* disables the indicator + completely. *static* always renders the indicator near the top at + the window, and *moving* renders the indicator at the position + corresponding to the current scrollback position. Default: + _moving_. *scrollback-indicator-format* Which format to use when displaying the scrollback position indicator. Either _percent_ or _line_. This option is ignored if - *scrollback-indicator=no*. Default: _percent_. + *scrollback-indicator-style=none*. Default: _percent_. *workers* Number of threads to use for rendering. Set to 0 to disable diff --git a/footrc b/footrc index 624c688b..911ebb28 100644 --- a/footrc +++ b/footrc @@ -2,6 +2,8 @@ # font=monospace # scrollback=1000 +# scrollback-indicator-style=moving +# scrollback-indicator-format=percent # geometry=700x500 # pad=2x2 # initial-window-mode=windowed diff --git a/render.c b/render.c index d5cdb8dc..bab87cf4 100644 --- a/render.c +++ b/render.c @@ -1290,7 +1290,7 @@ render_csd(struct terminal *term) static void render_scrollback_position(struct terminal *term) { - if (!term->conf->scrollback_indicator) + if (term->conf->scrollback.indicator.style == SCROLLBACK_INDICATOR_STYLE_NONE) return; /* Find absolute row number of the scrollback start */ diff --git a/terminal.c b/terminal.c index 86672f06..1e355fe3 100644 --- a/terminal.c +++ b/terminal.c @@ -909,7 +909,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, .tab_stops = tll_init(), .wl = wayl, .render = { - .scrollback_lines = conf->scrollback_lines, + .scrollback_lines = conf->scrollback.lines, .app_sync_updates.timer_fd = app_sync_updates_fd, .workers = { .count = conf->render_worker_count, From e3be2cbd6f62baaa81dcae62b24731668ac764b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 25 Jul 2020 14:38:36 +0200 Subject: [PATCH 06/24] config: rename scrollback-indicator-style value 'moving' to 'relative' --- config.c | 4 ++-- config.h | 2 +- doc/foot.5.scd | 6 +++--- footrc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config.c b/config.c index 7c4c9d9f..59b824b8 100644 --- a/config.c +++ b/config.c @@ -297,7 +297,7 @@ parse_section_main(const char *key, const char *value, struct config *conf, else if (strcmp(value, "static") == 0) conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_STATIC; else if (strcmp(value, "moving") == 0) - conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_MOVING; + conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_RELATIVE; else { LOG_ERR("%s:%d: scrollback-indicator-style must be one of " "'none', 'static' or 'moving'", @@ -948,7 +948,7 @@ config_load(struct config *conf, const char *conf_path) .scrollback = { .lines = 1000, .indicator = { - .style = SCROLLBACK_INDICATOR_STYLE_MOVING, + .style = SCROLLBACK_INDICATOR_STYLE_RELATIVE, .format = SCROLLBACK_INDICATOR_FORMAT_PERCENT, }, }, diff --git a/config.h b/config.h index 9ff83b77..030bfc88 100644 --- a/config.h +++ b/config.h @@ -46,7 +46,7 @@ struct config { enum { SCROLLBACK_INDICATOR_STYLE_NONE, SCROLLBACK_INDICATOR_STYLE_STATIC, - SCROLLBACK_INDICATOR_STYLE_MOVING + SCROLLBACK_INDICATOR_STYLE_RELATIVE } style; enum { diff --git a/doc/foot.5.scd b/doc/foot.5.scd index 9813741c..496042b3 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -70,11 +70,11 @@ in this order: *scrollback-indicator-style* Configures the style of the scrollback position indicator. One of - *none*, *static* or *moving*. *none* disables the indicator + *none*, *static* or *relative*. *none* disables the indicator completely. *static* always renders the indicator near the top at - the window, and *moving* renders the indicator at the position + the window, and *relative* renders the indicator at the position corresponding to the current scrollback position. Default: - _moving_. + _relative_. *scrollback-indicator-format* Which format to use when displaying the scrollback position diff --git a/footrc b/footrc index 911ebb28..c2ee52e7 100644 --- a/footrc +++ b/footrc @@ -2,7 +2,7 @@ # font=monospace # scrollback=1000 -# scrollback-indicator-style=moving +# scrollback-indicator-style=relative # scrollback-indicator-format=percent # geometry=700x500 # pad=2x2 From 9edd71a741a3aeff89fe04f51582214d69bbde5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 25 Jul 2020 14:40:46 +0200 Subject: [PATCH 07/24] config: rename scrollback-indicator-style value 'static' to 'fixed' --- config.c | 6 +++--- config.h | 2 +- doc/foot.5.scd | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config.c b/config.c index 59b824b8..b6af1d26 100644 --- a/config.c +++ b/config.c @@ -294,9 +294,9 @@ parse_section_main(const char *key, const char *value, struct config *conf, else if (strcmp(key, "scrollback-indicator") == 0) { if (strcmp(value, "none") == 0) conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_NONE; - else if (strcmp(value, "static") == 0) - conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_STATIC; - else if (strcmp(value, "moving") == 0) + else if (strcmp(value, "fixed") == 0) + conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_FIXED; + else if (strcmp(value, "relative") == 0) conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_RELATIVE; else { LOG_ERR("%s:%d: scrollback-indicator-style must be one of " diff --git a/config.h b/config.h index 030bfc88..57701606 100644 --- a/config.h +++ b/config.h @@ -45,7 +45,7 @@ struct config { struct { enum { SCROLLBACK_INDICATOR_STYLE_NONE, - SCROLLBACK_INDICATOR_STYLE_STATIC, + SCROLLBACK_INDICATOR_STYLE_FIXED, SCROLLBACK_INDICATOR_STYLE_RELATIVE } style; diff --git a/doc/foot.5.scd b/doc/foot.5.scd index 496042b3..573eb313 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -70,8 +70,8 @@ in this order: *scrollback-indicator-style* Configures the style of the scrollback position indicator. One of - *none*, *static* or *relative*. *none* disables the indicator - completely. *static* always renders the indicator near the top at + *none*, *fixed* or *relative*. *none* disables the indicator + completely. *fixed* always renders the indicator near the top at the window, and *relative* renders the indicator at the position corresponding to the current scrollback position. Default: _relative_. From be7d0a5615fafc81a0f88c45bc2e670339960e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 09:43:58 +0200 Subject: [PATCH 08/24] config: fix key check for 'scrollback-indicator-style' --- config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.c b/config.c index b6af1d26..18c88228 100644 --- a/config.c +++ b/config.c @@ -291,7 +291,7 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->scrollback.lines = lines; } - else if (strcmp(key, "scrollback-indicator") == 0) { + else if (strcmp(key, "scrollback-indicator-style") == 0) { if (strcmp(value, "none") == 0) conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_NONE; else if (strcmp(value, "fixed") == 0) From d180de00a9dab2ea2a8dbd9b48ab0e98f5595b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 09:44:16 +0200 Subject: [PATCH 09/24] config: fix error message for 'scrollback-indicator-style' --- config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.c b/config.c index 18c88228..f87eb67f 100644 --- a/config.c +++ b/config.c @@ -300,7 +300,7 @@ parse_section_main(const char *key, const char *value, struct config *conf, conf->scrollback.indicator.style = SCROLLBACK_INDICATOR_STYLE_RELATIVE; else { LOG_ERR("%s:%d: scrollback-indicator-style must be one of " - "'none', 'static' or 'moving'", + "'none', 'fixed' or 'moving'", path, lineno); return false; } From a39c490d9b1d82700dcd48cc9ac28d58051197f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 10:00:21 +0200 Subject: [PATCH 10/24] shm: add shm_cookie_scrollback_indicator() --- shm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shm.h b/shm.h index 4c8e9506..0bfb3839 100644 --- a/shm.h +++ b/shm.h @@ -49,4 +49,5 @@ void shm_purge(struct wl_shm *shm, unsigned long cookie); struct terminal; static inline unsigned long shm_cookie_grid(const struct terminal *term) { return (unsigned long)((uintptr_t)term + 0); } static inline unsigned long shm_cookie_search(const struct terminal *term) { return (unsigned long)((uintptr_t)term + 1); } -static inline unsigned long shm_cookie_csd(const struct terminal *term, int n) { return (unsigned long)((uintptr_t)term + 2 + (n)); } +static inline unsigned long shm_cookie_scrollback_indicator(const struct terminal *term) { return (unsigned long)(uintptr_t)term + 2; } +static inline unsigned long shm_cookie_csd(const struct terminal *term, int n) { return (unsigned long)((uintptr_t)term + 3 + (n)); } From 2815c1c0764cbc79625aa9c6623601d2188e0500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 10:00:50 +0200 Subject: [PATCH 11/24] wayland: add scrollback indicator surface + sub-surface to wl_window --- wayland.c | 9 +++++++++ wayland.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/wayland.c b/wayland.c index 70d5e0f1..66f2c3b3 100644 --- a/wayland.c +++ b/wayland.c @@ -1203,6 +1203,11 @@ wayl_win_destroy(struct wl_window *win) * nor mouse focus). */ + if (win->scrollback_indicator_surface != NULL) { + wl_surface_attach(win->scrollback_indicator_surface, NULL, 0, 0); + wl_surface_commit(win->scrollback_indicator_surface); + } + /* Scrollback search */ if (win->search_surface != NULL) { wl_surface_attach(win->search_surface, NULL, 0, 0); @@ -1227,6 +1232,10 @@ wayl_win_destroy(struct wl_window *win) tll_free(win->on_outputs); csd_destroy(win); + if (win->scrollback_indicator_sub_surface != NULL) + wl_subsurface_destroy(win->scrollback_indicator_sub_surface); + if (win->scrollback_indicator_surface != NULL) + wl_surface_destroy(win->scrollback_indicator_surface); if (win->search_sub_surface != NULL) wl_subsurface_destroy(win->search_sub_surface); if (win->search_surface != NULL) diff --git a/wayland.h b/wayland.h index dbf63c1b..e67d514a 100644 --- a/wayland.h +++ b/wayland.h @@ -273,6 +273,9 @@ struct wl_window { struct wl_surface *search_surface; struct wl_subsurface *search_sub_surface; + struct wl_surface *scrollback_indicator_surface; + struct wl_subsurface *scrollback_indicator_sub_surface; + struct wl_callback *frame_callback; tll(const struct monitor *) on_outputs; /* Outputs we're mapped on */ From c2362c10f133c707101302249763e5c66d5c8653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 10:01:05 +0200 Subject: [PATCH 12/24] render: search: fix subpixel argument to fcft_glyph_rasterize() --- render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render.c b/render.c index bab87cf4..ffab85ab 100644 --- a/render.c +++ b/render.c @@ -1660,7 +1660,7 @@ render_search_box(struct terminal *term) draw_bar(term, buf->pix[0], font, &fg, x, y); const struct fcft_glyph *glyph = fcft_glyph_rasterize( - font, term->search.buf[i], true); + font, term->search.buf[i], term->font_subpixel); if (glyph == NULL) continue; From 67758a7cb7207582671d223730123a63c0231642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 10:01:26 +0200 Subject: [PATCH 13/24] 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. --- render.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 100 insertions(+), 10 deletions(-) diff --git a/render.c b/render.c index ffab85ab..a64654f2 100644 --- a/render.c +++ b/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( From 2e519ed5b6f94940f7c70b7eba42b68ccf5c18a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 10:18:05 +0200 Subject: [PATCH 14/24] render: scrollback indicator: implement 'relative' and 'line' variants We now implement all combinations of 'scrollback-indicator-style' and 'scrollback-indicator-format'. --- render.c | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/render.c b/render.c index a64654f2..1d21a615 100644 --- a/render.c +++ b/render.c @@ -1303,8 +1303,6 @@ render_scrollback_position(struct terminal *term) win->scrollback_indicator_surface = NULL; win->scrollback_indicator_sub_surface = NULL; - - LOG_INFO("destroyed indicator surfaces"); } return; } @@ -1334,7 +1332,6 @@ render_scrollback_position(struct terminal *term) } wl_subsurface_set_sync(win->scrollback_indicator_sub_surface); - LOG_INFO("instantiated indicator surfaces"); } assert(win->scrollback_indicator_surface != NULL); @@ -1356,14 +1353,30 @@ 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 = + unsigned percent = rebased_view + term->rows == term->grid->num_rows ? 100 : 100 * rebased_view / term->grid->num_rows; + wchar_t text[64]; + int cell_count; + + /* *What* to render */ + switch (term->conf->scrollback.indicator.format) { + case SCROLLBACK_INDICATOR_FORMAT_PERCENT: + swprintf(text, sizeof(text) / sizeof(text[0]), L"%u%%", percent); + cell_count = 3; + break; + + case SCROLLBACK_INDICATOR_FORMAT_LINENO: + swprintf(text, sizeof(text) / sizeof(text[0]), L"%d", rebased_view + 1); + cell_count = 1 + (int)log10(term->grid->num_rows); + break; + } + 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 width = 2 * margin + cell_count * term->cell_width; const int height = 2 * margin + term->cell_height; unsigned long cookie = shm_cookie_scrollback_indicator(term); @@ -1378,9 +1391,7 @@ render_scrollback_position(struct terminal *term) 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); - + /* Sub-surface relative coordinates */ unsigned x = width - margin - wcslen(text) * term->cell_width; const unsigned y = margin; @@ -1401,10 +1412,31 @@ render_scrollback_position(struct terminal *term) x += term->cell_width; } + /* *Where* to render - parent relative coordinates */ + int surf_top = 0; + switch (term->conf->scrollback.indicator.style) { + case SCROLLBACK_INDICATOR_STYLE_NONE: + assert(false); + return; + + case SCROLLBACK_INDICATOR_STYLE_FIXED: + surf_top = margin + term->cell_height; + break; + + case SCROLLBACK_INDICATOR_STYLE_RELATIVE: { + int lines = term->rows - 2; /* Avoid using first and last row */ + assert(lines > 0); + + int on_line = 1 + percent * lines / 100; + surf_top = margin + on_line * term->cell_height; + break; + } + } + wl_subsurface_set_position( win->scrollback_indicator_sub_surface, (term->width - term->margins.right - width) / scale, - term->margins.top / scale + term->cell_height); + surf_top / scale); 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); From 9a9e876d6e41da21eb3fdfc385135c8a94ce1183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 10:42:38 +0200 Subject: [PATCH 15/24] render: scrollback indicator: use black on bright blue --- render.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/render.c b/render.c index 1d21a615..55213408 100644 --- a/render.c +++ b/render.c @@ -1383,13 +1383,13 @@ render_scrollback_position(struct terminal *term) struct buffer *buf = shm_get_buffer( term->wl->shm, width, height, cookie, false, 1); - pixman_color_t bg = color_hex_to_pixman(term->colors.table[4]); + pixman_color_t bg = color_hex_to_pixman(term->colors.table[8 + 4]); pixman_image_fill_rectangles( PIXMAN_OP_SRC, buf->pix[0], &bg, 1, &(pixman_rectangle16_t){0, 0, width, height}); struct fcft_font *font = term->fonts[0]; - pixman_color_t fg = color_hex_to_pixman(term->colors.table[7]); + pixman_color_t fg = color_hex_to_pixman(term->colors.table[0]); /* Sub-surface relative coordinates */ unsigned x = width - margin - wcslen(text) * term->cell_width; From 50d116dcb9183047899d93095117632c669d5f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 11:39:02 +0200 Subject: [PATCH 16/24] config: scrollback-indicator-format: percent -> percentage --- config.c | 14 ++++++++------ config.h | 2 +- doc/foot.5.scd | 4 ++-- footrc | 2 +- render.c | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/config.c b/config.c index f87eb67f..2b989d62 100644 --- a/config.c +++ b/config.c @@ -307,11 +307,13 @@ parse_section_main(const char *key, const char *value, struct config *conf, } else if (strcmp(key, "scrollback-indicator-format") == 0) { - if (strcmp(value, "percent") == 0) - conf->scrollback.indicator.format = SCROLLBACK_INDICATOR_FORMAT_PERCENT; - else if (strcmp(value, "line") == 0) - conf->scrollback.indicator.format = SCROLLBACK_INDICATOR_FORMAT_LINENO; - else { + if (strcmp(value, "percent") == 0) { + conf->scrollback.indicator.format + = SCROLLBACK_INDICATOR_FORMAT_PERCENTAGE; + } else if (strcmp(value, "line") == 0) { + conf->scrollback.indicator.format + = SCROLLBACK_INDICATOR_FORMAT_LINENO; + } else { LOG_ERR("%s:%d: 'scrollback-indicator-format must be one " "of 'percent' or 'line'", path, lineno); @@ -949,7 +951,7 @@ config_load(struct config *conf, const char *conf_path) .lines = 1000, .indicator = { .style = SCROLLBACK_INDICATOR_STYLE_RELATIVE, - .format = SCROLLBACK_INDICATOR_FORMAT_PERCENT, + .format = SCROLLBACK_INDICATOR_FORMAT_PERCENTAGE, }, }, .colors = { diff --git a/config.h b/config.h index 57701606..456019b5 100644 --- a/config.h +++ b/config.h @@ -50,7 +50,7 @@ struct config { } style; enum { - SCROLLBACK_INDICATOR_FORMAT_PERCENT, + SCROLLBACK_INDICATOR_FORMAT_PERCENTAGE, SCROLLBACK_INDICATOR_FORMAT_LINENO } format; } indicator; diff --git a/doc/foot.5.scd b/doc/foot.5.scd index 573eb313..c348391b 100644 --- a/doc/foot.5.scd +++ b/doc/foot.5.scd @@ -78,8 +78,8 @@ in this order: *scrollback-indicator-format* Which format to use when displaying the scrollback position - indicator. Either _percent_ or _line_. This option is ignored if - *scrollback-indicator-style=none*. Default: _percent_. + indicator. Either _percentage_ or _line_. This option is ignored + if *scrollback-indicator-style=none*. Default: _percentage_. *workers* Number of threads to use for rendering. Set to 0 to disable diff --git a/footrc b/footrc index c2ee52e7..3ab2e6c1 100644 --- a/footrc +++ b/footrc @@ -3,7 +3,7 @@ # font=monospace # scrollback=1000 # scrollback-indicator-style=relative -# scrollback-indicator-format=percent +# scrollback-indicator-format=percentage # geometry=700x500 # pad=2x2 # initial-window-mode=windowed diff --git a/render.c b/render.c index 55213408..6e8a56d4 100644 --- a/render.c +++ b/render.c @@ -1363,7 +1363,7 @@ render_scrollback_position(struct terminal *term) /* *What* to render */ switch (term->conf->scrollback.indicator.format) { - case SCROLLBACK_INDICATOR_FORMAT_PERCENT: + case SCROLLBACK_INDICATOR_FORMAT_PERCENTAGE: swprintf(text, sizeof(text) / sizeof(text[0]), L"%u%%", percent); cell_count = 3; break; From c1f35731e0a98344b605d5b07caa77c2f00e3791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 12:31:13 +0200 Subject: [PATCH 17/24] input: margins are not selectable * Fix col/row calculation in pointer-enter event; we did not take the margins into account. * seat->mouse.col,row are now set to -1 if the cursor is inside the margins. That is, col/row are only ever valid when the mouse is actually over the grid, and not in the margins. * Use regular 'left-ptr' mouse cursor when mouse is inside the margins, to not make the user think he/she can start a selection. Besides making things clearer, this also fixes a crash that occurred if you started a selection in e.g. the right margin. --- CHANGELOG.md | 6 ++++++ input.c | 40 ++++++++++++++++++++++++++-------------- selection.c | 7 ++++--- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea392a60..22da9175 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,11 +32,17 @@ outside it. * Scrollback search to focus match, that requires a viewport change, roughly in the center of the screen. +* Mouse cursor is now always a `left_ptr` when inside the margins, to + indicate it is not possible to start a selection. ### Deprecated ### Removed ### Fixed + +* Crash when starting a selection inside the margins. + + ### Security diff --git a/input.c b/input.c index 442cd322..4dd8cf39 100644 --- a/input.c +++ b/input.c @@ -1023,11 +1023,16 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, int y = wl_fixed_to_int(surface_y) * term->scale; switch ((term->active_surface = term_surface_kind(term, surface))) { - case TERM_SURF_GRID: - seat->mouse.col = x / term->cell_width; - seat->mouse.row = y / term->cell_height; + case TERM_SURF_GRID: { + int col = (x - term->margins.left) / term->cell_width; + int row = (y - term->margins.top) / term->cell_height; + + seat->mouse.col = col >= 0 && col < term->cols ? col : -1; + seat->mouse.row = row >= 0 && row < term->rows ? row : -1; + term_xcursor_update(term); break; + } case TERM_SURF_SEARCH: case TERM_SURF_TITLE: @@ -1165,26 +1170,31 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, break; case TERM_SURF_GRID: { + term_xcursor_update(term); + int col = (x - term->margins.left) / term->cell_width; int row = (y - term->margins.top) / term->cell_height; - if (col < 0 || row < 0 || col >= term->cols || row >= term->rows) - return; + int old_col = seat->mouse.col; + int old_row = seat->mouse.row; + + seat->mouse.col = col >= 0 && col < term->cols ? col : -1; + seat->mouse.row = row >= 0 && row < term->rows ? row : -1; + + if (seat->mouse.col < 0 || seat->mouse.row < 0) + break; bool update_selection = seat->mouse.button == BTN_LEFT; bool update_selection_early = term->selection.end.row == -1; if (update_selection && update_selection_early) - selection_update(term, col, row); + selection_update(term, seat->mouse.col, seat->mouse.row); - if (col == seat->mouse.col && row == seat->mouse.row) + if (old_col == seat->mouse.col && old_row == seat->mouse.row) break; - seat->mouse.col = col; - seat->mouse.row = row; - if (update_selection && !update_selection_early) - selection_update(term, col, row); + selection_update(term, seat->mouse.col, seat->mouse.row); if (!term_mouse_grabbed(term, seat)) { term_mouse_motion( @@ -1360,9 +1370,11 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, if (selection_enabled(term, seat)) { switch (seat->mouse.count) { case 1: - selection_start( - term, seat->mouse.col, seat->mouse.row, - seat->kbd.ctrl ? SELECTION_BLOCK : SELECTION_NORMAL); + if (seat->mouse.col >= 0 && seat->mouse.row >= 0) { + selection_start( + term, seat->mouse.col, seat->mouse.row, + seat->kbd.ctrl ? SELECTION_BLOCK : SELECTION_NORMAL); + } break; case 2: diff --git a/selection.c b/selection.c index d5add464..3b8c1969 100644 --- a/selection.c +++ b/selection.c @@ -25,9 +25,10 @@ bool selection_enabled(const struct terminal *term, struct seat *seat) { return - term->mouse_tracking == MOUSE_NONE || - term_mouse_grabbed(term, seat) || - term->is_searching; + seat->mouse.col >= 0 && seat->mouse.row >= 0 && + (term->mouse_tracking == MOUSE_NONE || + term_mouse_grabbed(term, seat) || + term->is_searching); } bool From 76350c568e6a64dd0f8cea1138348ea97cf93aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 12:37:12 +0200 Subject: [PATCH 18/24] term: term_surface_kind(): recognize the scrollback indicator sub-surface --- terminal.c | 2 ++ terminal.h | 1 + 2 files changed, 3 insertions(+) diff --git a/terminal.c b/terminal.c index 1e355fe3..f1b528fb 100644 --- a/terminal.c +++ b/terminal.c @@ -2407,6 +2407,8 @@ term_surface_kind(const struct terminal *term, const struct wl_surface *surface) return TERM_SURF_GRID; else if (surface == term->window->search_surface) return TERM_SURF_SEARCH; + else if (surface == term->window->scrollback_indicator_surface) + return TERM_SURF_SCROLLBACK_INDICATOR; else if (surface == term->window->csd.surface[CSD_SURF_TITLE]) return TERM_SURF_TITLE; else if (surface == term->window->csd.surface[CSD_SURF_LEFT]) diff --git a/terminal.h b/terminal.h index 85f89abf..eae636cc 100644 --- a/terminal.h +++ b/terminal.h @@ -195,6 +195,7 @@ enum term_surface { TERM_SURF_NONE, TERM_SURF_GRID, TERM_SURF_SEARCH, + TERM_SURF_SCROLLBACK_INDICATOR, TERM_SURF_TITLE, TERM_SURF_BORDER_LEFT, TERM_SURF_BORDER_RIGHT, From 1a65b161dc03bb1ab42913866a111be16abc7e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 12:37:35 +0200 Subject: [PATCH 19/24] input: handle the scrollback indicator surface in pointer events --- input.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/input.c b/input.c index 4dd8cf39..fbf6b517 100644 --- a/input.c +++ b/input.c @@ -1035,6 +1035,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, } case TERM_SURF_SEARCH: + case TERM_SURF_SCROLLBACK_INDICATOR: case TERM_SURF_TITLE: render_xcursor_set(seat, term, XCURSOR_LEFT_PTR); break; @@ -1112,6 +1113,7 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, case TERM_SURF_NONE: case TERM_SURF_GRID: case TERM_SURF_SEARCH: + case TERM_SURF_SCROLLBACK_INDICATOR: case TERM_SURF_TITLE: case TERM_SURF_BORDER_LEFT: case TERM_SURF_BORDER_RIGHT: @@ -1146,6 +1148,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, switch (term->active_surface) { case TERM_SURF_NONE: case TERM_SURF_SEARCH: + case TERM_SURF_SCROLLBACK_INDICATOR: case TERM_SURF_BUTTON_MINIMIZE: case TERM_SURF_BUTTON_MAXIMIZE: case TERM_SURF_BUTTON_CLOSE: @@ -1357,6 +1360,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, break; case TERM_SURF_SEARCH: + case TERM_SURF_SCROLLBACK_INDICATOR: break; case TERM_SURF_GRID: { From a98484c6ebb2aa7f0ba1f99bb1f03e2d6a251b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 12:37:57 +0200 Subject: [PATCH 20/24] render: scrollback indicator: add top margin --- render.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/render.c b/render.c index 6e8a56d4..d9999bf0 100644 --- a/render.c +++ b/render.c @@ -1420,7 +1420,7 @@ render_scrollback_position(struct terminal *term) return; case SCROLLBACK_INDICATOR_STYLE_FIXED: - surf_top = margin + term->cell_height; + surf_top = term->cell_height - margin; break; case SCROLLBACK_INDICATOR_STYLE_RELATIVE: { @@ -1428,15 +1428,15 @@ render_scrollback_position(struct terminal *term) assert(lines > 0); int on_line = 1 + percent * lines / 100; - surf_top = margin + on_line * term->cell_height; + surf_top = on_line * term->cell_height - margin; break; } } wl_subsurface_set_position( win->scrollback_indicator_sub_surface, - (term->width - term->margins.right - width) / scale, - surf_top / scale); + (term->width - margin - width) / scale, + (term->margins.top + surf_top) / scale); 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); From ee5c9d714a31b0bdf2b46188c30c30eb1bb27e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 26 Jul 2020 12:41:32 +0200 Subject: [PATCH 21/24] changelog: scrollback position indicator --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 638609a9..fd2b1d79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,9 @@ roughly in the center of the screen. * Mouse cursor is now always a `left_ptr` when inside the margins, to indicate it is not possible to start a selection. +* Scrollback position indicator. This feature is optional and + controlled by the **scrollback-indicator-style** and + **scrollback-indicator-format** options in `footrc`. ### Deprecated From 9bc10cdb01056fc22f6eef601a7113c8efefc195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 27 Jul 2020 16:39:08 +0200 Subject: [PATCH 22/24] render: scrollback indicator: render relative indicator "smoothly" That is, don't require it to be placed on a grid row. --- render.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/render.c b/render.c index d9999bf0..2f95e5b3 100644 --- a/render.c +++ b/render.c @@ -1353,10 +1353,10 @@ render_scrollback_position(struct terminal *term) * 0% -> at the beginning of the scrollback * 100% -> at the bottom, i.e. where new lines are inserted */ - unsigned percent = + double percent = rebased_view + term->rows == term->grid->num_rows - ? 100 - : 100 * rebased_view / term->grid->num_rows; + ? 1.0 + : (double)rebased_view / term->grid->num_rows; wchar_t text[64]; int cell_count; @@ -1364,7 +1364,7 @@ render_scrollback_position(struct terminal *term) /* *What* to render */ switch (term->conf->scrollback.indicator.format) { case SCROLLBACK_INDICATOR_FORMAT_PERCENTAGE: - swprintf(text, sizeof(text) / sizeof(text[0]), L"%u%%", percent); + swprintf(text, sizeof(text) / sizeof(text[0]), L"%u%%", (int)(100 * percent)); cell_count = 3; break; @@ -1424,11 +1424,11 @@ render_scrollback_position(struct terminal *term) break; case SCROLLBACK_INDICATOR_STYLE_RELATIVE: { - int lines = term->rows - 2; /* Avoid using first and last row */ + int lines = term->rows - 3; /* Avoid using first and two last rows */ assert(lines > 0); - int on_line = 1 + percent * lines / 100; - surf_top = on_line * term->cell_height - margin; + int pixels = lines * term->cell_height - height + 2 * margin; + surf_top = term->cell_height - margin + (int)(percent * pixels); break; } } From 0c8b44ab67bdcffee6fe7f16c400c254a37b1d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 27 Jul 2020 19:07:00 +0200 Subject: [PATCH 23/24] changelog: add link to issue --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd38f103..4f57df94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,8 @@ indicate it is not possible to start a selection. * Scrollback position indicator. This feature is optional and controlled by the **scrollback-indicator-style** and - **scrollback-indicator-format** options in `footrc`. + **scrollback-indicator-format** options in `footrc` + (https://codeberg.org/dnkl/foot/issues/42). ### Fixed From 9d859131367cea63ac4d604dd269db35a9a0bdb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 27 Jul 2020 19:08:28 +0200 Subject: [PATCH 24/24] changelog: move scrollback indicator entries from 1.4.3 to 'unreleased' --- CHANGELOG.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f57df94..35669232 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,21 @@ ### Added ### Deprecated ### Removed +### Changed + +* Mouse cursor is now always a `left_ptr` when inside the margins, to + indicate it is not possible to start a selection. +* Scrollback position indicator. This feature is optional and + controlled by the **scrollback-indicator-style** and + **scrollback-indicator-format** options in `footrc` + (https://codeberg.org/dnkl/foot/issues/42). + + ### Fixed + +* Crash when starting a selection inside the margins. + + ### Security ### Contributors @@ -49,12 +63,6 @@ roughly in the center of the screen. * Extending a selection with the right mouse button now works while dragging the mouse. -* Mouse cursor is now always a `left_ptr` when inside the margins, to - indicate it is not possible to start a selection. -* Scrollback position indicator. This feature is optional and - controlled by the **scrollback-indicator-style** and - **scrollback-indicator-format** options in `footrc` - (https://codeberg.org/dnkl/foot/issues/42). ### Fixed @@ -63,7 +71,6 @@ * Crash when a **pipe-visible** or **pipe-scrollback** command contained an unclosed quote (https://codeberg.org/dnkl/foot/issues/49). -* Crash when starting a selection inside the margins. ### Contributors