diff --git a/cosmic rage/worlds/plugins/output_functions.xml b/cosmic rage/worlds/plugins/output_functions.xml index 84c23cf..7eb8895 100644 --- a/cosmic rage/worlds/plugins/output_functions.xml +++ b/cosmic rage/worlds/plugins/output_functions.xml @@ -407,11 +407,7 @@ end -- Note: text should use "\r\n" line endings, not bare "\n" - the plain -- Win32 Edit control that backs the notepad doesn't recognise bare "\n" -- as a line break for scrolling/line-count purposes. -last_append_clock = 0 - function SmartAppendToNotepad(title, text) - last_append_clock = os.clock() - local edit = find_notepad_edit(title) local was_at_end = true local sel_start, sel_end, first_visible @@ -459,36 +455,49 @@ end -- 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 - -- fell back to identity comparison), causing spurious "just gained - -- focus" edges and repeated jump-to-end even while focus never moved. + -- falls back to identity comparison). local is_focused = (tostring(focused) == tostring(edit)) - -- Skip the jump if a SmartAppendToNotepad call happened very recently: - -- AppendToNotepad's own SetSel/ReplaceSel appears to momentarily - -- perturb GetFocus() around each append, which was making this poll - -- see a spurious "just gained focus" edge - and jump to the end - on - -- practically every incoming line, even though the user never left - -- the window. - local recent_append = (os.clock() - last_append_clock) < 0.5 - if is_focused and not was_output_focused and not recent_append then - jump_notepad_to_end(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 - was_output_focused = is_focused end ------------------------------------------------------------------