1
0
mirror of https://github.com/Tha14/toxic.git synced 2025-06-27 02:06:45 +02:00

Compare commits

...

8 Commits

Author SHA1 Message Date
8fa3f6fd8c Greatly reduce redundant window refreshing
This should substantially reduce CPU usage and possibly fix some
issues with interface jittering/flashing
2021-11-19 15:03:08 -05:00
13337041ce Show friend connection type (UDP/TCP) in friend status bar 2021-11-10 13:27:11 -05:00
41e93adbdb game_chess.c: always use "%s"-style format for printf()-style functions
`ncuses-6.3` added printf-style function attributes and now makes
it easier to catch cases when user input is used in palce of format
string when built with CFLAGS=-Werror=format-security:

    toxic/src/game_chess.c:1633:63: error:
      format not a string literal and no format arguments [-Werror=format-security]
     1633 |         mvwprintw(win, board->y_bottom_bound + 2, x_mid, state->status_message);
          |                                                          ~~~~~^~~~~~~~~~~~~~~~

Let's wrap all the missing places with "%s" format.
2021-11-04 09:44:33 +00:00
34b7c0a0d8 Options parsing code cleanup 2021-11-03 16:23:38 -04:00
bcdec5d624 Improve installation instructions 2021-09-12 16:58:28 +02:00
9e353443c2 Fix outdated help message 2021-08-16 11:14:09 -04:00
d02f3b4acb Fix a graphical bug with the game border on some terminal emulators 2021-07-27 14:15:36 -04:00
f2b1c81279 Fix static build script and update libcurl version 2021-06-28 23:07:03 -04:00
13 changed files with 174 additions and 82 deletions

View File

@ -10,7 +10,7 @@
## Dependencies
| Name | Needed by | Debian package |
|------------------------------------------------------|----------------------------|---------------------|
| [Tox Core](https://github.com/toktok/c-toxcore) | BASE | *None* |
| [Tox Core](https://github.com/toktok/c-toxcore) | BASE | libtoxcore-dev |
| [NCurses](https://www.gnu.org/software/ncurses) | BASE | libncursesw5-dev |
| [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev |
| [GNUmake](https://www.gnu.org/software/make) | BASE | make |
@ -55,8 +55,8 @@ Run `make doc` in the build directory after editing the asciidoc files to regene
* `DISABLE_X11=1` → Disable X11 support (needed for focus tracking)
* `DISABLE_AV=1` → Disable audio call support
* `DISABLE_SOUND_NOTIFY=1` → Disable sound notifications support
* `DISABLE_QRCODE` → Disable QR exporting support
* `DISABLE_QRPNG` → Disable support for exporting QR as PNG
* `DISABLE_QRCODE=1` → Disable QR exporting support
* `DISABLE_QRPNG=1` → Disable support for exporting QR as PNG
* `DISABLE_DESKTOP_NOTIFY=1` → Disable desktop notifications support
* `DISABLE_GAMES=1` → Disable support for games
* `ENABLE_PYTHON=1` → Build toxic with Python scripting support

View File

@ -131,11 +131,15 @@ mkdir -p "$BUILD_DIR"
# Build Toxcore
cd "$BUILD_DIR"
# The git hash of the c-toxcore version we're using
TOXCORE_VERSION="25a56c354937e9c8c4c50a64c3b4cfc099c34e29"
TOXCORE_HASH="78749dccfd2e6ec95d59d7a07c882aa034754a9ff62113b95281927e71b42574"
# The sha256sum of the c-toxcore tarball for TOXCORE_VERSION
TOXCORE_HASH="8448752e6286c747130254571fde2db8e2fc073a8116f9fff489ed53af546c0a"
TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz"
wget --timeout=10 -O "$TOXCORE_FILENAME" "https://github.com/TokTok/c-toxcore/archive/master.tar.gz"
wget --timeout=10 -O "$TOXCORE_FILENAME" "https://github.com/TokTok/c-toxcore/archive/$TOXCORE_VERSION.tar.gz"
check_sha256 "$TOXCORE_HASH" "$TOXCORE_FILENAME"
tar -o -xf "$TOXCORE_FILENAME"
rm "$TOXCORE_FILENAME"
@ -160,8 +164,8 @@ cmake --build _build --target install
# location with SSL_CERT_FILE env variable.
cd "$BUILD_DIR"
CURL_VERSION="7.74.0"
CURL_HASH="e56b3921eeb7a2951959c02db0912b5fcd5fdba5aca071da819e1accf338bbd7"
CURL_VERSION="7.77.0"
CURL_HASH="b0a3428acb60fa59044c4d0baae4e4fc09ae9af1d8a3aa84b2e3fbcd99841f77"
CURL_FILENAME="curl-$CURL_VERSION.tar.gz"
wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME"
@ -178,7 +182,8 @@ cd curl*
--without-ca-path \
--with-ca-fallback \
--with-nghttp2 \
--with-brotli
--with-brotli \
--with-openssl
make
make install
sed -i 's|-lbrotlidec |-lbrotlidec-static -lbrotlicommon-static |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc

View File

@ -1072,13 +1072,12 @@ static void draw_infobox(ToxWindow *self)
time_t curtime = get_unix_time();
/* update elapsed time string once per second */
if (curtime > infobox->lastupdate) {
/* update interface once per second */
if (timed_out(infobox->lastupdate, 1)) {
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 *out_is_muted = infobox->out_is_muted ? "yes" : "no";
@ -1307,12 +1306,14 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
break;
}
const char *connection_status_s = statusbar->connection == TOX_CONNECTION_TCP ? "TCP" : "UDP";
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, " [");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
wprintw(statusbar->topline, "%s", ONLINE_CHAR);
wprintw(statusbar->topline, "%s", connection_status_s);
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
@ -1342,7 +1343,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wprintw(statusbar->topline, "%s", OFFLINE_CHAR);
wprintw(statusbar->topline, "Offline");
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));

View File

@ -540,20 +540,20 @@ static void game_draw_border(const GameData *game, const int max_x, const int ma
const int x = (max_x - game_max_x) / 2;
const int y = (max_y - game_max_y) / 2;
wattron(win, A_BOLD | COLOR_PAIR(GAME_BORDER_COLOUR));
wattron(win, COLOR_PAIR(GAME_BORDER_COLOUR));
mvwaddch(win, y, x, ' ');
mvwhline(win, y, x + 1, ' ', game_max_x - 1);
mvwvline(win, y + 1, x, ' ', game_max_y - 1);
mvwvline(win, y, x - 1, ' ', game_max_y + 1);
mvwaddch(win, y, x + game_max_x, ' ');
mvwvline(win, y + 1, x + game_max_x, ' ', game_max_y - 1);
mvwvline(win, y, x + game_max_x + 1, ' ', game_max_y + 1);
mvwaddch(win, y + game_max_y, x, ' ');
mvwhline(win, y + game_max_y, x + 1, ' ', game_max_x - 1);
mvwaddch(win, y + game_max_y, x + game_max_x, ' ');
mvwaddch(win, y, x, ACS_ULCORNER);
mvwhline(win, y, x + 1, ACS_HLINE, game_max_x - 1);
mvwvline(win, y + 1, x, ACS_VLINE, game_max_y - 1);
mvwvline(win, y, x - 1, ACS_VLINE, game_max_y + 1);
mvwaddch(win, y, x + game_max_x, ACS_URCORNER);
mvwvline(win, y + 1, x + game_max_x, ACS_VLINE, game_max_y - 1);
mvwvline(win, y, x + game_max_x + 1, ACS_VLINE, game_max_y + 1);
mvwaddch(win, y + game_max_y, x, ACS_LLCORNER);
mvwhline(win, y + game_max_y, x + 1, ACS_HLINE, game_max_x - 1);
mvwaddch(win, y + game_max_y, x + game_max_x, ACS_LRCORNER);
wattroff(win, A_BOLD | COLOR_PAIR(GAME_BORDER_COLOUR));
wattroff(win, COLOR_PAIR(GAME_BORDER_COLOUR));
}
static void game_draw_status(const GameData *game, const int max_x, const int max_y)
@ -561,7 +561,7 @@ static void game_draw_status(const GameData *game, const int max_x, const int ma
WINDOW *win = game->window;
int x = ((max_x - game->game_max_x) / 2) - 1;
int y = ((max_y - game->game_max_y) / 2) - 1;
const int y = ((max_y - game->game_max_y) / 2) - 1;
wattron(win, A_BOLD);

View File

@ -31,7 +31,7 @@
#include "game_util.h"
#include "windows.h"
#define GAME_BORDER_COLOUR BAR_TEXT
#define GAME_BORDER_COLOUR BAR_SOLID
/* Max size of a default square game window */

View File

@ -1626,11 +1626,11 @@ static void chess_print_status(WINDOW *win, ChessState *state)
}
int x_mid = (board->x_left_bound + (CHESS_TILE_SIZE_X * (CHESS_BOARD_COLUMNS / 2))) - (strlen(message) / 2);
mvwprintw(win, board->y_top_bound - 2, x_mid, message);
mvwprintw(win, board->y_top_bound - 2, x_mid, "%s", message);
if (state->message_length > 0) {
x_mid = (board->x_left_bound + (CHESS_TILE_SIZE_X * (CHESS_BOARD_COLUMNS / 2))) - (state->message_length / 2);
mvwprintw(win, board->y_bottom_bound + 2, x_mid, state->status_message);
mvwprintw(win, board->y_bottom_bound + 2, x_mid, "%s", state->status_message);
}
wattroff(win, A_BOLD);

View File

@ -174,7 +174,7 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /decline <id> : Decline friend request\n");
wprintw(win, " /requests : List pending friend requests\n");
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
wprintw(win, " /status <type> <msg> : Set status with optional note\n");
wprintw(win, " /status <type> : Set status (Online, Busy, Away)\n");
wprintw(win, " /note <msg> : Set a personal note\n");
wprintw(win, " /nick <nick> : Set your nickname\n");
wprintw(win, " /nospam <value> : Change part of your Tox ID to stop spam\n");

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;
}

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;
flag_interface_change(1);
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);
if (line == NULL) {
flag_interface_change(0);
return;
}
@ -469,6 +472,8 @@ static void line_info_check_queue(ToxWindow *self)
if (!self->scroll_pause) {
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 */
@ -763,6 +768,8 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
line = line->prev;
}
flag_interface_change(1);
}
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;
self->scroll_pause = true;
}
flag_interface_change(1);
}
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 {
line_info_reset_start(self, hst);
}
flag_interface_change(1);
}
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;
flag_interface_change(1);
}
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;
next = hst->line_start->next;
}
flag_interface_change(1);
}
bool line_info_onKey(ToxWindow *self, wint_t key)
@ -855,6 +870,10 @@ bool line_info_onKey(ToxWindow *self, wint_t key)
match = false;
}
if (match) {
flag_interface_change(1);
}
return match;
}
@ -862,4 +881,6 @@ void line_info_clear(struct history *hst)
{
hst->line_start = hst->line_end;
hst->start_id = hst->line_start->id;
flag_interface_change(1);
}

View File

@ -383,6 +383,7 @@ static void init_term(void)
init_pair(BLACK_BG, COLOR_BLACK, bar_bg_color);
init_pair(PURPLE_BG, COLOR_MAGENTA, bar_bg_color);
init_pair(BAR_TEXT, bar_fg_color, bar_bg_color);
init_pair(BAR_SOLID, bar_bg_color, bar_bg_color);
init_pair(BAR_ACCENT, bar_accent_color, bar_bg_color);
init_pair(BAR_NOTIFY, bar_notify_color, bar_bg_color);
init_pair(STATUS_ONLINE, COLOR_GREEN, bar_bg_color);
@ -1071,8 +1072,24 @@ static void do_toxic(Tox *m)
pthread_mutex_unlock(&Winthread.lock);
}
/* How often we refresh windows that aren't focused */
#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)
{
Tox *m = (Tox *) data;
@ -1081,8 +1098,8 @@ void *thread_winref(void *data)
init_signal_catchers();
while (true) {
draw_active_window(m);
draw_count++;
draw_active_window(m);
if (Winthread.flag_resize) {
on_window_resize();
@ -1203,21 +1220,23 @@ static void parse_args(int argc, char *argv[])
};
const char *opts_str = "4bdehLotuxvc:f:l:n:r:p:P:T:";
int opt, indexptr;
long int port = 0;
int opt = 0;
int indexptr = 0;
while ((opt = getopt_long(argc, argv, opts_str, long_opts, &indexptr)) != -1) {
switch (opt) {
case '4':
case '4': {
arg_opts.use_ipv4 = 1;
break;
}
case 'b':
case 'b': {
arg_opts.debug = 1;
queue_init_message("stderr enabled");
break;
}
case 'c':
case 'c': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
@ -1230,17 +1249,20 @@ static void parse_args(int argc, char *argv[])
}
break;
}
case 'd':
case 'd': {
arg_opts.default_locale = 1;
queue_init_message("Using default POSIX locale");
break;
}
case 'e':
case 'e': {
arg_opts.encrypt_data = 1;
break;
}
case 'f':
case 'f': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
@ -1278,8 +1300,9 @@ static void parse_args(int argc, char *argv[])
queue_init_message("Using '%s' data file", DATA_FILE);
break;
}
case 'l':
case 'l': {
if (optarg) {
arg_opts.logging = true;
@ -1299,13 +1322,15 @@ static void parse_args(int argc, char *argv[])
}
break;
}
case 'L':
case 'L': {
arg_opts.disable_local_discovery = 1;
queue_init_message("Local discovery disabled");
break;
}
case 'n':
case 'n': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
@ -1313,48 +1338,38 @@ static void parse_args(int argc, char *argv[])
snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg);
break;
}
case 'o':
case 'o': {
arg_opts.no_connect = 1;
queue_init_message("DHT disabled");
break;
}
case 'p':
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
}
case 'p': {
arg_opts.proxy_type = TOX_PROXY_TYPE_SOCKS5;
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
}
if (++optind > argc || argv[optind - 1][0] == '-') {
exit_toxic_err("Proxy error", FATALERR_PROXY);
}
// Intentional fallthrough
port = strtol(argv[optind - 1], NULL, 10);
if (port <= 0 || port > MAX_PORT_RANGE) {
exit_toxic_err("Proxy error", FATALERR_PROXY);
}
arg_opts.proxy_port = port;
break;
case 'P':
case 'P': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
arg_opts.proxy_type = TOX_PROXY_TYPE_NONE;
break;
}
arg_opts.proxy_type = TOX_PROXY_TYPE_HTTP;
if (arg_opts.proxy_type == TOX_PROXY_TYPE_NONE) {
arg_opts.proxy_type = TOX_PROXY_TYPE_HTTP;
}
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
if (++optind > argc || argv[optind - 1][0] == '-') {
exit_toxic_err("Proxy error", FATALERR_PROXY);
}
port = strtol(argv[optind - 1], NULL, 10);
long int port = strtol(argv[optind - 1], NULL, 10);
if (port <= 0 || port > MAX_PORT_RANGE) {
exit_toxic_err("Proxy error", FATALERR_PROXY);
@ -1362,8 +1377,9 @@ static void parse_args(int argc, char *argv[])
arg_opts.proxy_port = port;
break;
}
case 'r':
case 'r': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
@ -1376,18 +1392,20 @@ static void parse_args(int argc, char *argv[])
}
break;
}
case 't':
case 't': {
arg_opts.force_tcp = 1;
break;
}
case 'T':
case 'T': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
}
port = strtol(optarg, NULL, 10);
long int port = strtol(optarg, NULL, 10);
if (port <= 0 || port > MAX_PORT_RANGE) {
port = MAX_PORT_RANGE;
@ -1395,21 +1413,25 @@ static void parse_args(int argc, char *argv[])
arg_opts.tcp_port = port;
break;
}
case 'u':
case 'u': {
arg_opts.unencrypt_data = 1;
break;
}
case 'v':
case 'v': {
print_version();
exit(EXIT_SUCCESS);
}
case 'h':
// Intentional fallthrough
default:
default: {
print_usage();
exit(EXIT_SUCCESS);
}
}
}
}
@ -1464,6 +1486,8 @@ int main(int argc, char **argv)
/* Make sure all written files are read/writeable only by the current user. */
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
parse_args(argc, argv);

View File

@ -102,6 +102,8 @@ typedef enum _FATAL_ERRS {
void lock_status(void);
void unlock_status(void);
void flag_interface_change(unsigned int flag);
void exit_toxic_success(Tox *m);
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);
}
}
flag_interface_change(1);
}
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);
}
}
flag_interface_change(1);
}
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);
}
@ -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);
}
}
flag_interface_change(1);
}
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);
}
}
flag_interface_change(1);
}
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);
}
}
flag_interface_change(1);
}
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)
{
uint8_t index = 0;
if (ch == user_settings->key_next_tab) {
for (uint8_t i = active_window_index + 1; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL) {
set_active_window_index(i);
return;
index = i;
break;
}
}
} else {
@ -435,13 +449,15 @@ void set_next_window(int ch)
for (uint8_t i = start; i > 0; --i) {
if (windows[i] != NULL) {
set_active_window_index(i);
return;
index = i;
break;
}
}
}
set_active_window_index(0);
set_active_window_index(index);
flag_interface_change(1);
}
/* Deletes window w and cleans up */
@ -784,21 +800,33 @@ void draw_active_window(Tox *m)
pthread_mutex_lock(&Winthread.lock);
a->alert = WINDOW_ALERT_NONE;
a->pending_messages = 0;
bool flag_refresh = Winthread.flag_refresh;
pthread_mutex_unlock(&Winthread.lock);
touchwin(a->window);
a->onDraw(a, m);
wrefresh(a->window);
if (flag_refresh || (a->is_call && timed_out(a->chatwin->infobox.lastupdate, 1))) {
touchwin(a->window);
a->onDraw(a, m);
wrefresh(a->window);
}
#ifdef GAMES
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();
if (ch == ERR) {
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) {
set_next_window(ch);
}
@ -817,6 +845,10 @@ void draw_active_window(Tox *m)
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)) {
set_next_window((int) ch);
return;

View File

@ -72,6 +72,7 @@ typedef enum {
STATUS_BUSY,
STATUS_AWAY,
BAR_NOTIFY,
BAR_SOLID,
} C_COLOURS;
/* tab alert types: lower types take priority (this relies on the order of C_COLOURS) */
@ -102,6 +103,8 @@ struct Winthread {
pthread_mutex_t lock;
volatile sig_atomic_t sig_exit_toxic;
volatile sig_atomic_t flag_resize;
volatile sig_atomic_t flag_refresh;
volatile sig_atomic_t flag_refresh_timeout;
};
struct cqueue_thread {