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"
|
send_to="12"
|
||||||
sequence="100">
|
sequence="100">
|
||||||
</alias>
|
</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>
|
</aliases>
|
||||||
|
|
||||||
<!-- Timers -->
|
|
||||||
|
|
||||||
<timers>
|
|
||||||
<timer
|
|
||||||
enabled="y"
|
|
||||||
second="0.2"
|
|
||||||
script="poll_output_focus"
|
|
||||||
>
|
|
||||||
</timer>
|
|
||||||
</timers>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Get our standard constants -->
|
<!-- Get our standard constants -->
|
||||||
|
|
||||||
<include name="constants.lua"/>
|
<include name="constants.lua"/>
|
||||||
@@ -222,7 +199,6 @@ Accelerator("ctrl+shift+n","endline")
|
|||||||
Accelerator("ctrl+shift+y","topline")
|
Accelerator("ctrl+shift+y","topline")
|
||||||
Accelerator("ctrl+shift+h","whichline")
|
Accelerator("ctrl+shift+h","whichline")
|
||||||
Accelerator("ctrl+shift+alt+s","snap_shot")
|
Accelerator("ctrl+shift+alt+s","snap_shot")
|
||||||
Accelerator("ctrl+alt+j","toggle_jump_to_end")
|
|
||||||
|
|
||||||
function selectscr(eol)
|
function selectscr(eol)
|
||||||
buffercheck()
|
buffercheck()
|
||||||
@@ -332,9 +308,6 @@ GetModuleHandle:types{ ret = "pointer", "string", abi = "stdcall" }
|
|||||||
local GetProcAddress = kernel32.GetProcAddress
|
local GetProcAddress = kernel32.GetProcAddress
|
||||||
GetProcAddress:types{ ret = "pointer", "pointer", "string", abi = "stdcall" }
|
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
|
-- 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
|
-- real 32-bit selection range - the classic packed-return form is capped
|
||||||
-- at 64K). SendMessage above is already typed with "uint"/"long" for its
|
-- 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_LINESCROLL = 0x00B6
|
||||||
local EM_GETSEL = 0x00B0
|
local EM_GETSEL = 0x00B0
|
||||||
local EM_SETSEL = 0x00B1
|
local EM_SETSEL = 0x00B1
|
||||||
local EM_SCROLLCARET = 0x00B7
|
|
||||||
|
|
||||||
local my_pid = GetCurrentProcessId()
|
local my_pid = GetCurrentProcessId()
|
||||||
|
|
||||||
@@ -431,84 +403,12 @@ function SmartAppendToNotepad(title, text)
|
|||||||
end
|
end
|
||||||
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()
|
function OnPluginInstall()
|
||||||
if GetVariable("output") == nil then
|
if GetVariable("output") == nil then
|
||||||
SetVariable("output","1")
|
SetVariable("output","1")
|
||||||
end
|
end
|
||||||
if GetVariable("jump_to_end_on_focus") == nil then
|
|
||||||
SetVariable("jump_to_end_on_focus","1")
|
|
||||||
end
|
|
||||||
modes = {}
|
modes = {}
|
||||||
cline = 1
|
cline = 1
|
||||||
lastcount=0
|
lastcount=0
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ MushClient is a portable client designed specifically for Cosmic Rage. The game
|
|||||||
The soundpack mirrors game text into a separate notepad-style window titled "output", useful for reviewing text with a screen reader without losing your place when new lines arrive.
|
The soundpack mirrors game text into a separate notepad-style window titled "output", useful for reviewing text with a screen reader without losing your place when new lines arrive.
|
||||||
|
|
||||||
- **Ctrl + Alt + O**: Toggle whether output is mirrored to the output window
|
- **Ctrl + Alt + O**: Toggle whether output is mirrored to the output window
|
||||||
- **Ctrl + Alt + J**: Toggle whether switching to the output window jumps you to the newest line
|
|
||||||
- **Ctrl + Shift + C**: Clear the output buffer
|
- **Ctrl + Shift + C**: Clear the output buffer
|
||||||
- **Ctrl + Alt + Shift + C**: Clear the output window
|
- **Ctrl + Alt + Shift + C**: Clear the output window
|
||||||
- **Ctrl + Shift + I**: Speak the current line
|
- **Ctrl + Shift + I**: Speak the current line
|
||||||
|
|||||||
Reference in New Issue
Block a user