From 88e713b981c8760c255b19009918ee94f60fbdc1 Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Tue, 26 Jul 2022 17:51:31 +0100 Subject: 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. --- src/drun.c | 5 +++++ src/entry.c | 10 ++++++++-- src/entry.h | 6 ++++++ src/entry_backend/harfbuzz.c | 21 ++++++++++++++++++++- src/entry_backend/pango.c | 21 ++++++++++++++++++++- src/main.c | 8 +++++--- 6 files changed, 64 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/drun.c b/src/drun.c index bc755fb..8e1e0b4 100644 --- a/src/drun.c +++ b/src/drun.c @@ -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; diff --git a/src/main.c b/src/main.c index ef0dc48..9429408 100644 --- a/src/main.c +++ b/src/main.c @@ -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, -- cgit v1.2.3