ffi 1.32: uikit_keyboard_will_change_frame via #objc_call

The keyboard notification callback. First standalone exercises of
`#objc_call(CGRect)` (HFA — structurally equivalent to UIEdgeInsets,
already verified by 1.25 and ffi-objc-call-07) and `#objc_call(u64)`
(LLVM-equivalent to s64; ffi-objc-call-04 already locks in the i64
return path).

Migrates:
- `userInfo` (*void)
- `objectForKey:` with NSString arg (*void)
- `CGRectValue` (CGRect HFA)
- `doubleValue` (f64)
- `unsignedLongValue` (u64)
- `screen` (*void)
- `bounds` (CGRect HFA)

Net -14 lines. uikit.sx now 854 lines (-83 cumulative across Phase 1D).

iOS-sim chess regression smoke: launch is clean; the callback is
registered through cluster 1.30's notification-center wiring and the
function lowers without IR-verifier complaints. The callback body
itself isn't exercised at runtime by chess startup (the game doesn't
open the soft keyboard) — runtime verification of this specific
function is transitive via the other clusters that exercise the same
call shapes.
This commit is contained in:
agra
2026-05-19 21:00:46 +03:00
parent b3558c3274
commit e1d300c661

View File

@@ -355,42 +355,28 @@ uikit_keyboard_will_change_frame :: (self: *void, _cmd: *void, notification: *vo
if g_uikit_plat == null { return; }
plat := g_uikit_plat;
sel_user_info := sel_registerName("userInfo".ptr);
sel_obj_for_key := sel_registerName("objectForKey:".ptr);
sel_cg_rect_value := sel_registerName("CGRectValue".ptr);
sel_double_value := sel_registerName("doubleValue".ptr);
sel_screen := sel_registerName("screen".ptr);
sel_bounds := sel_registerName("bounds".ptr);
msg_o : (*void, *void) -> *void = xx objc_msgSend;
msg_oo : (*void, *void, *void) -> *void = xx objc_msgSend;
msg_rect : (*void, *void) -> CGRect = xx objc_msgSend;
msg_d : (*void, *void) -> f64 = xx objc_msgSend;
user_info := msg_o(notification, sel_user_info);
user_info := #objc_call(*void)(notification, "userInfo");
if user_info == null { return; }
end_value := msg_oo(user_info, sel_obj_for_key,
end_value := #objc_call(*void)(user_info, "objectForKey:",
ns_string("UIKeyboardFrameEndUserInfoKey".ptr));
if end_value == null { return; }
end_rect := msg_rect(end_value, sel_cg_rect_value);
end_rect := #objc_call(CGRect)(end_value, "CGRectValue");
dur_value := msg_oo(user_info, sel_obj_for_key,
dur_value := #objc_call(*void)(user_info, "objectForKey:",
ns_string("UIKeyboardAnimationDurationUserInfoKey".ptr));
anim_dur : f64 = 0.0;
if dur_value != null { anim_dur = msg_d(dur_value, sel_double_value); }
if dur_value != null { anim_dur = #objc_call(f64)(dur_value, "doubleValue"); }
sel_unsigned_long_value := sel_registerName("unsignedLongValue".ptr);
msg_ul : (*void, *void) -> u64 = xx objc_msgSend;
curve_value := msg_oo(user_info, sel_obj_for_key,
curve_value := #objc_call(*void)(user_info, "objectForKey:",
ns_string("UIKeyboardAnimationCurveUserInfoKey".ptr));
curve_int : u64 = 0;
if curve_value != null { curve_int = msg_ul(curve_value, sel_unsigned_long_value); }
if curve_value != null { curve_int = #objc_call(u64)(curve_value, "unsignedLongValue"); }
// Screen height in points. The window lives on the connected scene's screen.
if plat.window == null { return; }
win_screen := msg_o(plat.window, sel_screen);
screen_bounds := msg_rect(win_screen, sel_bounds);
win_screen := #objc_call(*void)(plat.window, "screen");
screen_bounds := #objc_call(CGRect)(win_screen, "bounds");
// Keyboard height = how much of the screen the keyboard covers from the
// bottom. When the keyboard is hiding, its end-frame.y == screen.height,