1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-25 03:33:03 +01:00

Greatly reduce redundant window refreshing

This should substantially reduce CPU usage and possibly fix some
issues with interface jittering/flashing
This commit is contained in:
jfreegman 2021-11-19 15:03:08 -05:00
parent 13337041ce
commit 8fa3f6fd8c
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
7 changed files with 92 additions and 14 deletions

View File

@ -1072,13 +1072,12 @@ static void draw_infobox(ToxWindow *self)
time_t curtime = get_unix_time(); time_t curtime = get_unix_time();
/* update elapsed time string once per second */ /* update interface once per second */
if (curtime > infobox->lastupdate) { if (timed_out(infobox->lastupdate, 1)) {
get_elapsed_time_str(infobox->timestr, sizeof(infobox->timestr), curtime - infobox->starttime); get_elapsed_time_str(infobox->timestr, sizeof(infobox->timestr), curtime - infobox->starttime);
infobox->lastupdate = curtime;
} }
infobox->lastupdate = curtime;
const char *in_is_muted = infobox->in_is_muted ? "yes" : "no"; const char *in_is_muted = infobox->in_is_muted ? "yes" : "no";
const char *out_is_muted = infobox->out_is_muted ? "yes" : "no"; const char *out_is_muted = infobox->out_is_muted ? "yes" : "no";

View File

@ -346,5 +346,9 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int mx_x)
} }
} }
if (match) {
flag_interface_change(1);
}
return match; return match;
} }

View File

@ -444,6 +444,8 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
hst->queue[hst->queue_size++] = new_line; hst->queue[hst->queue_size++] = new_line;
flag_interface_change(1);
return new_line->id; return new_line->id;
} }
@ -454,6 +456,7 @@ static void line_info_check_queue(ToxWindow *self)
struct line_info *line = line_info_ret_queue(hst); struct line_info *line = line_info_ret_queue(hst);
if (line == NULL) { if (line == NULL) {
flag_interface_change(0);
return; return;
} }
@ -469,6 +472,8 @@ static void line_info_check_queue(ToxWindow *self)
if (!self->scroll_pause) { if (!self->scroll_pause) {
line_info_reset_start(self, hst); line_info_reset_start(self, hst);
} }
flag_interface_change(1);
} }
#define NOREAD_FLAG_TIMEOUT 5 /* seconds before a sent message with no read receipt is flagged as unread */ #define NOREAD_FLAG_TIMEOUT 5 /* seconds before a sent message with no read receipt is flagged as unread */
@ -763,6 +768,8 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
line = line->prev; line = line->prev;
} }
flag_interface_change(1);
} }
static void line_info_scroll_up(ToxWindow *self, struct history *hst) static void line_info_scroll_up(ToxWindow *self, struct history *hst)
@ -771,6 +778,8 @@ static void line_info_scroll_up(ToxWindow *self, struct history *hst)
hst->line_start = hst->line_start->prev; hst->line_start = hst->line_start->prev;
self->scroll_pause = true; self->scroll_pause = true;
} }
flag_interface_change(1);
} }
static void line_info_scroll_down(ToxWindow *self, struct history *hst) static void line_info_scroll_down(ToxWindow *self, struct history *hst)
@ -786,6 +795,8 @@ static void line_info_scroll_down(ToxWindow *self, struct history *hst)
} else { } else {
line_info_reset_start(self, hst); line_info_reset_start(self, hst);
} }
flag_interface_change(1);
} }
static void line_info_page_up(ToxWindow *self, struct history *hst) static void line_info_page_up(ToxWindow *self, struct history *hst)
@ -805,6 +816,8 @@ static void line_info_page_up(ToxWindow *self, struct history *hst)
} }
self->scroll_pause = true; self->scroll_pause = true;
flag_interface_change(1);
} }
static void line_info_page_down(ToxWindow *self, struct history *hst) static void line_info_page_down(ToxWindow *self, struct history *hst)
@ -834,6 +847,8 @@ static void line_info_page_down(ToxWindow *self, struct history *hst)
hst->line_start = next; hst->line_start = next;
next = hst->line_start->next; next = hst->line_start->next;
} }
flag_interface_change(1);
} }
bool line_info_onKey(ToxWindow *self, wint_t key) bool line_info_onKey(ToxWindow *self, wint_t key)
@ -855,6 +870,10 @@ bool line_info_onKey(ToxWindow *self, wint_t key)
match = false; match = false;
} }
if (match) {
flag_interface_change(1);
}
return match; return match;
} }
@ -862,4 +881,6 @@ void line_info_clear(struct history *hst)
{ {
hst->line_start = hst->line_end; hst->line_start = hst->line_end;
hst->start_id = hst->line_start->id; hst->start_id = hst->line_start->id;
flag_interface_change(1);
} }

View File

@ -1072,8 +1072,24 @@ static void do_toxic(Tox *m)
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
} }
/* How often we refresh windows that aren't focused */
#define INACTIVE_WIN_REFRESH_RATE 10 #define INACTIVE_WIN_REFRESH_RATE 10
/* Set interface change flag. This should be called whenever the interface changes.
*
* `flag` should be a non-zero value if we need to redraw the window or 0 if we want to idle.
*/
void flag_interface_change(unsigned int flag)
{
if (flag == 0 && timed_out(Winthread.flag_refresh_timeout, 1)) {
Winthread.flag_refresh = flag;
} else if (flag != 0) {
Winthread.flag_refresh = 1;
}
Winthread.flag_refresh_timeout = get_unix_time();
}
void *thread_winref(void *data) void *thread_winref(void *data)
{ {
Tox *m = (Tox *) data; Tox *m = (Tox *) data;
@ -1082,8 +1098,8 @@ void *thread_winref(void *data)
init_signal_catchers(); init_signal_catchers();
while (true) { while (true) {
draw_active_window(m);
draw_count++; draw_count++;
draw_active_window(m);
if (Winthread.flag_resize) { if (Winthread.flag_resize) {
on_window_resize(); on_window_resize();
@ -1470,6 +1486,8 @@ int main(int argc, char **argv)
/* Make sure all written files are read/writeable only by the current user. */ /* Make sure all written files are read/writeable only by the current user. */
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
flag_interface_change(1);
srand(time(NULL)); // We use rand() for trivial/non-security related things srand(time(NULL)); // We use rand() for trivial/non-security related things
parse_args(argc, argv); parse_args(argc, argv);

View File

@ -102,6 +102,8 @@ typedef enum _FATAL_ERRS {
void lock_status(void); void lock_status(void);
void unlock_status(void); void unlock_status(void);
void flag_interface_change(unsigned int flag);
void exit_toxic_success(Tox *m); void exit_toxic_success(Tox *m);
void exit_toxic_err(const char *errmsg, int errcode); void exit_toxic_err(const char *errmsg, int errcode);

View File

@ -77,6 +77,8 @@ void on_friend_connection_status(Tox *m, uint32_t friendnumber, Tox_Connection c
windows[i]->onConnectionChange(windows[i], m, friendnumber, connection_status); windows[i]->onConnectionChange(windows[i], m, friendnumber, connection_status);
} }
} }
flag_interface_change(1);
} }
void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata) void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata)
@ -92,6 +94,8 @@ void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userd
windows[i]->onTypingChange(windows[i], m, friendnumber, is_typing); windows[i]->onTypingChange(windows[i], m, friendnumber, is_typing);
} }
} }
flag_interface_change(1);
} }
void on_friend_message(Tox *m, uint32_t friendnumber, Tox_Message_Type type, const uint8_t *string, size_t length, void on_friend_message(Tox *m, uint32_t friendnumber, Tox_Message_Type type, const uint8_t *string, size_t length,
@ -123,6 +127,8 @@ void on_friend_name(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t
} }
} }
flag_interface_change(1);
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
} }
@ -140,6 +146,8 @@ void on_friend_status_message(Tox *m, uint32_t friendnumber, const uint8_t *stri
windows[i]->onStatusMessageChange(windows[i], friendnumber, msg, length); windows[i]->onStatusMessageChange(windows[i], friendnumber, msg, length);
} }
} }
flag_interface_change(1);
} }
void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, void *userdata) void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, void *userdata)
@ -151,6 +159,8 @@ void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, voi
windows[i]->onStatusChange(windows[i], m, friendnumber, status); windows[i]->onStatusChange(windows[i], m, friendnumber, status);
} }
} }
flag_interface_change(1);
} }
void on_friend_added(Tox *m, uint32_t friendnumber, bool sort) void on_friend_added(Tox *m, uint32_t friendnumber, bool sort)
@ -200,6 +210,8 @@ void on_conference_peer_list_changed(Tox *m, uint32_t conferencenumber, void *us
windows[i]->onConferenceNameListChange(windows[i], m, conferencenumber); windows[i]->onConferenceNameListChange(windows[i], m, conferencenumber);
} }
} }
flag_interface_change(1);
} }
void on_conference_peer_name(Tox *m, uint32_t conferencenumber, uint32_t peernumber, const uint8_t *name, void on_conference_peer_name(Tox *m, uint32_t conferencenumber, uint32_t peernumber, const uint8_t *name,
@ -423,11 +435,13 @@ void set_active_window_index(uint8_t index)
*/ */
void set_next_window(int ch) void set_next_window(int ch)
{ {
uint8_t index = 0;
if (ch == user_settings->key_next_tab) { if (ch == user_settings->key_next_tab) {
for (uint8_t i = active_window_index + 1; i < MAX_WINDOWS_NUM; ++i) { for (uint8_t i = active_window_index + 1; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL) { if (windows[i] != NULL) {
set_active_window_index(i); index = i;
return; break;
} }
} }
} else { } else {
@ -435,13 +449,15 @@ void set_next_window(int ch)
for (uint8_t i = start; i > 0; --i) { for (uint8_t i = start; i > 0; --i) {
if (windows[i] != NULL) { if (windows[i] != NULL) {
set_active_window_index(i); index = i;
return; break;
} }
} }
} }
set_active_window_index(0); set_active_window_index(index);
flag_interface_change(1);
} }
/* Deletes window w and cleans up */ /* Deletes window w and cleans up */
@ -784,21 +800,33 @@ void draw_active_window(Tox *m)
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
a->alert = WINDOW_ALERT_NONE; a->alert = WINDOW_ALERT_NONE;
a->pending_messages = 0; a->pending_messages = 0;
bool flag_refresh = Winthread.flag_refresh;
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
touchwin(a->window); if (flag_refresh || (a->is_call && timed_out(a->chatwin->infobox.lastupdate, 1))) {
a->onDraw(a, m); touchwin(a->window);
wrefresh(a->window); a->onDraw(a, m);
wrefresh(a->window);
}
#ifdef GAMES #ifdef GAMES
if (a->type == WINDOW_TYPE_GAME) { if (a->type == WINDOW_TYPE_GAME) {
if (!flag_refresh) { // we always want to be continously refreshing game windows
touchwin(a->window);
a->onDraw(a, m);
wrefresh(a->window);
}
int ch = getch(); int ch = getch();
if (ch == ERR) { if (ch == ERR) {
return; return;
} }
pthread_mutex_lock(&Winthread.lock);
flag_interface_change(1);
pthread_mutex_unlock(&Winthread.lock);
if (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab) { if (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab) {
set_next_window(ch); set_next_window(ch);
} }
@ -817,6 +845,10 @@ void draw_active_window(Tox *m)
return; return;
} }
pthread_mutex_lock(&Winthread.lock);
flag_interface_change(1);
pthread_mutex_unlock(&Winthread.lock);
if (printable == 0 && (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab)) { if (printable == 0 && (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab)) {
set_next_window((int) ch); set_next_window((int) ch);
return; return;

View File

@ -103,6 +103,8 @@ struct Winthread {
pthread_mutex_t lock; pthread_mutex_t lock;
volatile sig_atomic_t sig_exit_toxic; volatile sig_atomic_t sig_exit_toxic;
volatile sig_atomic_t flag_resize; volatile sig_atomic_t flag_resize;
volatile sig_atomic_t flag_refresh;
volatile sig_atomic_t flag_refresh_timeout;
}; };
struct cqueue_thread { struct cqueue_thread {