From afecc83c6230eed628d6507b614edc6fc4deb883 Mon Sep 17 00:00:00 2001 From: Alex Alabuzhev Date: Tue, 6 Jul 2021 17:17:17 +0100 Subject: [PATCH] M#3877, M#3878, wrapper fixes, throttle down panel updates 1. #0003877: Exit to archive root via cd \ breaks the panel title. 2. #0003878: Incorrect selection when the block is beyond the screen border. 3. Several fixes in 1.x plugin wrapper related to colors processing. 4. Throttle down file panel updates on FS changes to one per second at most. --- far/PluginA.cpp | 38 +++++++++++++++++++++++--------------- far/changelog | 11 +++++++++++ far/edit.cpp | 4 ++-- far/editor.cpp | 6 +++--- far/exception_handler.cpp | 4 ++-- far/farlang.templ.m4 | 21 ++++++++++++++++++++- far/filelist.cpp | 4 +++- far/filesystemwatcher.cpp | 15 +++++++++++++++ far/vbuild.m4 | 2 +- 9 files changed, 80 insertions(+), 25 deletions(-) diff --git a/far/PluginA.cpp b/far/PluginA.cpp index 838ce13aec..ee9f081b43 100644 --- a/far/PluginA.cpp +++ b/far/PluginA.cpp @@ -76,7 +76,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common/scope_exit.hpp" #include "common/uuid.hpp" #include "common/view/select.hpp" -#include "common/view/select.hpp" #include "common/view/zip.hpp" // External: @@ -118,6 +117,21 @@ DECLARE_PLUGIN_FUNCTION(iProcessDialogEvent, int (WINAPI*)(int Event, void * #undef DECLARE_PLUGIN_FUNCTION +namespace oldfar +{ + // This was removed in 3.x and the enums don't match anymore :( + constexpr auto COL_RESERVED0 = 71; +} + +static_assert(COL_DIALOGLISTSCROLLBAR == COL_VIEWERARROWS + 1); +static_assert(COL_VIEWERARROWS == oldfar::COL_RESERVED0 - 1); +static_assert(COL_DIALOGLISTSCROLLBAR == oldfar::COL_RESERVED0); + +static int old_palette_to_palette(int const Color) +{ + return Color < oldfar::COL_RESERVED0? Color : Color - 1; +} + class oem_plugin_module: public native_plugin_module { public: @@ -1104,9 +1118,8 @@ static void AnsiDialogItemToUnicode(const oldfar::FarDialogItem &diA, FarDialogI if (diA.Type == oldfar::DI_USERCONTROL) { - auto Data = std::make_unique(std::size(diA.Data)); - copy_memory(diA.Data, Data.get(), sizeof(diA.Data)); - di.Data = Data.release(); + // Data is opaque, no need to propagate it + di.Data = {}; di.MaxLength = 0; } else if ((diA.Type == oldfar::DI_EDIT || diA.Type == oldfar::DI_COMBOBOX) && diA.Flags&oldfar::DIF_VAREDIT) @@ -1282,8 +1295,7 @@ static oldfar::FarDialogItem* UnicodeDialogItemToAnsi(FarDialogItem &di, HANDLE if (diA->Type == oldfar::DI_USERCONTROL) { - if (di.Data) - copy_memory(di.Data, diA->Data, sizeof(diA->Data)); + // Data is opaque, no need to touch it } else if ((diA->Type == oldfar::DI_EDIT || diA->Type == oldfar::DI_COMBOBOX) && diA->Flags&oldfar::DIF_VAREDIT) { @@ -3931,13 +3943,7 @@ static intptr_t WINAPI FarAdvControlA(intptr_t ModuleNumber, oldfar::ADVANCED_CO case oldfar::ACTL_GETCOLOR: { FarColor Color; - int ColorIndex = static_cast(reinterpret_cast(Param)); - - // there was a reserved position after COL_VIEWERARROWS in Far 1.x. - if(ColorIndex > COL_VIEWERARROWS) - { - ColorIndex--; - } + const auto ColorIndex = old_palette_to_palette(static_cast(reinterpret_cast(Param))); return pluginapi::apiAdvControl(GetPluginUuid(ModuleNumber), ACTL_GETCOLOR, ColorIndex, &Color)? colors::FarColorToConsoleColor(Color) :-1; } @@ -3946,8 +3952,9 @@ static intptr_t WINAPI FarAdvControlA(intptr_t ModuleNumber, oldfar::ADVANCED_CO const auto PaletteSize = pluginapi::apiAdvControl(GetPluginUuid(ModuleNumber), ACTL_GETARRAYCOLOR, 0, nullptr); if(Param) { - std::vector Color(PaletteSize); - pluginapi::apiAdvControl(GetPluginUuid(ModuleNumber), ACTL_GETARRAYCOLOR, 0, Color.data()); + std::vector Color(PaletteSize + 1); + pluginapi::apiAdvControl(GetPluginUuid(ModuleNumber), ACTL_GETARRAYCOLOR, Color.size(), Color.data()); + Color.insert(Color.begin() + oldfar::COL_RESERVED0, FarColor{}); const auto OldColors = static_cast(Param); std::transform(ALL_CONST_RANGE(Color), OldColors, colors::FarColorToConsoleColor); } @@ -4179,6 +4186,7 @@ static intptr_t WINAPI FarAdvControlA(intptr_t ModuleNumber, oldfar::ADVANCED_CO const auto scA = static_cast(Param); std::vector Colors(scA->ColorCount); std::transform(scA->Colors, scA->Colors + scA->ColorCount, Colors.begin(), colors::ConsoleColorToFarColor); + Colors.erase(Colors.begin() + oldfar::COL_RESERVED0); FarSetColors sc = {sizeof(FarSetColors), 0, static_cast(scA->StartIndex), Colors.size(), Colors.data()}; if (scA->Flags&oldfar::FCLR_REDRAW) sc.Flags|=FSETCLR_REDRAW; diff --git a/far/changelog b/far/changelog index ada1a0e4fb..61e69818ba 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,14 @@ +-------------------------------------------------------------------------------- +drkns 06.07.2021 17:17:17 +0100 - build 5844 + +1. #0003877: Exit to archive root via cd \ breaks the panel title. + +2. #0003878: Incorrect selection when the block is beyond the screen border. + +3. Several fixes in 1.x plugin wrapper related to colors processing. + +4. Throttle down file panel updates on FS changes to one per second at most. + -------------------------------------------------------------------------------- drkns 01.07.2021 03:01:55 +0100 - build 5843 diff --git a/far/edit.cpp b/far/edit.cpp index 9049f408e8..976fe6227f 100644 --- a/far/edit.cpp +++ b/far/edit.cpp @@ -425,9 +425,9 @@ void Edit::FastShow(const ShowInfo* Info) Global->ScrBuf->ApplyColor( { - std::min(m_Where.left + TabSelStart, static_cast(m_Where.right)), + std::min(m_Where.left + TabSelStart, static_cast(m_Where.right + 1)), m_Where.top, - std::min(m_Where.left + TabSelEnd - 1, static_cast(m_Where.right)), + std::min(m_Where.left + TabSelEnd - 1, static_cast(m_Where.right + 1)), m_Where.top }, GetSelectedColor() diff --git a/far/editor.cpp b/far/editor.cpp index 86739d59ac..f5b0cdbd38 100644 --- a/far/editor.cpp +++ b/far/editor.cpp @@ -335,7 +335,7 @@ void Editor::ShowEditor() if (Y != m_Where.bottom + 1) { - SetScreen({ m_Where.left, Y, XX2, m_Where.bottom }, L' ', colors::PaletteColorToFarColor(COL_EDITORTEXT)); //Пустые строки после конца текста + SetScreen({ m_Where.left, Y, XX2, m_Where.bottom }, L' ', Color); //Пустые строки после конца текста } if (IsVerticalSelection() && VBlockSizeX > 0 && VBlockSizeY > 0) @@ -360,7 +360,7 @@ void Editor::ShowEditor() BlockX2=XX2; if (BlockX1 <= XX2 && BlockX2 >= m_Where.left) - Global->ScrBuf->ApplyColor({ BlockX1, Y, BlockX2, Y }, colors::PaletteColorToFarColor(COL_EDITORSELECTEDTEXT)); + Global->ScrBuf->ApplyColor({ BlockX1, Y, BlockX2, Y }, SelColor); } ++CurPtr; @@ -3569,7 +3569,7 @@ bool Editor::Search(bool Next) ColorItem newcol = {}; newcol.StartPos=m_FoundPos; newcol.EndPos=m_FoundPos + m_FoundSize - 1; - newcol.SetColor(colors::PaletteColorToFarColor(COL_EDITORSELECTEDTEXT)); + newcol.SetColor(SelColor); newcol.SetOwner(FarUuid); newcol.Priority=EDITOR_COLOR_SELECTION_PRIORITY; CurPtr->AddColor(newcol); diff --git a/far/exception_handler.cpp b/far/exception_handler.cpp index 64032c7ae8..2f12367a4f 100644 --- a/far/exception_handler.cpp +++ b/far/exception_handler.cpp @@ -442,12 +442,12 @@ static bool ExcDialog(string const& ReportLocation, bool const CanUnload) if (CanUnload) { lng const MsgIDs[]{ lng::MExcTerminate, lng::MExcUnload, lng::MIgnore }; - Builder.AddButtons(MsgIDs, 0, 2); + Builder.AddButtons(MsgIDs, 0, std::size(MsgIDs) - 1); } else { lng const MsgIDs[]{ lng::MExcTerminate, lng::MIgnore }; - Builder.AddButtons(MsgIDs, 0, 1); + Builder.AddButtons(MsgIDs, 0, std::size(MsgIDs) - 1); } Builder.SetDialogMode(DMODE_WARNINGSTYLE | DMODE_NOPLUGINS); diff --git a/far/farlang.templ.m4 b/far/farlang.templ.m4 index c22373ba2f..29add55886 100644 --- a/far/farlang.templ.m4 +++ b/far/farlang.templ.m4 @@ -1,4 +1,8 @@ -m4_include(`farversion.m4')m4_dnl +# +# Note: https://www.microsoft.com/language is a good source of system- and UI-specific translations. +# + +m4_include(`farversion.m4')m4_dnl #hpp file name lang.inc @@ -22766,6 +22770,21 @@ upd:"Unload plugin" "Выгрузіць дадатак" upd:"&Unload plugin" +MExcFullDump +"Полный дамп" +"Full dump" +"Úplný výpis" +"Vollständiges Abbild" +"Teljes memóriakép" +"Pełny zrzut" +"Volcado completo" +"Úplný výpis" +"Dump completo" +"Повний дамп" +"Поўны дамп" +"Visa iškeltis" + + MNetUserName l: "Имя пользователя" diff --git a/far/filelist.cpp b/far/filelist.cpp index 54df1fa5db..5b7be62ab5 100644 --- a/far/filelist.cpp +++ b/far/filelist.cpp @@ -2819,7 +2819,9 @@ bool FileList::SetCurDir(string_view const NewDir, bool ClosePanel, bool IsUpdat if (!NewDir.empty()) { - Panel::SetCurDir(NewDir, ClosePanel, IsUpdated, Silent); + if (m_PanelMode != panel_mode::PLUGIN_PANEL) + Panel::SetCurDir(NewDir, ClosePanel, IsUpdated, Silent); + return ChangeDir(NewDir, NewDir == L".."sv, true, IsUpdated, &UsedData, OFP_NORMAL, Silent); } diff --git a/far/filesystemwatcher.cpp b/far/filesystemwatcher.cpp index 92f9984917..4fc7029e0c 100644 --- a/far/filesystemwatcher.cpp +++ b/far/filesystemwatcher.cpp @@ -183,6 +183,21 @@ void FileSystemWatcher::Register() message_manager::instance().notify(m_EventId); + // FS changes can occur at a high rate. + // We don't want to DoS ourselves here, so notifications are throttled down to one per second at most: + if (m_Cancelled.is_signaled(1s)) + { + LOGDEBUG(L"Stop monitoring {}"sv, m_Directory); + return; + } + + // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextchangenotification + // If a change occurs after a call to FindFirstChangeNotification + // but before a call to FindNextChangeNotification, the operating system records the change. + // When FindNextChangeNotification is executed, the recorded change + // immediately satisfies a wait for the change notification. + + // In other words, even with throttled notifications we shouldn't miss anything. if (!os::fs::find_next_change_notification(Notification)) { LOGWARNING(L"find_next_change_notification({}): {}"sv, m_Directory, last_error()); diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 7e401facdf..50371deed9 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -5843 +5844