Non-blocking reading before timeout after keystroke

This commit is contained in:
Markus Gans 2020-11-02 22:17:07 +01:00
parent a053ccd69e
commit 396985f594
9 changed files with 46 additions and 17 deletions

View File

@ -1,3 +1,7 @@
2020-11-02 Markus Gans <guru.mail@muenster.de>
* Non-blocking reading before timeout after keystroke
* Every fourth event processing causes a terminal flush
2020-11-01 Markus Gans <guru.mail@muenster.de> 2020-11-01 Markus Gans <guru.mail@muenster.de>
* Now FINAL CUT queues keyboard and mouse input to speed up * Now FINAL CUT queues keyboard and mouse input to speed up
the processing of widget events the processing of widget events

View File

@ -28,6 +28,9 @@ int main (int argc, char* argv[])
// Create the application object // Create the application object
finalcut::FApplication app{argc, argv}; finalcut::FApplication app{argc, argv};
// Enable the non-blocking reading mode
//app.setNonBlockingRead();
// Create a simple dialog box // Create a simple dialog box
finalcut::FMessageBox mbox{&app}; finalcut::FMessageBox mbox{&app};
mbox.setText("Hello world"); mbox.setText("Hello world");

View File

@ -73,7 +73,7 @@ FMouseControl* FApplication::mouse {nullptr}; // mouse control
int FApplication::loop_level {0}; // event loop level int FApplication::loop_level {0}; // event loop level
int FApplication::quit_code {EXIT_SUCCESS}; int FApplication::quit_code {EXIT_SUCCESS};
bool FApplication::quit_now {false}; bool FApplication::quit_now {false};
uInt64 FApplication::next_event_wait {5000}; // preset to 5 ms (200 Hz) uInt64 FApplication::next_event_wait {5000}; // 5 ms (200 Hz)
struct timeval FApplication::time_last_event {}; struct timeval FApplication::time_last_event {};
@ -693,7 +693,7 @@ void FApplication::escapeKeyPressed() const
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FApplication::mouseTracking() void FApplication::mouseTracking() const
{ {
performMouseAction(); performMouseAction();
} }
@ -1231,6 +1231,16 @@ void FApplication::sendWheelEvent ( const FMouseData& md
} }
} }
//----------------------------------------------------------------------
inline void FApplication::flushTerminal()
{
if ( flush_count == 0 || flush_count % 4 != 0 )
return;
flush();
flush_count = 0;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FWidget* FApplication::processParameters (const int& argc, char* argv[]) FWidget* FApplication::processParameters (const int& argc, char* argv[])
{ {
@ -1312,7 +1322,8 @@ bool FApplication::processNextEvent()
processResizeEvent(); processResizeEvent();
processCloseWidget(); processCloseWidget();
processTerminalUpdate(); // after terminal changes processTerminalUpdate(); // after terminal changes
flush(); flushTerminal();
flush_count++;
processLogger(); processLogger();
} }

View File

@ -46,8 +46,10 @@ namespace finalcut
{ {
// static class attributes // static class attributes
uInt64 FKeyboard::read_blocking_time{100000}; // preset to 100 ms (10 Hz) uInt64 FKeyboard::key_timeout{100000}; // 100 ms (10 Hz)
uInt64 FKeyboard::key_timeout{100000}; // preset to 100 ms (10 Hz) uInt64 FKeyboard::read_blocking_time{100000}; // 100 ms (10 Hz)
uInt64 FKeyboard::read_blocking_time_short{5000}; // 5 ms (200 Hz)
bool FKeyboard::non_blocking_input_support{true};
struct timeval FKeyboard::time_keypressed{}; struct timeval FKeyboard::time_keypressed{};
#if defined(__linux__) #if defined(__linux__)
@ -163,7 +165,7 @@ bool FKeyboard::isKeyPressed (uInt64 blocking_time)
tv.tv_sec = tv.tv_usec = 0; // Non-blocking input tv.tv_sec = tv.tv_usec = 0; // Non-blocking input
if ( blocking_time > 0 if ( blocking_time > 0
&& term_detection->hasNonBlockingInputSupport() && non_blocking_input_support
&& select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 && select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0
&& FD_ISSET(stdin_no, &ifds) ) && FD_ISSET(stdin_no, &ifds) )
{ {
@ -172,7 +174,10 @@ bool FKeyboard::isKeyPressed (uInt64 blocking_time)
tv.tv_sec = 0; tv.tv_sec = 0;
} }
tv.tv_usec = suseconds_t(blocking_time); // preset to 100 ms if ( isKeypressTimeout() || ! non_blocking_input_support )
tv.tv_usec = suseconds_t(blocking_time);
else
tv.tv_usec = suseconds_t(read_blocking_time_short);
if ( ! has_pending_input if ( ! has_pending_input
&& select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 && select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0

View File

@ -60,7 +60,7 @@ FKeyboard* FTermDetection::keyboard{nullptr};
char FTermDetection::termtype[256]{}; char FTermDetection::termtype[256]{};
char FTermDetection::ttytypename[256]{}; char FTermDetection::ttytypename[256]{};
bool FTermDetection::decscusr_support{}; bool FTermDetection::decscusr_support{};
bool FTermDetection::non_blocking_input_support{};
bool FTermDetection::terminal_detection{}; bool FTermDetection::terminal_detection{};
bool FTermDetection::color256{}; bool FTermDetection::color256{};
const FString* FTermDetection::answer_back{nullptr}; const FString* FTermDetection::answer_back{nullptr};
@ -84,7 +84,6 @@ FTermDetection::FTermDetection()
{ {
// Preset to true // Preset to true
terminal_detection = true; terminal_detection = true;
non_blocking_input_support = true;
// Preset to false // Preset to false
decscusr_support = false; decscusr_support = false;
@ -411,8 +410,9 @@ void FTermDetection::detectTerminal()
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
const auto& termfilename = fterm_data->getTermFileName(); const auto& termfilename = fterm_data->getTermFileName();
// Fixes problem with mouse input
if ( std::strncmp(termfilename, "/dev/cons", 9) == 0 ) if ( std::strncmp(termfilename, "/dev/cons", 9) == 0 )
non_blocking_input_support = false; // Fixes problem with mouse input FKeyboard::setNonBlockingInputSupport(false);
#endif #endif
} }

View File

@ -217,7 +217,10 @@ void FVTerm::setNonBlockingRead (bool enable)
termfilename[0] = '\0'; termfilename[0] = '\0';
if ( std::strncmp(termfilename, "/dev/cons", 9) == 0 ) if ( std::strncmp(termfilename, "/dev/cons", 9) == 0 )
{
FKeyboard::setNonBlockingInputSupport(false);
return; return;
}
#endif #endif
uInt64 blocking_time = (enable) ? 5000 : 100000; // 5 or 100 ms uInt64 blocking_time = (enable) ? 5000 : 100000; // 5 or 100 ms

View File

@ -182,7 +182,7 @@ class FApplication : public FWidget
void keyPressed(); void keyPressed();
void keyReleased() const; void keyReleased() const;
void escapeKeyPressed() const; void escapeKeyPressed() const;
void mouseTracking(); void mouseTracking() const;
void performKeyboardAction(); void performKeyboardAction();
void performMouseAction() const; void performMouseAction() const;
void mouseEvent (const FMouseData&); void mouseEvent (const FMouseData&);
@ -222,6 +222,7 @@ class FApplication : public FWidget
void sendWheelEvent ( const FMouseData& void sendWheelEvent ( const FMouseData&
, const FPoint& , const FPoint&
, const FPoint& ) const; , const FPoint& ) const;
void flushTerminal();
static FWidget* processParameters (const int&, char*[]); static FWidget* processParameters (const int&, char*[]);
void processResizeEvent() const; void processResizeEvent() const;
void processCloseWidget(); void processCloseWidget();
@ -239,6 +240,7 @@ class FApplication : public FWidget
std::streambuf* default_clog_rdbuf{std::clog.rdbuf()}; std::streambuf* default_clog_rdbuf{std::clog.rdbuf()};
FWidget* clicked_widget{}; FWidget* clicked_widget{};
FEventQueue event_queue{}; FEventQueue event_queue{};
int flush_count{0};
static uInt64 next_event_wait; static uInt64 next_event_wait;
static timeval time_last_event; static timeval time_last_event;
static int quit_code; static int quit_code;

View File

@ -119,6 +119,7 @@ class FKeyboard final
void setTermcapMap (const T&); void setTermcapMap (const T&);
static void setKeypressTimeout (const uInt64); static void setKeypressTimeout (const uInt64);
static void setReadBlockingTime (const uInt64); static void setReadBlockingTime (const uInt64);
static void setNonBlockingInputSupport (bool);
bool setNonBlockingInput (bool); bool setNonBlockingInput (bool);
bool setNonBlockingInput(); bool setNonBlockingInput();
bool unsetNonBlockingInput(); bool unsetNonBlockingInput();
@ -189,7 +190,9 @@ class FKeyboard final
FTermDetection* term_detection{nullptr}; FTermDetection* term_detection{nullptr};
static timeval time_keypressed; static timeval time_keypressed;
static uInt64 read_blocking_time; static uInt64 read_blocking_time;
static uInt64 read_blocking_time_short;
static uInt64 key_timeout; static uInt64 key_timeout;
static bool non_blocking_input_support;
FKeyMapPtr key_map{}; FKeyMapPtr key_map{};
std::queue<FKey> fkey_queue{}; std::queue<FKey> fkey_queue{};
FKey fkey{0}; FKey fkey{0};
@ -244,6 +247,10 @@ inline void FKeyboard::setKeypressTimeout (const uInt64 timeout)
inline void FKeyboard::setReadBlockingTime (const uInt64 blocking_time) inline void FKeyboard::setReadBlockingTime (const uInt64 blocking_time)
{ read_blocking_time = blocking_time; } { read_blocking_time = blocking_time; }
//----------------------------------------------------------------------
inline void FKeyboard::setNonBlockingInputSupport (bool enable)
{ non_blocking_input_support = enable; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FKeyboard::setNonBlockingInput() inline bool FKeyboard::setNonBlockingInput()
{ return setNonBlockingInput(true); } { return setNonBlockingInput(true); }

View File

@ -128,7 +128,6 @@ class FTermDetection final
static bool isMltermTerminal(); static bool isMltermTerminal();
static bool canDisplay256Colors(); static bool canDisplay256Colors();
static bool hasTerminalDetection(); static bool hasTerminalDetection();
static bool hasNonBlockingInputSupport();
static bool hasSetCursorStyleSupport(); static bool hasSetCursorStyleSupport();
// Mutators // Mutators
@ -204,7 +203,6 @@ class FTermDetection final
static char termtype[256]; static char termtype[256];
static char ttytypename[256]; static char ttytypename[256];
static bool decscusr_support; static bool decscusr_support;
static bool non_blocking_input_support;
static bool terminal_detection; static bool terminal_detection;
static bool color256; static bool color256;
static int gnome_terminal_id; static int gnome_terminal_id;
@ -279,10 +277,6 @@ inline const char* FTermDetection::getTermType_SecDA()
inline bool FTermDetection::canDisplay256Colors() inline bool FTermDetection::canDisplay256Colors()
{ return color256; } { return color256; }
//----------------------------------------------------------------------
inline bool FTermDetection::hasNonBlockingInputSupport()
{ return non_blocking_input_support; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool FTermDetection::hasSetCursorStyleSupport() inline bool FTermDetection::hasSetCursorStyleSupport()
{ return decscusr_support; } { return decscusr_support; }