summaryrefslogtreecommitdiffstats
path: root/blkshowr.c
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-06-09 22:00:09 +0200
committerMattias Andrée <m@maandree.se>2026-06-09 22:00:09 +0200
commitcee4170316a424317ad8757b42985ca0190c8faa (patch)
treed815e92716c4d98d3df35bdc45786f707c3a382e /blkshowr.c
parentWork on blkshowr (diff)
downloadblkseekr-cee4170316a424317ad8757b42985ca0190c8faa.tar.gz
blkseekr-cee4170316a424317ad8757b42985ca0190c8faa.tar.bz2
blkseekr-cee4170316a424317ad8757b42985ca0190c8faa.tar.xz
Improve mouse scrolling supportHEADmaster
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'blkshowr.c')
-rw-r--r--blkshowr.c85
1 files changed, 55 insertions, 30 deletions
diff --git a/blkshowr.c b/blkshowr.c
index 4ca0724..3228d12 100644
--- a/blkshowr.c
+++ b/blkshowr.c
@@ -42,6 +42,7 @@ static size_t term_width;
static size_t term_height;
static int exiting = 0;
static int interrupt_deferred = 0;
+static int deferred_redraw = 0;
static size_t selected_block = 0u;
static size_t first_visible_block = 0u;
@@ -93,6 +94,8 @@ do_redraw(void)
size_t right_pad;
size_t text_top, text_bottom;
+ deferred_redraw = 0;
+
if (current_block_off != blocks[selected_block]) {
off_t off;
ssize_t r;
@@ -456,7 +459,6 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
return;
/* TODO optimise redraw to only affected areas */
- /* TODO defer redraw until all repeations have been processed */
if (input->keypress.key == LIBTERMINPUT_UP) {
if (selected_block > 0u) {
@@ -464,7 +466,7 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
line_count = 0u;
selected_block -= 1u;
ensure_selected_block_visible();
- do_redraw();
+ deferred_redraw |= input->keypress.times <= 1u;
}
} else if (input->keypress.key == LIBTERMINPUT_DOWN) {
@@ -473,7 +475,7 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
line_count = 0u;
selected_block += 1u;
ensure_selected_block_visible();
- do_redraw();
+ deferred_redraw |= input->keypress.times <= 1u;
}
} else if (input->keypress.key == LIBTERMINPUT_HOME) {
@@ -482,7 +484,8 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
line_count = 0u;
selected_block = 0u;
ensure_selected_block_visible();
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
} else if (input->keypress.key == LIBTERMINPUT_END) {
@@ -491,7 +494,8 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
line_count = 0u;
selected_block = nblocks - 1u;
ensure_selected_block_visible();
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
} else if (input->keypress.key == LIBTERMINPUT_PRIOR) {
@@ -500,14 +504,16 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
line_count = 0u;
if (selected_block != first_visible_block) {
selected_block = first_visible_block;
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
} else {
if (selected_block > term_height - 2u)
selected_block -= term_height - 2u;
else
selected_block = 0u;
ensure_selected_block_visible();
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
}
@@ -518,14 +524,16 @@ handle_keyboard_input_to_block_selector(union libterminput_input *input)
line_count = 0u;
if (selected_block != last) {
selected_block = last;
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
} else {
if (term_height - 2u > nblocks - 1u - selected_block)
selected_block = nblocks - 1u;
else
selected_block += term_height - 2u;
ensure_selected_block_visible();
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
}
}
@@ -539,33 +547,34 @@ handle_keyboard_input_to_block_display(union libterminput_input *input)
return;
/* TODO optimise redraw to only affected areas */
- /* TODO defer redraw until all repeations have been processed */
if (input->keypress.key == LIBTERMINPUT_UP) {
if (first_visible_line > 0u) {
first_visible_line -= 1u;
- do_redraw();
+ deferred_redraw |= input->keypress.times <= 1u;
}
} else if (input->keypress.key == LIBTERMINPUT_DOWN) {
if (line_count > first_visible_line && term_height > 2u) {
if (term_height - 2u < line_count - first_visible_line) {
first_visible_line += 1;
- do_redraw();
+ deferred_redraw |= input->keypress.times <= 1u;
}
}
} else if (input->keypress.key == LIBTERMINPUT_HOME) {
if (first_visible_line != 0u) {
first_visible_line = 0u;
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
} else if (input->keypress.key == LIBTERMINPUT_END) {
if (line_count && term_height > 2u && line_count > term_height - 1u) {
if (first_visible_line != line_count - (term_height - 2u)) {
first_visible_line = line_count - (term_height - 2u);
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
}
@@ -575,7 +584,8 @@ handle_keyboard_input_to_block_display(union libterminput_input *input)
first_visible_line = 0u;
else
first_visible_line -= term_height - 2u;
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
} else if (input->keypress.key == LIBTERMINPUT_NEXT) {
@@ -589,7 +599,8 @@ handle_keyboard_input_to_block_display(union libterminput_input *input)
first_visible_line = 0u;
}
if (first_visible_line != prev)
- do_redraw();
+ if (input->keypress.times <= 1u)
+ do_redraw();
}
}
}
@@ -855,7 +866,7 @@ main(int argc, char *argv[])
struct libterminput_state input_ctx;
union libterminput_input input;
const char *listpath, *env;
- int listfd;
+ int listfd, ttyfd_nb, fd;
ARGBEGIN {
case 'b':
@@ -884,6 +895,13 @@ main(int argc, char *argv[])
eprintf("open /dev/tty O_RDWR:");
if (getpgrp() != tcgetpgrp(ttyfd))
eprintf("process not running in the foreground");
+ /* O_NONBLOCK is on open file descriptor level and preadv2(2) (with RWF_NOWAIT)
+ * do not support TTYs (how knows why, pipes are supports, ...) */
+ ttyfd_nb = open("/dev/tty", O_RDWR | O_NONBLOCK);
+ if (ttyfd_nb < 0)
+ eprintf("open /dev/tty O_RDWR|O_NONBLOCK:");
+ if (getpgrp() != tcgetpgrp(ttyfd_nb))
+ eprintf("process not running in the foreground");
/* Open block list */
listfd = get_fd(listpath);
@@ -939,24 +957,31 @@ main(int argc, char *argv[])
}
}
- switch (libterminput_read(ttyfd, &input, &input_ctx)) {
- case 1:
- handle_keyboard_input(&input);
- break;
- case 0:
- exiting = 1;
- break;
- default:
- if (errno == EINTR)
- interrupt_deferred = 1;
- else
- eprintf("libterminput_read /dev/tty:");
- break;
+ for (fd = ttyfd;; fd = ttyfd_nb) {
+ switch (libterminput_read(fd, &input, &input_ctx)) {
+ case 1:
+ handle_keyboard_input(&input);
+ break;
+ case 0:
+ exiting = 1;
+ goto read_blocked;
+ default:
+ if (errno == EINTR)
+ interrupt_deferred = 1;
+ else if (errno != EAGAIN)
+ eprintf("libterminput_read /dev/tty:");
+ goto read_blocked;
+ }
}
+
+ read_blocked:
+ if (deferred_redraw)
+ do_redraw();
} while (!exiting);
libterminput_destroy(&input_ctx);
close(textfd);
+ close(ttyfd_nb);
free(current_block_text);
free(line_map);
return 0;