Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions crates/perry-ui-android/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1328,9 +1328,11 @@ pub extern "C" fn perry_ui_alert(
// Sheet (new)
// =============================================================================

// #1033: signature aligned with the perry-dispatch row
// `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(width: f64, height: f64, title_val: f64) -> i64 {
sheet::create(width, height, title_val)
pub extern "C" fn perry_ui_sheet_create(body_handle: i64, width: f64, height: f64) -> i64 {
sheet::create(body_handle, width, height)
}

#[no_mangle]
Expand Down
8 changes: 6 additions & 2 deletions crates/perry-ui-android/src/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ thread_local! {
static NEXT_SHEET_ID: RefCell<i64> = RefCell::new(1);
}

pub fn create(width: f64, height: f64, _title_val: f64) -> i64 {
/// Create a sheet whose contents are `body_handle`. #1033: signature is
/// `(body_handle, width, height)` to match perry-dispatch
/// `[Widget, F64, F64]`. The previous shape `(width, height, title)`
/// silently dropped the body on every Apple-platform call.
pub fn create(body_handle: i64, width: f64, height: f64) -> i64 {
let id = NEXT_SHEET_ID.with(|n| {
let mut n = n.borrow_mut();
let id = *n;
Expand All @@ -31,7 +35,7 @@ pub fn create(width: f64, height: f64, _title_val: f64) -> i64 {
SheetState {
width,
height,
body_handle: None,
body_handle: Some(body_handle),
dialog_ref: None,
},
);
Expand Down
7 changes: 4 additions & 3 deletions crates/perry-ui-gtk4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1651,10 +1651,11 @@ pub extern "C" fn perry_ui_image_set_tint(handle: i64, r: f64, g: f64, b: f64, a
// Sheet
// =============================================================================

/// Create a sheet (modal window).
/// Create a sheet (modal window). #1033: signature aligned with the
/// perry-dispatch row `[Widget, F64, F64]`.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(width: f64, height: f64, title_val: f64) -> i64 {
sheet::create(width, height, title_val)
pub extern "C" fn perry_ui_sheet_create(body_handle: i64, width: f64, height: f64) -> i64 {
sheet::create(body_handle, width, height)
}

/// Present (show) a sheet.
Expand Down
36 changes: 8 additions & 28 deletions crates/perry-ui-gtk4/src/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,20 @@ thread_local! {
static NEXT_SHEET_ID: RefCell<i64> = RefCell::new(1);
}

fn str_from_header(ptr: *const u8) -> &'static str {
if ptr.is_null() {
return "";
}
unsafe {
let header = ptr as *const perry_runtime::string::StringHeader;
let len = (*header).byte_len as usize;
let data = ptr.add(std::mem::size_of::<perry_runtime::string::StringHeader>());
std::str::from_utf8_unchecked(std::slice::from_raw_parts(data, len))
}
}

/// Create a sheet (modal window). title_val is a NaN-boxed string (or 0 for no title).
pub fn create(width: f64, height: f64, title_val: f64) -> i64 {
/// Create a modal window holding the given body widget. #1033: signature
/// is `(body_handle, width, height)` to match the perry-dispatch row
/// `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
pub fn create(_body_handle: i64, width: f64, height: f64) -> i64 {
crate::app::ensure_gtk_init();

// Extract title from NaN-boxed value
let title = {
extern "C" {
fn js_get_string_pointer_unified(value: f64) -> *const u8;
}
let ptr = unsafe { js_get_string_pointer_unified(title_val) };
if ptr.is_null() {
"Sheet".to_string()
} else {
str_from_header(ptr).to_string()
}
};

let window = gtk4::Window::new();
window.set_title(Some(&title));
window.set_default_size(width as i32, height as i32);
window.set_modal(true);
window.set_resizable(true);
// GTK widget hand-off across the perry-ui-gtk4 widget registry is
// tracked separately — for now we leave the body unattached, which
// matches the pre-#1033 behavior here. The signature fix is the
// load-bearing change for the macOS sheet bug.

let id = NEXT_SHEET_ID.with(|id| {
let mut id = id.borrow_mut();
Expand Down
4 changes: 3 additions & 1 deletion crates/perry-ui-ios/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2108,8 +2108,10 @@ pub extern "C" fn perry_ui_alert_simple(title_ptr: i64, message_ptr: i64) {
// Sheet
// =============================================================================

// #1033: signature aligned with the perry-dispatch row
// `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(_width: f64, _height: f64, _title: i64) -> i64 {
pub extern "C" fn perry_ui_sheet_create(_body: i64, _width: f64, _height: f64) -> i64 {
0 // stub
}

Expand Down
18 changes: 9 additions & 9 deletions crates/perry-ui-macos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2026,15 +2026,15 @@ pub extern "C" fn perry_ui_alert_simple(title_ptr: i64, message_ptr: i64) {
// Sheet (Modal Panel)
// =============================================================================

/// Create a sheet (panel). Returns handle.
/// title_val arrives as NaN-boxed f64 from codegen — extract pointer internally.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(width: f64, height: f64, title_val: f64) -> i64 {
extern "C" {
fn js_nanbox_get_pointer(value: f64) -> i64;
}
let title_ptr = unsafe { js_nanbox_get_pointer(title_val) } as *const u8;
widgets::sheet::create(width, height, title_ptr)
/// Create a sheet (panel) with a body widget, width, and height. Returns
/// the sheet handle. #1033: aligned with the TS surface
/// `sheetCreate(body, width, height): Widget` and the perry-dispatch row
/// `[Widget, F64, F64]`. The previous `(width, height, title)` signature
/// silently dropped the body handle (it landed in X0; this fn read width
/// from D0), producing a blank sheet at the requested size.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(body_handle: i64, width: f64, height: f64) -> i64 {
widgets::sheet::create(body_handle, width, height)
}

/// Present a sheet on the key window.
Expand Down
35 changes: 19 additions & 16 deletions crates/perry-ui-macos/src/widgets/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,17 @@ thread_local! {
static SHEETS: RefCell<Vec<Retained<NSWindow>>> = const { RefCell::new(Vec::new()) };
}

fn str_from_header(ptr: *const u8) -> &'static str {
if ptr.is_null() {
return "";
}
unsafe {
let header = ptr as *const crate::string_header::StringHeader;
let len = (*header).byte_len as usize;
let data = ptr.add(std::mem::size_of::<crate::string_header::StringHeader>());
std::str::from_utf8_unchecked(std::slice::from_raw_parts(data, len))
}
}

/// Create a sheet (NSPanel). Returns 1-based handle.
pub fn create(width: f64, height: f64, title_ptr: *const u8) -> i64 {
let title = str_from_header(title_ptr);
/// Create a sheet (NSPanel) and install `body_handle` as its content view.
/// Returns the 1-based sheet handle.
///
/// #1033: the TS surface is `sheetCreate(body, width, height): Widget` and
/// the perry-dispatch row matches (`[Widget, F64, F64]`), but the FFI
/// previously took `(width, height, title_ptr)`. On AArch64 the dispatch
/// passed the body handle in X0 and the dimensions in D0/D1, so the
/// dimensions landed in the right registers by luck and the body handle
/// was silently dropped — producing a blank sheet at the requested size.
/// Aligning the FFI signature with the dispatch closes the gap.
pub fn create(body_handle: i64, width: f64, height: f64) -> i64 {
let mtm = MainThreadMarker::new().expect("perry/ui must run on the main thread");

unsafe {
Expand All @@ -39,9 +35,16 @@ pub fn create(width: f64, height: f64, title_ptr: *const u8) -> i64 {
NSBackingStoreType::Buffered,
false,
);
let ns_title = NSString::from_str(title);
// Sheets in the TS surface take no title arg; AppKit still
// requires an NSString, so set the empty string — modern macOS
// sheets typically render without titlebar text anyway.
let ns_title = NSString::from_str("");
panel.setTitle(&ns_title);

if let Some(view) = super::get_widget(body_handle) {
panel.setContentView(Some(&view));
}

SHEETS.with(|s| {
let mut sheets = s.borrow_mut();
sheets.push(panel);
Expand Down
4 changes: 3 additions & 1 deletion crates/perry-ui-tvos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1821,8 +1821,10 @@ pub extern "C" fn perry_ui_alert_simple(title_ptr: i64, message_ptr: i64) {
// Sheet
// =============================================================================

// #1033: signature aligned with the perry-dispatch row
// `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(_width: f64, _height: f64, _title: i64) -> i64 {
pub extern "C" fn perry_ui_sheet_create(_body: i64, _width: f64, _height: f64) -> i64 {
0 // stub
}

Expand Down
4 changes: 3 additions & 1 deletion crates/perry-ui-visionos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1973,8 +1973,10 @@ pub extern "C" fn perry_ui_alert_simple(title_ptr: i64, message_ptr: i64) {
// Sheet
// =============================================================================

// #1033: signature aligned with the perry-dispatch row
// `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(_width: f64, _height: f64, _title: i64) -> i64 {
pub extern "C" fn perry_ui_sheet_create(_body: i64, _width: f64, _height: f64) -> i64 {
0 // stub
}

Expand Down
4 changes: 3 additions & 1 deletion crates/perry-ui-watchos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,9 @@ pub extern "C" fn perry_ui_alert(_title: i64, _msg: i64, _btns: f64, _cb: f64) {
#[no_mangle]
pub extern "C" fn perry_ui_alert_simple(_title: i64, _msg: i64) {}
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(_w: f64, _h: f64, _title: i64) -> i64 {
// #1033: signature aligned with the perry-dispatch row
// `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
pub extern "C" fn perry_ui_sheet_create(_body: i64, _w: f64, _h: f64) -> i64 {
0
}
#[no_mangle]
Expand Down
7 changes: 4 additions & 3 deletions crates/perry-ui-windows/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1481,10 +1481,11 @@ pub extern "C" fn perry_ui_image_set_tint(handle: i64, r: f64, g: f64, b: f64, a
// Sheet
// =============================================================================

/// Create a sheet (modal window).
/// Create a sheet (modal window). #1033: signature aligned with the
/// perry-dispatch row `[Widget, F64, F64]`.
#[no_mangle]
pub extern "C" fn perry_ui_sheet_create(width: f64, height: f64, title_val: f64) -> i64 {
sheet::create(width, height, title_val)
pub extern "C" fn perry_ui_sheet_create(body_handle: i64, width: f64, height: f64) -> i64 {
sheet::create(body_handle, width, height)
}

/// Present (show) a sheet.
Expand Down
38 changes: 9 additions & 29 deletions crates/perry-ui-windows/src/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,6 @@ thread_local! {
static NEXT_SHEET_ID: RefCell<i64> = RefCell::new(1);
}

extern "C" {
fn js_get_string_pointer_unified(value: f64) -> *const u8;
}

fn str_from_header(ptr: *const u8) -> &'static str {
if ptr.is_null() {
return "";
}
unsafe {
let header = ptr as *const perry_runtime::string::StringHeader;
let len = (*header).byte_len as usize;
let data = ptr.add(std::mem::size_of::<perry_runtime::string::StringHeader>());
std::str::from_utf8_unchecked(std::slice::from_raw_parts(data, len))
}
}

#[cfg(target_os = "windows")]
fn to_wide(s: &str) -> Vec<u16> {
s.encode_utf16().chain(std::iter::once(0)).collect()
Expand All @@ -42,17 +26,13 @@ unsafe extern "system" fn sheet_default_wnd_proc(
windows::Win32::UI::WindowsAndMessaging::DefWindowProcW(hwnd, msg, wparam, lparam)
}

/// Create a sheet (modal popup window).
pub fn create(width: f64, height: f64, title_val: f64) -> i64 {
let title = {
let ptr = unsafe { js_get_string_pointer_unified(title_val) };
if ptr.is_null() {
"Sheet".to_string()
} else {
str_from_header(ptr).to_string()
}
};

/// Create a sheet (modal popup window) with the body widget installed
/// as the content view. #1033: signature aligned with the perry-dispatch
/// row `[Widget, F64, F64]` and the TS surface `sheetCreate(body, w, h)`.
/// Win32 child-view attach is a separate change; for now the body handle
/// is accepted so the ABI matches and the call doesn't shuffle the
/// dimensions through the wrong registers.
pub fn create(_body_handle: i64, width: f64, height: f64) -> i64 {
let id = NEXT_SHEET_ID.with(|id| {
let mut id = id.borrow_mut();
let current = *id;
Expand Down Expand Up @@ -85,7 +65,7 @@ pub fn create(width: f64, height: f64, title_val: f64) -> i64 {
};
RegisterClassExW(&wc);

let title_wide = to_wide(&title);
let title_wide = to_wide("");
let hwnd = CreateWindowExW(
WINDOW_EX_STYLE::default(),
PCWSTR(class_name.as_ptr()),
Expand All @@ -108,7 +88,7 @@ pub fn create(width: f64, height: f64, title_val: f64) -> i64 {

#[cfg(not(target_os = "windows"))]
{
let _ = (width, height, title);
let _ = (width, height);
SHEETS.with(|s| s.borrow_mut().insert(id, 0));
}

Expand Down
Loading