Skip to content
Open
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
53 changes: 53 additions & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,38 @@ pub enum Event<'a, T: 'static> {
/// This lets you determine why the scene was requested.
options: objc2::rc::Retained<objc2_ui_kit::UISceneConnectionOptions>,
},

/// Emitted when the application has been started.
///
/// ## Platform-specific
///
/// - **OHOS**: Triggered by `onAbilityStart` lifecycle callback.
/// - **Other**: Unsupported.
#[cfg(target_env = "ohos")]
Started,

/// Emitted when the system requests the application to save its state.
///
/// ## Platform-specific
///
/// - **OHOS**: Triggered by `onAbilitySaveState` lifecycle callback.
/// - **Other**: Unsupported.
#[cfg(target_env = "ohos")]
SaveStateRequested,

/// Emitted when the application's content rect has changed (e.g. keyboard shown/hidden).
///
/// ## Platform-specific
///
/// - **OHOS**: Triggered by `window.on("contentRectChange")` callback.
/// - **Other**: Unsupported.
#[cfg(target_env = "ohos")]
ContentRectChanged {
/// The new content rectangle (left, top, width, height).
rect: (i32, i32, i32, i32),
/// Reason for the change.
reason: u32,
},
}

impl<T: Clone> Clone for Event<'static, T> {
Expand Down Expand Up @@ -202,6 +234,15 @@ impl<T: Clone> Clone for Event<'static, T> {
scene: scene.clone(),
options: options.clone(),
},
#[cfg(target_env = "ohos")]
Started => Started,
#[cfg(target_env = "ohos")]
SaveStateRequested => SaveStateRequested,
#[cfg(target_env = "ohos")]
ContentRectChanged { rect, reason } => ContentRectChanged {
rect: *rect,
reason: *reason,
},
}
}
}
Expand All @@ -228,6 +269,12 @@ impl<'a, T> Event<'a, T> {
}),
#[cfg(target_os = "ios")]
SceneRequested { scene, options } => Ok(SceneRequested { scene, options }),
#[cfg(target_env = "ohos")]
Started => Ok(Started),
#[cfg(target_env = "ohos")]
SaveStateRequested => Ok(SaveStateRequested),
#[cfg(target_env = "ohos")]
ContentRectChanged { rect, reason } => Ok(ContentRectChanged { rect, reason }),
}
}

Expand Down Expand Up @@ -256,6 +303,12 @@ impl<'a, T> Event<'a, T> {
}),
#[cfg(target_os = "ios")]
SceneRequested { scene, options } => Some(SceneRequested { scene, options }),
#[cfg(target_env = "ohos")]
Started => Some(Started),
#[cfg(target_env = "ohos")]
SaveStateRequested => Some(SaveStateRequested),
#[cfg(target_env = "ohos")]
ContentRectChanged { rect, reason } => Some(ContentRectChanged { rect, reason }),
}
}
}
Expand Down
51 changes: 41 additions & 10 deletions src/platform_impl/ohos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,28 @@ impl<T: 'static> EventLoop<T> {
// Propagate as Resized so tauri's resize handler fires and calls
// webview.set_bounds() with the new window dimensions.
let size = PhysicalSize::new(content_rect.rect.width as _, content_rect.rect.height as _);
let event = event::Event::WindowEvent {
let resized_event = event::Event::WindowEvent {
window_id: window::WindowId(WindowId),
event: event::WindowEvent::Resized(size),
};

if let Some(ref mut h) = *self.event_loop.borrow_mut() {
h(event);
h(resized_event);

// Also emit ContentRectChanged for lifecycle-aware applications
let reason = match content_rect.reason {
openharmony_ability::RectChangeReason::Undefined => 0,
openharmony_ability::RectChangeReason::Maximize => 1,
openharmony_ability::RectChangeReason::Recover => 2,
openharmony_ability::RectChangeReason::Move => 3,
openharmony_ability::RectChangeReason::Drag => 4,
openharmony_ability::RectChangeReason::DragStart => 5,
openharmony_ability::RectChangeReason::DragEnd => 6,
};
h(event::Event::ContentRectChanged {
rect: (content_rect.rect.left, content_rect.rect.top, content_rect.rect.width, content_rect.rect.height),
reason,
});
}
}
MainEvent::GainedFocus => {
Expand Down Expand Up @@ -556,23 +571,39 @@ impl<T: 'static> EventLoop<T> {
}
}
MainEvent::Start => {
// XXX: how to forward this state to applications?
warn!("TODO: forward onStart notification to application");
if let Some(ref mut h) = *self.event_loop.borrow_mut() {
h(event::Event::Started);
}
}
MainEvent::Resume { .. } => {
// NOTE: The SaveLoader handle for state restoration is intentionally
// discarded. State I/O is not yet wired through to applications.
if let Some(ref mut h) = *self.event_loop.borrow_mut() {
h(event::Event::Resumed);
}
}
MainEvent::SaveState { .. } => {
// XXX: how to forward this state to applications?
// XXX: also how do we expose state restoration to apps?
warn!("TODO: forward saveState notification to application");
// NOTE: The SaveSaver handle for state persistence is intentionally
// discarded. Applications receive SaveStateRequested as a notification
// only; actual state writing via SaveSaver is not yet supported.
if let Some(ref mut h) = *self.event_loop.borrow_mut() {
h(event::Event::SaveStateRequested);
}
}
// OHOS lifecycle: Pause = about to enter background (surface still alive).
// Mapped to Suspended for cross-platform consistency with Android/iOS.
// Note: this fires earlier than a full "Stop/Hidden" state.
MainEvent::Pause => {
debug!("App Paused - stopped running");
// TODO: This is incorrect - will be solved in https://github.com/rust-windowing/winit/pull/3897
// self.running = false;
if let Some(ref mut h) = *self.event_loop.borrow_mut() {
h(event::Event::Suspended);
}
}
// OHOS lifecycle: Stop = ability fully hidden/backgrounded (StageEventType::Hidden).
// Also mapped to Suspended — apps see a second Suspended when fully backgrounded.
MainEvent::Stop => {
if let Some(ref mut h) = *self.event_loop.borrow_mut() {
h(event::Event::Suspended);
}
}
MainEvent::WindowDestroy => {
if let Some(ref mut h) = *self.event_loop.borrow_mut() {
Expand Down