diff options
author | Phil Jones <philj56@gmail.com> | 2022-07-26 17:51:31 +0100 |
---|---|---|
committer | Phil Jones <philj56@gmail.com> | 2022-07-26 17:51:31 +0100 |
commit | 88e713b981c8760c255b19009918ee94f60fbdc1 (patch) | |
tree | ecdca68c12425bbec7fb2f353d28a03c4e2f5a5c | |
parent | d3bf3b017b8129ff772ad9c5658ccdfc826d0e51 (diff) |
Add automatic detection of number of results.
Tofi will now try to autodetect how many results can be drawn if
--num-results=0 is specified, which is now the default.
-rw-r--r-- | doc/tofi.5.md | 5 | ||||
-rw-r--r-- | doc/tofi.5.scd | 5 | ||||
-rw-r--r-- | src/drun.c | 5 | ||||
-rw-r--r-- | src/entry.c | 10 | ||||
-rw-r--r-- | src/entry.h | 6 | ||||
-rw-r--r-- | src/entry_backend/harfbuzz.c | 21 | ||||
-rw-r--r-- | src/entry_backend/pango.c | 21 | ||||
-rw-r--r-- | src/main.c | 8 |
8 files changed, 70 insertions, 11 deletions
diff --git a/doc/tofi.5.md b/doc/tofi.5.md index 55e615f..916fc22 100644 --- a/doc/tofi.5.md +++ b/doc/tofi.5.md @@ -83,9 +83,10 @@ options. **num-results**=*n* -> Maximum number of results to display. +> Maximum number of results to display. If *n* = 0, tofi will draw as +> many results as it can fit in the window. > -> Default: 5 +> Default: 0 **selection-color**=*color* diff --git a/doc/tofi.5.scd b/doc/tofi.5.scd index 41c5fe9..3ad7015 100644 --- a/doc/tofi.5.scd +++ b/doc/tofi.5.scd @@ -75,9 +75,10 @@ options. Default: "run: " *num-results*=_n_ - Maximum number of results to display. + Maximum number of results to display. If _n_ = 0, tofi will draw as + many results as it can fit in the window. - Default: 5 + Default: 0 *selection-color*=_color_ Color of selected result. See *COLORS* for more information. @@ -122,6 +122,11 @@ static void parse_desktop_file(gpointer key, gpointer value, void *data) struct desktop_vec drun_generate(void) { + /* + * Note for the future: this custom logic could be replaced with + * g_app_info_get_all(), but that's slower. Worth remembering + * though if this runs into issues. + */ log_debug("Retrieving application dirs.\n"); struct string_vec paths = get_application_paths(); struct string_vec desktop_files = string_vec_create(); diff --git a/src/entry.c b/src/entry.c index 89f274f..e308a3c 100644 --- a/src/entry.c +++ b/src/entry.c @@ -131,6 +131,14 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u entry_backend_harfbuzz_init(entry, &width, &height); } + /* Store the clip rectangle width and height. */ + cairo_matrix_t mat; + cairo_get_matrix(cr, &mat); + entry->clip_x = mat.x0; + entry->clip_y = mat.y0; + entry->clip_width = width; + entry->clip_height = height; + /* * Perform an initial render of the text. * This is done here rather than by calling entry_update to avoid the @@ -159,8 +167,6 @@ void entry_init(struct entry *entry, uint8_t *restrict buffer, uint32_t width, u * frame has been displayed on screen (and while the user is unlikely * to press another key for the <10ms it takes to memcpy). */ - cairo_matrix_t mat; - cairo_get_matrix(cr, &mat); cairo_set_matrix(entry->cairo[1].cr, &mat); cairo_rectangle(entry->cairo[1].cr, 0, 0, width, height); cairo_clip(entry->cairo[1].cr); diff --git a/src/entry.h b/src/entry.h index 63aad8a..c45bb85 100644 --- a/src/entry.h +++ b/src/entry.h @@ -40,10 +40,16 @@ struct entry { struct history history; bool use_pango; + uint32_t clip_x; + uint32_t clip_y; + uint32_t clip_width; + uint32_t clip_height; + /* Options */ bool drun; bool horizontal; uint32_t num_results; + uint32_t num_results_drawn; int32_t result_spacing; uint32_t font_size; char font_name[MAX_FONT_NAME_LENGTH]; diff --git a/src/entry_backend/harfbuzz.c b/src/entry_backend/harfbuzz.c index bb4429c..ed2a5aa 100644 --- a/src/entry_backend/harfbuzz.c +++ b/src/entry_backend/harfbuzz.c @@ -218,13 +218,32 @@ void entry_backend_harfbuzz_update(struct entry *entry) cairo_font_extents_t font_extents; cairo_font_extents(cr, &font_extents); + cairo_matrix_t mat; /* Render our results entry text */ - for (size_t i = 0; i < entry->num_results && i < entry->results.count; i++) { + for (size_t i = 0; i < entry->results.count; i++) { if (entry->horizontal) { cairo_translate(cr, width + entry->result_spacing, 0); } else { cairo_translate(cr, 0, font_extents.height + entry->result_spacing); } + if (entry->num_results == 0) { + cairo_get_matrix(cr, &mat); + if (entry->horizontal) { + if (mat.x0 > entry->clip_x + entry->clip_width) { + entry->num_results_drawn = i; + log_debug("Drew %zu results.\n", i); + break; + } + } else { + if (mat.y0 > entry->clip_y + entry->clip_height) { + entry->num_results_drawn = i; + log_debug("Drew %zu results.\n", i); + break; + } + } + } else if (i >= entry->num_results) { + break; + } hb_buffer_clear_contents(buffer); setup_hb_buffer(buffer); diff --git a/src/entry_backend/pango.c b/src/entry_backend/pango.c index 34bb05e..13e21ee 100644 --- a/src/entry_backend/pango.c +++ b/src/entry_backend/pango.c @@ -72,12 +72,31 @@ void entry_backend_pango_update(struct entry *entry) pango_layout_get_size(layout, &width, &height); width = MAX(width, (int)entry->input_width * PANGO_SCALE); - for (size_t i = 0; i < entry->num_results && i < entry->results.count; i++) { + cairo_matrix_t mat; + for (size_t i = 0; i < entry->results.count; i++) { if (entry->horizontal) { cairo_translate(cr, (int)(width / PANGO_SCALE) + entry->result_spacing, 0); } else { cairo_translate(cr, 0, (int)(height / PANGO_SCALE) + entry->result_spacing); } + if (entry->num_results == 0) { + cairo_get_matrix(cr, &mat); + if (entry->horizontal) { + if (mat.x0 > entry->clip_x + entry->clip_width) { + entry->num_results_drawn = i; + log_debug("Drew %zu results.\n", i); + break; + } + } else { + if (mat.y0 > entry->clip_y + entry->clip_height) { + entry->num_results_drawn = i; + log_debug("Drew %zu results.\n", i); + break; + } + } + } else if (i >= entry->num_results) { + break; + } const char *str; if (i < entry->results.count) { str = entry->results.buf[i].string; @@ -201,6 +201,11 @@ static void wl_keyboard_key( return; } + uint32_t num_results = tofi->window.entry.num_results; + if (num_results == 0) { + num_results = tofi->window.entry.num_results_drawn; + } + uint32_t nsel = MAX(MIN(num_results, tofi->window.entry.results.count), 1); if (sym == XKB_KEY_Up || sym == XKB_KEY_Left || (sym == XKB_KEY_k && xkb_state_mod_name_is_active( @@ -209,7 +214,6 @@ static void wl_keyboard_key( XKB_STATE_MODS_EFFECTIVE) ) ) { - uint32_t nsel = MAX(MIN(tofi->window.entry.num_results, tofi->window.entry.results.count), 1); tofi->window.entry.selection += nsel; tofi->window.entry.selection--; tofi->window.entry.selection %= nsel; @@ -221,7 +225,6 @@ static void wl_keyboard_key( XKB_STATE_MODS_EFFECTIVE) ) ) { - uint32_t nsel = MAX(MIN(tofi->window.entry.num_results, tofi->window.entry.results.count), 1); tofi->window.entry.selection++; tofi->window.entry.selection %= nsel; } else { @@ -839,7 +842,6 @@ int main(int argc, char *argv[]) .font_name = "Sans", .font_size = 24, .prompt_text = "run: ", - .num_results = 5, .padding_top = 8, .padding_bottom = 8, .padding_left = 8, |