mirror of
https://github.com/Tha14/toxic.git
synced 2024-12-26 01:53:25 +01:00
Interface improvements and bump to v0.10.0
- Give window tab and statusbar a make over - Place window tab above input field - Reduce input field to one square in height - Refactor window tab so that it's now a subwin of its parent ToxWindow - Fix bug causing notification counter to sometimes increment by 2 - No longer scroll on output when output is not at bottom of screen - Show a small indicator on far left of window tab when output is not at bottom of screen - Reduce ncurses/UI thread sleep time by half - Handle nanosleep errors better
This commit is contained in:
parent
61740bda85
commit
1e985c1456
2
Makefile
2
Makefile
@ -30,7 +30,7 @@ endif
|
||||
# Check if LLVM Address Sanitizer is enabled
|
||||
ASAN_ENABLED := $(shell if [ -z "$(ENABLE_ASAN)" ] || [ "$(ENABLE_ASAN)" = "0" ] ; then echo disabled ; else echo enabled ; fi)
|
||||
ifneq ($(ASAN_ENABLED), disabled)
|
||||
CFLAGS += -fsanitize=address -fno-omit-frame-pointer -mllvm -asan-use-private-alias=1 -Wno-unused-command-line-argument
|
||||
CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||
endif
|
||||
|
||||
# Check on wich system we are running
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
Toxic is a [Tox](https://tox.chat)-based instant messaging and video chat client.
|
||||
|
||||
[![Toxic Screenshot](https://i.imgur.com/5S577z6.png "Toxic Audio Conference")](https://i.imgur.com/5S577z6.png)
|
||||
[![Toxic Screenshot](https://i.imgur.com/TwYA8L0.png "Toxic Home Screen")](https://i.imgur.com/TwYA8L0.png)
|
||||
|
||||
## Installation
|
||||
[See the install instructions](/INSTALL.md)
|
||||
|
@ -55,9 +55,9 @@ author = 'Jakob Kreuze'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.9.1'
|
||||
version = '0.10.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.9.1'
|
||||
release = '0.10.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Version
|
||||
TOXIC_VERSION = 0.9.1
|
||||
TOXIC_VERSION = 0.10.0
|
||||
REV = $(shell git rev-list HEAD --count 2>/dev/null || echo -n "error")
|
||||
ifneq (, $(findstring error, $(REV)))
|
||||
VERSION = $(TOXIC_VERSION)
|
||||
|
123
src/chat.c
123
src/chat.c
@ -745,17 +745,17 @@ static void chat_onConferenceInvite(ToxWindow *self, Tox *m, int32_t friendnumbe
|
||||
Friends.list[friendnumber].conference_invite.length = length;
|
||||
Friends.list[friendnumber].conference_invite.type = type;
|
||||
|
||||
sound_notify(self, generic_message, NT_WNDALERT_2 | user_settings->bell_on_invite, NULL);
|
||||
|
||||
char name[TOX_MAX_NAME_LENGTH];
|
||||
get_nick_truncate(m, name, friendnumber);
|
||||
|
||||
const char *description = type == TOX_CONFERENCE_TYPE_AV ? "an audio conference" : "a conference";
|
||||
|
||||
if (self->active_box != -1) {
|
||||
box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, "invites you to join %s", description);
|
||||
box_notify2(self, generic_message, NT_WNDALERT_2 | user_settings->bell_on_invite, self->active_box,
|
||||
"invites you to join %s", description);
|
||||
} else {
|
||||
box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join %s", description);
|
||||
box_notify(self, generic_message, NT_WNDALERT_2 | user_settings->bell_on_invite, &self->active_box, name,
|
||||
"invites you to join %s", description);
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to %s.", name, description);
|
||||
@ -1181,7 +1181,7 @@ bool chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
}
|
||||
|
||||
wclear(ctx->linewin);
|
||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||
wmove(self->window, y2, 0);
|
||||
reset_buf(ctx);
|
||||
}
|
||||
|
||||
@ -1194,7 +1194,8 @@ bool chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
|
||||
static void chat_onDraw(ToxWindow *self, Tox *m)
|
||||
{
|
||||
int x2, y2;
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
@ -1209,15 +1210,14 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
||||
|
||||
wclear(ctx->linewin);
|
||||
|
||||
curs_set(1);
|
||||
|
||||
if (ctx->len > 0) {
|
||||
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
||||
mvwprintw(ctx->linewin, 0, 0, "%ls", &ctx->line[ctx->start]);
|
||||
}
|
||||
|
||||
curs_set(1);
|
||||
|
||||
/* Draw status bar */
|
||||
StatusBar *statusbar = self->stb;
|
||||
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
|
||||
wmove(statusbar->topline, 0, 0);
|
||||
|
||||
/* Draw name, status and note in statusbar */
|
||||
@ -1227,38 +1227,63 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
||||
|
||||
switch (status) {
|
||||
case TOX_USER_STATUS_NONE:
|
||||
colour = GREEN;
|
||||
colour = GREEN_BLUE;
|
||||
break;
|
||||
|
||||
case TOX_USER_STATUS_AWAY:
|
||||
colour = YELLOW;
|
||||
colour = YELLOW_BLUE;
|
||||
break;
|
||||
|
||||
case TOX_USER_STATUS_BUSY:
|
||||
colour = RED;
|
||||
colour = RED_BLUE;
|
||||
break;
|
||||
}
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, " [");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
|
||||
wprintw(statusbar->topline, " %s", ONLINE_CHAR);
|
||||
wprintw(statusbar->topline, "%s", ONLINE_CHAR);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
|
||||
|
||||
if (Friends.list[self->num].is_typing) {
|
||||
wattron(statusbar->topline, COLOR_PAIR(YELLOW));
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, "] ");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
const bool is_typing = Friends.list[self->num].is_typing;
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
if (is_typing) {
|
||||
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(YELLOW_BLUE));
|
||||
} else {
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
|
||||
wattron(statusbar->topline, A_BOLD);
|
||||
wprintw(statusbar->topline, " %s ", statusbar->nick);
|
||||
wattroff(statusbar->topline, A_BOLD);
|
||||
wprintw(statusbar->topline, "%s", statusbar->nick);
|
||||
|
||||
if (Friends.list[self->num].is_typing) {
|
||||
wattroff(statusbar->topline, COLOR_PAIR(YELLOW));
|
||||
if (is_typing) {
|
||||
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(YELLOW_BLUE));
|
||||
} else {
|
||||
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
} else {
|
||||
wprintw(statusbar->topline, " %s", OFFLINE_CHAR);
|
||||
wattron(statusbar->topline, A_BOLD);
|
||||
wprintw(statusbar->topline, " %s ", statusbar->nick);
|
||||
wattroff(statusbar->topline, A_BOLD);
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, " [");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
wprintw(statusbar->topline, "%s", OFFLINE_CHAR);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, "] ");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
wprintw(statusbar->topline, "%s", statusbar->nick);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
|
||||
/* Reset statusbar->statusmsg on window resize */
|
||||
@ -1287,30 +1312,51 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
||||
}
|
||||
|
||||
if (statusbar->statusmsg[0]) {
|
||||
wprintw(statusbar->topline, ": %s ", statusbar->statusmsg);
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, " | ");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
wprintw(statusbar->topline, "%s ", statusbar->statusmsg);
|
||||
} else {
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
|
||||
wclrtoeol(statusbar->topline);
|
||||
int s_y;
|
||||
int s_x;
|
||||
getyx(statusbar->topline, s_y, s_x);
|
||||
|
||||
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - (KEY_IDENT_DIGITS * 2) - 3);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3);
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, "{");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
size_t i;
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
for (i = 0; i < KEY_IDENT_DIGITS; ++i) {
|
||||
for (size_t i = 0; i < KEY_IDENT_DIGITS; ++i) {
|
||||
wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff);
|
||||
}
|
||||
|
||||
wprintw(statusbar->topline, "}\n");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, "} ");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
int y, x;
|
||||
int y;
|
||||
int x;
|
||||
getyx(self->window, y, x);
|
||||
|
||||
UNUSED_VAR(x);
|
||||
|
||||
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
|
||||
wmove(self->window, y + 1, new_x);
|
||||
wmove(self->window, y, new_x);
|
||||
|
||||
draw_window_bar(self);
|
||||
|
||||
wnoutrefresh(self->window);
|
||||
|
||||
@ -1357,7 +1403,9 @@ static void chat_init_log(ToxWindow *self, Tox *m, const char *self_nick)
|
||||
static void chat_onInit(ToxWindow *self, Tox *m)
|
||||
{
|
||||
curs_set(1);
|
||||
int x2, y2;
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
@ -1390,9 +1438,10 @@ static void chat_onInit(ToxWindow *self, Tox *m)
|
||||
/* Init subwindows */
|
||||
ChatContext *ctx = self->chatwin;
|
||||
|
||||
statusbar->topline = subwin(self->window, 2, x2, 0, 0);
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
|
||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
||||
statusbar->topline = subwin(self->window, TOP_BAR_HEIGHT, x2, 0, 0);
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0);
|
||||
self->window_bar = subwin(self->window, WINDOW_BAR_HEIGHT, x2, y2 - (CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT), 0);
|
||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - WINDOW_BAR_HEIGHT, 0);
|
||||
|
||||
ctx->hst = calloc(1, sizeof(struct history));
|
||||
ctx->log = calloc(1, sizeof(struct chatlog));
|
||||
|
@ -307,9 +307,9 @@ void redraw_conference_win(ToxWindow *self)
|
||||
refresh();
|
||||
clear();
|
||||
|
||||
int x2, y2;
|
||||
getmaxyx(stdscr, y2, x2);
|
||||
y2 -= 2;
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
return;
|
||||
@ -322,20 +322,22 @@ void redraw_conference_win(ToxWindow *self)
|
||||
|
||||
delwin(ctx->linewin);
|
||||
delwin(ctx->history);
|
||||
delwin(self->window_bar);
|
||||
delwin(self->window);
|
||||
|
||||
self->window = newwin(y2, x2, 0, 0);
|
||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
||||
self->window_bar = subwin(self->window, WINDOW_BAR_HEIGHT, x2, y2 - (CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT), 0);
|
||||
|
||||
if (self->show_peerlist) {
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||
ctx->sidebar = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, SIDEBAR_WIDTH, 0, x2 - SIDEBAR_WIDTH);
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||
ctx->sidebar = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, SIDEBAR_WIDTH, 0, x2 - SIDEBAR_WIDTH);
|
||||
} else {
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0);
|
||||
}
|
||||
|
||||
scrollok(ctx->history, 0);
|
||||
|
||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||
}
|
||||
|
||||
static void conference_onConferenceMessage(ToxWindow *self, Tox *m, uint32_t conferencenum, uint32_t peernum,
|
||||
@ -362,12 +364,12 @@ static void conference_onConferenceMessage(ToxWindow *self, Tox *m, uint32_t con
|
||||
|
||||
/* Only play sound if mentioned by someone else */
|
||||
if (strcasestr(msg, selfnick) && strcmp(selfnick, nick)) {
|
||||
sound_notify(self, generic_message, NT_WNDALERT_0 | user_settings->bell_on_message, NULL);
|
||||
|
||||
if (self->active_box != -1) {
|
||||
box_silent_notify2(self, NT_NOFOCUS, self->active_box, "%s %s", nick, msg);
|
||||
box_notify2(self, generic_message, NT_WNDALERT_0 | NT_NOFOCUS | user_settings->bell_on_message,
|
||||
self->active_box, "%s %s", nick, msg);
|
||||
} else {
|
||||
box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "%s %s", nick, msg);
|
||||
box_notify(self, generic_message, NT_WNDALERT_0 | NT_NOFOCUS | user_settings->bell_on_message,
|
||||
&self->active_box, self->name, "%s %s", nick, msg);
|
||||
}
|
||||
|
||||
nick_clr = RED;
|
||||
@ -963,7 +965,7 @@ static bool conference_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
}
|
||||
|
||||
wclear(ctx->linewin);
|
||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||
wmove(self->window, y2, 0);
|
||||
reset_buf(ctx);
|
||||
}
|
||||
|
||||
@ -1049,15 +1051,16 @@ static void conference_onDraw(ToxWindow *self, Tox *m)
|
||||
curs_set(1);
|
||||
|
||||
if (ctx->len > 0) {
|
||||
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
||||
mvwprintw(ctx->linewin, 0, 0, "%ls", &ctx->line[ctx->start]);
|
||||
}
|
||||
|
||||
wclear(ctx->sidebar);
|
||||
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
|
||||
|
||||
if (self->show_peerlist) {
|
||||
wattron(ctx->sidebar, COLOR_PAIR(BLUE));
|
||||
mvwvline(ctx->sidebar, 0, 0, ACS_VLINE, y2 - CHATBOX_HEIGHT);
|
||||
mvwaddch(ctx->sidebar, y2 - CHATBOX_HEIGHT, 0, ACS_BTEE);
|
||||
wattroff(ctx->sidebar, COLOR_PAIR(BLUE));
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
const uint32_t num_peers = chat->num_peers;
|
||||
@ -1117,8 +1120,11 @@ static void conference_onDraw(ToxWindow *self, Tox *m)
|
||||
wattroff(ctx->sidebar, A_BOLD);
|
||||
++line;
|
||||
|
||||
wattron(ctx->sidebar, COLOR_PAIR(BLUE));
|
||||
mvwaddch(ctx->sidebar, line, 0, ACS_LTEE);
|
||||
mvwhline(ctx->sidebar, line, 1, ACS_HLINE, SIDEBAR_WIDTH - 1);
|
||||
wattroff(ctx->sidebar, COLOR_PAIR(BLUE));
|
||||
|
||||
++line;
|
||||
|
||||
for (uint32_t i = 0;
|
||||
@ -1135,7 +1141,9 @@ static void conference_onDraw(ToxWindow *self, Tox *m)
|
||||
UNUSED_VAR(x);
|
||||
|
||||
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
|
||||
wmove(self->window, y + 1, new_x);
|
||||
wmove(self->window, y, new_x);
|
||||
|
||||
draw_window_bar(self);
|
||||
|
||||
wnoutrefresh(self->window);
|
||||
|
||||
@ -1155,9 +1163,10 @@ static void conference_onInit(ToxWindow *self, Tox *m)
|
||||
|
||||
ChatContext *ctx = self->chatwin;
|
||||
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||
self->window_bar = subwin(self->window, WINDOW_BAR_HEIGHT, x2, y2 - (CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT), 0);
|
||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
||||
ctx->sidebar = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, SIDEBAR_WIDTH, 0, x2 - SIDEBAR_WIDTH);
|
||||
ctx->sidebar = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, SIDEBAR_WIDTH, 0, x2 - SIDEBAR_WIDTH);
|
||||
|
||||
ctx->hst = calloc(1, sizeof(struct history));
|
||||
ctx->log = calloc(1, sizeof(struct chatlog));
|
||||
|
@ -1022,7 +1022,7 @@ static void blocklist_onDraw(ToxWindow *self, Tox *m, int y2, int x2)
|
||||
wmove(self->window, y2 - 1, 1);
|
||||
|
||||
wattron(self->window, A_BOLD);
|
||||
wprintw(self->window, "Key: ");
|
||||
wprintw(self->window, "Public key: ");
|
||||
wattroff(self->window, A_BOLD);
|
||||
|
||||
int i;
|
||||
@ -1057,6 +1057,8 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
||||
wprintw(self->window, "key for help\n\n");
|
||||
wattroff(self->window, COLOR_PAIR(CYAN));
|
||||
|
||||
draw_window_bar(self);
|
||||
|
||||
if (blocklist_view == 1) {
|
||||
blocklist_onDraw(self, m, y2, x2);
|
||||
return;
|
||||
@ -1247,7 +1249,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
||||
wmove(self->window, y2 - 1, 1);
|
||||
|
||||
wattron(self->window, A_BOLD);
|
||||
wprintw(self->window, "Key: ");
|
||||
wprintw(self->window, "Public key: ");
|
||||
wattroff(self->window, A_BOLD);
|
||||
|
||||
int i;
|
||||
@ -1265,6 +1267,21 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
||||
}
|
||||
}
|
||||
|
||||
void friendlist_onInit(ToxWindow *self, Tox *m)
|
||||
{
|
||||
UNUSED_VAR(m);
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
exit_toxic_err("failed in friendlist_onInit", FATALERR_CURSES);
|
||||
}
|
||||
|
||||
self->window_bar = subwin(self->window, WINDOW_BAR_HEIGHT, x2, y2 - 2, 0);
|
||||
}
|
||||
|
||||
void disable_chatwin(uint32_t f_num)
|
||||
{
|
||||
Friends.list[f_num].chatwin = -1;
|
||||
@ -1343,6 +1360,7 @@ ToxWindow *new_friendlist(void)
|
||||
|
||||
ret->type = WINDOW_TYPE_FRIEND_LIST;
|
||||
|
||||
ret->onInit = &friendlist_onInit;
|
||||
ret->onKey = &friendlist_onKey;
|
||||
ret->onDraw = &friendlist_onDraw;
|
||||
ret->onFriendAdded = &friendlist_onFriendAdded;
|
||||
|
@ -82,6 +82,7 @@ typedef struct {
|
||||
} FriendsList;
|
||||
|
||||
ToxWindow *new_friendlist(void);
|
||||
void friendlist_onInit(ToxWindow *self, Tox *m);
|
||||
void disable_chatwin(uint32_t f_num);
|
||||
int get_friendnum(uint8_t *name);
|
||||
int load_blocklist(char *data);
|
||||
|
249
src/line_info.c
249
src/line_info.c
@ -63,10 +63,10 @@ void line_info_reset_start(ToxWindow *self, struct history *hst)
|
||||
getmaxyx(self->window, y2, x2);
|
||||
UNUSED_VAR(x2);
|
||||
|
||||
int top_offst = (self->type == WINDOW_TYPE_CHAT) || (self->type == WINDOW_TYPE_PROMPT) ? 2 : 0;
|
||||
int max_y = y2 - CHATBOX_HEIGHT - top_offst;
|
||||
int top_offst = (self->type == WINDOW_TYPE_CHAT) || (self->type == WINDOW_TYPE_PROMPT) ? TOP_BAR_HEIGHT : 0;
|
||||
int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT - top_offst;
|
||||
|
||||
int curlines = 0;
|
||||
uint16_t curlines = 0;
|
||||
|
||||
do {
|
||||
curlines += line->format_lines;
|
||||
@ -74,6 +74,8 @@ void line_info_reset_start(ToxWindow *self, struct history *hst)
|
||||
} while (line->prev && curlines + line->format_lines <= max_y);
|
||||
|
||||
hst->line_start = line;
|
||||
|
||||
self->scroll_pause = false;
|
||||
}
|
||||
|
||||
void line_info_cleanup(struct history *hst)
|
||||
@ -131,20 +133,32 @@ static struct line_info *line_info_ret_queue(struct history *hst)
|
||||
|
||||
/* Prints a maximum of `n` chars from `s` to `win`.
|
||||
*
|
||||
* Return true if the string contains a newline or tab byte.
|
||||
* Return 1 if the string contains a newline byte.
|
||||
* Return 0 if string does not contain a newline byte.
|
||||
* Return -1 if printing was aborted.
|
||||
*/
|
||||
static bool print_n_chars(WINDOW *win, const char *s, size_t n)
|
||||
static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y)
|
||||
{
|
||||
bool newline = false;
|
||||
char ch;
|
||||
|
||||
for (size_t i = 0; i < n && (ch = s[i]); ++i) {
|
||||
if (win) {
|
||||
wprintw(win, "%c", ch);
|
||||
}
|
||||
|
||||
if (ch == '\n') {
|
||||
newline = true;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
UNUSED_VAR(x);
|
||||
getyx(win, y, x);
|
||||
|
||||
// make sure cursor will wrap correctly after newline to prevent display bugs
|
||||
if (y + 1 >= max_y) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (win) {
|
||||
wprintw(win, "%c", ch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,24 +215,42 @@ static unsigned int newline_count(const char *s)
|
||||
*
|
||||
* If `win` is null nothing will be printed to the window. This is useful to set the
|
||||
* `format_lines` field on initialization.
|
||||
*
|
||||
* Return 0 on success.
|
||||
* Return -1 if not all characters in line's message were printed to screen.
|
||||
*/
|
||||
static void print_wrap(WINDOW *win, struct line_info *line, int max_x)
|
||||
static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
UNUSED_VAR(y);
|
||||
|
||||
const char *msg = line->msg;
|
||||
uint16_t length = line->msg_len;
|
||||
uint16_t lines = 0;
|
||||
const int x_start = line->len - line->msg_len - 1; // manually keep track of x position because ncurses sucks
|
||||
int x_limit = max_x - x_start;
|
||||
|
||||
if (x_limit <= 0) {
|
||||
if (x_limit <= 1) {
|
||||
fprintf(stderr, "Warning: x_limit <= 0 in print_wrap(): %d\n", x_limit);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (msg) {
|
||||
getyx(win, y, x);
|
||||
|
||||
// next line would print past window limit so we abort; we don't want to update format_lines
|
||||
if (x > x_start) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length < x_limit) {
|
||||
if (print_n_chars(win, msg, length)) {
|
||||
int p_ret = print_n_chars(win, msg, length, max_y);
|
||||
|
||||
if (p_ret == 1) {
|
||||
lines += newline_count(msg);
|
||||
} else if (p_ret == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
++lines;
|
||||
@ -228,8 +260,11 @@ static void print_wrap(WINDOW *win, struct line_info *line, int max_x)
|
||||
int newline_idx = newline_index(msg, x_limit - 1);
|
||||
|
||||
if (newline_idx >= 0) {
|
||||
print_n_chars(win, msg, newline_idx + 1);
|
||||
msg += newline_idx + 1;
|
||||
if (print_n_chars(win, msg, newline_idx + 1, max_y) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg += (newline_idx + 1);
|
||||
length -= (newline_idx + 1);
|
||||
x_limit = max_x; // if we find a newline we stop adding column padding for rest of message
|
||||
++lines;
|
||||
@ -239,7 +274,10 @@ static void print_wrap(WINDOW *win, struct line_info *line, int max_x)
|
||||
int space_idx = rspace_index(msg, x_limit - 1);
|
||||
|
||||
if (space_idx >= 1) {
|
||||
print_n_chars(win, msg, space_idx);
|
||||
if (print_n_chars(win, msg, space_idx, max_y) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg += space_idx + 1;
|
||||
length -= (space_idx + 1);
|
||||
|
||||
@ -247,7 +285,10 @@ static void print_wrap(WINDOW *win, struct line_info *line, int max_x)
|
||||
waddch(win, '\n');
|
||||
}
|
||||
} else {
|
||||
print_n_chars(win, msg, x_limit);
|
||||
if (print_n_chars(win, msg, x_limit, max_y) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg += x_limit;
|
||||
length -= x_limit;
|
||||
}
|
||||
@ -263,10 +304,6 @@ static void print_wrap(WINDOW *win, struct line_info *line, int max_x)
|
||||
}
|
||||
|
||||
if (win && line->noread_flag) {
|
||||
int x;
|
||||
int y;
|
||||
UNUSED_VAR(y);
|
||||
|
||||
getyx(win, y, x);
|
||||
|
||||
if (x >= max_x - 1 || x == x_start) {
|
||||
@ -279,17 +316,22 @@ static void print_wrap(WINDOW *win, struct line_info *line, int max_x)
|
||||
}
|
||||
|
||||
line->format_lines = lines;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void line_info_init_line(WINDOW *win, struct line_info *line)
|
||||
static void line_info_init_line(ToxWindow *self, struct line_info *line)
|
||||
{
|
||||
int max_y;
|
||||
int max_x;
|
||||
UNUSED_VAR(max_y);
|
||||
int y2;
|
||||
int x2;
|
||||
UNUSED_VAR(y2);
|
||||
|
||||
getmaxyx(win, max_y, max_x);
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
print_wrap(NULL, line, max_x);
|
||||
const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT;
|
||||
const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2;
|
||||
|
||||
print_wrap(NULL, line, max_x, max_y);
|
||||
}
|
||||
|
||||
/* creates new line_info line and puts it in the queue.
|
||||
@ -358,7 +400,7 @@ int line_info_add(ToxWindow *self, const char *timestr, const char *name1, const
|
||||
break;
|
||||
|
||||
case PROMPT:
|
||||
++len;
|
||||
len += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -398,7 +440,7 @@ int line_info_add(ToxWindow *self, const char *timestr, const char *name1, const
|
||||
new_line->noread_flag = false;
|
||||
new_line->timestamp = get_unix_time();
|
||||
|
||||
line_info_init_line(self->chatwin->history, new_line);
|
||||
line_info_init_line(self, new_line);
|
||||
|
||||
hst->queue[hst->queue_size++] = new_line;
|
||||
|
||||
@ -424,29 +466,8 @@ static void line_info_check_queue(ToxWindow *self)
|
||||
hst->line_end = line;
|
||||
hst->line_end->id = line->id;
|
||||
|
||||
int y;
|
||||
int y2;
|
||||
int x;
|
||||
int x2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
getyx(self->chatwin->history, y, x);
|
||||
|
||||
UNUSED_VAR(x);
|
||||
|
||||
if (x2 <= SIDEBAR_WIDTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
int lines = line->format_lines;
|
||||
int max_y = y2 - CHATBOX_HEIGHT;
|
||||
|
||||
/* move line_start forward proportionate to the number of new lines */
|
||||
if (y + lines > max_y) {
|
||||
while (lines > 0 && hst->line_start->next) {
|
||||
lines -= hst->line_start->next->format_lines;
|
||||
hst->line_start = hst->line_start->next;
|
||||
++hst->start_id;
|
||||
}
|
||||
if (!self->scroll_pause) {
|
||||
line_info_reset_start(self, hst);
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,16 +503,31 @@ void line_info_print(ToxWindow *self)
|
||||
if (self->type == WINDOW_TYPE_CONFERENCE) {
|
||||
wmove(win, 0, 0);
|
||||
} else {
|
||||
wmove(win, 2, 0);
|
||||
wmove(win, TOP_BAR_HEIGHT, 0);
|
||||
}
|
||||
|
||||
struct line_info *line = hst->line_start->next;
|
||||
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT;
|
||||
const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2;
|
||||
uint16_t numlines = line->format_lines;
|
||||
int print_ret = 0;
|
||||
|
||||
int numlines = 0;
|
||||
while (line && numlines++ <= max_y && print_ret == 0) {
|
||||
int y;
|
||||
int x;
|
||||
UNUSED_VAR(y);
|
||||
|
||||
getyx(win, y, x);
|
||||
|
||||
if (x > 0) { // Prevents us from printing off the screen
|
||||
break;
|
||||
}
|
||||
|
||||
while (line && numlines++ <= y2) {
|
||||
uint8_t type = line->type;
|
||||
|
||||
switch (type) {
|
||||
@ -529,7 +565,7 @@ void line_info_print(ToxWindow *self)
|
||||
wattron(win, COLOR_PAIR(RED));
|
||||
}
|
||||
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
|
||||
if (line->msg[0] == '>') {
|
||||
wattroff(win, COLOR_PAIR(GREEN));
|
||||
@ -559,7 +595,7 @@ void line_info_print(ToxWindow *self)
|
||||
|
||||
wattron(win, COLOR_PAIR(YELLOW));
|
||||
wprintw(win, "%s %s ", user_settings->line_normal, line->name1);
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
wattroff(win, COLOR_PAIR(YELLOW));
|
||||
|
||||
if (type == OUT_ACTION && !line->read_flag) {
|
||||
@ -586,7 +622,7 @@ void line_info_print(ToxWindow *self)
|
||||
wattron(win, COLOR_PAIR(line->colour));
|
||||
}
|
||||
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
waddch(win, '\n');
|
||||
|
||||
if (line->bold) {
|
||||
@ -605,7 +641,7 @@ void line_info_print(ToxWindow *self)
|
||||
wattroff(win, COLOR_PAIR(GREEN));
|
||||
|
||||
if (line->msg[0]) {
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
}
|
||||
|
||||
waddch(win, '\n');
|
||||
@ -623,7 +659,7 @@ void line_info_print(ToxWindow *self)
|
||||
wprintw(win, "%s ", line->name1);
|
||||
wattroff(win, A_BOLD);
|
||||
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
waddch(win, '\n');
|
||||
|
||||
wattroff(win, COLOR_PAIR(line->colour));
|
||||
@ -642,7 +678,7 @@ void line_info_print(ToxWindow *self)
|
||||
wprintw(win, "%s ", line->name1);
|
||||
wattroff(win, A_BOLD);
|
||||
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
waddch(win, '\n');
|
||||
|
||||
wattroff(win, COLOR_PAIR(line->colour));
|
||||
@ -660,7 +696,7 @@ void line_info_print(ToxWindow *self)
|
||||
wprintw(win, "%s", line->name1);
|
||||
wattroff(win, A_BOLD);
|
||||
|
||||
print_wrap(win, line, max_x);
|
||||
print_ret = print_wrap(win, line, max_x, max_y);
|
||||
|
||||
wattron(win, A_BOLD);
|
||||
wprintw(win, "%s\n", line->name2);
|
||||
@ -679,6 +715,38 @@ void line_info_print(ToxWindow *self)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if all lines starting from `line` can fit on the screen.
|
||||
*/
|
||||
static bool line_info_screen_fit(ToxWindow *self, struct line_info *line)
|
||||
{
|
||||
if (!line) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->chatwin->history, y2, x2);
|
||||
|
||||
UNUSED_VAR(x2);
|
||||
|
||||
const int top_offset = (self->type == WINDOW_TYPE_CHAT) || (self->type == WINDOW_TYPE_PROMPT) ? TOP_BAR_HEIGHT : 0;
|
||||
const int max_y = y2 - top_offset;
|
||||
|
||||
uint16_t lines = line->format_lines;
|
||||
|
||||
while (line) {
|
||||
if (lines > max_y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lines += line->format_lines;
|
||||
line = line->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* puts msg in specified line_info msg buffer */
|
||||
void line_info_set(ToxWindow *self, uint32_t id, char *msg)
|
||||
{
|
||||
@ -697,49 +765,74 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
|
||||
}
|
||||
}
|
||||
|
||||
static void line_info_scroll_up(struct history *hst)
|
||||
static void line_info_scroll_up(ToxWindow *self, struct history *hst)
|
||||
{
|
||||
if (hst->line_start->prev) {
|
||||
hst->line_start = hst->line_start->prev;
|
||||
} else {
|
||||
sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
|
||||
self->scroll_pause = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void line_info_scroll_down(struct history *hst)
|
||||
static void line_info_scroll_down(ToxWindow *self, struct history *hst)
|
||||
{
|
||||
if (hst->line_start->next) {
|
||||
hst->line_start = hst->line_start->next;
|
||||
struct line_info *next = hst->line_start->next;
|
||||
|
||||
if (next && self->scroll_pause) {
|
||||
if (line_info_screen_fit(self, next->next)) {
|
||||
line_info_reset_start(self, hst);
|
||||
} else {
|
||||
hst->line_start = next;
|
||||
}
|
||||
} else {
|
||||
sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
|
||||
line_info_reset_start(self, hst);
|
||||
}
|
||||
}
|
||||
|
||||
static void line_info_page_up(ToxWindow *self, struct history *hst)
|
||||
{
|
||||
int x2, y2;
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
UNUSED_VAR(x2);
|
||||
|
||||
size_t jump_dist = y2 / 2;
|
||||
const int top_offset = (self->type == WINDOW_TYPE_CHAT) || (self->type == WINDOW_TYPE_PROMPT) ? TOP_BAR_HEIGHT : 0;
|
||||
const int max_y = y2 - top_offset;
|
||||
size_t jump_dist = max_y / 2;
|
||||
|
||||
for (size_t i = 0; i < jump_dist && hst->line_start->prev; ++i) {
|
||||
hst->line_start = hst->line_start->prev;
|
||||
}
|
||||
|
||||
self->scroll_pause = true;
|
||||
}
|
||||
|
||||
static void line_info_page_down(ToxWindow *self, struct history *hst)
|
||||
{
|
||||
int x2, y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
if (!self->scroll_pause) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->chatwin->history, y2, x2);
|
||||
|
||||
UNUSED_VAR(x2);
|
||||
|
||||
size_t jump_dist = y2 / 2;
|
||||
const int top_offset = (self->type == WINDOW_TYPE_CHAT) || (self->type == WINDOW_TYPE_PROMPT) ? TOP_BAR_HEIGHT : 0;
|
||||
const int max_y = y2 - top_offset;
|
||||
size_t jump_dist = max_y / 2;
|
||||
|
||||
for (size_t i = 0; i < jump_dist && hst->line_start->next; ++i) {
|
||||
hst->line_start = hst->line_start->next;
|
||||
struct line_info *next = hst->line_start->next;
|
||||
|
||||
for (size_t i = 0; i < jump_dist && next; ++i) {
|
||||
if (line_info_screen_fit(self, next->next)) {
|
||||
line_info_reset_start(self, hst);
|
||||
break;
|
||||
}
|
||||
|
||||
hst->line_start = next;
|
||||
next = hst->line_start->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -753,9 +846,9 @@ bool line_info_onKey(ToxWindow *self, wint_t key)
|
||||
} else if (key == user_settings->key_half_page_down) {
|
||||
line_info_page_down(self, hst);
|
||||
} else if (key == user_settings->key_scroll_line_up) {
|
||||
line_info_scroll_up(hst);
|
||||
line_info_scroll_up(self, hst);
|
||||
} else if (key == user_settings->key_scroll_line_down) {
|
||||
line_info_scroll_down(hst);
|
||||
line_info_scroll_down(self, hst);
|
||||
} else if (key == user_settings->key_page_bottom) {
|
||||
line_info_reset_start(self, hst);
|
||||
} else {
|
||||
|
@ -306,7 +306,7 @@ int load_chat_history(ToxWindow *self, struct chatlog *log)
|
||||
line = strtok_r(NULL, "\n", &tmp);
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, YELLOW, "---");
|
||||
|
||||
free(buf);
|
||||
|
||||
|
@ -71,16 +71,19 @@ int timed_out(time_t timestamp, time_t timeout)
|
||||
return timestamp + timeout <= get_unix_time();
|
||||
}
|
||||
|
||||
/* Sleeps the caller's thread for `usec` microseconds */
|
||||
/* Attempts to sleep the caller's thread for `usec` microseconds */
|
||||
void sleep_thread(long int usec)
|
||||
{
|
||||
struct timespec req;
|
||||
struct timespec rem;
|
||||
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = usec * 1000L;
|
||||
|
||||
if (nanosleep(&req, NULL) == -1) {
|
||||
fprintf(stderr, "nanosleep() returned -1\n");
|
||||
if (nanosleep(&req, &rem) == -1) {
|
||||
if (nanosleep(&rem, NULL) == -1) {
|
||||
fprintf(stderr, "nanosleep() returned -1\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ int mbs_to_wcs_buf(wchar_t *buf, const char *string, size_t n);
|
||||
/* Returns 1 if connection has timed out, 0 otherwise */
|
||||
int timed_out(time_t timestamp, time_t timeout);
|
||||
|
||||
/* Sleeps the caller's thread for `usec` microseconds */
|
||||
/* Attempts to sleep the caller's thread for `usec` microseconds */
|
||||
void sleep_thread(long int usec);
|
||||
|
||||
/* Colours the window tab according to type. Beeps if is_beep is true */
|
||||
|
96
src/prompt.c
96
src/prompt.c
@ -292,7 +292,7 @@ static bool prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
}
|
||||
|
||||
wclear(ctx->linewin);
|
||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||
wmove(self->window, y2, 0);
|
||||
reset_buf(ctx);
|
||||
}
|
||||
|
||||
@ -301,7 +301,8 @@ static bool prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
|
||||
static void prompt_onDraw(ToxWindow *self, Tox *m)
|
||||
{
|
||||
int x2, y2;
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
@ -316,64 +317,88 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
||||
|
||||
wclear(ctx->linewin);
|
||||
|
||||
curs_set(1);
|
||||
|
||||
if (ctx->len > 0) {
|
||||
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
||||
mvwprintw(ctx->linewin, 0, 0, "%ls", &ctx->line[ctx->start]);
|
||||
}
|
||||
|
||||
mvwhline(ctx->linewin, 0, ctx->len, ' ', x2 - ctx->len);
|
||||
|
||||
curs_set(1);
|
||||
|
||||
StatusBar *statusbar = self->stb;
|
||||
|
||||
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
|
||||
wmove(statusbar->topline, 0, 0);
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
Tox_Connection connection = statusbar->connection;
|
||||
Tox_User_Status status = statusbar->status;
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
if (connection != TOX_CONNECTION_NONE) {
|
||||
int colour = MAGENTA;
|
||||
const char *status_text = "ERROR";
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
Tox_User_Status status = statusbar->status;
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
switch (status) {
|
||||
case TOX_USER_STATUS_NONE:
|
||||
status_text = "Online";
|
||||
colour = GREEN;
|
||||
colour = GREEN_BLUE;
|
||||
break;
|
||||
|
||||
case TOX_USER_STATUS_AWAY:
|
||||
status_text = "Away";
|
||||
colour = YELLOW;
|
||||
colour = YELLOW_BLUE;
|
||||
break;
|
||||
|
||||
case TOX_USER_STATUS_BUSY:
|
||||
status_text = "Busy";
|
||||
colour = RED;
|
||||
colour = RED_BLUE;
|
||||
break;
|
||||
}
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
|
||||
wprintw(statusbar->topline, " [%s]", status_text);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, " [");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(colour));
|
||||
wprintw(statusbar->topline, "%s", status_text);
|
||||
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(colour));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, "]");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
wattron(statusbar->topline, A_BOLD);
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
wprintw(statusbar->topline, " %s", statusbar->nick);
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
wattroff(statusbar->topline, A_BOLD);
|
||||
} else {
|
||||
wprintw(statusbar->topline, " [Offline]");
|
||||
wattron(statusbar->topline, A_BOLD);
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, " [");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
wprintw(statusbar->topline, "Offline");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, "]");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
wprintw(statusbar->topline, " %s", statusbar->nick);
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
wattroff(statusbar->topline, A_BOLD);
|
||||
}
|
||||
|
||||
int s_y;
|
||||
int s_x;
|
||||
getyx(statusbar->topline, s_y, s_x);
|
||||
|
||||
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
|
||||
/* Reset statusbar->statusmsg on window resize */
|
||||
if (x2 != self->x) {
|
||||
char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
|
||||
@ -401,20 +426,27 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
||||
}
|
||||
|
||||
if (statusbar->statusmsg[0]) {
|
||||
wprintw(statusbar->topline, " : %s", statusbar->statusmsg);
|
||||
wattron(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(statusbar->topline, " | ");
|
||||
wattroff(statusbar->topline, COLOR_PAIR(CYAN_BLUE));
|
||||
|
||||
wattron(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
wprintw(statusbar->topline, "%s", statusbar->statusmsg);
|
||||
wattroff(statusbar->topline, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
|
||||
|
||||
int y, x;
|
||||
int y;
|
||||
int x;
|
||||
getyx(self->window, y, x);
|
||||
|
||||
UNUSED_VAR(x);
|
||||
|
||||
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
|
||||
wmove(self->window, y + 1, new_x);
|
||||
wmove(self->window, y, new_x);
|
||||
|
||||
draw_window_bar(self);
|
||||
|
||||
wnoutrefresh(self->window);
|
||||
|
||||
@ -535,7 +567,7 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m, bool first_time_run)
|
||||
prompt_update_nick(prompt, nick);
|
||||
|
||||
/* Init statusbar subwindow */
|
||||
statusbar->topline = subwin(self->window, 2, x2, 0, 0);
|
||||
statusbar->topline = subwin(self->window, TOP_BAR_HEIGHT, x2, 0, 0);
|
||||
}
|
||||
|
||||
static void print_welcome_msg(ToxWindow *self)
|
||||
@ -576,7 +608,9 @@ static void prompt_init_log(ToxWindow *self, Tox *m, const char *self_name)
|
||||
static void prompt_onInit(ToxWindow *self, Tox *m)
|
||||
{
|
||||
curs_set(1);
|
||||
int y2, x2;
|
||||
|
||||
int y2;
|
||||
int x2;
|
||||
getmaxyx(self->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
@ -584,8 +618,10 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
|
||||
}
|
||||
|
||||
ChatContext *ctx = self->chatwin;
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
|
||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
||||
|
||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0);
|
||||
self->window_bar = subwin(self->window, WINDOW_BAR_HEIGHT, x2, y2 - (CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT), 0);
|
||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - WINDOW_BAR_HEIGHT, 0);
|
||||
|
||||
ctx->log = calloc(1, sizeof(struct chatlog));
|
||||
ctx->hst = calloc(1, sizeof(struct history));
|
||||
|
30
src/toxic.c
30
src/toxic.c
@ -256,7 +256,7 @@ static void init_term(void)
|
||||
keypad(stdscr, 1);
|
||||
noecho();
|
||||
nonl();
|
||||
timeout(100);
|
||||
timeout(50);
|
||||
|
||||
if (has_colors()) {
|
||||
short bg_color = COLOR_BLACK;
|
||||
@ -268,15 +268,23 @@ static void init_term(void)
|
||||
}
|
||||
}
|
||||
|
||||
init_pair(0, COLOR_WHITE, COLOR_BLACK);
|
||||
init_pair(1, COLOR_GREEN, bg_color);
|
||||
init_pair(2, COLOR_CYAN, bg_color);
|
||||
init_pair(3, COLOR_RED, bg_color);
|
||||
init_pair(4, COLOR_BLUE, bg_color);
|
||||
init_pair(5, COLOR_YELLOW, bg_color);
|
||||
init_pair(6, COLOR_MAGENTA, bg_color);
|
||||
init_pair(7, COLOR_BLACK, COLOR_BLACK);
|
||||
init_pair(8, COLOR_BLACK, COLOR_WHITE);
|
||||
init_pair(WHITE, COLOR_WHITE, COLOR_BLACK);
|
||||
init_pair(GREEN, COLOR_GREEN, bg_color);
|
||||
init_pair(CYAN, COLOR_CYAN, bg_color);
|
||||
init_pair(RED, COLOR_RED, bg_color);
|
||||
init_pair(BLUE, COLOR_BLUE, bg_color);
|
||||
init_pair(YELLOW, COLOR_YELLOW, bg_color);
|
||||
init_pair(MAGENTA, COLOR_MAGENTA, bg_color);
|
||||
init_pair(BLACK, COLOR_BLACK, COLOR_BLACK);
|
||||
init_pair(BLUE_BLACK, COLOR_BLUE, COLOR_BLACK);
|
||||
init_pair(BLACK_WHITE, COLOR_BLACK, COLOR_WHITE);
|
||||
init_pair(WHITE_BLUE, COLOR_WHITE, COLOR_BLUE);
|
||||
init_pair(CYAN_BLUE, COLOR_CYAN, COLOR_BLUE);
|
||||
init_pair(GREEN_BLUE, COLOR_GREEN, COLOR_BLUE);
|
||||
init_pair(PURPLE_BLUE, COLOR_MAGENTA, COLOR_BLUE);
|
||||
init_pair(BLACK_BLUE, COLOR_BLACK, COLOR_BLUE);
|
||||
init_pair(YELLOW_BLUE, COLOR_YELLOW, COLOR_BLUE);
|
||||
init_pair(RED_BLUE, COLOR_RED, COLOR_BLUE);
|
||||
}
|
||||
|
||||
refresh();
|
||||
@ -1421,6 +1429,7 @@ int main(int argc, char **argv)
|
||||
prompt = init_windows(m);
|
||||
prompt_init_statusbar(prompt, m, !datafile_exists);
|
||||
load_conferences(m);
|
||||
set_active_window_index(0);
|
||||
|
||||
if (pthread_mutex_init(&Winthread.lock, NULL) != 0) {
|
||||
exit_toxic_err("failed in main", FATALERR_MUTEX_INIT);
|
||||
@ -1483,7 +1492,6 @@ int main(int argc, char **argv)
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
print_init_messages(prompt);
|
||||
set_active_window_index(0);
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
cleanup_init_messages();
|
||||
|
@ -75,7 +75,7 @@
|
||||
#define T_KEY_C_DOWN 0x20D /* ctrl-down arrow */
|
||||
#define T_KEY_TAB 0x09 /* TAB key */
|
||||
|
||||
#define ONLINE_CHAR "*"
|
||||
#define ONLINE_CHAR "o"
|
||||
#define OFFLINE_CHAR "o"
|
||||
|
||||
typedef enum _FATAL_ERRS {
|
||||
|
178
src/windows.c
178
src/windows.c
@ -336,7 +336,7 @@ int add_window(Tox *m, ToxWindow *w)
|
||||
}
|
||||
|
||||
w->index = i;
|
||||
w->window = newwin(LINES - 2, COLS, 0, 0);
|
||||
w->window = newwin(LINES, COLS, 0, 0);
|
||||
|
||||
if (w->window == NULL) {
|
||||
return -1;
|
||||
@ -397,8 +397,9 @@ void del_window(ToxWindow *w)
|
||||
set_active_window_index(0);
|
||||
|
||||
uint8_t idx = w->index;
|
||||
delwin(w->window_bar);
|
||||
delwin(w->window);
|
||||
free(windows[idx]);
|
||||
free(w);
|
||||
windows[idx] = NULL;
|
||||
|
||||
clear();
|
||||
@ -408,7 +409,12 @@ void del_window(ToxWindow *w)
|
||||
|
||||
ToxWindow *init_windows(Tox *m)
|
||||
{
|
||||
if (COLS <= CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT) {
|
||||
exit_toxic_err("add_window() for prompt failed in init_windows", FATALERR_WININIT);
|
||||
}
|
||||
|
||||
prompt = new_prompt();
|
||||
|
||||
int n_prompt = add_window(m, prompt);
|
||||
|
||||
if (n_prompt < 0) {
|
||||
@ -430,25 +436,18 @@ void on_window_resize(void)
|
||||
refresh();
|
||||
clear();
|
||||
|
||||
/* equivalent to LINES and COLS */
|
||||
int x2, y2;
|
||||
getmaxyx(stdscr, y2, x2);
|
||||
y2 -= 2;
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||
if (windows[i] == NULL) {
|
||||
ToxWindow *w = windows[i];
|
||||
|
||||
if (w == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ToxWindow *w = windows[i];
|
||||
|
||||
if (windows[i]->type == WINDOW_TYPE_FRIEND_LIST) {
|
||||
if (w->type == WINDOW_TYPE_FRIEND_LIST) {
|
||||
delwin(w->window_bar);
|
||||
delwin(w->window);
|
||||
w->window = newwin(y2, x2, 0, 0);
|
||||
w->window = newwin(LINES, COLS, 0, 0);
|
||||
w->window_bar = subwin(w->window, WINDOW_BAR_HEIGHT, COLS, LINES - 2, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -465,22 +464,35 @@ void on_window_resize(void)
|
||||
|
||||
delwin(w->chatwin->linewin);
|
||||
delwin(w->chatwin->history);
|
||||
delwin(w->window_bar);
|
||||
delwin(w->window);
|
||||
|
||||
w->window = newwin(y2, x2, 0, 0);
|
||||
w->chatwin->linewin = subwin(w->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
||||
w->window = newwin(LINES, COLS, 0, 0);
|
||||
|
||||
int x2;
|
||||
int y2;
|
||||
getmaxyx(w->window, y2, x2);
|
||||
|
||||
if (y2 <= 0 || x2 <= 0) {
|
||||
fprintf(stderr, "Failed to resize window: max_x: %d, max_y: %d\n", x2, y2);
|
||||
delwin(w->window);
|
||||
return;
|
||||
}
|
||||
|
||||
if (w->show_peerlist) {
|
||||
w->chatwin->history = subwin(w->window, y2 - CHATBOX_HEIGHT + 1, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||
w->chatwin->sidebar = subwin(w->window, y2 - CHATBOX_HEIGHT + 1, SIDEBAR_WIDTH, 0, x2 - SIDEBAR_WIDTH);
|
||||
w->chatwin->history = subwin(w->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||
w->chatwin->sidebar = subwin(w->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, SIDEBAR_WIDTH, 0, x2 - SIDEBAR_WIDTH);
|
||||
} else {
|
||||
w->chatwin->history = subwin(w->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
|
||||
w->chatwin->history = subwin(w->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0);
|
||||
|
||||
if (w->type != WINDOW_TYPE_CONFERENCE) {
|
||||
w->stb->topline = subwin(w->window, 2, x2, 0, 0);
|
||||
w->stb->topline = subwin(w->window, TOP_BAR_HEIGHT, x2, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
w->window_bar = subwin(w->window, WINDOW_BAR_HEIGHT, x2, y2 - (CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT), 0);
|
||||
w->chatwin->linewin = subwin(w->window, CHATBOX_HEIGHT, x2, y2 - WINDOW_BAR_HEIGHT, 0);
|
||||
|
||||
#ifdef AUDIO
|
||||
|
||||
if (w->chatwin->infobox.active) {
|
||||
@ -491,97 +503,103 @@ void on_window_resize(void)
|
||||
#endif /* AUDIO */
|
||||
|
||||
scrollok(w->chatwin->history, 0);
|
||||
wmove(w->window, y2 - CURS_Y_OFFSET, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_window_tab(ToxWindow *toxwin, bool active_window)
|
||||
static void draw_window_tab(WINDOW *win, ToxWindow *toxwin, bool active_window)
|
||||
{
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
|
||||
if (toxwin->alert != WINDOW_ALERT_NONE) {
|
||||
attron(COLOR_PAIR(toxwin->alert));
|
||||
}
|
||||
|
||||
bool has_alert = toxwin->alert != WINDOW_ALERT_NONE;
|
||||
unsigned int pending_messages = toxwin->pending_messages;
|
||||
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
clrtoeol();
|
||||
|
||||
WINDOW_TYPE type = toxwin->type;
|
||||
|
||||
if (active_window || (type == WINDOW_TYPE_PROMPT || type == WINDOW_TYPE_FRIEND_LIST)) {
|
||||
printw(" [%s]", toxwin->name);
|
||||
if (active_window) {
|
||||
wattron(win, A_BOLD | COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(win, " [");
|
||||
wattroff(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wattron(win, COLOR_PAIR(WHITE_BLUE));
|
||||
} else {
|
||||
if (pending_messages > 0) {
|
||||
printw(" [%u]", pending_messages);
|
||||
if (has_alert) {
|
||||
wattron(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(win, " [");
|
||||
wattroff(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wattron(win, A_BOLD | COLOR_PAIR(toxwin->alert));
|
||||
} else {
|
||||
printw(" [*]");
|
||||
wattron(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(win, " [");
|
||||
wattroff(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wattron(win, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
|
||||
if (toxwin->alert != WINDOW_ALERT_NONE) {
|
||||
attroff(COLOR_PAIR(toxwin->alert));
|
||||
if (active_window || (type == WINDOW_TYPE_PROMPT || type == WINDOW_TYPE_FRIEND_LIST)) {
|
||||
wprintw(win, "%s", toxwin->name);
|
||||
} else {
|
||||
if (pending_messages > 0) {
|
||||
wprintw(win, "%u", pending_messages);
|
||||
} else {
|
||||
wprintw(win, "-");
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
if (active_window) {
|
||||
wattroff(win, COLOR_PAIR(WHITE_BLUE));
|
||||
wattron(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(win, "]");
|
||||
wattroff(win, A_BOLD | COLOR_PAIR(CYAN_BLUE));
|
||||
} else {
|
||||
if (has_alert) {
|
||||
wattroff(win, A_BOLD | COLOR_PAIR(toxwin->alert));
|
||||
wattron(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(win, "]");
|
||||
wattroff(win, COLOR_PAIR(CYAN_BLUE));
|
||||
} else {
|
||||
wattroff(win, COLOR_PAIR(WHITE_BLUE));
|
||||
wattron(win, COLOR_PAIR(CYAN_BLUE));
|
||||
wprintw(win, "]");
|
||||
wattroff(win, COLOR_PAIR(CYAN_BLUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_bar(void)
|
||||
void draw_window_bar(ToxWindow *self)
|
||||
{
|
||||
int y, x;
|
||||
WINDOW *win = self->window_bar;
|
||||
wclear(win);
|
||||
|
||||
ToxWindow *w = windows[active_window_index];
|
||||
|
||||
if (w == NULL) {
|
||||
return;
|
||||
if (self->scroll_pause) {
|
||||
wattron(win, A_BLINK | A_BOLD | COLOR_PAIR(YELLOW_BLUE));
|
||||
wprintw(win, "^");
|
||||
wattroff(win, A_BLINK | A_BOLD | COLOR_PAIR(YELLOW_BLUE));
|
||||
} else {
|
||||
wattron(win, COLOR_PAIR(WHITE_BLUE));
|
||||
wprintw(win, " ");
|
||||
wattroff(win, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
|
||||
// save current cursor position
|
||||
getyx(w->window, y, x);
|
||||
|
||||
attron(COLOR_PAIR(BLUE));
|
||||
mvhline(LINES - 2, 0, '_', COLS);
|
||||
attroff(COLOR_PAIR(BLUE));
|
||||
|
||||
move(LINES - 1, 0);
|
||||
|
||||
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||
if (windows[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool active_window = i == active_window_index;
|
||||
|
||||
if (active_window) {
|
||||
|
||||
#ifdef URXVT_FIX
|
||||
attron(A_BOLD | COLOR_PAIR(GREEN));
|
||||
} else {
|
||||
#endif
|
||||
|
||||
attron(A_BOLD);
|
||||
}
|
||||
|
||||
draw_window_tab(windows[i], active_window);
|
||||
|
||||
if (active_window) {
|
||||
|
||||
#ifdef URXVT_FIX
|
||||
attroff(A_BOLD | COLOR_PAIR(GREEN));
|
||||
} else {
|
||||
#endif
|
||||
|
||||
attroff(A_BOLD);
|
||||
}
|
||||
draw_window_tab(win, windows[i], active_window);
|
||||
}
|
||||
|
||||
// restore cursor position after drawing
|
||||
move(y, x);
|
||||
int cur_x;
|
||||
int cur_y;
|
||||
UNUSED_VAR(cur_y);
|
||||
|
||||
refresh();
|
||||
getyx(win, cur_y, cur_x);
|
||||
|
||||
wattron(win, COLOR_PAIR(WHITE_BLUE));
|
||||
mvwhline(win, 0, cur_x, ' ', COLS - cur_x);
|
||||
wattroff(win, COLOR_PAIR(WHITE_BLUE));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -684,8 +702,6 @@ void draw_active_window(Tox *m)
|
||||
a->pending_messages = 0;
|
||||
pthread_mutex_unlock(&Winthread.lock);
|
||||
|
||||
draw_bar();
|
||||
|
||||
touchwin(a->window);
|
||||
a->onDraw(a, m);
|
||||
wrefresh(a->window);
|
||||
|
@ -39,9 +39,11 @@
|
||||
#define MAX_WINDOWS_NUM 20
|
||||
#define MAX_WINDOW_NAME_LENGTH 22
|
||||
#define CURS_Y_OFFSET 1 /* y-axis cursor offset for chat contexts */
|
||||
#define CHATBOX_HEIGHT 2
|
||||
#define CHATBOX_HEIGHT 1
|
||||
#define TOP_BAR_HEIGHT 1
|
||||
#define WINDOW_BAR_HEIGHT 1
|
||||
|
||||
/* Curses foreground colours (background is black) */
|
||||
/* ncurses colour pairs as FOREGROUND_BACKGROUND. No background defaults to black. */
|
||||
typedef enum {
|
||||
WHITE,
|
||||
GREEN,
|
||||
@ -51,14 +53,23 @@ typedef enum {
|
||||
YELLOW,
|
||||
MAGENTA,
|
||||
BLACK,
|
||||
BLUE_BLACK,
|
||||
BLACK_WHITE,
|
||||
WHITE_BLUE,
|
||||
GREEN_BLUE,
|
||||
CYAN_BLUE,
|
||||
PURPLE_BLUE,
|
||||
BLACK_BLUE,
|
||||
RED_BLUE,
|
||||
YELLOW_BLUE,
|
||||
} C_COLOURS;
|
||||
|
||||
/* tab alert types: lower types take priority (this relies on the order of C_COLOURS) */
|
||||
typedef enum {
|
||||
WINDOW_ALERT_NONE = 0,
|
||||
WINDOW_ALERT_0 = GREEN,
|
||||
WINDOW_ALERT_1 = RED,
|
||||
WINDOW_ALERT_2 = MAGENTA,
|
||||
WINDOW_ALERT_0 = GREEN_BLUE,
|
||||
WINDOW_ALERT_1 = CYAN_BLUE,
|
||||
WINDOW_ALERT_2 = PURPLE_BLUE,
|
||||
} WINDOW_ALERTS;
|
||||
|
||||
typedef enum {
|
||||
@ -167,6 +178,7 @@ struct ToxWindow {
|
||||
char name[TOXIC_MAX_NAME_LENGTH + 1];
|
||||
uint32_t num; /* corresponds to friendnumber in chat windows */
|
||||
uint8_t index; /* This window's index in the windows array */
|
||||
bool scroll_pause; /* true if this window is not scrolled to the bottom */
|
||||
unsigned int pending_messages; /* # of new messages in this window since the last time it was focused */
|
||||
int x;
|
||||
|
||||
@ -181,6 +193,7 @@ struct ToxWindow {
|
||||
Help *help;
|
||||
|
||||
WINDOW *window;
|
||||
WINDOW *window_bar;
|
||||
};
|
||||
|
||||
/* statusbar info holder */
|
||||
@ -264,6 +277,7 @@ void on_window_resize(void);
|
||||
void force_refresh(WINDOW *w);
|
||||
ToxWindow *get_window_ptr(size_t i);
|
||||
ToxWindow *get_active_window(void);
|
||||
void draw_window_bar(ToxWindow *self);
|
||||
|
||||
/* refresh inactive windows to prevent scrolling bugs.
|
||||
call at least once per second */
|
||||
|
Loading…
Reference in New Issue
Block a user