Remove jump-to-end-on-focus entirely
Two debounce attempts (recent-append recency, then sustained-unfocus streak) both failed to stop it firing on almost every incoming line while the toggle was on. Rather than keep chasing GetFocus() polling noise, removed the whole feature: poll_output_focus, jump_notepad_to_end, toggle_jump_to_end, the Ctrl+Alt+J accelerator/alias, the polling timer, the jump_to_end_on_focus variable, and the now-unused GetFocus/ EM_SCROLLCARET Alien bindings. SmartAppendToNotepad (the actual smart- scroll fix, unrelated to this and confirmed working) is untouched. Updated the readme to drop the Ctrl+Alt+J entry.
This commit is contained in:
@@ -170,31 +170,8 @@ omit_from_command_history="y"
|
||||
send_to="12"
|
||||
sequence="100">
|
||||
</alias>
|
||||
|
||||
<alias
|
||||
match="toggle_jump_to_end"
|
||||
enabled="y"
|
||||
script="toggle_jump_to_end"
|
||||
omit_from_output="y"
|
||||
omit_from_log="y"
|
||||
omit_from_command_history="y"
|
||||
send_to="12"
|
||||
sequence="100">
|
||||
</alias>
|
||||
</aliases>
|
||||
|
||||
<!-- Timers -->
|
||||
|
||||
<timers>
|
||||
<timer
|
||||
enabled="y"
|
||||
second="0.2"
|
||||
script="poll_output_focus"
|
||||
>
|
||||
</timer>
|
||||
</timers>
|
||||
|
||||
|
||||
<!-- Get our standard constants -->
|
||||
|
||||
<include name="constants.lua"/>
|
||||
@@ -222,7 +199,6 @@ Accelerator("ctrl+shift+n","endline")
|
||||
Accelerator("ctrl+shift+y","topline")
|
||||
Accelerator("ctrl+shift+h","whichline")
|
||||
Accelerator("ctrl+shift+alt+s","snap_shot")
|
||||
Accelerator("ctrl+alt+j","toggle_jump_to_end")
|
||||
|
||||
function selectscr(eol)
|
||||
buffercheck()
|
||||
@@ -332,9 +308,6 @@ GetModuleHandle:types{ ret = "pointer", "string", abi = "stdcall" }
|
||||
local GetProcAddress = kernel32.GetProcAddress
|
||||
GetProcAddress:types{ ret = "pointer", "pointer", "string", abi = "stdcall" }
|
||||
|
||||
local GetFocus = user32.GetFocus
|
||||
GetFocus:types{ ret = "pointer", abi = "stdcall" }
|
||||
|
||||
-- EM_GETSEL's wParam/lParam are *pointers* to DWORD (needed to get the
|
||||
-- real 32-bit selection range - the classic packed-return form is capped
|
||||
-- at 64K). SendMessage above is already typed with "uint"/"long" for its
|
||||
@@ -349,7 +322,6 @@ local EM_GETFIRSTVISIBLELINE = 0x00CE
|
||||
local EM_LINESCROLL = 0x00B6
|
||||
local EM_GETSEL = 0x00B0
|
||||
local EM_SETSEL = 0x00B1
|
||||
local EM_SCROLLCARET = 0x00B7
|
||||
|
||||
local my_pid = GetCurrentProcessId()
|
||||
|
||||
@@ -431,84 +403,12 @@ function SmartAppendToNotepad(title, text)
|
||||
end
|
||||
end
|
||||
|
||||
-- Moves the caret to the very end of a notepad and scrolls it into view.
|
||||
local function jump_notepad_to_end(edit)
|
||||
local len = SendMessage(edit, WM_GETTEXTLENGTH, 0, 0)
|
||||
SendMessage(edit, EM_SETSEL, len, len)
|
||||
SendMessage(edit, EM_SCROLLCARET, 0, 0)
|
||||
end
|
||||
|
||||
function toggle_jump_to_end()
|
||||
if GetVariable("jump_to_end_on_focus") == "0" then
|
||||
SetVariable("jump_to_end_on_focus", "1")
|
||||
Execute("tts_interrupt Jump to end when switching to output: on")
|
||||
else
|
||||
SetVariable("jump_to_end_on_focus", "0")
|
||||
Execute("tts_interrupt Jump to end when switching to output: off")
|
||||
end
|
||||
end
|
||||
|
||||
-- Polls for the "output" notepad gaining focus (mouse click, Ctrl+Tab
|
||||
-- between MDI windows, ActivateNotepad from a script, etc.), so the
|
||||
-- jump-to-end behaviour applies regardless of how the user switches to
|
||||
-- it. MUSHclient's own Accelerator/hotkey system can't see keystrokes
|
||||
-- while a separate notepad window has focus (confirmed by Nick Gammon on
|
||||
-- the MUSHclient forum), so this can't be event-driven - polling every
|
||||
-- 0.2s is the safe, non-hooking way to catch it.
|
||||
--
|
||||
-- GetFocus() genuinely reports "not focused" for a single poll tick now
|
||||
-- and then, even while the user never left the window and nothing was
|
||||
-- just appended (confirmed via logging - one case was 7+ seconds after
|
||||
-- the last append) - just noise from MUSHclient's own UI thread being
|
||||
-- momentarily busy. A single such blip was enough to make this treat
|
||||
-- the very next tick as "just switched to the window" and jump, on
|
||||
-- practically every incoming line. Requiring several *consecutive*
|
||||
-- unfocused ticks before the next focused tick counts as a genuine
|
||||
-- switch filters that out.
|
||||
was_output_focused = false
|
||||
unfocused_streak = 0
|
||||
FOCUS_DEBOUNCE_TICKS = 3 -- ~0.6s of sustained unfocus at the 0.2s poll rate
|
||||
|
||||
function poll_output_focus()
|
||||
if GetVariable("jump_to_end_on_focus") == "0" then
|
||||
was_output_focused = false
|
||||
unfocused_streak = 0
|
||||
return
|
||||
end
|
||||
local edit = find_notepad_edit("output")
|
||||
if not edit then
|
||||
was_output_focused = false
|
||||
unfocused_streak = 0
|
||||
return
|
||||
end
|
||||
local focused = GetFocus()
|
||||
-- Compare by string representation, not raw "==": Alien's pointer
|
||||
-- returns are full userdata objects, so two separate calls returning
|
||||
-- the same real HWND don't reliably compare equal with "==" (which
|
||||
-- falls back to identity comparison).
|
||||
local is_focused = (tostring(focused) == tostring(edit))
|
||||
|
||||
if is_focused then
|
||||
if not was_output_focused and unfocused_streak >= FOCUS_DEBOUNCE_TICKS then
|
||||
jump_notepad_to_end(edit)
|
||||
end
|
||||
unfocused_streak = 0
|
||||
was_output_focused = true
|
||||
else
|
||||
unfocused_streak = unfocused_streak + 1
|
||||
was_output_focused = false
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
function OnPluginInstall()
|
||||
if GetVariable("output") == nil then
|
||||
SetVariable("output","1")
|
||||
end
|
||||
if GetVariable("jump_to_end_on_focus") == nil then
|
||||
SetVariable("jump_to_end_on_focus","1")
|
||||
end
|
||||
modes = {}
|
||||
cline = 1
|
||||
lastcount=0
|
||||
|
||||
Reference in New Issue
Block a user