summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2022-07-26 17:51:31 +0100
committerPhil Jones <philj56@gmail.com>2022-07-26 17:51:31 +0100
commit88e713b981c8760c255b19009918ee94f60fbdc1 (patch)
treeecdca68c12425bbec7fb2f353d28a03c4e2f5a5c
parentd3bf3b017b8129ff772ad9c5658ccdfc826d0e51 (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.md5
-rw-r--r--doc/tofi.5.scd5
-rw-r--r--src/drun.c5
-rw-r--r--src/entry.c10
-rw-r--r--src/entry.h6
-rw-r--r--src/entry_backend/harfbuzz.c21
-rw-r--r--src/entry_backend/pango.c21
-rw-r--r--src/main.c8
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.
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,