fix: unresponsive UI when animation is too fast (#489)

the previous check_timeouts() logic tried to greedily handle as
many timeouts as possible until there are no more active
timeouts left. this caused a number of issues such as:

https://codeberg.org/nsxiv/nsxiv/issues/439
https://codeberg.org/nsxiv/nsxiv-record/issues/281

the new logic relaxes this and only does a single iteration.
any remaining active timeout will be picked up by the next
iteration instead.

Fixes: https://codeberg.org/nsxiv/nsxiv/issues/439
This commit is contained in:
NRK 2024-06-05 19:37:46 +00:00
parent a581cd6344
commit 65acb98396
1 changed files with 15 additions and 9 deletions

24
main.c
View File

@ -249,10 +249,10 @@ void reset_timeout(timeout_f handler)
static bool check_timeouts(int *t) static bool check_timeouts(int *t)
{ {
int i = 0, tdiff, tmin = -1; int i = 0, tdiff, tmin;
struct timeval now; struct timeval now;
while (i < (int)ARRLEN(timeouts)) { for (i = 0; i < (int)ARRLEN(timeouts); ++i) {
if (timeouts[i].active) { if (timeouts[i].active) {
gettimeofday(&now, 0); gettimeofday(&now, 0);
tdiff = TV_DIFF(&timeouts[i].when, &now); tdiff = TV_DIFF(&timeouts[i].when, &now);
@ -260,16 +260,22 @@ static bool check_timeouts(int *t)
timeouts[i].active = false; timeouts[i].active = false;
if (timeouts[i].handler != NULL) if (timeouts[i].handler != NULL)
timeouts[i].handler(); timeouts[i].handler();
i = tmin = -1;
} else if (tmin < 0 || tdiff < tmin) {
tmin = tdiff;
} }
} }
i++;
} }
if (tmin > 0 && t != NULL)
*t = tmin; tmin = INT_MAX;
return tmin > 0; gettimeofday(&now, 0);
for (i = 0; i < (int)ARRLEN(timeouts); ++i) {
if (timeouts[i].active) {
tdiff = TV_DIFF(&timeouts[i].when, &now);
tmin = MIN(tmin, tdiff);
}
}
if (tmin != INT_MAX && t != NULL)
*t = MAX(tmin, 0);
return tmin != INT_MAX;
} }
static void autoreload(void) static void autoreload(void)