@effindomv2/fui-rs 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/Cargo.toml +1 -1
  2. package/README.md +69 -0
  3. package/package.json +1 -1
  4. package/scripts/hostgen/rust-host-events.ts +43 -13
  5. package/src/app.rs +7 -0
  6. package/src/assets.rs +2 -2
  7. package/src/bindings/ui.rs +2 -0
  8. package/src/bridge_callbacks.rs +27 -17
  9. package/src/color.rs +112 -0
  10. package/src/controls/button.rs +1 -0
  11. package/src/controls/checkbox.rs +1 -0
  12. package/src/controls/combobox.rs +5 -3
  13. package/src/controls/dropdown.rs +3 -1
  14. package/src/controls/internal/pressable_labeled_control.rs +1 -0
  15. package/src/controls/internal/text_input_core.rs +7 -3
  16. package/src/controls/radio_button.rs +1 -0
  17. package/src/controls/shared.rs +2 -5
  18. package/src/controls/slider.rs +1 -0
  19. package/src/controls/switch.rs +1 -0
  20. package/src/controls/tests.rs +36 -7
  21. package/src/debug.rs +8 -5
  22. package/src/drag_drop.rs +1 -3
  23. package/src/drawing.rs +8 -0
  24. package/src/event.rs +39 -27
  25. package/src/fetch.rs +21 -7
  26. package/src/ffi.rs +3 -1
  27. package/src/file.rs +88 -59
  28. package/src/host_events.rs +41 -0
  29. package/src/lib.rs +55 -9
  30. package/src/node/core.rs +22 -21
  31. package/src/node/helpers.rs +1 -1
  32. package/src/node/mod.rs +1 -1
  33. package/src/node/scroll_bar.rs +101 -0
  34. package/src/node/scroll_box.rs +7 -0
  35. package/src/node/scroll_view.rs +20 -14
  36. package/src/node/virtual_list.rs +120 -33
  37. package/src/platform.rs +3 -0
  38. package/src/popup_presenter.rs +1 -0
  39. package/src/theme.rs +8 -48
  40. package/src/timers.rs +1 -1
  41. package/src/typography.rs +6 -14
  42. package/src/worker.rs +25 -9
  43. package/src/worker_runtime.rs +61 -17
@@ -213,7 +213,9 @@ fn press_enter(node_ref: &crate::node::NodeRef) {
213
213
  }
214
214
 
215
215
  fn key_event(event_type: KeyEventType, key: &str, modifiers: u32) -> bool {
216
- event::__fui_on_key_event(event_type as u32, key.as_ptr(), key.len() as u32, modifiers)
216
+ unsafe {
217
+ event::__fui_on_key_event(event_type as u32, key.as_ptr(), key.len() as u32, modifiers)
218
+ }
217
219
  }
218
220
 
219
221
  fn blur(node_ref: &crate::node::NodeRef) {
@@ -1407,7 +1409,7 @@ fn retained_dropdown_keeps_theme_subscription_after_wrapper_drop() {
1407
1409
  let mut theme = current_theme();
1408
1410
  theme.colors.surface = 0x135724FF;
1409
1411
  theme.colors.border = 0x246813FF;
1410
- theme.colors.text_primary = 0xABCDEFff;
1412
+ theme.colors.text_primary = 0xABCDEFFF;
1411
1413
  use_custom_theme(theme.clone());
1412
1414
  let calls = ffi::test::take_calls();
1413
1415
 
@@ -2925,6 +2927,23 @@ fn checkbox_user_activation_emits_changed_and_semantic_announcement() {
2925
2927
  Application::unmount();
2926
2928
  }
2927
2929
 
2930
+ #[test]
2931
+ fn checkbox_prebuild_state_is_retained_into_semantic_build_state() {
2932
+ ffi::test::reset();
2933
+ let checkbox = checkbox("Agree");
2934
+ checkbox.check(true);
2935
+
2936
+ Application::mount(checkbox.clone());
2937
+ let handle = checkbox.retained_node_ref().handle().raw();
2938
+ let calls = ffi::test::take_calls();
2939
+ assert!(calls.iter().any(|call| matches!(
2940
+ call,
2941
+ Call::SetSemanticChecked { handle: checked_handle, checked_state_enum }
2942
+ if *checked_handle == handle && *checked_state_enum == SemanticCheckedState::True as u32
2943
+ )));
2944
+ Application::unmount();
2945
+ }
2946
+
2928
2947
  #[test]
2929
2948
  fn radio_and_switch_programmatic_changes_emit_without_semantic_announcement() {
2930
2949
  ffi::test::reset();
@@ -4212,7 +4231,9 @@ fn text_input_text_replaced_event_updates_value_and_emits_changed() {
4212
4231
  })
4213
4232
  .expect("expected text input editor node id to be applied");
4214
4233
 
4215
- event::__fui_on_text_replaced(editor_handle, 0, 0, b"hello".as_ptr(), 5);
4234
+ unsafe {
4235
+ event::__fui_on_text_replaced(editor_handle, 0, 0, b"hello".as_ptr(), 5);
4236
+ }
4216
4237
 
4217
4238
  assert_eq!(input.value(), "hello");
4218
4239
  assert_eq!(&*last_text.borrow(), "hello");
@@ -4474,7 +4495,9 @@ fn text_input_text_replacement_clamps_selection_bytes_from_char_positions() {
4474
4495
  })
4475
4496
  .expect("expected text input editor node id to be applied");
4476
4497
 
4477
- event::__fui_on_text_replaced(editor_handle, 1, 5, std::ptr::null(), 0);
4498
+ unsafe {
4499
+ event::__fui_on_text_replaced(editor_handle, 1, 5, std::ptr::null(), 0);
4500
+ }
4478
4501
 
4479
4502
  assert_eq!(input.value(), "ab");
4480
4503
  assert_eq!(input.selection_start(), 0);
@@ -4660,16 +4683,22 @@ fn text_area_readonly_disabled_placeholder_and_line_height_follow_text_input_cor
4660
4683
  if *handle == editor_handle && (*line_height - 26.0).abs() < f32::EPSILON
4661
4684
  )));
4662
4685
 
4663
- event::__fui_on_text_replaced(editor_handle, 0, 0, b"Hello\nworld".as_ptr(), 11);
4686
+ unsafe {
4687
+ event::__fui_on_text_replaced(editor_handle, 0, 0, b"Hello\nworld".as_ptr(), 11);
4688
+ }
4664
4689
  assert_eq!(input.value(), "Hello\nworld");
4665
4690
 
4666
- event::__fui_on_text_changed(editor_handle, b"alpha\nbeta".as_ptr(), 10);
4691
+ unsafe {
4692
+ event::__fui_on_text_changed(editor_handle, b"alpha\nbeta".as_ptr(), 10);
4693
+ }
4667
4694
  assert_eq!(input.value(), "alpha\nbeta");
4668
4695
  event::__fui_on_selection_changed(editor_handle, 6, 10);
4669
4696
  assert_eq!(input.selection_start(), 6);
4670
4697
  assert_eq!(input.selection_end(), 10);
4671
4698
 
4672
- event::__fui_on_text_replaced(editor_handle, 0, 11, std::ptr::null(), 0);
4699
+ unsafe {
4700
+ event::__fui_on_text_replaced(editor_handle, 0, 11, std::ptr::null(), 0);
4701
+ }
4673
4702
  assert_eq!(input.value(), "");
4674
4703
  Application::unmount();
4675
4704
  }
package/src/debug.rs CHANGED
@@ -2,6 +2,7 @@ use crate::event::{self, PointerType};
2
2
  use crate::ffi::{self, KeyEventType, PointerEventType};
3
3
  use crate::node::NodeHandle;
4
4
 
5
+ #[allow(clippy::too_many_arguments)]
5
6
  pub fn pointer_event(
6
7
  event_type: PointerEventType,
7
8
  handle: NodeHandle,
@@ -42,7 +43,7 @@ pub fn key_event(event_type: KeyEventType, key: &str, modifiers: u32) -> bool {
42
43
  event::dispatch_key_event(event_type, key.to_string(), modifiers)
43
44
  }
44
45
 
45
- #[no_mangle]
46
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
46
47
  pub extern "C" fn __fui_debug_pointer_event(
47
48
  event_type: u32,
48
49
  handle: u64,
@@ -74,8 +75,10 @@ pub extern "C" fn __fui_debug_pointer_event(
74
75
  );
75
76
  }
76
77
 
77
- #[no_mangle]
78
- pub extern "C" fn __fui_debug_key_event(
78
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
79
+ /// # Safety
80
+ /// `key_ptr` must be null for an empty key or point to `key_len` readable bytes.
81
+ pub unsafe extern "C" fn __fui_debug_key_event(
79
82
  event_type: u32,
80
83
  key_ptr: *const u8,
81
84
  key_len: u32,
@@ -97,12 +100,12 @@ pub extern "C" fn __fui_debug_key_event(
97
100
  );
98
101
  }
99
102
 
100
- #[no_mangle]
103
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
101
104
  pub extern "C" fn __fui_debug_focus_changed(handle: u64, focused: bool) {
102
105
  event::dispatch_focus_changed(NodeHandle::from_raw(handle), focused);
103
106
  }
104
107
 
105
- #[no_mangle]
108
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
106
109
  pub extern "C" fn __fui_debug_scroll(
107
110
  handle: u64,
108
111
  offset_x: f32,
package/src/drag_drop.rs CHANGED
@@ -399,9 +399,7 @@ fn finish_session(
399
399
  notify_target_leave: bool,
400
400
  ) {
401
401
  let target = with_state(|state| {
402
- let Some(active) = state.active_session.as_ref() else {
403
- return None;
404
- };
402
+ let active = state.active_session.as_ref()?;
405
403
  if !Rc::ptr_eq(&active.inner, &session.inner) {
406
404
  return None;
407
405
  }
package/src/drawing.rs CHANGED
@@ -1,3 +1,5 @@
1
+ #![allow(clippy::too_many_arguments)]
2
+
1
3
  use crate::ffi;
2
4
  use crate::image_sampling::ImageSampling;
3
5
  use crate::logger::error;
@@ -78,6 +80,12 @@ pub struct Path {
78
80
  resource: Rc<PathResource>,
79
81
  }
80
82
 
83
+ impl Default for Path {
84
+ fn default() -> Self {
85
+ Self::new()
86
+ }
87
+ }
88
+
81
89
  impl Path {
82
90
  pub fn new() -> Self {
83
91
  let id = unsafe { ffi::fui_path_create() };
package/src/event.rs CHANGED
@@ -1,3 +1,5 @@
1
+ #![allow(clippy::too_many_arguments)]
2
+
1
3
  use crate::context_menu_manager;
2
4
  use crate::drag_drop;
3
5
  use crate::external_drop;
@@ -1331,27 +1333,27 @@ pub(crate) fn dispatch_external_drop_event(
1331
1333
  })
1332
1334
  }
1333
1335
 
1334
- #[no_mangle]
1336
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1335
1337
  pub extern "C" fn __fui_key_buffer() -> *const u8 {
1336
1338
  std::ptr::addr_of_mut!(KEY_BUFFER).cast::<u8>()
1337
1339
  }
1338
1340
 
1339
- #[no_mangle]
1341
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1340
1342
  pub extern "C" fn __fui_key_buffer_size() -> u32 {
1341
1343
  256
1342
1344
  }
1343
1345
 
1344
- #[no_mangle]
1346
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1345
1347
  pub extern "C" fn __fui_text_buffer() -> *const u8 {
1346
1348
  std::ptr::addr_of_mut!(TEXT_BUFFER).cast::<u8>()
1347
1349
  }
1348
1350
 
1349
- #[no_mangle]
1351
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1350
1352
  pub extern "C" fn __fui_text_buffer_size() -> u32 {
1351
1353
  (16 * 1024) as u32
1352
1354
  }
1353
1355
 
1354
- #[no_mangle]
1356
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1355
1357
  pub extern "C" fn __fui_on_pointer_event_with_metadata(
1356
1358
  event_type: u32,
1357
1359
  handle: u64,
@@ -1391,7 +1393,7 @@ pub extern "C" fn __fui_on_pointer_event_with_metadata(
1391
1393
  )
1392
1394
  }
1393
1395
 
1394
- #[no_mangle]
1396
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1395
1397
  pub extern "C" fn __fui_on_wheel_event(
1396
1398
  handle: u64,
1397
1399
  x: f32,
@@ -1412,8 +1414,10 @@ pub extern "C" fn __fui_on_wheel_event(
1412
1414
  )
1413
1415
  }
1414
1416
 
1415
- #[no_mangle]
1416
- pub extern "C" fn __fui_on_key_event(
1417
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1418
+ /// # Safety
1419
+ /// `key_ptr` must be null for an empty key or point to `key_len` readable bytes.
1420
+ pub unsafe extern "C" fn __fui_on_key_event(
1417
1421
  event_type: u32,
1418
1422
  key_ptr: *const u8,
1419
1423
  key_len: u32,
@@ -1435,13 +1439,15 @@ pub extern "C" fn __fui_on_key_event(
1435
1439
  )
1436
1440
  }
1437
1441
 
1438
- #[no_mangle]
1442
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1439
1443
  pub extern "C" fn __fui_on_focus_changed(handle: u64, focused: bool) {
1440
1444
  dispatch_focus_changed(NodeHandle::from_raw(handle), focused);
1441
1445
  }
1442
1446
 
1443
- #[no_mangle]
1444
- pub extern "C" fn __fui_on_text_changed(handle: u64, text_ptr: *const u8, text_len: u32) {
1447
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1448
+ /// # Safety
1449
+ /// `text_ptr` must be null for empty text or point to `text_len` readable bytes.
1450
+ pub unsafe extern "C" fn __fui_on_text_changed(handle: u64, text_ptr: *const u8, text_len: u32) {
1445
1451
  let text = if text_ptr.is_null() || text_len == 0 {
1446
1452
  String::new()
1447
1453
  } else {
@@ -1451,8 +1457,10 @@ pub extern "C" fn __fui_on_text_changed(handle: u64, text_ptr: *const u8, text_l
1451
1457
  dispatch_text_changed(NodeHandle::from_raw(handle), text);
1452
1458
  }
1453
1459
 
1454
- #[no_mangle]
1455
- pub extern "C" fn __fui_on_text_replaced(
1460
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1461
+ /// # Safety
1462
+ /// `text_ptr` must be null for empty replacement text or point to `text_len` readable bytes.
1463
+ pub unsafe extern "C" fn __fui_on_text_replaced(
1456
1464
  handle: u64,
1457
1465
  start: u32,
1458
1466
  end: u32,
@@ -1468,13 +1476,15 @@ pub extern "C" fn __fui_on_text_replaced(
1468
1476
  dispatch_text_replaced(NodeHandle::from_raw(handle), start, end, text);
1469
1477
  }
1470
1478
 
1471
- #[no_mangle]
1479
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1472
1480
  pub extern "C" fn __fui_on_selection_changed(handle: u64, start: u32, end: u32) {
1473
1481
  dispatch_selection_changed(NodeHandle::from_raw(handle), start, end);
1474
1482
  }
1475
1483
 
1476
- #[no_mangle]
1477
- pub extern "C" fn __fui_on_cross_selection_changed(
1484
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1485
+ /// # Safety
1486
+ /// `text_ptr` must be null for empty text or point to `text_len` readable bytes.
1487
+ pub unsafe extern "C" fn __fui_on_cross_selection_changed(
1478
1488
  handle: u64,
1479
1489
  text_ptr: *const u8,
1480
1490
  text_len: u32,
@@ -1488,17 +1498,17 @@ pub extern "C" fn __fui_on_cross_selection_changed(
1488
1498
  dispatch_cross_selection_changed(NodeHandle::from_raw(handle), text);
1489
1499
  }
1490
1500
 
1491
- #[no_mangle]
1501
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1492
1502
  pub extern "C" fn __fui_resolve_gesture_owner(handle: u64) -> u64 {
1493
1503
  resolve_gesture_owner(NodeHandle::from_raw(handle)).raw()
1494
1504
  }
1495
1505
 
1496
- #[no_mangle]
1506
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1497
1507
  pub extern "C" fn __fui_get_gesture_intent(handle: u64) -> u32 {
1498
1508
  get_gesture_intent(NodeHandle::from_raw(handle)) as u32
1499
1509
  }
1500
1510
 
1501
- #[no_mangle]
1511
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1502
1512
  pub extern "C" fn __fui_on_gesture_event(
1503
1513
  handle: u64,
1504
1514
  phase: u32,
@@ -1523,27 +1533,27 @@ pub extern "C" fn __fui_on_gesture_event(
1523
1533
  )
1524
1534
  }
1525
1535
 
1526
- #[no_mangle]
1536
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1527
1537
  pub extern "C" fn __fui_resolve_long_press_owner(handle: u64) -> u64 {
1528
1538
  resolve_long_press_owner(NodeHandle::from_raw(handle)).raw()
1529
1539
  }
1530
1540
 
1531
- #[no_mangle]
1541
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1532
1542
  pub extern "C" fn __fui_get_long_press_minimum_duration_ms(handle: u64) -> i32 {
1533
1543
  get_long_press_minimum_duration_ms(NodeHandle::from_raw(handle))
1534
1544
  }
1535
1545
 
1536
- #[no_mangle]
1546
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1537
1547
  pub extern "C" fn __fui_get_long_press_movement_tolerance(handle: u64) -> f32 {
1538
1548
  get_long_press_movement_tolerance(NodeHandle::from_raw(handle))
1539
1549
  }
1540
1550
 
1541
- #[no_mangle]
1551
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1542
1552
  pub extern "C" fn __fui_long_press_continues_pointer_events(handle: u64) -> bool {
1543
1553
  registered_node(handle).is_some_and(|node| node.has_drag_source())
1544
1554
  }
1545
1555
 
1546
- #[no_mangle]
1556
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1547
1557
  pub extern "C" fn __fui_on_long_press_event(
1548
1558
  handle: u64,
1549
1559
  scene_x: f32,
@@ -1564,8 +1574,10 @@ pub extern "C" fn __fui_on_long_press_event(
1564
1574
  )
1565
1575
  }
1566
1576
 
1567
- #[no_mangle]
1568
- pub extern "C" fn __fui_on_external_drag_event(
1577
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1578
+ /// # Safety
1579
+ /// `payload_ptr` must be null for an empty payload or point to `payload_len` readable bytes.
1580
+ pub unsafe extern "C" fn __fui_on_external_drag_event(
1569
1581
  event_type: u32,
1570
1582
  handle: u64,
1571
1583
  x: f32,
@@ -1595,7 +1607,7 @@ pub extern "C" fn __fui_on_external_drag_event(
1595
1607
  effect as u32
1596
1608
  }
1597
1609
 
1598
- #[no_mangle]
1610
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
1599
1611
  pub extern "C" fn fui_dispatch_custom_draw(handle: u64, canvas_ptr: usize) {
1600
1612
  if let Some(node) = resolve_node(NodeHandle::from_raw(handle)) {
1601
1613
  node.handle_custom_draw(canvas_ptr);
package/src/fetch.rs CHANGED
@@ -337,8 +337,10 @@ pub fn reset_fetch_runtime() {
337
337
  });
338
338
  }
339
339
 
340
- #[no_mangle]
341
- pub extern "C" fn __fui_on_fetch_complete(
340
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
341
+ /// # Safety
342
+ /// `payload_ptr` must be null for an empty payload or point to `payload_len` readable bytes.
343
+ pub unsafe extern "C" fn __fui_on_fetch_complete(
342
344
  request_id: u32,
343
345
  ok: bool,
344
346
  status: i32,
@@ -361,8 +363,14 @@ pub extern "C" fn __fui_on_fetch_complete(
361
363
  );
362
364
  }
363
365
 
364
- #[no_mangle]
365
- pub extern "C" fn __fui_on_fetch_error(request_id: u32, payload_ptr: *const u8, payload_len: u32) {
366
+ #[cfg_attr(not(feature = "worker-runtime"), no_mangle)]
367
+ /// # Safety
368
+ /// `payload_ptr` must be null for an empty payload or point to `payload_len` readable bytes.
369
+ pub unsafe extern "C" fn __fui_on_fetch_error(
370
+ request_id: u32,
371
+ payload_ptr: *const u8,
372
+ payload_len: u32,
373
+ ) {
366
374
  let message = if payload_ptr.is_null() || payload_len == 0 {
367
375
  "Fetch request failed.".to_string()
368
376
  } else {
@@ -413,7 +421,9 @@ mod tests {
413
421
  }
414
422
  bytes
415
423
  };
416
- super::__fui_on_fetch_complete(1, true, 200, payload.as_ptr(), payload.len() as u32);
424
+ unsafe {
425
+ super::__fui_on_fetch_complete(1, true, 200, payload.as_ptr(), payload.len() as u32);
426
+ }
417
427
  assert_eq!(&*result.borrow(), "OK");
418
428
  drop(request);
419
429
  }
@@ -464,7 +474,9 @@ mod tests {
464
474
  }
465
475
  bytes
466
476
  };
467
- super::__fui_on_fetch_complete(1, true, 200, payload.as_ptr(), payload.len() as u32);
477
+ unsafe {
478
+ super::__fui_on_fetch_complete(1, true, 200, payload.as_ptr(), payload.len() as u32);
479
+ }
468
480
  assert_eq!(&*result.borrow(), "");
469
481
  drop(request);
470
482
  }
@@ -493,7 +505,9 @@ mod tests {
493
505
  result_clone.replace(event.message);
494
506
  })
495
507
  .start();
496
- super::__fui_on_fetch_error(1, std::ptr::null(), 0);
508
+ unsafe {
509
+ super::__fui_on_fetch_error(1, std::ptr::null(), 0);
510
+ }
497
511
  assert_eq!(&*result.borrow(), "Fetch request failed.");
498
512
  drop(request);
499
513
  }
package/src/ffi.rs CHANGED
@@ -1,3 +1,5 @@
1
+ #![allow(clippy::too_many_arguments, clippy::type_complexity)]
2
+
1
3
  pub use crate::generated::ffi::*;
2
4
 
3
5
  #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
@@ -3433,7 +3435,7 @@ pub unsafe fn fui_canvas_create_offscreen(width: u32, height: u32) -> u32 {
3433
3435
  #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]
3434
3436
  pub unsafe fn fui_canvas_get_offscreen_ptr(offscreen_id: u32) -> usize {
3435
3437
  push_call(Call::CanvasGetOffscreenPtr { offscreen_id });
3436
- (0x1000 + offscreen_id as usize) as usize
3438
+ 0x1000 + offscreen_id as usize
3437
3439
  }
3438
3440
 
3439
3441
  #[cfg(all(not(target_arch = "wasm32"), not(feature = "native-runtime")))]