the mailbox takes typing again, and events carry their real arguments
- the mail window's send tab takes typing again: the subject, body and money boxes were taking no input while the recipient box swallowed every key, and a sent letter clears its subject and item icon instead of putting them straight back (2145) - seven events fire the way the reference does: UNIT_DYNAMIC_FLAGS fires at all, swapping two identical stacks between bank slots fires PLAYERBANKSLOTS_CHANGED twice, the pet sheet's training points repaint, and ITEM_LOCK_CHANGED loses its invented arguments (2140) - nine widget methods 1.12 addons probe for are in: ShaguTweaks stops recolouring textures the reference leaves alone, pfUI and _Nameplates stop raising on a tooltip's GetAnchorType, and 63 AceEvent addons get RegisterAllEvents (2142) - six post-1.12 methods leave the widget surface (SetSize, SetShown, HasFocus, SetFormattedText and two tooltip verbs), so an addon reaching for a later client's API finds what a real 1.12 client gives it (2142, 2146) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
use mlua::{Lua, Table, Value};
|
||||
|
||||
use crate::script::object::frame_handle_of;
|
||||
use crate::script::Model;
|
||||
use crate::widget::EditBoxState;
|
||||
|
||||
use super::{
|
||||
@@ -127,14 +126,12 @@ pub(in crate::script) fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
Ok(())
|
||||
})?,
|
||||
)?;
|
||||
m.set(
|
||||
"HasFocus",
|
||||
lua.create_function(|lua, this: Table| {
|
||||
let h = frame_handle_of(lua, &this)?;
|
||||
let model = lua.app_data_ref::<Model>().expect("model app_data");
|
||||
Ok(model.focused_editbox == Some(h))
|
||||
})?,
|
||||
)?;
|
||||
// **No `HasFocus`.** 1.12's EditBox table registers the two setters above and no getter at
|
||||
// all, and an addon that wants the answer keeps its own flag around `SetFocus`/`ClearFocus` —
|
||||
// `pfQuest/browser.lua:760` documents exactly that and ships the workaround. Ours was an
|
||||
// unexplained superset a feature-detecting addon would take the wrong branch on (1188, and
|
||||
// the census that removed it, 2142). Host-side, the focus cell reads back through
|
||||
// [`crate::script::UiScript::focused_editbox_name`].
|
||||
|
||||
// GetInputLanguage() / ToggleInputLanguage() — `0x799550` / `0x799610`, the edit box's
|
||||
// **IME** language, not the chat language: `ChatEdit_OnInputLanguageChanged` shows
|
||||
|
||||
@@ -32,7 +32,7 @@ fn an_autofocus_box_self_acquires_on_the_first_event() {
|
||||
.unwrap();
|
||||
// No show transition has run for this box, so nothing owns the keyboard yet.
|
||||
assert!(!s.has_keyboard_focus());
|
||||
assert!(!s.eval::<bool>("return E:HasFocus()").unwrap());
|
||||
assert_eq!(s.focused_editbox_name(), None);
|
||||
|
||||
// The first char self-acquires focus AND processes that same event.
|
||||
assert!(
|
||||
@@ -40,7 +40,7 @@ fn an_autofocus_box_self_acquires_on_the_first_event() {
|
||||
"an autoFocus box consumes the acquiring event"
|
||||
);
|
||||
assert!(s.has_keyboard_focus());
|
||||
assert!(s.eval::<bool>("return E:HasFocus()").unwrap());
|
||||
assert_eq!(s.focused_editbox_name().as_deref(), Some("E"));
|
||||
assert_eq!(s.eval::<String>("return E:GetText()").unwrap(), "a");
|
||||
}
|
||||
|
||||
@@ -62,8 +62,9 @@ fn an_autofocus_box_takes_the_keyboard_when_it_is_shown() {
|
||||
assert!(!s.has_keyboard_focus(), "hidden and unfocused to start");
|
||||
|
||||
s.run("E:Show()").unwrap();
|
||||
assert!(
|
||||
s.eval::<bool>("return E:HasFocus()").unwrap(),
|
||||
assert_eq!(
|
||||
s.focused_editbox_name().as_deref(),
|
||||
Some("E"),
|
||||
"showing an autoFocus box focuses it",
|
||||
);
|
||||
|
||||
@@ -108,18 +109,19 @@ fn the_show_focus_is_refused_without_autofocus_or_with_the_keyboard_taken() {
|
||||
)
|
||||
.unwrap();
|
||||
s.run("LATE:Show()").unwrap();
|
||||
assert!(
|
||||
s.eval::<bool>("return HOLDER:HasFocus()").unwrap(),
|
||||
assert_eq!(
|
||||
s.focused_editbox_name().as_deref(),
|
||||
Some("Holder"),
|
||||
"a shown autoFocus box does not steal a focus that is already held",
|
||||
);
|
||||
assert!(!s.eval::<bool>("return LATE:HasFocus()").unwrap());
|
||||
|
||||
// And hiding a box that does NOT hold the keyboard leaves it where it is — `0x77e410`'s own
|
||||
// per-box guard (`cmp ecx,eax; jne ret`), which is what makes the override's unconditional
|
||||
// tail-jmp harmless.
|
||||
s.run("LATE:Hide()").unwrap();
|
||||
assert!(
|
||||
s.eval::<bool>("return HOLDER:HasFocus()").unwrap(),
|
||||
assert_eq!(
|
||||
s.focused_editbox_name().as_deref(),
|
||||
Some("Holder"),
|
||||
"hiding an unfocused box does not clear somebody else's focus",
|
||||
);
|
||||
assert!(s.errors().is_empty(), "{:?}", s.errors());
|
||||
@@ -179,7 +181,7 @@ fn set_focus_on_hidden_box_is_a_noop() {
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!s.eval::<bool>("return E:HasFocus()").unwrap());
|
||||
assert_eq!(s.focused_editbox_name(), None);
|
||||
assert!(!s.has_keyboard_focus());
|
||||
assert_eq!(
|
||||
s.eval::<i64>("return gained").unwrap(),
|
||||
@@ -198,7 +200,7 @@ fn click_focuses_regardless_of_autofocus_and_transition_order_is_lost_then_gaine
|
||||
local function wire(name, y)
|
||||
local f = CreateFrame("EditBox", name)
|
||||
f:SetPoint("BOTTOMLEFT", nil, "BOTTOMLEFT", 0, y)
|
||||
f:SetSize(100, 20)
|
||||
f:SetWidth(100); f:SetHeight(20)
|
||||
f:SetScript("OnEditFocusGained", function() table.insert(log, "gained"..name) end)
|
||||
f:SetScript("OnEditFocusLost", function() table.insert(log, "lost"..name) end)
|
||||
end
|
||||
@@ -212,11 +214,11 @@ fn click_focuses_regardless_of_autofocus_and_transition_order_is_lost_then_gaine
|
||||
// Neither box has autoFocus, yet a click focuses each.
|
||||
s.mouse_button(50.0, 10.0, "LeftButton", true);
|
||||
s.mouse_button(50.0, 10.0, "LeftButton", false);
|
||||
assert!(s.eval::<bool>("return A:HasFocus()").unwrap());
|
||||
assert_eq!(s.focused_editbox_name().as_deref(), Some("A"));
|
||||
|
||||
s.mouse_button(50.0, 110.0, "LeftButton", true);
|
||||
s.mouse_button(50.0, 110.0, "LeftButton", false);
|
||||
assert!(s.eval::<bool>("return B:HasFocus()").unwrap());
|
||||
assert_eq!(s.focused_editbox_name().as_deref(), Some("B"));
|
||||
|
||||
let log: Vec<String> = s.eval("return log").unwrap();
|
||||
assert_eq!(log, vec!["gainedA", "lostA", "gainedB"]);
|
||||
@@ -473,8 +475,9 @@ fn enter_escape_tab_space_fire_their_slots() {
|
||||
.unwrap();
|
||||
assert!(s.key_input("ENTER")); // single-line → OnEnterPressed
|
||||
assert!(s.key_input("ESCAPE")); // fires, does NOT release focus
|
||||
assert!(
|
||||
s.eval::<bool>("return E:HasFocus()").unwrap(),
|
||||
assert_eq!(
|
||||
s.focused_editbox_name().as_deref(),
|
||||
Some("E"),
|
||||
"ESCAPE keeps focus"
|
||||
);
|
||||
assert!(s.key_input("TAB"));
|
||||
@@ -1353,7 +1356,7 @@ fn creating_a_box_does_not_focus_it_the_way_showing_one_does() {
|
||||
!s.has_keyboard_focus(),
|
||||
"a box born visible has not been SHOWN, so it takes no keyboard",
|
||||
);
|
||||
assert!(!s.eval::<bool>("return E:HasFocus()").unwrap());
|
||||
assert_eq!(s.focused_editbox_name(), None);
|
||||
assert!(s.errors().is_empty(), "{:?}", s.errors());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user