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>
* Now FINAL CUT queues keyboard and mouse input to speed up
the processing of widget events

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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