From a640d8e91f0c03e8073468d19e9d6a1438b5bfcd Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sat, 3 Oct 2015 01:45:13 +0200 Subject: [PATCH] No terminal updates until input data is pending --- ChangeLog | 8 ++++- src/fapp.cpp | 84 +++++++++++++++++++++++++++++++++++++---------- src/fapp.h | 22 ++++++++----- src/fmenubar.cpp | 2 +- src/foptimove.cpp | 2 +- src/fterm.cpp | 78 +++++++++++++++++++++++++++++++++---------- src/fterm.h | 3 ++ 7 files changed, 152 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 64890b2a..bb72ba4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,10 @@ -2015-09-39 Markus Gans +2015-10-02 Markus Gans + * No terminal updates until input data is pending. + This speeds up the window moving with the mouse on terminals + with a high latency. + * Use now the select command before read ENQ and SEC_DA + +2015-09-29 Markus Gans * Some code improvements 2015-09-27 Markus Gans diff --git a/src/fapp.cpp b/src/fapp.cpp index ea372db8..fe73d7e9 100644 --- a/src/fapp.cpp +++ b/src/fapp.cpp @@ -30,6 +30,7 @@ std::deque* FApplication::event_queue = 0; FApplication::FApplication (int &_argc, char* _argv[]) : app_argc(0) , app_argv(0) + , skipped_terminal_update(0) , key(0) #ifdef F_HAVE_LIBGPM , gpm_ev() @@ -147,7 +148,7 @@ void FApplication::cmd_options () //---------------------------------------------------------------------- #ifdef F_HAVE_LIBGPM -inline int FApplication::gpmEvent(void) +inline int FApplication::gpmEvent(bool clear) { register int result; register int max = (gpm_fd > stdin_no) ? gpm_fd : stdin_no; @@ -162,10 +163,11 @@ inline int FApplication::gpmEvent(void) result = select (max+1, &ifds, 0, 0, &tv); if ( FD_ISSET(stdin_no, &ifds) ) { - FD_CLR (stdin_no, &ifds); + if ( clear ) + FD_CLR (stdin_no, &ifds); return keyboard_event; } - if ( FD_ISSET(gpm_fd, &ifds) ) + if ( clear && FD_ISSET(gpm_fd, &ifds) ) FD_CLR (gpm_fd, &ifds); if (result > 0) return mouse_event; @@ -225,6 +227,8 @@ void FApplication::processKeyboardEvent() fifo_in_use = false; } + flush_out(); + #ifdef F_HAVE_LIBGPM if ( gpm_mouse_enabled ) { @@ -272,7 +276,7 @@ void FApplication::processKeyboardEvent() // read the rest from the fifo buffer while ( ! widget->isKeyTimeout(&time_keypressed, key_timeout) - && fifo_offset + && fifo_offset > 0 && key != NEED_MORE_DATA ) { key = FTerm::parseKeyString(fifo_buf, fifo_buf_size, &time_keypressed); @@ -289,39 +293,55 @@ void FApplication::processKeyboardEvent() x11_mouse[1] = fifo_buf[4]; x11_mouse[2] = fifo_buf[5]; x11_mouse[3] = '\0'; - len = int(strlen(fifo_buf)); + len = 6; n = len; - for (; n < fifo_buf_size; n++) - fifo_buf[n-len] = fifo_buf[n]; // remove the founded entry - for (; n-len < len; n++) + for (; n < fifo_buf_size; n++) // Remove founded entry + fifo_buf[n-len] = fifo_buf[n]; + for (; n-len < len; n++) // Fill rest with '\0' fifo_buf[n-len] = '\0'; + input_data_pending = bool(fifo_buf[0] != '\0'); + processMouseEvent(); } else if ( key == fc::Fkey_extended_mouse ) { int n = 3; int len = int(strlen(fifo_buf)); - for (; n < len && n < fifo_buf_size; n++) + while ( n < len && n < fifo_buf_size ) + { sgr_mouse[n-3] = fifo_buf[n]; + n++; + if ( fifo_buf[n] == 'M' || fifo_buf[n] == 'm' ) + len = n + 1; + } sgr_mouse[n-3] = '\0'; - for (n=len; n < fifo_buf_size; n++) - fifo_buf[n-len] = fifo_buf[n]; // remove the founded entry - for (; n-len < len; n++) + for (n=len; n < fifo_buf_size; n++) // Remove founded entry + fifo_buf[n-len] = fifo_buf[n]; + for (; n-len < len; n++) // Fill rest with '\0' fifo_buf[n-len] = '\0'; + input_data_pending = bool(fifo_buf[0] != '\0'); + processMouseEvent(); } else if ( key == fc::Fkey_urxvt_mouse ) { int n = 2; int len = int(strlen(fifo_buf)); - for (; n < len && n < fifo_buf_size; n++) + while ( n < len && n < fifo_buf_size ) + { urxvt_mouse[n-2] = fifo_buf[n]; + n++; + if ( fifo_buf[n] == 'M' || fifo_buf[n] == 'm' ) + len = n + 1; + } urxvt_mouse[n-2] = '\0'; - for (n=len; n < fifo_buf_size; n++) - fifo_buf[n-len] = fifo_buf[n]; // remove the founded entry - for (; n-len < len; n++) + for (n=len; n < fifo_buf_size; n++) // Remove founded entry + fifo_buf[n-len] = fifo_buf[n]; + for (; n-len < len; n++) // Fill rest with '\0' fifo_buf[n-len] = '\0'; + input_data_pending = bool(fifo_buf[0] != '\0'); + processMouseEvent(); } else { @@ -377,6 +397,7 @@ void FApplication::processKeyboardEvent() { FKeyEvent k_press_ev(KeyPress_Event, fc::Fkey_escape); sendEvent(widget, &k_press_ev); + input_data_pending = false; } } @@ -904,10 +925,18 @@ bool FApplication::processGpmEvent() break; } mouse->setPoint(gpm_ev.x, gpm_ev.y); - flush_out(); + + if ( gpmEvent(false) == mouse_event ) + input_data_pending = true; + else + input_data_pending = false; + GPM_DRAWPOINTER(&gpm_ev); + gpmMouseEvent = false; + return true; } + gpmMouseEvent = false; return false; } #endif // F_HAVE_LIBGPM @@ -1101,7 +1130,6 @@ void FApplication::processMouseEvent() sendEvent(scroll_over_widget, &wheel_ev); } } - flush_out(); #ifdef F_HAVE_LIBGPM if ( gpm_mouse_enabled && gpm_ev.x != -1 ) @@ -1175,6 +1203,26 @@ bool FApplication::processNextEvent() processMouseEvent(); processResizeEvent(); + if ( terminal_update_pending ) + { + if ( ! input_data_pending ) + { + updateTerminal(); + terminal_update_pending = false; + skipped_terminal_update = 0; + } + else if ( skipped_terminal_update > 8 ) + { + force_terminal_update = true; + updateTerminal(); + force_terminal_update = false; + terminal_update_pending = false; + skipped_terminal_update = 0; + } + else + skipped_terminal_update++; + } + if ( close_widget && ! close_widget->empty() ) { widgetList::iterator iter; diff --git a/src/fapp.h b/src/fapp.h index 15acacb4..826f5ec0 100644 --- a/src/fapp.h +++ b/src/fapp.h @@ -61,6 +61,7 @@ class FApplication : public FWidget static int loop_level; static bool process_timer_event; static FPoint* zero_point; + int skipped_terminal_update; int key; char k_buf[1024]; char x11_mouse[4]; @@ -127,7 +128,7 @@ class FApplication : public FWidget bool parseUrxvtMouse(); #ifdef F_HAVE_LIBGPM - int gpmEvent(); + int gpmEvent(bool = true); bool processGpmEvent(); #endif @@ -143,11 +144,12 @@ class FApplication : public FWidget FApplication (int &argc, char* argv[]); // constructor virtual ~FApplication(); // destructor - const char* getClassName() const; - int argc() const; - char** argv() const; - FWidget* mainWidget() const; - FWidget* focusWidget() const; + const char* getClassName() const; + int argc() const; + char** argv() const; + FWidget* mainWidget() const; + FWidget* focusWidget() const; + bool unprocessedInput() const; static void print_cmd_Options(); void setMainWidget (FWidget*); int exec(); // run @@ -166,6 +168,10 @@ class FApplication : public FWidget // FApplication inline functions +//---------------------------------------------------------------------- +inline const char* FApplication::getClassName() const +{ return "FApplication"; } + //---------------------------------------------------------------------- inline int FApplication::argc() const { return app_argc; } @@ -183,7 +189,7 @@ inline FWidget* FApplication::focusWidget() const { return focus_widget; } //---------------------------------------------------------------------- -inline const char* FApplication::getClassName() const -{ return "FApplication"; } +inline bool FApplication::unprocessedInput() const +{ return input_data_pending; } #endif // _FAPPLICATION_H diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index 1b841625..b281dfb2 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -56,7 +56,7 @@ void FMenuBar::menu_dimension() { int item_X = 1; int item_Y = 1; - std::vector::const_iterator begin, end, iter; + std::vector::const_iterator end, iter; iter = itemlist.begin(); end = itemlist.end(); diff --git a/src/foptimove.cpp b/src/foptimove.cpp index ec59598c..932536ee 100644 --- a/src/foptimove.cpp +++ b/src/foptimove.cpp @@ -511,7 +511,7 @@ int FOptiMove::relative_move ( char*& move if ( htime >= LONG_DURATION ) return LONG_DURATION; - if ( move ) + if ( *move ) strcat (move, hmove); else strcpy (move, hmove); diff --git a/src/fterm.cpp b/src/fterm.cpp index 580e1a60..262ef956 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -48,6 +48,9 @@ bool FTerm::mouse_support; bool FTerm::vt100_state; bool FTerm::ignore_vt100_state; bool FTerm::raw_mode; +bool FTerm::input_data_pending; +bool FTerm::terminal_update_pending; +bool FTerm::force_terminal_update; bool FTerm::non_blocking_stdin; bool FTerm::gpm_mouse_enabled; bool FTerm::color256; @@ -762,10 +765,11 @@ int FTerm::parseKeyString ( char* buffer if ( k && strncmp(k, buffer, uInt(len)) == 0 ) // found { n = len; - for (; n < buf_size; n++) - buffer[n-len] = buffer[n]; // remove the founded entry - for (; n-len < len; n++) + for (; n < buf_size; n++) // Remove founded entry + buffer[n-len] = buffer[n]; + for (; n-len < len; n++) // Fill rest with '\0' buffer[n-len] = '\0'; + input_data_pending = bool(buffer[0] != '\0'); return Fkey[i].num; } } @@ -785,10 +789,11 @@ int FTerm::parseKeyString ( char* buffer return NEED_MORE_DATA; } n = len; - for (; n < buf_size; n++) - buffer[n-len] = buffer[n]; // remove the founded entry - for (; n-len < len; n++) + for (; n < buf_size; n++) // Remove founded entry + buffer[n-len] = buffer[n]; + for (; n-len < len; n++) // Fill rest with '\0' buffer[n-len] = '\0'; + input_data_pending = bool(buffer[0] != '\0'); return Fmetakey[i].num; } } @@ -822,6 +827,7 @@ int FTerm::parseKeyString ( char* buffer buffer[n-len] = buffer[n]; for (n=n-len; n < buf_size; n++) // fill the rest with '\0' bytes buffer[n] = '\0'; + input_data_pending = bool(buffer[0] != '\0'); return int(key == 127 ? fc::Fkey_backspace : key); } @@ -940,6 +946,9 @@ void FTerm::init() // assertion: programm start in cooked mode raw_mode = false; + input_data_pending = false; + terminal_update_pending = false; + force_terminal_update = false; non_blocking_stdin = false; stdin_no = fileno(stdin); @@ -2468,8 +2477,17 @@ void FTerm::updateTerminal() if ( static_cast(term_object)->isQuit() ) return; - if ( ! terminal_updates ) - return; + if ( ! force_terminal_update ) + { + if ( ! terminal_updates ) + return; + + if ( input_data_pending ) + { + terminal_update_pending = true; + return; + } + } vt = vterm; term_width = term->getWidth(); @@ -3440,16 +3458,28 @@ FString FTerm::getAnswerbackMsg() if ( raw_mode ) { int n; + fd_set ifds; + struct timeval tv; char temp[10] = {}; + + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 150000; // 150 ms + putchar(0x05); // send enquiry character fflush(stdout); - usleep(150000); // wait 150 ms + // read the answerback message - n = read(fileno(stdin), &temp, sizeof(temp)-1); - if ( n > 0 ) + if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0) { - temp[n] = '\0'; - answerback = temp; + n = read(fileno(stdin), &temp, sizeof(temp)-1); + + if ( n > 0 ) + { + temp[n] = '\0'; + answerback = temp; + } } } return answerback; @@ -3463,20 +3493,32 @@ FString FTerm::getSecDA() if ( raw_mode ) { int n; + fd_set ifds; + struct timeval tv; char temp[16] = {}; + + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 150000; // 150 ms + // get the secondary device attributes putchar(0x1b); // ESC putchar(0x5b); // [ putchar(0x3e); // > putchar(0x63); // c fflush(stdout); - usleep(150000); // wait 150 ms + // read the answer - n = read(fileno(stdin), &temp, sizeof(temp)-1); - if ( n > 0 ) + if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0 ) { - temp[n] = '\0'; - sec_da = temp; + n = read(fileno(stdin), &temp, sizeof(temp)-1); + + if ( n > 0 ) + { + temp[n] = '\0'; + sec_da = temp; + } } } return sec_da; diff --git a/src/fterm.h b/src/fterm.h index d2f0d9b0..5baea383 100644 --- a/src/fterm.h +++ b/src/fterm.h @@ -98,6 +98,9 @@ class FTerm static bool vt100_state; static bool ignore_vt100_state; static bool raw_mode; + static bool input_data_pending; + static bool terminal_update_pending; + static bool force_terminal_update; static bool non_blocking_stdin; static bool gpm_mouse_enabled; static bool pc_charset_state;