From f99594473494a3ad2c50317ff2b39ff7c42550e4 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Sun, 9 Jan 2022 21:53:52 +0100 Subject: [PATCH 1/4] Run the main loop with GMainLoop --- src/profanity.c | 67 ++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/profanity.c b/src/profanity.c index 9660945c1..541f3880a 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -86,15 +87,15 @@ static void _init(char* log_level, char* config_file, char* log_file, char* theme_name); static void _shutdown(void); static void _connect_default(const char* const account); +static gboolean _main_update(gpointer data); pthread_mutex_t lock; static gboolean force_quit = FALSE; +static GMainLoop* main_loop = NULL; void prof_run(char* log_level, char* account_name, char* config_file, char* log_file, char* theme_name) { - gboolean cont = TRUE; - _init(log_level, config_file, log_file, theme_name); plugins_on_start(); _connect_default(account_name); @@ -105,39 +106,49 @@ prof_run(char* log_level, char* account_name, char* config_file, char* log_file, session_init_activity(); - char* line = NULL; - while (cont && !force_quit) { - log_stderr_handler(); - session_check_autoaway(); + main_loop = g_main_loop_new(NULL, TRUE); + g_timeout_add(1000/60, _main_update, NULL); + g_main_loop_run(main_loop); +} - line = inp_readline(); - if (line) { - ProfWin* window = wins_get_current(); - cont = cmd_process_input(window, line); - free(line); - line = NULL; - } else { - cont = TRUE; - } +void +prof_set_quit(void) +{ + force_quit = TRUE; +} + +static gboolean +_main_update(gpointer data) +{ + log_stderr_handler(); + session_check_autoaway(); + + gboolean cont = TRUE; + char *line = inp_readline(); + if (line) { + ProfWin* window = wins_get_current(); + cont = cmd_process_input(window, line); + free(line); + line = NULL; + } #ifdef HAVE_LIBOTR - otr_poll(); + otr_poll(); #endif - plugins_run_timed(); - notify_remind(); - session_process_events(); - iq_autoping_check(); - ui_update(); + plugins_run_timed(); + notify_remind(); + session_process_events(); + iq_autoping_check(); + ui_update(); #ifdef HAVE_GTK - tray_update(); + tray_update(); #endif - } -} -void -prof_set_quit(void) -{ - force_quit = TRUE; + if (!cont) + g_main_loop_quit(main_loop); + + // Always repeat + return TRUE; } static void From 7eac636fc80016dbf18eea60a7d59576dd2a4925 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Sun, 9 Jan 2022 21:53:52 +0100 Subject: [PATCH 2/4] Implement keyboard input using GIOChannel --- src/profanity.c | 20 +++++--------------- src/profanity.h | 1 + src/ui/inputwin.c | 38 ++++++++++++++++++++++++++++++++++++++ src/ui/inputwin.h | 1 + 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/profanity.c b/src/profanity.c index 541f3880a..ad352658d 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -61,6 +61,7 @@ #include "command/cmd_defs.h" #include "plugins/plugins.h" #include "event/client_events.h" +#include "ui/inputwin.h" #include "ui/ui.h" #include "ui/window_list.h" #include "xmpp/resource.h" @@ -91,7 +92,7 @@ static gboolean _main_update(gpointer data); pthread_mutex_t lock; static gboolean force_quit = FALSE; -static GMainLoop* main_loop = NULL; +GMainLoop* mainloop = NULL; void prof_run(char* log_level, char* account_name, char* config_file, char* log_file, char* theme_name) @@ -106,9 +107,10 @@ prof_run(char* log_level, char* account_name, char* config_file, char* log_file, session_init_activity(); - main_loop = g_main_loop_new(NULL, TRUE); + mainloop = g_main_loop_new(NULL, TRUE); g_timeout_add(1000/60, _main_update, NULL); - g_main_loop_run(main_loop); + inp_add_watch(); + g_main_loop_run(mainloop); } void @@ -123,15 +125,6 @@ _main_update(gpointer data) log_stderr_handler(); session_check_autoaway(); - gboolean cont = TRUE; - char *line = inp_readline(); - if (line) { - ProfWin* window = wins_get_current(); - cont = cmd_process_input(window, line); - free(line); - line = NULL; - } - #ifdef HAVE_LIBOTR otr_poll(); #endif @@ -144,9 +137,6 @@ _main_update(gpointer data) tray_update(); #endif - if (!cont) - g_main_loop_quit(main_loop); - // Always repeat return TRUE; } diff --git a/src/profanity.h b/src/profanity.h index 0e5faba1f..e5e6cbcb0 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -44,5 +44,6 @@ void prof_run(char* log_level, char* account_name, char* config_file, char* log_ void prof_set_quit(void); extern pthread_mutex_t lock; +extern GMainLoop* mainloop; #endif diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index d1d278070..f7ce9105a 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -171,6 +171,44 @@ create_input_window(void) _inp_win_update_virtual(); } +static gboolean +_inp_callback(GIOChannel *source, GIOCondition condition, gpointer data) +{ + rl_callback_read_char(); + + ui_reset_idle_time(); + if (!get_password) { + // Update the input buffer on screen + _inp_write(rl_line_buffer, rl_point); + } + // TODO set idle or activity with a timeout + //chat_state_idle(); + //chat_state_activity(); + + if (inp_line) { + ProfWin* window = wins_get_current(); + + if (!cmd_process_input(window, inp_line)) + g_main_loop_quit(mainloop); + + free(inp_line); + inp_line = NULL; + } + + return TRUE; +} + +void +inp_add_watch(void) +{ + GIOChannel* channel = g_io_channel_unix_new(fileno(rl_instream)); + if (g_io_channel_set_encoding(channel, NULL, NULL) != G_IO_STATUS_NORMAL) { + log_error("cannot set NULL encoding"); + } + + g_io_add_watch(channel, G_IO_IN, _inp_callback, NULL); +} + char* inp_readline(void) { diff --git a/src/ui/inputwin.h b/src/ui/inputwin.h index 3aefcc0a7..ec428e43b 100644 --- a/src/ui/inputwin.h +++ b/src/ui/inputwin.h @@ -46,5 +46,6 @@ void inp_win_resize(void); void inp_put_back(void); char* inp_get_password(void); char* inp_get_line(void); +void inp_add_watch(void); #endif From f322639668aa9e0346bb6a3cd8aa290373e23213 Mon Sep 17 00:00:00 2001 From: John Hernandez <129467592+H3rnand3zzz@users.noreply.github.com> Date: Thu, 28 Dec 2023 18:03:45 +0100 Subject: [PATCH 3/4] Fix chat state updating Previous commits introduced a problem that chat state stopped working, this commit resolves it by updating it on each cycle. --- src/profanity.c | 3 ++- src/ui/inputwin.c | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/profanity.c b/src/profanity.c index ad352658d..09bf29df3 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -108,7 +108,7 @@ prof_run(char* log_level, char* account_name, char* config_file, char* log_file, session_init_activity(); mainloop = g_main_loop_new(NULL, TRUE); - g_timeout_add(1000/60, _main_update, NULL); + g_timeout_add(1000 / 60, _main_update, NULL); inp_add_watch(); g_main_loop_run(mainloop); } @@ -133,6 +133,7 @@ _main_update(gpointer data) session_process_events(); iq_autoping_check(); ui_update(); + chat_state_idle(); #ifdef HAVE_GTK tray_update(); #endif diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index f7ce9105a..979b0b0a3 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -172,18 +172,19 @@ create_input_window(void) } static gboolean -_inp_callback(GIOChannel *source, GIOCondition condition, gpointer data) +_inp_callback(GIOChannel* source, GIOCondition condition, gpointer data) { rl_callback_read_char(); + if (rl_line_buffer && rl_line_buffer[0] != '/' && rl_line_buffer[0] != '\0' && rl_line_buffer[0] != '\n') { + chat_state_activity(); + } + ui_reset_idle_time(); if (!get_password) { // Update the input buffer on screen _inp_write(rl_line_buffer, rl_point); } - // TODO set idle or activity with a timeout - //chat_state_idle(); - //chat_state_activity(); if (inp_line) { ProfWin* window = wins_get_current(); From 080b0f825a1abdaecb68fded3a3e7211f24581df Mon Sep 17 00:00:00 2001 From: John Hernandez <129467592+H3rnand3zzz@users.noreply.github.com> Date: Thu, 28 Dec 2023 18:18:40 +0100 Subject: [PATCH 4/4] Add stubs for inputwin to fix autotests --- Makefile.am | 1 + tests/unittests/ui/stub_inputwin.c | 4 ++++ tests/unittests/ui/stub_inputwin.h | 1 + 3 files changed, 6 insertions(+) create mode 100644 tests/unittests/ui/stub_inputwin.c create mode 100644 tests/unittests/ui/stub_inputwin.h diff --git a/Makefile.am b/Makefile.am index f9c89d648..eef812aaf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -130,6 +130,7 @@ unittest_sources = \ tests/unittests/xmpp/stub_xmpp.c \ tests/unittests/xmpp/stub_message.c \ tests/unittests/ui/stub_ui.c tests/unittests/ui/stub_ui.h \ + tests/unittests/ui/stub_inputwin.c tests/unittests/ui/stub_inputwin.h \ tests/unittests/ui/stub_vcardwin.c \ tests/unittests/log/stub_log.c \ tests/unittests/chatlog/stub_chatlog.c \ diff --git a/tests/unittests/ui/stub_inputwin.c b/tests/unittests/ui/stub_inputwin.c new file mode 100644 index 000000000..f4005bae8 --- /dev/null +++ b/tests/unittests/ui/stub_inputwin.c @@ -0,0 +1,4 @@ +void +inp_add_watch(void) +{ +} \ No newline at end of file diff --git a/tests/unittests/ui/stub_inputwin.h b/tests/unittests/ui/stub_inputwin.h new file mode 100644 index 000000000..a7535da4a --- /dev/null +++ b/tests/unittests/ui/stub_inputwin.h @@ -0,0 +1 @@ +void inp_add_watch(void); \ No newline at end of file