From f7477dc4c3faffdf5bbd13790bf25ae7c72d5fb7 Mon Sep 17 00:00:00 2001 From: OlegTheSnowman <123775785+OlegTheSnowman@users.noreply.github.com> Date: Sat, 11 Jul 2026 00:42:54 +0300 Subject: [PATCH] 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. --- .../worlds/plugins/output_functions.xml | 100 ------------------ readme.md | 1 - 2 files changed, 101 deletions(-) diff --git a/cosmic rage/worlds/plugins/output_functions.xml b/cosmic rage/worlds/plugins/output_functions.xml index 7eb8895..a1b6278 100644 --- a/cosmic rage/worlds/plugins/output_functions.xml +++ b/cosmic rage/worlds/plugins/output_functions.xml @@ -170,31 +170,8 @@ omit_from_command_history="y" send_to="12" sequence="100"> - - - - - - - - - - - @@ -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 diff --git a/readme.md b/readme.md index bf8f4a5..8cb068c 100644 --- a/readme.md +++ b/readme.md @@ -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. - **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 + Alt + Shift + C**: Clear the output window - **Ctrl + Shift + I**: Speak the current line