From ad2766e7062d44132c67f9ca9469ad98bb404575 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 18 Aug 2019 02:04:44 +0200 Subject: [PATCH] Solved problem detecting terminal size on quick changes --- ChangeLog | 3 +++ examples/termcap.cpp | 3 ++- src/ffiledialog.cpp | 29 ++++++++++++++++++++++++----- src/fterm.cpp | 33 ++++++++++++--------------------- src/ftermcap.cpp | 2 +- src/fvterm.cpp | 8 +++++++- src/fwidget.cpp | 5 +++++ src/include/final/ffiledialog.h | 27 +++++++++++++++------------ src/include/final/fsystem.h | 5 +++++ src/include/final/fsystemimpl.h | 21 ++++++++++++++++++++- src/include/final/fvterm.h | 9 --------- test/ftermfreebsd-test.cpp | 21 +++++++++++++++++++++ test/ftermlinux-test.cpp | 21 +++++++++++++++++++++ test/ftermopenbsd-test.cpp | 21 +++++++++++++++++++++ 14 files changed, 157 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42f819c5..8250db2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2019-08-18 Markus Gans + * Solved problem detecting terminal size on quick changes + 2019-08-11 Markus Gans * FRect has now got a scaleBy() method * Convert drawBorder() to a non-member function using FRect diff --git a/examples/termcap.cpp b/examples/termcap.cpp index ecdf5cf2..db1588d8 100644 --- a/examples/termcap.cpp +++ b/examples/termcap.cpp @@ -226,7 +226,8 @@ void tcapString (const std::string& name, const char cap_str[]) #if DEBUG void debug (finalcut::FApplication& TermApp) { - finalcut::FTermDebugData& debug_data = TermApp.getFTermDebugData(); + auto& fterm = TermApp.getFTerm(); + auto& debug_data = fterm.getFTermDebugData(); const finalcut::FString& ab_s = debug_data.getAnswerbackString(); const finalcut::FString& sec_da = debug_data.getSecDAString(); std::cout << "\n.------------------- debug -------------------\r\n"; diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index 5820dd36..3a8190d9 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -21,18 +21,23 @@ ***********************************************************************/ #if defined(__CYGWIN__) - #undef __STRICT_ANSI__ // need for realpath and strdup + #undef __STRICT_ANSI__ // need for strdup #include // need for strcasecmp #endif +#include #include #include "final/fevent.h" +#include "final/fsystem.h" #include "final/ffiledialog.h" namespace finalcut { +// static class attributes +FSystem* FFileDialog::fsystem = nullptr; + // non-member functions //---------------------------------------------------------------------- bool sortByName ( const FFileDialog::dir_entry& lhs @@ -200,7 +205,7 @@ void FFileDialog::setPath (const FString& dir) return; } - if ( realpath(dir.c_str(), resolved_path) != 0 ) + if ( fsystem->realpath(dir.c_str(), resolved_path) != 0 ) r_dir = resolved_path; else r_dir = dir; @@ -321,7 +326,10 @@ void FFileDialog::init() { static constexpr std::size_t w = 42; static constexpr std::size_t h = 15; - int x, y; + int x{}, y{}; + + if ( ! fsystem ) + fsystem = FTerm::getFSystem(); setGeometry(FPoint(1, 1), FSize(w, h), false); auto parent_widget = getParentWidget(); @@ -602,6 +610,9 @@ void FFileDialog::followSymLink (const char* const dir, dir_entry& entry) char symLink[MAXPATHLEN] = { }; struct stat sb; + if ( ! fsystem ) + fsystem = FTerm::getFSystem(); + std::strncpy (symLink, dir, sizeof(symLink)); symLink[sizeof(symLink) - 1] = '\0'; std::strncat ( symLink @@ -609,7 +620,7 @@ void FFileDialog::followSymLink (const char* const dir, dir_entry& entry) , sizeof(symLink) - std::strlen(symLink) - 1); symLink[sizeof(symLink) - 1] = '\0'; - if ( realpath(symLink, resolved_path) == 0 ) + if ( fsystem->realpath(symLink, resolved_path) == 0 ) return; // Cannot follow the symlink if ( lstat(resolved_path, &sb) == -1 ) @@ -665,6 +676,9 @@ int FFileDialog::changeDir (const FString& dirname) FString lastdir = directory; FString newdir = dirname; + if ( ! fsystem ) + fsystem = FTerm::getFSystem(); + if ( newdir.includes('~') ) newdir = newdir.replace('~', getHomeDir()); @@ -733,7 +747,12 @@ const FString FFileDialog::getHomeDir() struct passwd* pwd_ptr; char buf[1024]; - if ( getpwuid_r (geteuid(), &pwd, buf, sizeof(buf), &pwd_ptr) ) + if ( ! fsystem ) + fsystem = FTerm::getFSystem(); + + uid_t euid = fsystem->geteuid(); + + if ( fsystem->getpwuid_r(euid, &pwd, buf, sizeof(buf), &pwd_ptr) ) return FString(""); else return FString(pwd.pw_dir); diff --git a/src/fterm.cpp b/src/fterm.cpp index 580abdc8..cd34954c 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -895,25 +895,18 @@ void FTerm::detectTermSize() data = FTerm::getFTermData(); struct winsize win_size; - bool close_after_detect = false; - int fd = data->getTTYFileDescriptor(); - int ret; - - if ( fd < 0 ) // console is closed - { - if ( openConsole() != 0 ) - return; - - fd = data->getTTYFileDescriptor(); - close_after_detect = true; - } - auto& term_geometry = data->getTermGeometry(); + int ret; + errno = 0; - if ( fsys ) - ret = fsys->ioctl (fd, TIOCGWINSZ, &win_size); - else - ret = -1; + do + { + if ( fsys ) + ret = fsys->ioctl (FTermios::getStdOut(), TIOCGWINSZ, &win_size); + else + ret = -1; + } + while (errno == EINTR); if ( ret != 0 || win_size.ws_col == 0 || win_size.ws_row == 0 ) { @@ -933,9 +926,6 @@ void FTerm::detectTermSize() if ( opti_move ) opti_move->setTermSize ( term_geometry.getWidth() , term_geometry.getHeight() ); - - if ( close_after_detect ) - closeConsole(); } //---------------------------------------------------------------------- @@ -2549,7 +2539,8 @@ void FTerm::signal_handler (int signum) case SIGWINCH: if ( ! data ) break; - else if ( data->hasTermResized() ) + + if ( data->hasTermResized() ) break; // initialize a resize event to the root element diff --git a/src/ftermcap.cpp b/src/ftermcap.cpp index 5f955151..33822f54 100644 --- a/src/ftermcap.cpp +++ b/src/ftermcap.cpp @@ -286,7 +286,7 @@ void FTermcap::termcapKeysVt100 (char*& buffer) const char* key_up_string = tgetstr(C_STR("ku"), &buffer); - if ( (key_up_string && (std::strcmp(key_up_string, CSI "A") == 0)) + if ( (key_up_string && (std::strcmp(key_up_string, ESC "OA") == 0)) || ( TCAP(fc::t_cursor_up) && (std::strcmp(TCAP(fc::t_cursor_up), CSI "A") == 0) ) ) { diff --git a/src/fvterm.cpp b/src/fvterm.cpp index a449569e..c3a388b1 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -262,6 +262,12 @@ void FVTerm::updateTerminal() } } + // Check terminal size has changed + auto data = getFTerm().getFTermData(); + + if ( data->hasTermResized() ) + return; + // Update data on VTerm updateVTerm(); @@ -2511,7 +2517,7 @@ void FVTerm::updateTerminalLine (uInt y) uInt& xmin = vt->changes[y].xmin; uInt& xmax = vt->changes[y].xmax; - if ( xmin <= xmax ) + if ( xmin <= xmax ) // Line has changes { bool draw_leading_ws = false; bool draw_trailing_ws = false; diff --git a/src/fwidget.cpp b/src/fwidget.cpp index c832a6a2..4db505e5 100644 --- a/src/fwidget.cpp +++ b/src/fwidget.cpp @@ -27,6 +27,7 @@ #include "final/fmenubar.h" #include "final/fstatusbar.h" #include "final/fstring.h" +#include "final/ftermdata.h" #include "final/fwidget.h" #include "final/fwidgetcolors.h" @@ -1020,10 +1021,14 @@ void FWidget::resize() { if ( isRootWidget() ) { + FRect old_term_geometry = getTermGeometry(); detectTermSize(); FRect term_geometry = getTermGeometry(); term_geometry.move (-1, -1); + if ( old_term_geometry.getSize() == term_geometry.getSize() ) + return; + resizeVTerm (term_geometry.getSize()); resizeArea (term_geometry, getShadow(), vdesktop); adjustSizeGlobal(); diff --git a/src/include/final/ffiledialog.h b/src/include/final/ffiledialog.h index 282a9c27..a6d4615c 100644 --- a/src/include/final/ffiledialog.h +++ b/src/include/final/ffiledialog.h @@ -68,7 +68,6 @@ #include #include #include -#include #include #include @@ -86,6 +85,9 @@ namespace finalcut { +// class forward declaration +class FSystem; + //---------------------------------------------------------------------- // class FFileDialog //---------------------------------------------------------------------- @@ -195,17 +197,18 @@ class FFileDialog : public FDialog void cb_processShowHidden (FWidget*, FDataPtr); // Data Members - DIR* directory_stream{nullptr}; - dirEntries dir_entries{}; - FString directory{}; - FString filter_pattern{}; - FLineEdit filename{this}; - FListBox filebrowser{this}; - FCheckBox hidden_check{this}; - FButton cancel_btn{this}; - FButton open_btn{this}; - DialogType dlg_type{FFileDialog::Open}; - bool show_hidden{false}; + static FSystem* fsystem; + DIR* directory_stream{nullptr}; + dirEntries dir_entries{}; + FString directory{}; + FString filter_pattern{}; + FLineEdit filename{this}; + FListBox filebrowser{this}; + FCheckBox hidden_check{this}; + FButton cancel_btn{this}; + FButton open_btn{this}; + DialogType dlg_type{FFileDialog::Open}; + bool show_hidden{false}; // Friend functions friend bool sortByName ( const FFileDialog::dir_entry& diff --git a/src/include/final/fsystem.h b/src/include/final/fsystem.h index 7d1ed7e6..122f9138 100644 --- a/src/include/final/fsystem.h +++ b/src/include/final/fsystem.h @@ -35,6 +35,7 @@ #error "Only can be included directly." #endif +#include #include "final/ftypes.h" namespace finalcut @@ -68,6 +69,10 @@ class FSystem virtual int putchar (int) = 0; virtual int tputs (const char*, int, int (*)(int)) = 0; virtual uid_t getuid() = 0; + virtual uid_t geteuid() = 0; + virtual int getpwuid_r ( uid_t, struct passwd*, char*, size_t , + struct passwd**) = 0; + virtual char* realpath (const char*, char*) = 0; }; #pragma pack(pop) diff --git a/src/include/final/fsystemimpl.h b/src/include/final/fsystemimpl.h index ec9a0a55..0fe7d24a 100644 --- a/src/include/final/fsystemimpl.h +++ b/src/include/final/fsystemimpl.h @@ -61,6 +61,10 @@ #undef buttons // from term.h #endif +#if defined(__CYGWIN__) + #undef __STRICT_ANSI__ // need for realpath and strdup +#endif + #include #include #include @@ -71,7 +75,6 @@ #include "final/fc.h" #include "final/fsystem.h" - namespace finalcut { @@ -190,6 +193,22 @@ class FSystemImpl : public FSystem { return ::getuid(); } + + uid_t geteuid() override + { + return ::geteuid(); + } + + int getpwuid_r ( uid_t uid, struct passwd* pwd + , char* buf, size_t buflen, struct passwd** result ) + { + return ::getpwuid_r (uid, pwd, buf, buflen, result); + } + + char* realpath (const char* path, char* resolved_path) override + { + return ::realpath(path, resolved_path); + } }; #pragma pack(pop) diff --git a/src/include/final/fvterm.h b/src/include/final/fvterm.h index 64030eab..fea9eb68 100644 --- a/src/include/final/fvterm.h +++ b/src/include/final/fvterm.h @@ -159,9 +159,6 @@ class FVTerm static char* getTermType(); static char* getTermFileName(); FTerm& getFTerm(); -#if DEBUG - FTermDebugData& getFTermDebugData(); -#endif // Mutators void setTermXY (int, int); @@ -637,12 +634,6 @@ inline char* FVTerm::getTermFileName() inline FTerm& FVTerm::getFTerm() { return *fterm; } -//---------------------------------------------------------------------- -#if DEBUG -inline FTermDebugData& FVTerm::getFTermDebugData() -{ return getFTerm().getFTermDebugData(); } -#endif - //---------------------------------------------------------------------- inline void FVTerm::hideCursor() { return hideCursor(true); } diff --git a/test/ftermfreebsd-test.cpp b/test/ftermfreebsd-test.cpp index bfd6dfce..c4f9996a 100644 --- a/test/ftermfreebsd-test.cpp +++ b/test/ftermfreebsd-test.cpp @@ -66,6 +66,8 @@ class FSystemTest : public finalcut::FSystem int putchar (int) override; int tputs (const char*, int, int (*)(int)) override; uid_t getuid() override; + uid_t geteuid() override; + char* realpath (const char*, char*) override; std::string& getCharacters(); int& getCursorType(); struct keymap_t& getTerminalKeymap(); @@ -534,6 +536,25 @@ uid_t FSystemTest::getuid() return 0; } +//---------------------------------------------------------------------- +uid_t FSystemTest::geteuid() +{ + return 0; +} + +//---------------------------------------------------------------------- +int FSystemTest::getpwuid_r ( uid_t, struct passwd*, char*, size_t + , struct passwd** ) +{ + return 0; +} + +//---------------------------------------------------------------------- +char* FSystemTest::realpath (const char*, char*); +{ + return ""; +} + //---------------------------------------------------------------------- std::string& FSystemTest::getCharacters() { diff --git a/test/ftermlinux-test.cpp b/test/ftermlinux-test.cpp index 64494192..8b9e78d5 100644 --- a/test/ftermlinux-test.cpp +++ b/test/ftermlinux-test.cpp @@ -116,6 +116,8 @@ class FSystemTest : public finalcut::FSystem int putchar (int) override; int tputs (const char*, int, int (*)(int)) override; uid_t getuid() override; + uid_t geteuid() override; + char* realpath (const char*, char*) override; rgb& getRGB (std::size_t); console_font_op& getConsoleFont(); shiftstate& getShiftState(); @@ -1348,6 +1350,25 @@ uid_t FSystemTest::getuid() return 0; } +//---------------------------------------------------------------------- +uid_t FSystemTest::geteuid() +{ + return 0; +} + +//---------------------------------------------------------------------- +int FSystemTest::getpwuid_r ( uid_t, struct passwd*, char*, size_t + , struct passwd** ) +{ + return 0; +} + +//---------------------------------------------------------------------- +char* FSystemTest::realpath (const char*, char*); +{ + return ""; +} + //---------------------------------------------------------------------- FSystemTest::rgb& FSystemTest::getRGB (std::size_t i) { diff --git a/test/ftermopenbsd-test.cpp b/test/ftermopenbsd-test.cpp index 3bddc163..341fdd1b 100644 --- a/test/ftermopenbsd-test.cpp +++ b/test/ftermopenbsd-test.cpp @@ -84,6 +84,8 @@ class FSystemTest : public finalcut::FSystem int putchar (int) override; int tputs (const char*, int, int (*)(int)) override; uid_t getuid() override; + uid_t geteuid() override; + char* realpath (const char*, char*) override; wskbd_bell_data& getBell(); private: @@ -274,6 +276,25 @@ uid_t FSystemTest::getuid() return 0; } +//---------------------------------------------------------------------- +uid_t FSystemTest::geteuid() +{ + return 0; +} + +//---------------------------------------------------------------------- +int FSystemTest::getpwuid_r ( uid_t, struct passwd*, char*, size_t + , struct passwd** ) +{ + return 0; +} + +//---------------------------------------------------------------------- +char* FSystemTest::realpath (const char*, char*); +{ + return ""; +} + //---------------------------------------------------------------------- wskbd_bell_data& FSystemTest::getBell() {