diff --git a/ChangeLog b/ChangeLog index 117f37a9..864bc31b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2019-11-18 Markus Gans + * The terminal update rate is now limited to 60 Hz + 2019-11-14 Markus Gans * Version 0.7.1 * Bugfix: The cursor position was not changed anymore diff --git a/examples/transparent.cpp b/examples/transparent.cpp index b12392e1..b4cca03b 100644 --- a/examples/transparent.cpp +++ b/examples/transparent.cpp @@ -248,7 +248,7 @@ void MainWindow::onClose (finalcut::FCloseEvent* ev) //---------------------------------------------------------------------- void MainWindow::onShow (finalcut::FShowEvent*) { - addTimer(100); // Call onTimer() every 100 ms + addTimer(90); // Call onTimer() every 90 ms } //---------------------------------------------------------------------- diff --git a/src/fapplication.cpp b/src/fapplication.cpp index 01878a30..f2d93803 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -73,7 +73,6 @@ 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}; -bool FApplication::pending_updates {false}; uInt64 FApplication::next_event_wait {5000}; // 5 ms (200 Hz) struct timeval FApplication::time_last_event {}; @@ -391,9 +390,6 @@ void FApplication::closeConfirmationDialog (FWidget* w, FCloseEvent* ev) void FApplication::processExternalUserEvent() { // This method can be overloaded and replaced by own code - - if ( FKeyboard::getReadBlockingTime() < 10000 ) - std::this_thread::sleep_for(std::chrono::milliseconds(5)); } @@ -758,9 +754,6 @@ void FApplication::mouseEvent (const FMouseData& md) unselectMenubarItems (md); sendMouseEvent (md); } - - if ( mouse ) - mouse->drawGpmPointer(); } //---------------------------------------------------------------------- @@ -1231,23 +1224,6 @@ void FApplication::sendWheelEvent ( const FMouseData& md } } -//---------------------------------------------------------------------- -inline void FApplication::flushTerminal() -{ - if ( ! pending_updates ) - return; - - if ( flush_count < 4 ) - { - flush_count++; - return; - } - - flush(); - flush_count = 0; - pending_updates = false; -} - //---------------------------------------------------------------------- FWidget* FApplication::processParameters (const int& argc, char* argv[]) { @@ -1328,11 +1304,8 @@ bool FApplication::processNextEvent() processMouseEvent(); processResizeEvent(); processCloseWidget(); - - if ( processTerminalUpdate() ) // after terminal changes - pending_updates = true; - - flushTerminal(); + processTerminalUpdate(); // after terminal changes + flush(); processLogger(); } @@ -1342,8 +1315,6 @@ bool FApplication::processNextEvent() { sendQueuedEvents(); num_events += processTimerEvent(); - uInt64 wait{next_event_wait / 2}; - std::this_thread::sleep_for(std::chrono::microseconds(wait)); } return ( num_events > 0 ); diff --git a/src/fmouse.cpp b/src/fmouse.cpp index d609959a..5db6a52c 100644 --- a/src/fmouse.cpp +++ b/src/fmouse.cpp @@ -510,7 +510,7 @@ bool FMouseGPM::getGpmKeyPressed (bool is_pending) } //---------------------------------------------------------------------- -void FMouseGPM::drawGpmPointer() const +void FMouseGPM::drawPointer() const { if ( isGpmMouseEnabled() && gpm_ev.x != -1 ) GPM_DRAWPOINTER(&gpm_ev); @@ -1605,7 +1605,7 @@ bool FMouseControl::getGpmKeyPressed (bool) //---------------------------------------------------------------------- #ifdef F_HAVE_LIBGPM -void FMouseControl::drawGpmPointer() +void FMouseControl::drawPointer() { if ( mouse_protocol.empty() ) return; @@ -1614,10 +1614,10 @@ void FMouseControl::drawGpmPointer() auto gpm_mouse = static_cast(mouse); if ( gpm_mouse ) - gpm_mouse->drawGpmPointer(); + gpm_mouse->drawPointer(); } #else // F_HAVE_LIBGPM -void FMouseControl::drawGpmPointer() +void FMouseControl::drawPointer() { } #endif // F_HAVE_LIBGPM diff --git a/src/fvterm.cpp b/src/fvterm.cpp index ecee8531..a46c1513 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -34,6 +34,7 @@ #include "final/fcolorpair.h" #include "final/fkeyboard.h" #include "final/flog.h" +#include "final/fmouse.h" #include "final/foptiattr.h" #include "final/foptimove.h" #include "final/fstyle.h" @@ -55,13 +56,14 @@ bool FVTerm::draw_completed{false}; bool FVTerm::no_terminal_updates{false}; bool FVTerm::cursor_hideable{false}; bool FVTerm::force_terminal_update{false}; -int FVTerm::skipped_terminal_update{0}; +uInt64 FVTerm::flush_wait{16667}; // 16.6 ms (60 Hz) uInt64 FVTerm::term_size_check_timeout{500000}; // 500 ms uInt FVTerm::erase_char_length{}; uInt FVTerm::repeat_char_length{}; uInt FVTerm::clr_bol_length{}; uInt FVTerm::clr_eol_length{}; uInt FVTerm::cursor_address_length{}; +struct timeval FVTerm::time_last_flush{}; struct timeval FVTerm::last_term_size_check{}; std::vector* FVTerm::output_buffer{nullptr}; FPoint* FVTerm::term_pos{nullptr}; @@ -71,7 +73,7 @@ FTerm* FVTerm::fterm{nullptr}; FVTerm::FTermArea* FVTerm::vterm{nullptr}; FVTerm::FTermArea* FVTerm::vdesktop{nullptr}; FVTerm::FTermArea* FVTerm::active_area{nullptr}; -FKeyboard* FVTerm::keyboard{nullptr}; +FMouseControl* FVTerm::mouse{nullptr}; FChar FVTerm::term_attribute{}; FChar FVTerm::next_attribute{}; FChar FVTerm::s_ch{}; @@ -280,25 +282,14 @@ bool FVTerm::updateTerminal() const } std::size_t changedlines = 0; - static constexpr int check_interval = 5; + for (uInt y{0}; y < uInt(vterm->height); y++) { if ( updateTerminalLine(y) ) changedlines++; - - if ( ! force_terminal_update - && changedlines % check_interval == 0 - && (keyboard->hasUnprocessedInput() || keyboard->isKeyPressed(0) ) - && skipped_terminal_update < max_skip ) - { - // Skipping terminal updates if there is unprocessed inputs - skipped_terminal_update++; - return false; - } } - skipped_terminal_update = 0; vterm->has_changes = false; // sets the new input cursor position @@ -586,7 +577,8 @@ void FVTerm::flush() { // Flush the output buffer - if ( ! output_buffer || output_buffer->empty() ) + if ( ! output_buffer || output_buffer->empty() + || ! (isFlushTimeout() || force_terminal_update) ) return; static const FTerm::defaultPutChar& FTermPutchar = FTerm::putchar(); @@ -599,6 +591,8 @@ void FVTerm::flush() output_buffer->clear(); std::fflush(stdout); + mouse->drawPointer(); + FObject::getCurrentTime (&time_last_flush); } @@ -1259,8 +1253,7 @@ bool FVTerm::processTerminalUpdate() const } // Update data on VTerm - if ( force_terminal_update || skipped_terminal_update == 0 ) - updateVTerm(); + updateVTerm(); // Update the visible terminal return updateTerminal(); @@ -1286,8 +1279,8 @@ void FVTerm::initTerminal() if ( fterm ) fterm->initTerminal(); - // Get FKeyboard object - keyboard = FTerm::getFKeyboard(); + // Get the global FMouseControl object + mouse = FTerm::getFMouseControl(); // Hide the input cursor cursor_hideable = FTerm::isCursorHideable(); @@ -1863,7 +1856,9 @@ void FVTerm::init() vdesktop->visible = true; active_area = vdesktop; - // Initialize the last terminal size check time + // Initialize the flush and last terminal size check time + time_last_flush.tv_sec = 0; + time_last_flush.tv_usec = 0; last_term_size_check.tv_sec = 0; last_term_size_check.tv_usec = 0; } @@ -1902,7 +1897,7 @@ void FVTerm::finish() && FTerm::getFTermData()->isInAlternateScreen() ) clearTerm(); - flush(); + forceTerminalUpdate(); if ( output_buffer ) delete output_buffer; @@ -2866,6 +2861,12 @@ inline bool FVTerm::isTermSizeChanged() const return false; } +//---------------------------------------------------------------------- +inline bool FVTerm::isFlushTimeout() +{ + return FObject::isTimeout (&time_last_flush, flush_wait); +} + //---------------------------------------------------------------------- inline bool FVTerm::isTermSizeCheckTimeout() { diff --git a/src/include/final/fapplication.h b/src/include/final/fapplication.h index bb6dacd2..79ba0bc5 100644 --- a/src/include/final/fapplication.h +++ b/src/include/final/fapplication.h @@ -222,7 +222,6 @@ 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(); @@ -240,13 +239,11 @@ 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 loop_level; static int quit_code; static bool quit_now; - static bool pending_updates; static FMouseControl* mouse; static FKeyboard* keyboard; static FWidget* keyboard_widget; diff --git a/src/include/final/fmouse.h b/src/include/final/fmouse.h index 28ad2800..e265c9e7 100644 --- a/src/include/final/fmouse.h +++ b/src/include/final/fmouse.h @@ -279,7 +279,7 @@ class FMouseGPM final : public FMouse void interpretKeyDown(); void interpretKeyUp(); bool getGpmKeyPressed(bool); - void drawGpmPointer() const; + void drawPointer() const; private: // Enumeration @@ -578,7 +578,7 @@ class FMouseControl virtual void processEvent (struct timeval* time); void processQueuedInput(); bool getGpmKeyPressed (bool); - void drawGpmPointer(); + void drawPointer(); private: // Typedef diff --git a/src/include/final/fvterm.h b/src/include/final/fvterm.h index c96a0a22..db0c3a91 100644 --- a/src/include/final/fvterm.h +++ b/src/include/final/fvterm.h @@ -68,7 +68,6 @@ namespace finalcut // class forward declaration class FColorPair; -class FKeyboard; class FMouseControl; class FPoint; class FRect; @@ -341,7 +340,6 @@ class FVTerm // Constants // Buffer size for character output on the terminal static constexpr uInt TERMINAL_OUTPUT_BUFFER_SIZE = 131072; - static constexpr int max_skip = 2; // Methods void resetTextAreaToDefault ( const FTermArea* @@ -408,6 +406,7 @@ class FVTerm bool updateTerminalCursor() const; bool isInsideTerminal (const FPoint&) const; bool isTermSizeChanged() const; + static bool isFlushTimeout(); static bool isTermSizeCheckTimeout(); static bool hasPendingUpdates (const FTermArea*); static void markAsPrinted (uInt, uInt); @@ -438,12 +437,13 @@ class FVTerm static FChar s_ch; // shadow character static FChar i_ch; // inherit background character static FPoint* term_pos; // terminal cursor position - static FKeyboard* keyboard; + static FMouseControl* mouse; + static timeval time_last_flush; static timeval last_term_size_check; static bool draw_completed; static bool no_terminal_updates; static bool force_terminal_update; - static int skipped_terminal_update; + static uInt64 flush_wait; static uInt64 term_size_check_timeout; static uInt erase_char_length; static uInt repeat_char_length;