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