tray

Cross-platform native tray helpers for MoonBit.

tray
desktop
native
windows
macos
linux
moon add justjavac/tray@0.1.7
Download zip
Author
Version
0.1.7
License
MIT
Last updated
last month
Downloads
6K
README

#justjavac/tray

CI coverage linux macos windows

Cross-platform native tray helpers for MoonBit.

#Example

guard @tray.is_supported() else {
return
}

let tray = @tray.create(
identifier="com.example.demo",
tooltip="MoonBit tray demo",
)

match tray {
Ok(tray) => {
match tray.show() {
Ok(_) =>
match tray.pump() {
Ok(_) => ()
Err(error) => println(error)
}
Err(error) => println(error)
}
tray.destroy()
}
Err(error) => println(error)
}

#
Platform

pub enum Platform {
Windows
Linux
MacOS
Unknown
} derive(Eq, ToJson,
Debug
)

Desktop platform reported by the native tray backend.

Windows, Linux, and MacOS identify a backend this package knows how to drive. Unknown is returned when the native stub cannot map the host operating system to a supported variant, which typically also means tray creation will fail. Use this to branch platform-specific setup or to enrich diagnostics; the value is derived from current_platform().
impl Show for Platform

#
Tray

pub struct Tray {
handle : Int64
native : Bool
platform : Platform
identifier : String
icon : String?
tooltip : String
visible : Bool
destroyed : Bool
}

Represents a system tray handle created by this package.

A Tray tracks the user-visible state that the MoonBit layer believes is active, including whether the tray is currently visible, which tooltip is being shown, and which icon path was last requested. The underlying native resources are released by calling destroy().

#
Tray::destroy

fn Tray::destroy(self : Tray) -> Unit

Releases the underlying native resources and turns the handle into a no-op object that rejects later operations.

Calling destroy() more than once is safe; repeated calls are ignored after the first teardown has marked the handle as destroyed.

After destruction the tray becomes permanently unusable: show(), hide(), set_tooltip(), set_icon(), and pump() will all return errors instead of touching the native backend again.

#
Tray::hide

fn Tray::hide(self : Tray) -> Result[Bool, String]

Hides the tray icon while keeping the handle valid for later show() calls.

The returned boolean reflects the post-call visibility state, so successful calls resolve to Ok(false) whether the tray is native or simulated.

This is safe to call even when the tray is already hidden; the handle stays valid and can be shown again later. Destroyed trays still reject the call with an error.

#
Tray::pump

fn Tray::pump(self : Tray, blocking? : Bool) -> Result[Bool, String]

Pumps one native tray loop iteration.

Call this from long-running native applications when the host platform needs event-loop progress from the tray backend. A return value of Ok(false) means the backend asked to stop processing. Simulated trays always return Ok(true) so unit tests can exercise state transitions without a native message loop.

Passing blocking=true lets the backend wait for work before returning; blocking=false performs at most one non-blocking iteration. Backend errors and calls on destroyed trays return Err(message).

#
Tray::set_icon

fn Tray::set_icon(self : Tray, icon : String?) -> Result[Bool, String]

Changes the tray icon path or resets it to the platform default when None is passed.

This updates the stored icon preference even for simulated trays used in tests, and the returned boolean mirrors whether the tray is visible after the change.

Pass Some(path) to request a specific icon file, or None to fall back to the backend's default tray icon. Successful calls return the current visible state; destroyed trays and backend failures return Err(message).

#
Tray::set_tooltip

fn Tray::set_tooltip(self : Tray, tooltip : String) -> Result[Bool, String]

Replaces the current tooltip text without changing visibility.

Platforms that cannot show a real tooltip may map this value to the nearest native concept available to the host desktop environment. The returned boolean mirrors whether the tray is visible after the update.

Hidden trays keep the new tooltip so the next show() call reuses it by default. Successful calls return the current visible state, while destroyed trays or backend failures return Err(message).

#
Tray::show

fn Tray::show(self : Tray, tooltip? : String?) -> Result[Bool, String]

Shows the tray icon and optionally replaces the tooltip in the same call.

Passing tooltip=Some(...) is the most efficient way to update the tooltip immediately before the tray becomes visible. The result reports the tray's visible state after the call, and invoking this on a simulated test tray updates only the MoonBit-side state.

Passing tooltip=None reuses the most recently stored tooltip. Successful calls always resolve to Ok(true). If the tray has already been destroyed, or if the native backend rejects the operation, this returns Err(message).

#
create

fn create(identifier? : String, icon? : String?, tooltip? : String) -> Result[Tray, String]

Creates a tray handle with an optional icon path and initial tooltip.

  • identifier should be a stable, non-empty id for the tray instance.
  • icon may be None to request the platform default tray icon.
  • tooltip becomes the initial hover text when the platform supports it.

The returned handle starts hidden, so callers can finish any last setup and then call show(). Empty or whitespace-only identifiers are normalized back to default_identifier(), and failures include the latest native error when the backend provides one.

On success this returns Ok(tray) with a live handle that can be shown, hidden, updated, pumped, and eventually destroyed. On failure this returns Err(message) with either the support-probe failure or the most recent backend creation error.

Example

let tray = @tray.create(icon=Some("/path/to/icon.png"), tooltip="My App").unwrap()
let _ = tray.show()
// ... run the application event loop, calling `tray.pump()` as needed ...
tray.destroy()

#
current_platform

fn current_platform() -> Platform

Returns the desktop platform detected by the native backend for the current process.

The value is computed by the native stub so it matches the operating system that actually builds and runs the package.

Use this to branch platform-specific setup code around tray creation or to surface clearer diagnostics in logs and error messages. When the backend cannot map the host operating system to a known variant, this returns Unknown.

#
default_identifier

fn default_identifier() -> String

Returns the default identifier used by create() when callers do not provide one.

The identifier is used as the native tray instance id on platforms that require one, and keeping it stable makes logs and diagnostics easier to follow.

Applications with a single tray icon can usually rely on this value as-is. Multi-tray applications may still prefer to provide their own stable, application-specific identifiers so native backends can distinguish instances consistently across runs.

#
ensure_supported

fn ensure_supported() -> Result[Unit, String]

Validates that the native backend is available before any tray is created.

Use this when an application wants to show an actionable startup error instead of deferring the failure until create(). The error string is produced by the native backend when available, so callers can surface a platform-specific explanation to users.

Returns Ok(()) when tray creation should be possible on the current machine. Returns Err(message) when the backend is missing, the desktop runtime is unavailable, or the platform is unsupported.

#
is_supported

fn is_supported() -> Bool

Returns whether the native backend can create tray instances on the current machine.

On Windows this is expected to be true. On other platforms, or when the required desktop runtime is unavailable, this returns false. This probe is side-effect free from the MoonBit caller's perspective and is useful for gating UI paths that would otherwise call create().

This function answers only whether tray support appears available right now; it does not allocate a tray handle or make one visible. If you need a human readable explanation for a false result, call ensure_supported() instead.

Example

test "is_supported probes capability without creating a tray" {
let _ : Bool = is_supported()
}

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io