No terminal updates until input data is pending

This commit is contained in:
Markus Gans 2015-10-03 01:45:13 +02:00
parent 976f685ae0
commit a640d8e91f
7 changed files with 152 additions and 47 deletions

View File

@ -1,4 +1,10 @@
2015-09-39 Markus Gans <guru.mail@muenster.de> 2015-10-02 Markus Gans <guru.mail@muenster.de>
* 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 <guru.mail@muenster.de>
* Some code improvements * Some code improvements
2015-09-27 Markus Gans <guru.mail@muenster.de> 2015-09-27 Markus Gans <guru.mail@muenster.de>

View File

@ -30,6 +30,7 @@ std::deque<FApplication::eventPair>* FApplication::event_queue = 0;
FApplication::FApplication (int &_argc, char* _argv[]) FApplication::FApplication (int &_argc, char* _argv[])
: app_argc(0) : app_argc(0)
, app_argv(0) , app_argv(0)
, skipped_terminal_update(0)
, key(0) , key(0)
#ifdef F_HAVE_LIBGPM #ifdef F_HAVE_LIBGPM
, gpm_ev() , gpm_ev()
@ -147,7 +148,7 @@ void FApplication::cmd_options ()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
#ifdef F_HAVE_LIBGPM #ifdef F_HAVE_LIBGPM
inline int FApplication::gpmEvent(void) inline int FApplication::gpmEvent(bool clear)
{ {
register int result; register int result;
register int max = (gpm_fd > stdin_no) ? gpm_fd : stdin_no; 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); result = select (max+1, &ifds, 0, 0, &tv);
if ( FD_ISSET(stdin_no, &ifds) ) if ( FD_ISSET(stdin_no, &ifds) )
{ {
FD_CLR (stdin_no, &ifds); if ( clear )
FD_CLR (stdin_no, &ifds);
return keyboard_event; return keyboard_event;
} }
if ( FD_ISSET(gpm_fd, &ifds) ) if ( clear && FD_ISSET(gpm_fd, &ifds) )
FD_CLR (gpm_fd, &ifds); FD_CLR (gpm_fd, &ifds);
if (result > 0) if (result > 0)
return mouse_event; return mouse_event;
@ -225,6 +227,8 @@ void FApplication::processKeyboardEvent()
fifo_in_use = false; fifo_in_use = false;
} }
flush_out();
#ifdef F_HAVE_LIBGPM #ifdef F_HAVE_LIBGPM
if ( gpm_mouse_enabled ) if ( gpm_mouse_enabled )
{ {
@ -272,7 +276,7 @@ void FApplication::processKeyboardEvent()
// read the rest from the fifo buffer // read the rest from the fifo buffer
while ( ! widget->isKeyTimeout(&time_keypressed, key_timeout) while ( ! widget->isKeyTimeout(&time_keypressed, key_timeout)
&& fifo_offset && fifo_offset > 0
&& key != NEED_MORE_DATA ) && key != NEED_MORE_DATA )
{ {
key = FTerm::parseKeyString(fifo_buf, fifo_buf_size, &time_keypressed); 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[1] = fifo_buf[4];
x11_mouse[2] = fifo_buf[5]; x11_mouse[2] = fifo_buf[5];
x11_mouse[3] = '\0'; x11_mouse[3] = '\0';
len = int(strlen(fifo_buf)); len = 6;
n = len; n = len;
for (; n < fifo_buf_size; n++) for (; n < fifo_buf_size; n++) // Remove founded entry
fifo_buf[n-len] = fifo_buf[n]; // remove the founded entry fifo_buf[n-len] = fifo_buf[n];
for (; n-len < len; n++) for (; n-len < len; n++) // Fill rest with '\0'
fifo_buf[n-len] = '\0'; fifo_buf[n-len] = '\0';
input_data_pending = bool(fifo_buf[0] != '\0');
processMouseEvent();
} }
else if ( key == fc::Fkey_extended_mouse ) else if ( key == fc::Fkey_extended_mouse )
{ {
int n = 3; int n = 3;
int len = int(strlen(fifo_buf)); 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]; 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'; sgr_mouse[n-3] = '\0';
for (n=len; n < fifo_buf_size; n++) for (n=len; n < fifo_buf_size; n++) // Remove founded entry
fifo_buf[n-len] = fifo_buf[n]; // remove the founded entry fifo_buf[n-len] = fifo_buf[n];
for (; n-len < len; n++) for (; n-len < len; n++) // Fill rest with '\0'
fifo_buf[n-len] = '\0'; fifo_buf[n-len] = '\0';
input_data_pending = bool(fifo_buf[0] != '\0');
processMouseEvent();
} }
else if ( key == fc::Fkey_urxvt_mouse ) else if ( key == fc::Fkey_urxvt_mouse )
{ {
int n = 2; int n = 2;
int len = int(strlen(fifo_buf)); 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]; 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'; urxvt_mouse[n-2] = '\0';
for (n=len; n < fifo_buf_size; n++) for (n=len; n < fifo_buf_size; n++) // Remove founded entry
fifo_buf[n-len] = fifo_buf[n]; // remove the founded entry fifo_buf[n-len] = fifo_buf[n];
for (; n-len < len; n++) for (; n-len < len; n++) // Fill rest with '\0'
fifo_buf[n-len] = '\0'; fifo_buf[n-len] = '\0';
input_data_pending = bool(fifo_buf[0] != '\0');
processMouseEvent();
} }
else else
{ {
@ -377,6 +397,7 @@ void FApplication::processKeyboardEvent()
{ {
FKeyEvent k_press_ev(KeyPress_Event, fc::Fkey_escape); FKeyEvent k_press_ev(KeyPress_Event, fc::Fkey_escape);
sendEvent(widget, &k_press_ev); sendEvent(widget, &k_press_ev);
input_data_pending = false;
} }
} }
@ -904,10 +925,18 @@ bool FApplication::processGpmEvent()
break; break;
} }
mouse->setPoint(gpm_ev.x, gpm_ev.y); 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); GPM_DRAWPOINTER(&gpm_ev);
gpmMouseEvent = false;
return true; return true;
} }
gpmMouseEvent = false;
return false; return false;
} }
#endif // F_HAVE_LIBGPM #endif // F_HAVE_LIBGPM
@ -1101,7 +1130,6 @@ void FApplication::processMouseEvent()
sendEvent(scroll_over_widget, &wheel_ev); sendEvent(scroll_over_widget, &wheel_ev);
} }
} }
flush_out();
#ifdef F_HAVE_LIBGPM #ifdef F_HAVE_LIBGPM
if ( gpm_mouse_enabled && gpm_ev.x != -1 ) if ( gpm_mouse_enabled && gpm_ev.x != -1 )
@ -1175,6 +1203,26 @@ bool FApplication::processNextEvent()
processMouseEvent(); processMouseEvent();
processResizeEvent(); 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() ) if ( close_widget && ! close_widget->empty() )
{ {
widgetList::iterator iter; widgetList::iterator iter;

View File

@ -61,6 +61,7 @@ class FApplication : public FWidget
static int loop_level; static int loop_level;
static bool process_timer_event; static bool process_timer_event;
static FPoint* zero_point; static FPoint* zero_point;
int skipped_terminal_update;
int key; int key;
char k_buf[1024]; char k_buf[1024];
char x11_mouse[4]; char x11_mouse[4];
@ -127,7 +128,7 @@ class FApplication : public FWidget
bool parseUrxvtMouse(); bool parseUrxvtMouse();
#ifdef F_HAVE_LIBGPM #ifdef F_HAVE_LIBGPM
int gpmEvent(); int gpmEvent(bool = true);
bool processGpmEvent(); bool processGpmEvent();
#endif #endif
@ -143,11 +144,12 @@ class FApplication : public FWidget
FApplication (int &argc, char* argv[]); // constructor FApplication (int &argc, char* argv[]); // constructor
virtual ~FApplication(); // destructor virtual ~FApplication(); // destructor
const char* getClassName() const; const char* getClassName() const;
int argc() const; int argc() const;
char** argv() const; char** argv() const;
FWidget* mainWidget() const; FWidget* mainWidget() const;
FWidget* focusWidget() const; FWidget* focusWidget() const;
bool unprocessedInput() const;
static void print_cmd_Options(); static void print_cmd_Options();
void setMainWidget (FWidget*); void setMainWidget (FWidget*);
int exec(); // run int exec(); // run
@ -166,6 +168,10 @@ class FApplication : public FWidget
// FApplication inline functions // FApplication inline functions
//----------------------------------------------------------------------
inline const char* FApplication::getClassName() const
{ return "FApplication"; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline int FApplication::argc() const inline int FApplication::argc() const
{ return app_argc; } { return app_argc; }
@ -183,7 +189,7 @@ inline FWidget* FApplication::focusWidget() const
{ return focus_widget; } { return focus_widget; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline const char* FApplication::getClassName() const inline bool FApplication::unprocessedInput() const
{ return "FApplication"; } { return input_data_pending; }
#endif // _FAPPLICATION_H #endif // _FAPPLICATION_H

View File

@ -56,7 +56,7 @@ void FMenuBar::menu_dimension()
{ {
int item_X = 1; int item_X = 1;
int item_Y = 1; int item_Y = 1;
std::vector<FMenuItem*>::const_iterator begin, end, iter; std::vector<FMenuItem*>::const_iterator end, iter;
iter = itemlist.begin(); iter = itemlist.begin();
end = itemlist.end(); end = itemlist.end();

View File

@ -511,7 +511,7 @@ int FOptiMove::relative_move ( char*& move
if ( htime >= LONG_DURATION ) if ( htime >= LONG_DURATION )
return LONG_DURATION; return LONG_DURATION;
if ( move ) if ( *move )
strcat (move, hmove); strcat (move, hmove);
else else
strcpy (move, hmove); strcpy (move, hmove);

View File

@ -48,6 +48,9 @@ bool FTerm::mouse_support;
bool FTerm::vt100_state; bool FTerm::vt100_state;
bool FTerm::ignore_vt100_state; bool FTerm::ignore_vt100_state;
bool FTerm::raw_mode; 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::non_blocking_stdin;
bool FTerm::gpm_mouse_enabled; bool FTerm::gpm_mouse_enabled;
bool FTerm::color256; bool FTerm::color256;
@ -762,10 +765,11 @@ int FTerm::parseKeyString ( char* buffer
if ( k && strncmp(k, buffer, uInt(len)) == 0 ) // found if ( k && strncmp(k, buffer, uInt(len)) == 0 ) // found
{ {
n = len; n = len;
for (; n < buf_size; n++) for (; n < buf_size; n++) // Remove founded entry
buffer[n-len] = buffer[n]; // remove the founded entry buffer[n-len] = buffer[n];
for (; n-len < len; n++) for (; n-len < len; n++) // Fill rest with '\0'
buffer[n-len] = '\0'; buffer[n-len] = '\0';
input_data_pending = bool(buffer[0] != '\0');
return Fkey[i].num; return Fkey[i].num;
} }
} }
@ -785,10 +789,11 @@ int FTerm::parseKeyString ( char* buffer
return NEED_MORE_DATA; return NEED_MORE_DATA;
} }
n = len; n = len;
for (; n < buf_size; n++) for (; n < buf_size; n++) // Remove founded entry
buffer[n-len] = buffer[n]; // remove the founded entry buffer[n-len] = buffer[n];
for (; n-len < len; n++) for (; n-len < len; n++) // Fill rest with '\0'
buffer[n-len] = '\0'; buffer[n-len] = '\0';
input_data_pending = bool(buffer[0] != '\0');
return Fmetakey[i].num; return Fmetakey[i].num;
} }
} }
@ -822,6 +827,7 @@ int FTerm::parseKeyString ( char* buffer
buffer[n-len] = buffer[n]; buffer[n-len] = buffer[n];
for (n=n-len; n < buf_size; n++) // fill the rest with '\0' bytes for (n=n-len; n < buf_size; n++) // fill the rest with '\0' bytes
buffer[n] = '\0'; buffer[n] = '\0';
input_data_pending = bool(buffer[0] != '\0');
return int(key == 127 ? fc::Fkey_backspace : key); return int(key == 127 ? fc::Fkey_backspace : key);
} }
@ -940,6 +946,9 @@ void FTerm::init()
// assertion: programm start in cooked mode // assertion: programm start in cooked mode
raw_mode = false; raw_mode = false;
input_data_pending = false;
terminal_update_pending = false;
force_terminal_update = false;
non_blocking_stdin = false; non_blocking_stdin = false;
stdin_no = fileno(stdin); stdin_no = fileno(stdin);
@ -2468,8 +2477,17 @@ void FTerm::updateTerminal()
if ( static_cast<FApplication*>(term_object)->isQuit() ) if ( static_cast<FApplication*>(term_object)->isQuit() )
return; return;
if ( ! terminal_updates ) if ( ! force_terminal_update )
return; {
if ( ! terminal_updates )
return;
if ( input_data_pending )
{
terminal_update_pending = true;
return;
}
}
vt = vterm; vt = vterm;
term_width = term->getWidth(); term_width = term->getWidth();
@ -3440,16 +3458,28 @@ FString FTerm::getAnswerbackMsg()
if ( raw_mode ) if ( raw_mode )
{ {
int n; int n;
fd_set ifds;
struct timeval tv;
char temp[10] = {}; 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 putchar(0x05); // send enquiry character
fflush(stdout); fflush(stdout);
usleep(150000); // wait 150 ms
// read the answerback message // read the answerback message
n = read(fileno(stdin), &temp, sizeof(temp)-1); if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0)
if ( n > 0 )
{ {
temp[n] = '\0'; n = read(fileno(stdin), &temp, sizeof(temp)-1);
answerback = temp;
if ( n > 0 )
{
temp[n] = '\0';
answerback = temp;
}
} }
} }
return answerback; return answerback;
@ -3463,20 +3493,32 @@ FString FTerm::getSecDA()
if ( raw_mode ) if ( raw_mode )
{ {
int n; int n;
fd_set ifds;
struct timeval tv;
char temp[16] = {}; 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 // get the secondary device attributes
putchar(0x1b); // ESC putchar(0x1b); // ESC
putchar(0x5b); // [ putchar(0x5b); // [
putchar(0x3e); // > putchar(0x3e); // >
putchar(0x63); // c putchar(0x63); // c
fflush(stdout); fflush(stdout);
usleep(150000); // wait 150 ms
// read the answer // read the answer
n = read(fileno(stdin), &temp, sizeof(temp)-1); if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0 )
if ( n > 0 )
{ {
temp[n] = '\0'; n = read(fileno(stdin), &temp, sizeof(temp)-1);
sec_da = temp;
if ( n > 0 )
{
temp[n] = '\0';
sec_da = temp;
}
} }
} }
return sec_da; return sec_da;

View File

@ -98,6 +98,9 @@ class FTerm
static bool vt100_state; static bool vt100_state;
static bool ignore_vt100_state; static bool ignore_vt100_state;
static bool raw_mode; 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 non_blocking_stdin;
static bool gpm_mouse_enabled; static bool gpm_mouse_enabled;
static bool pc_charset_state; static bool pc_charset_state;