View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0003920 | Plugins | LuaMacro / Macro Browser | public | 2021-12-04 10:23 | 2021-12-09 18:54 |
Reporter | heilong | Assigned To | |||
Priority | normal | Severity | major | Reproducibility | sometimes |
Status | closed | Resolution | not fixable | ||
Platform | x64 | OS | Windows | OS Version | 10 |
Product Version | 3.0 | ||||
Summary | 0003920: Под нагрузкой, стрелки вверх-вниз (и др.) генерируют символы на ком строке | ||||
Description | При нагрузке процессора, нажатие разных клавиш в Фаре приводит к появлению неких key-кодов на командной строке. Например, при нажатии стрелок вверх-вниз вместо перемещения по списку файлов, на ком строке появляются [A или [B. Данная проблема усугубляется, если Far работает под ConEmu, но и без ConEmu у меня также получилось это воспроизвести. | ||||
Steps To Reproduce | - Запустить Far, желательно из-под ConEmu (воспроизвести легче) - Загрузить чем-то процессор, например я использовал онлайн стресс тест отсюда - В Far, быстро понажимать (или нажать и держать) стрелки вверх-вниз Far либо реагирует медленно на нажатия стрелок, либо на ком строке появляются символы [A / [B. | ||||
Additional Information | - Также воспроизводится на прочих других клавишах. - На моём Windows 7 (x64) ноутбуке эта проблема ни разу не замечалась - На 3х разных Windows 10 (x64) ноутбуках (та же модель, на год новее моего Win 7 ноутбука) проблема воспроизводится постоянно - Проблему я заметил год или два назад, когда впервые поставил Windows 10. Far и прочая конфигурация была скопирована с моего Windows 7 ноутбука. Периодически обновляюсь на nightly версию Far-а, на данный момент 3.0.0.5927. - Приложен скриншот standalone Far-а (без ConEmu) с вылезшим (при нажатии на стрелку вверх) на ком строке кодом [A | ||||
Tags | No tags attached. | ||||
|
|
|
Conemu уже был замечен в подобном, в несколько ином контексте.Приложен скриншот standalone Far-а (без ConEmu)Я надеюсь, вы проверяете совсем без conemu, в т.ч. и без его плагинов, а не просто запуская far.exe из той же папки напрямую? |
|
Был плагин conemu. Скопировал установку Far-а в отдельную директорию, удалил оттуда плагин conemu. Баг воспроизводится. |
|
Прочтение этой темы навело на мысль попробовать, а не влияют ли на проблему мои Lua-скрипты? Взял nightly archive Far, разархивировал в отдельную директорию, все дальнейшие тесты проводил с этим фаром, без ConEmu. Методом исключения обнаружилось, что проблема вызывается одним конкретным скриптом Panel.ChangeDir.lua (приаттачил). Если закомментировать строчку os.execute, проблема исчезает. Отключил этот скрипт в обычной установке Far, которой пользуюсь из-под ConEmu. Проблема также исчезла. Скрипт писал 5 лет назад, в коммите (скрипты у меня в git репозитории) написано "Panel.ChangeDir: On Far start, make sure both panels are visible and none of the panels are showing the user dir". Насколько я помню, при запуске Far (кажется, именно из-под ConEmu, но точно не помню) одна из панелей показывала home директорию юзера, а мне это не нравилось. Panel.ChangeDir.lua (4,076 bytes)
-- Timer poll interval in milliseconds. local POLL_INTERVAL = 5000 -- Timer boost on input event interval in milliseconds. local BOOST_INTERVAL = 500 local SQLITE = 'C:\\cygwin\\bin\\setsid.exe C:\\cygwin\\bin\\sqlite3.exe' -- Run sqlite3 in background (returns immediately, best performance). --local SQLITE = 'C:\\cygwin\\bin\\sqlite3.exe' -- Run sqlite3 directly (blocks execution until transaction has finished). local LOCALCONFIG_DB = win.GetEnv('FARPROFILE') .. '\\localconfig.db' --local dbg = require "dbgprint".filter("FAR:"," ") --local inspect = require "inspect" local function CommitPanelState() -- dbg.print('commit') local leftPanel = APanel.Left and APanel or PPanel local rightPanel = APanel.Left and PPanel or APanel local sql = "BEGIN TRANSACTION; DELETE FROM 'general_config'; " .. "INSERT INTO 'general_config' VALUES('Panel.Left','CurFile','" .. leftPanel.Current:gsub("'", "''") .. "'); " .. "INSERT INTO 'general_config' VALUES('Panel.Left','Folder','" .. leftPanel.Path0:gsub("'", "''") .. "'); " .. "INSERT INTO 'general_config' VALUES('Panel.Right','CurFile','" .. rightPanel.Current:gsub("'", "''") .. "'); " .. "INSERT INTO 'general_config' VALUES('Panel.Right','Folder','" .. rightPanel.Path0:gsub("'", "''") .. "'); " .. "INSERT INTO 'general_config' VALUES('Panel','LeftFocus'," .. (APanel.Left and 1 or 0) .. "); " .. "COMMIT;" -- os.execute(SQLITE .. ' "' .. LOCALCONFIG_DB .. '" "' .. sql .. '"') end local lastActiveLeft = APanel.Left local lastLeftPath = APanel.Left and APanel.Path0 or PPanel.Path0 local lastLeftCurrent = APanel.Left and APanel.Current or PPanel.Current local lastRightPath = APanel.Left and PPanel.Path0 or APanel.Path0 local lastRightCurrent = APanel.Left and PPanel.Current or APanel.Current local function UpdatePanelState() local leftPanel = APanel.Left and APanel or PPanel local rightPanel = APanel.Left and PPanel or APanel local modified = false if APanel.Left ~= lastActiveLeft then lastActiveLeft = APanel.Left modified = true end if (leftPanel.Type == 0) and ((leftPanel.Path0 ~= lastLeftPath) or (leftPanel.Current ~= lastLeftCurrent)) then lastLeftPath = leftPanel.Path0 lastLeftCurrent = leftPanel.Current modified = true end if (rightPanel.Type == 0) and ((rightPanel.Path0 ~= lastRightPath) or (rightPanel.Current ~= lastRightCurrent)) then lastRightPath = rightPanel.Path0 lastRightCurrent = rightPanel.Current modified = true end if modified then CommitPanelState() end end local timer = far.Timer(POLL_INTERVAL, function(timer) timer.Enabled = false UpdatePanelState() timer.Interval = POLL_INTERVAL timer.Enabled = true end) Event { description="PanelChangeDir: Clean up timer on exit"; group="ExitFAR"; uid="351F4780-2799-47BF-984A-EB429E8B431E"; action=function() timer:Close() end; } Event { description="PanelChangeDir: Listen to input events"; group="ConsoleInput"; action=function(Rec) if ((Rec.EventType == far.Flags.KEY_EVENT) and (Rec.VirtualKeyCode ~= 0)) or ((Rec.EventType == far.Flags.MOUSE_EVENT) and (Rec.EventFlags ~= far.Flags.MOUSE_MOVED)) then timer.Interval = BOOST_INTERVAL end end; } local function InitPanelState() -- Make sure both panels are visible. if (not APanel.Visible) and (not PPanel.Visible) then Keys('CtrlO') elseif not PPanel.Visible then Keys('CtrlP') end -- If one or both panels have the user's home directory open, go to last history item or two last history items respectively. local home = win.GetEnv('HOMEDRIVE') .. win.GetEnv('HOMEPATH') if (APanel.Path == home) or (PPanel.Path == home) then Keys('AltF12') local itemPos = Menu.Select(home) if itemPos > 0 then Keys('ShiftDel End') end if APanel.Path == home then panel.SetPanelDirectory(nil, 1, Menu.Value or 'C:\\') Keys('Up') end if PPanel.Path == home then panel.SetPanelDirectory(nil, 0, Menu.Value or 'C:\\') end Keys('Esc') end end Macro { description="PanelChangeDir: Init panels on start"; area="Shell"; key="auto"; flags="RunAfterFARStart"; action = InitPanelState; } |
|
Похоже, что дело именно в os.execute, потому что проблема также воспроизводится, если сразу при старте Far зажать стрелку вверх или вниз, и при этом есть скрипт Alias.lua (в аттаче), который запускает doskey с помощью os.execute. С точки зрения workaround-ов - полагаю, что мой 5-летней давности Panel.ChangeDir уже не нужен, я его отключил, и не вижу никаких изменений в худшую сторону - home директория юзера не открывается при старте нового Far (ConEmu). Alias, как я вижу, на форуме уже есть в обновлённой версии, которая, похоже, уже не использует os.execute и вообще doskey. Но всё же могу предположить, что некая проблема существует, os.execute-ом разные скрипты могут пользоваться, и соотв-но в этом случае возможны такие проблемы. Если это как-то устранимо, было бы здорово. Alias.lua (2,260 bytes)
--http://forum.farmanager.com/viewtopic.php?f=60&t=8546 --requires FAR 3 build >=3854 (EF_OPENMODE_USEEXISTING) local F = far.Flags local _name = "alias.doskey" local _filename = Macro and ... or _filename:match[[^\\%?\(.+)$]] local _aliasfile = _filename:match[[(.+\).+$]].._name local cmd_edit = "a" local cmd_reload = "rr" local flags = {EF_DISABLEHISTORY=1,EF_NONMODAL=1,EF_IMMEDIATERETURN=1,EF_OPENMODE_USEEXISTING=1} local function EditAlias(str) editor.Editor (_aliasfile, _name, nil, nil, nil, nil, flags, line, nil, win.GetOEMCP()) --todo check CP if not Area.Editor or not str or str=="" then return end local n,pattern = str:len(),"^%s*"..str:lower().."%s*=" --todo find spec symbols []()%.?+-* for i=1,editor.GetInfo().TotalLines do local line = editor.GetString(nil,i,3):lower() if line:match(pattern) then editor.SetPosition (nil, i, n, nil, i-2, 1) editor.Select (nil, "BTYPE_STREAM", i, line:find(str), n, 1) --Editor.Set(2,1) --Persistent blocks return editor.Redraw() end end far.Message(("Could not find the string\n%q"):format(str),"Search",nil,"w") end if not Macro then -- Aliases: open in editor from cmdline EditAlias(...) return end local function Utf8ToAnsi(str) return win.WideCharToMultiByte(win.Utf8ToUtf16(str),win.GetACP()) end local cmds = { string.format('doskey /exename=Far.exe %s=lua:@"%s" "$*"',cmd_edit,_filename), string.format('doskey /exename=Far.exe %s=doskey /macrofile="%s"',cmd_reload,Utf8ToAnsi(_aliasfile)), string.format('doskey /macrofile="%s"',Utf8ToAnsi(_aliasfile)), } local function Reload() local info = win.GetFileInfo(_aliasfile) if not info then far.Message(("File is absent: '%s'"):format(_aliasfile),"Console aliases",nil,"w") return end for i=1,#cmds do os.execute(cmds[i]) end end Event { description="Aliases: reload on edit"; group="EditorEvent"; filemask=_name; condition=function(id,Event) return Event==F.EE_CLOSE end; action=function() local EditorInfo = editor.GetInfo() if EditorInfo.FileName:lower()==_aliasfile:lower() and band(EditorInfo.CurState,F.ECSTATE_MODIFIED)~=0 then Reload(_aliasfile) end end; } Macro { description="Aliases: Load on start"; area="Shell"; key="auto"; flags="RunAfterFARStart"; action=Reload; } |
|
Насколько я понимаю этот скрипт, он по таймеру (т.е. из дополнительного треда) периодически запускает внешний процесс через os.execute. os.execute - это обертка над system(), т.е. над вызовом cmd.exe. cmd.exe для своих целей включает esc-последовательности в консоли, запускает sqlite или что вы ему там передали, и выходит, видимо, не утруждая себя восстановлением предыдущего режима. Far время от времени сбрасывает режим в свой и ситуация исправляется. А под нагрузкой, видимо, лаги между этими событиями больше и вы успеваете увидеть артефакты поломанного состояния. Far здесь точно не при чем, но в luamacro, наверное, неплохо было бы запоминать режим консоли внутри os.execute() до вызова system() и восстанавливать после. |
|
Ваше объяснение звучит логично. А luamacro - это часть Far-а, или внешняя сторонняя библиотека? Было бы здорово эту проблему починить, на пользу всех скриптописателей, пользующихся system() / os.execute |
|
Это плагин в комплекте, реализующий исполнение скриптов. ----------- Shmuel, a это реализуемо? Насколько я понимаю, win.system имплеменирована в luafar\ustring.c и туда это добавить можно, но os.execute берется напрямую из lua51.dll? |
|
DrKnS, случайно заглянул сюда и увидел ваш вопрос (уведомления приходят только на открытие новых тикетов или там, где участвовал). С данной проблемой ни разу не сталкивался. os.execute находится в lua51.dll, не юникодная. win.system - в Luafar3.dll, юникодная. Если нужно модифицировать, то лучше, наверное, её. |
|
Возможно, что ничего не надо модифицировать, а просто перед os.execute вызывать panel.GetUserScreen, а после - panel.SetUserScreen. |
|
Shmuel, спасибо. Добавил в 766. heilong, попробуйте пользоваться win.system вместо os.execute. Возможно, поможет. |
|
DrKnS, ещё нужно обновить номер билда в version.h. |
|
Спасибо, обновил. |
|
Попробовать win.system уже сейчас, или подождать следующего nightly? |
|
Попробовать с новой версией конечно же. Уже есть там - https://github.com/FarGroup/FarManager/releases/tag/ci/v3.0.5927.2630 |
|
Попробовал с версией 5928, поменял os.execute на win.system. По-прежнему воспроизвелось. |
|
Видимо, вы успеваете нажимать кнопки, пока оно еще в процессе исполнения, а с этим уже вряд ли что-то можно сделать. |
|
Ну если ничего не поделать, то наверно чёрт с ним. В любом случае эта проблема раздражала только из-за того, что у меня этот скрипт исполнял os.execute (win.system) очень регулярно. Сейчас нужды в этом скрипте нет, а если какой-то другой скрипт использует win.system изредка, то проблемы от этого будут весьма редко. Спасибо в любом случае ) |
Date Modified | Username | Field | Change |
---|---|---|---|
2021-12-04 10:23 | heilong | New Issue | |
2021-12-04 10:23 | heilong | File Added: 2021-12-04 11_13_37-{C__} - Far 3.0.5927.0 x64.png | |
2021-12-04 16:33 | DrKnS | Note Added: 0017262 | |
2021-12-04 19:37 | heilong | Note Added: 0017267 | |
2021-12-04 20:23 | heilong | Note Added: 0017269 | |
2021-12-04 20:23 | heilong | File Added: Panel.ChangeDir.lua | |
2021-12-04 20:32 | heilong | Note Added: 0017270 | |
2021-12-04 20:32 | heilong | File Added: Alias.lua | |
2021-12-04 20:50 | DrKnS | Note Added: 0017272 | |
2021-12-04 20:51 | DrKnS | Project | Far Manager => Plugins |
2021-12-04 20:51 | DrKnS | Category | Panel => General |
2021-12-04 20:51 | DrKnS | Category | General => LuaMacro / Macro Browser |
2021-12-04 20:55 | heilong | Note Added: 0017273 | |
2021-12-04 21:09 | DrKnS | Note Added: 0017274 | |
2021-12-04 21:39 | shmuel | Note Added: 0017277 | |
2021-12-04 22:36 | shmuel | Note Added: 0017278 | |
2021-12-04 22:36 | DrKnS | Note Added: 0017279 | |
2021-12-04 22:51 | shmuel | Note Added: 0017280 | |
2021-12-04 23:42 | DrKnS | Assigned To | => DrKnS |
2021-12-04 23:42 | DrKnS | Status | new => feedback |
2021-12-04 23:42 | DrKnS | Note Added: 0017281 | |
2021-12-05 00:06 | heilong | Note Added: 0017282 | |
2021-12-05 00:06 | heilong | Status | feedback => assigned |
2021-12-05 00:16 | DrKnS | Note Added: 0017283 | |
2021-12-09 07:38 | heilong | Note Added: 0017288 | |
2021-12-09 10:53 | DrKnS | Note Added: 0017289 | |
2021-12-09 18:43 | heilong | Note Added: 0017290 | |
2021-12-09 18:54 | DrKnS | Assigned To | DrKnS => |
2021-12-09 18:54 | DrKnS | Status | assigned => closed |
2021-12-09 18:54 | DrKnS | Resolution | open => not fixable |