diff --git a/ChangeLog b/ChangeLog index f7dcfd4d..eca68fb3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2020-11-02 Markus Gans + * Non-blocking reading before timeout after keystroke + * Every fourth event processing causes a terminal flush + 2020-11-01 Markus Gans * Now FINAL CUT queues keyboard and mouse input to speed up the processing of widget events diff --git a/examples/hello.cpp b/examples/hello.cpp index 613711c2..0ac66b9b 100644 --- a/examples/hello.cpp +++ b/examples/hello.cpp @@ -28,6 +28,9 @@ int main (int argc, char* argv[]) // Create the application object finalcut::FApplication app{argc, argv}; + // Enable the non-blocking reading mode + //app.setNonBlockingRead(); + // Create a simple dialog box finalcut::FMessageBox mbox{&app}; mbox.setText("Hello world"); diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 0144c8a1..2f3a7353 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -73,7 +73,7 @@ FMouseControl* FApplication::mouse {nullptr}; // mouse control int FApplication::loop_level {0}; // event loop level int FApplication::quit_code {EXIT_SUCCESS}; 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 {}; @@ -693,7 +693,7 @@ void FApplication::escapeKeyPressed() const } //---------------------------------------------------------------------- -void FApplication::mouseTracking() +void FApplication::mouseTracking() const { 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[]) { @@ -1312,7 +1322,8 @@ bool FApplication::processNextEvent() processResizeEvent(); processCloseWidget(); processTerminalUpdate(); // after terminal changes - flush(); + flushTerminal(); + flush_count++; processLogger(); } diff --git a/src/fkeyboard.cpp b/src/fkeyboard.cpp index 7ee947ed..2fddcdc8 100644 --- a/src/fkeyboard.cpp +++ b/src/fkeyboard.cpp @@ -46,8 +46,10 @@ namespace finalcut { // static class attributes -uInt64 FKeyboard::read_blocking_time{100000}; // preset to 100 ms (10 Hz) -uInt64 FKeyboard::key_timeout{100000}; // preset to 100 ms (10 Hz) +uInt64 FKeyboard::key_timeout{100000}; // 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{}; #if defined(__linux__) @@ -163,7 +165,7 @@ bool FKeyboard::isKeyPressed (uInt64 blocking_time) tv.tv_sec = tv.tv_usec = 0; // Non-blocking input if ( blocking_time > 0 - && term_detection->hasNonBlockingInputSupport() + && non_blocking_input_support && select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 && FD_ISSET(stdin_no, &ifds) ) { @@ -172,7 +174,10 @@ bool FKeyboard::isKeyPressed (uInt64 blocking_time) 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 && select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 diff --git a/src/ftermdetection.cpp b/src/ftermdetection.cpp index 040ee272..7044e19b 100644 --- a/src/ftermdetection.cpp +++ b/src/ftermdetection.cpp @@ -60,7 +60,7 @@ FKeyboard* FTermDetection::keyboard{nullptr}; char FTermDetection::termtype[256]{}; char FTermDetection::ttytypename[256]{}; bool FTermDetection::decscusr_support{}; -bool FTermDetection::non_blocking_input_support{}; + bool FTermDetection::terminal_detection{}; bool FTermDetection::color256{}; const FString* FTermDetection::answer_back{nullptr}; @@ -84,7 +84,6 @@ FTermDetection::FTermDetection() { // Preset to true terminal_detection = true; - non_blocking_input_support = true; // Preset to false decscusr_support = false; @@ -411,8 +410,9 @@ void FTermDetection::detectTerminal() #if defined(__CYGWIN__) const auto& termfilename = fterm_data->getTermFileName(); + // Fixes problem with mouse input if ( std::strncmp(termfilename, "/dev/cons", 9) == 0 ) - non_blocking_input_support = false; // Fixes problem with mouse input + FKeyboard::setNonBlockingInputSupport(false); #endif } diff --git a/src/fvterm.cpp b/src/fvterm.cpp index c314cebc..7fbacbf1 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -217,7 +217,10 @@ void FVTerm::setNonBlockingRead (bool enable) termfilename[0] = '\0'; if ( std::strncmp(termfilename, "/dev/cons", 9) == 0 ) + { + FKeyboard::setNonBlockingInputSupport(false); return; + } #endif uInt64 blocking_time = (enable) ? 5000 : 100000; // 5 or 100 ms diff --git a/src/include/final/fapplication.h b/src/include/final/fapplication.h index fb52e5df..1b4e7623 100644 --- a/src/include/final/fapplication.h +++ b/src/include/final/fapplication.h @@ -182,7 +182,7 @@ class FApplication : public FWidget void keyPressed(); void keyReleased() const; void escapeKeyPressed() const; - void mouseTracking(); + void mouseTracking() const; void performKeyboardAction(); void performMouseAction() const; void mouseEvent (const FMouseData&); @@ -222,6 +222,7 @@ class FApplication : public FWidget void sendWheelEvent ( const FMouseData& , const FPoint& , const FPoint& ) const; + void flushTerminal(); static FWidget* processParameters (const int&, char*[]); void processResizeEvent() const; void processCloseWidget(); @@ -239,6 +240,7 @@ class FApplication : public FWidget std::streambuf* default_clog_rdbuf{std::clog.rdbuf()}; FWidget* clicked_widget{}; FEventQueue event_queue{}; + int flush_count{0}; static uInt64 next_event_wait; static timeval time_last_event; static int quit_code; diff --git a/src/include/final/fkeyboard.h b/src/include/final/fkeyboard.h index a7b6d3b9..1be3f0ae 100644 --- a/src/include/final/fkeyboard.h +++ b/src/include/final/fkeyboard.h @@ -119,6 +119,7 @@ class FKeyboard final void setTermcapMap (const T&); static void setKeypressTimeout (const uInt64); static void setReadBlockingTime (const uInt64); + static void setNonBlockingInputSupport (bool); bool setNonBlockingInput (bool); bool setNonBlockingInput(); bool unsetNonBlockingInput(); @@ -189,7 +190,9 @@ class FKeyboard final FTermDetection* term_detection{nullptr}; static timeval time_keypressed; static uInt64 read_blocking_time; + static uInt64 read_blocking_time_short; static uInt64 key_timeout; + static bool non_blocking_input_support; FKeyMapPtr key_map{}; std::queue fkey_queue{}; FKey fkey{0}; @@ -244,6 +247,10 @@ inline void FKeyboard::setKeypressTimeout (const uInt64 timeout) inline void FKeyboard::setReadBlockingTime (const uInt64 blocking_time) { read_blocking_time = blocking_time; } +//---------------------------------------------------------------------- +inline void FKeyboard::setNonBlockingInputSupport (bool enable) +{ non_blocking_input_support = enable; } + //---------------------------------------------------------------------- inline bool FKeyboard::setNonBlockingInput() { return setNonBlockingInput(true); } diff --git a/src/include/final/ftermdetection.h b/src/include/final/ftermdetection.h index 0fff311a..89798b87 100644 --- a/src/include/final/ftermdetection.h +++ b/src/include/final/ftermdetection.h @@ -128,7 +128,6 @@ class FTermDetection final static bool isMltermTerminal(); static bool canDisplay256Colors(); static bool hasTerminalDetection(); - static bool hasNonBlockingInputSupport(); static bool hasSetCursorStyleSupport(); // Mutators @@ -204,7 +203,6 @@ class FTermDetection final static char termtype[256]; static char ttytypename[256]; static bool decscusr_support; - static bool non_blocking_input_support; static bool terminal_detection; static bool color256; static int gnome_terminal_id; @@ -279,10 +277,6 @@ inline const char* FTermDetection::getTermType_SecDA() inline bool FTermDetection::canDisplay256Colors() { return color256; } -//---------------------------------------------------------------------- -inline bool FTermDetection::hasNonBlockingInputSupport() -{ return non_blocking_input_support; } - //---------------------------------------------------------------------- inline bool FTermDetection::hasSetCursorStyleSupport() { return decscusr_support; }