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
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[])
: 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) )
{
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;

View File

@ -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
@ -148,6 +149,7 @@ class FApplication : public FWidget
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

View File

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

View File

@ -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);

View File

@ -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,9 +2477,18 @@ void FTerm::updateTerminal()
if ( static_cast<FApplication*>(term_object)->isQuit() )
return;
if ( ! force_terminal_update )
{
if ( ! terminal_updates )
return;
if ( input_data_pending )
{
terminal_update_pending = true;
return;
}
}
vt = vterm;
term_width = term->getWidth();
term_height = term->getHeight();
@ -3440,18 +3458,30 @@ 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
if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0)
{
n = read(fileno(stdin), &temp, sizeof(temp)-1);
if ( n > 0 )
{
temp[n] = '\0';
answerback = temp;
}
}
}
return answerback;
}
@ -3463,22 +3493,34 @@ 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
if ( select (stdin_no+1, &ifds, 0, 0, &tv) > 0 )
{
n = read(fileno(stdin), &temp, sizeof(temp)-1);
if ( n > 0 )
{
temp[n] = '\0';
sec_da = temp;
}
}
}
return sec_da;
}

View File

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