pub trait App: 'static {
type Message: Clone + 'static;
Show 109 methods
// Required methods
fn view(&self) -> Element<Self::Message>;
fn update(&mut self, msg: Self::Message);
fn app_id(&self) -> &str;
fn save_state(&self) -> Option<Vec<u8>>;
fn restore_state(&mut self, state: Vec<u8>);
// Provided methods
fn restore_on_launch(&self) -> bool { ... }
fn invalidate_after(&self, _msg: &Self::Message) -> InvalidationScope { ... }
fn overlays(&self) -> Vec<OverlaySpec<Self::Message>> { ... }
fn overlay_title(&self, _id: OverlayId) -> Option<String> { ... }
fn overlay_namespace(&self, _id: OverlayId) -> Option<&'static str> { ... }
fn subsurfaces(&self) -> Vec<SubsurfaceSpec<Self::Message>> { ... }
fn poll_external(&mut self) -> Vec<Self::Message> { ... }
fn take_activation_requests(&mut self) -> Vec<String> { ... }
fn on_activation_token(
&mut self,
_tag: String,
_token: String,
) -> Option<Self::Message> { ... }
fn on_first_frame_committed(&mut self) { ... }
fn on_main_frame_committed(&mut self) { ... }
fn on_overlay_frame_committed(&mut self, _id: OverlayId) { ... }
fn on_subsurface_committed(&mut self, _id: SubsurfaceId) { ... }
fn on_close_requested(&mut self) -> bool { ... }
fn on_tap(&mut self) -> Option<Self::Message> { ... }
fn on_key(&mut self, _keysym: Keysym) -> Option<Self::Message> { ... }
fn on_key_with_modifiers(
&mut self,
keysym: Keysym,
_ctrl: bool,
_shift: bool,
) -> Option<Self::Message> { ... }
fn on_back(&mut self) -> BackResponse<Self::Message> { ... }
fn back_at_root(&self) -> BackAtRoot { ... }
fn on_swipe_up(&mut self) -> Option<Self::Message> { ... }
fn on_swipe_progress(&mut self, _progress: f32) { ... }
fn on_swipe_down(&mut self) -> Option<Self::Message> { ... }
fn on_swipe_down_progress(&mut self, _progress: f32) { ... }
fn swipe_threshold(&self) -> f32 { ... }
fn swipe_down_threshold(&self) -> f32 { ... }
fn swipe_down_edge(&self) -> f32 { ... }
fn on_overscroll_down_progress(&mut self, _progress: f32) { ... }
fn on_overscroll_down(&mut self, _committed: bool) -> Option<Self::Message> { ... }
fn overscroll_dismiss_threshold(&self) -> f32 { ... }
fn on_swipe_left(&mut self) -> Option<Self::Message> { ... }
fn on_swipe_right(&mut self) -> Option<Self::Message> { ... }
fn on_swipe_horizontal_progress(&mut self, _progress: f32) { ... }
fn swipe_horizontal_threshold(&self) -> f32 { ... }
fn long_press_duration(&self) -> Duration { ... }
fn on_drag_move(&mut self, _x: f32, _y: f32) { ... }
fn on_drop(&mut self, _x: f32, _y: f32) -> Option<Self::Message> { ... }
fn on_text_input_focused(&mut self, _active: bool) { ... }
fn external_text_input(&self) -> Option<u64> { ... }
fn external_text_purpose(&self) -> Purpose { ... }
fn on_external_text_commit(&mut self, _text: &str) { ... }
fn on_external_text_delete(&mut self, _before: u32, _after: u32) { ... }
fn builtin_keyboard(&self) -> bool { ... }
fn on_toplevel_event(&self, _event: ToplevelEvent) -> Option<Self::Message> { ... }
fn on_files_changed(&self, _dir: &Path) -> Option<Self::Message> { ... }
fn on_mounts_changed(&self, _mounts: &[Mount]) -> Option<Self::Message> { ... }
fn on_open_files(&self, _paths: Vec<PathBuf>) -> Option<Self::Message> { ... }
fn take_focus_request(&mut self) -> Option<WidgetId> { ... }
fn take_blur_request(&mut self) -> bool { ... }
fn take_clipboard_request(&mut self) -> Option<String> { ... }
fn take_primary_request(&mut self) -> Option<String> { ... }
fn take_paste_request(&mut self) -> Option<SelectionKind> { ... }
fn on_paste(&mut self, _text: &str) { ... }
fn take_text_command(&mut self) -> Option<(WidgetId, TextCommand)> { ... }
fn on_pointer_move(&mut self, _x: f32, _y: f32) { ... }
fn on_pointer_hover(
&mut self,
_target: SurfaceTarget,
_position: Option<(f32, f32)>,
) { ... }
fn on_blur_regions(
&mut self,
_target: SurfaceTarget,
_regions: &[(Rect, f32)],
) { ... }
fn on_pointer_axis(&mut self, _x: f32, _y: f32, _dx: f32, _dy: f32) { ... }
fn on_pointer_wheel(
&mut self,
_x: f32,
_y: f32,
_notches_x: f32,
_notches_y: f32,
) -> bool { ... }
fn on_touch_down(&mut self, _id: i64, _x: f32, _y: f32) { ... }
fn on_touch_move(&mut self, _id: i64, _x: f32, _y: f32) { ... }
fn on_touch_up(&mut self, _id: i64, _x: f32, _y: f32) { ... }
fn claims_raw_touch(&self) -> bool { ... }
fn claims_raw_touch_at(&self, _x: f32, _y: f32) -> bool { ... }
fn on_drop_motion(&mut self, _x: f32, _y: f32) { ... }
fn on_drop_leave(&mut self) { ... }
fn on_drop_received(&mut self, _x: f32, _y: f32, _mime: &str, _text: &str) { ... }
fn on_pointer_button(&mut self, _x: f32, _y: f32, _pressed: bool) { ... }
fn on_pointer_secondary(&mut self, _x: f32, _y: f32) { ... }
fn on_pointer_middle(&mut self, _x: f32, _y: f32) { ... }
fn on_mouse_button(&mut self, _event: &MouseButtonEvent) { ... }
fn on_modifiers(&mut self, _ctrl: bool, _shift: bool, _alt: bool) { ... }
fn on_keyboard_leave(&mut self) { ... }
fn on_raw_key(
&mut self,
_keysym: Keysym,
_keycode: u32,
_pressed: bool,
_ctrl: bool,
_shift: bool,
) { ... }
fn on_raw_key_event(&mut self, key: &RawKey) { ... }
fn claims_keyboard(&self) -> bool { ... }
fn on_resize(&mut self, _width: u32, _height: u32) { ... }
fn on_scale_changed(&mut self, _scale: u32) { ... }
fn set_channel_sender(&mut self, _sender: ChannelSender<Self::Message>) { ... }
fn poll_interval(&self) -> Option<Duration> { ... }
fn key_repeat_delay(&self) -> Option<Duration> { ... }
fn key_repeat_interval(&self) -> Option<Duration> { ... }
fn cursor_override(&self) -> Option<CursorShape> { ... }
fn cursor_at(&self, _x: f32, _y: f32) -> Option<CursorShape> { ... }
fn key_repeats(&self, keysym: Keysym) -> bool { ... }
fn is_animating(&self) -> bool { ... }
fn needs_repaint(&mut self) -> bool { ... }
fn cap_software_animation(&self) -> bool { ... }
fn subsurface_motion_only(&self) -> bool { ... }
fn background_color(&self) -> Color { ... }
fn input_region(&self) -> Option<Vec<Rect>> { ... }
fn overlay_opaque_region(&self, _id: OverlayId) -> Option<Vec<Rect>> { ... }
fn window_config(&self) -> Option<(&str, &str)> { ... }
fn shell_mode(&self) -> ShellMode { ... }
fn secondary_view(
&self,
_width: u32,
_height: u32,
) -> Option<Element<Self::Message>> { ... }
fn requested_exit(&self) -> bool { ... }
fn window_size_hint(&self) -> Option<(u32, u32)> { ... }
fn window_title(&self) -> String { ... }
fn window_resizable(&self) -> bool { ... }
fn start_fullscreen(&self) -> bool { ... }
fn fullscreen(&self) -> Option<bool> { ... }
fn exclusive_zone(&self) -> i32 { ... }
fn layer_anchor(&self) -> Anchor { ... }
fn layer_size(&self) -> (u32, u32) { ... }
fn keyboard_exclusive(&self) -> bool { ... }
}Expand description
Trait that application types must implement to integrate with ltk.
Required Associated Types§
Required Methods§
Sourcefn app_id(&self) -> &str
fn app_id(&self) -> &str
Stable application identifier, reverse-DNS style
("net.liberux.settings", "io.eydos.Calls"), constant for the
life of the process.
The runtime uses it in three places:
xdg_toplevel.set_app_idon the main window, so the compositor, the dock and the task switcher can match the window to its.desktopentry (use the desktop file’s name minus.desktop, or itsStartupWMClass);- the accessibility tree — AccessKit / AT-SPI2 report it as the application name;
- the on-disk session directory
$XDG_STATE_HOME/<app_id>/wheresave_stateis persisted.
It must not be empty and must not contain /; the runtime then
disables session persistence and logs once. Layer-shell and
session-lock components still return one (it names them in the
a11y tree), even though they never get a toplevel. The app_id
element of the deprecated window_config
tuple is ignored in favour of this method — keep both pointing at
the same const.
const APP_ID: &str = "net.example.Notes";
impl App for Notes
{
fn app_id( &self ) -> &str { APP_ID }
}Sourcefn save_state(&self) -> Option<Vec<u8>>
fn save_state(&self) -> Option<Vec<u8>>
Serialize the part of the state worth surviving a restart.
Return the bytes the runtime should persist, or None when there
is nothing to bring back (a shell panel, a lock screen, a
stateless tool). The encoding is the app’s own — JSON, CBOR, a
hand-rolled line format — ltk never inspects it and puts no serde
bound on the trait. Keep it small and cheap: the runtime calls
this
- every ~30 s while the app runs, touching the disk only when the bytes differ from the last save (a UI-only change that round-trips to identical bytes costs one comparison);
- when the window closes — after
on_close_requestedallowed it orrequested_exitreturnedtrue; - on
SIGTERM/SIGINT, which the runtime turns into a clean exit of the event loop instead of letting the process die.
The bytes are written atomically (temp file + rename, mode
0600) to $XDG_STATE_HOME/<app_id>/state.bin
(~/.local/state/<app_id>/state.bin when the variable is unset)
next to a session.json holding the compositor’s
xdg-session-management-v1 session id and a clean-exit marker.
Returning None removes a stale state.bin. Only
ShellMode::Window apps (and the deprecated
window_config path) are persisted;
layer and session-lock surfaces are skipped silently, so shell
components simply return None.
The file is plain on disk: never put secrets in it (passwords
belong to the secure-mode text_edit and its wiped buffers),
and keep large blobs (images, caches) elsewhere. The signal
handler is installed process-wide when run is
entered, so the clean exit holds no matter which thread receives
the signal or when it was started.
restore_state explains when — and when
not — the bytes come back.
use ltk::{ App, Element, text };
use serde::{ Deserialize, Serialize };
#[ derive( Clone ) ]
enum Msg { Tab( usize ) }
#[ derive( Serialize, Deserialize ) ]
struct Persisted { version: u32, tab: usize, draft: String }
struct Editor { tab: usize, draft: String, cursor_blink: bool }
impl App for Editor
{
type Message = Msg;
fn app_id( &self ) -> &str { "net.example.Editor" }
fn save_state( &self ) -> Option<Vec<u8>>
{
// Only what a relaunch needs — the blink phase stays out.
let p = Persisted { version: 1, tab: self.tab, draft: self.draft.clone() };
serde_json::to_vec( &p ).ok()
}
fn restore_state( &mut self, state: Vec<u8> )
{
// Tolerate an older or corrupt file: keep the defaults.
if let Ok( p ) = serde_json::from_slice::<Persisted>( &state )
{
self.tab = p.tab;
self.draft = p.draft;
}
}
}Sourcefn restore_state(&mut self, state: Vec<u8>)
fn restore_state(&mut self, state: Vec<u8>)
Re-apply bytes previously returned by save_state.
Called at most once per process, synchronously inside
run / try_run, before the
window is created and before the first view — the
first frame already shows the restored state. It is not
called on an ordinary launch unless
restore_on_launch says so. The runtime
restores app state only when
- the process is relaunched as part of a session restore: the
shell sets
LTK_SESSION_RESTORE=1in the environment (the runtime removes the variable before the app can spawn children); or - the previous run of this
app_iddid not exit cleanly (crash,SIGKILL, power loss): itssession.jsonstill saysclean_exit: false.
This mirrors Android’s saved-instance-state contract: opening the
app from the launcher gives a fresh instance, coming back after
the system killed it lands where the user left off. Window
geometry (size, position, workspace) is separate — the compositor
restores it through xdg-session-management-v1 on every
launch, plain ones included, using the session id ltk stores.
state is exactly what save_state produced, possibly by an
older build: validate, version, and fall back to defaults instead
of panicking. Nothing is called when no state file exists or the
app returned None last time. Shell components never receive
this call and implement it as a no-op.
See save_state for the file layout and a
worked example.
Provided Methods§
Sourcefn restore_on_launch(&self) -> bool
fn restore_on_launch(&self) -> bool
Whether an ordinary launch also restores the saved state.
By default restore_state follows Android’s
saved-instance-state contract: the state comes back after a crash
or a session restore, and a launch from the launcher starts fresh.
Some apps keep state that the user expects to find on every launch,
however the last run ended, as Android browsers keep their tabs in
their own storage even when closed from the app switcher. Such an
app returns true, and the runtime then hands the saved bytes to
restore_state on a plain launch too. Nothing else changes: saving,
the file layout and the window geometry are the same either way.
Asked once per process, inside run /
try_run, right before restore_state would be
called and before the window exists, so the answer can only come
from the state the app was constructed with, for instance a user
setting read in main. It is not asked, and nothing is restored,
when persistence is off: no usable app_id,
another live instance holding the state directory, or a layer or
session-lock surface. With no state file, or after save_state
returned None, restore_state is not called either.
Since restore_state now runs on launches that carry their own
intent, such as a file or URL on the command line, it should merge
that intent into the restored state rather than let the restore
replace it. What save_state returns then outlives every exit, so
leave out what the user would expect to be forgotten on closing
the app (a private window, a half-typed password).
Default false.
struct Browser { tabs: Vec<String>, keep_tabs: bool, opened: Option<String> }
impl App for Browser
{
fn save_state( &self ) -> Option<Vec<u8>>
{
Some( self.tabs.join( "\n" ).into_bytes() )
}
fn restore_state( &mut self, state: Vec<u8> )
{
let Ok( text ) = String::from_utf8( state ) else { return };
self.tabs = text.lines().map( String::from ).collect();
// The URL this launch was asked to open goes after the restored tabs.
self.tabs.extend( self.opened.take() );
}
fn restore_on_launch( &self ) -> bool { self.keep_tabs }
}Sourcefn invalidate_after(&self, _msg: &Self::Message) -> InvalidationScope
fn invalidate_after(&self, _msg: &Self::Message) -> InvalidationScope
Tell the runtime which surfaces could have changed visibly as a
result of update being called with this message.
Default is InvalidationScope::All — every surface is redrawn.
A shell that knows, for example, that a SetVolume message only
affects its quick-settings overlay can return
InvalidationScope::Only( vec![ SurfaceTarget::Overlay( quick_id ) ] )
to skip pointless work on other surfaces.
Called before update (so it sees the message but
not the post-update state). Side-effect free: must not mutate self.
Sourcefn overlays(&self) -> Vec<OverlaySpec<Self::Message>>
fn overlays(&self) -> Vec<OverlaySpec<Self::Message>>
Describe the auxiliary overlay surfaces that should be active this
frame. Each entry becomes its own Wayland layer-shell surface
independent from the main surface returned by view.
Return an empty Vec (the default) to disable multi-surface support —
the app then renders only onto its main surface.
The runtime diffs the list across frames using OverlaySpec::id:
stable IDs are kept alive, new IDs cause a surface to be created, and
IDs that disappear cause the surface to be destroyed.
Sourcefn overlay_title(&self, _id: OverlayId) -> Option<String>
fn overlay_title(&self, _id: OverlayId) -> Option<String>
Title of a Layer::Window overlay, shown in its decoration and
in the compositor’s window lists. Default: the app_id.
Sourcefn overlay_namespace(&self, _id: OverlayId) -> Option<&'static str>
fn overlay_namespace(&self, _id: OverlayId) -> Option<&'static str>
wlr-layer-shell namespace of a layer overlay, so the compositor can
tell it apart from the rest. Read when the surface is created.
Default: "ltk-overlay".
Sourcefn subsurfaces(&self) -> Vec<SubsurfaceSpec<Self::Message>>
fn subsurfaces(&self) -> Vec<SubsurfaceSpec<Self::Message>>
Describe the input-transparent child surfaces composited over the main
surface this frame. Each becomes a wl_subsurface the compositor moves
by position; see SubsurfaceSpec. Diffed across frames by
SubsurfaceSpec::id. Default empty.
Sourcefn poll_external(&mut self) -> Vec<Self::Message>
fn poll_external(&mut self) -> Vec<Self::Message>
Return any pending messages from external sources (timers, async, etc.).
Sourcefn take_activation_requests(&mut self) -> Vec<String>
fn take_activation_requests(&mut self) -> Vec<String>
Tags for which the app wants a fresh xdg-activation-v1 token this
iteration. Drained once per loop; each tag is echoed back verbatim
through App::on_activation_token once the compositor issues the
token, so the app can hand it to a child it is about to spawn via the
$XDG_ACTIVATION_TOKEN launch convention. Default none.
Sourcefn on_activation_token(
&mut self,
_tag: String,
_token: String,
) -> Option<Self::Message>
fn on_activation_token( &mut self, _tag: String, _token: String, ) -> Option<Self::Message>
Deliver a token issued for an earlier App::take_activation_requests
tag. tag is the string the app handed out; token is the opaque
activation token to place in the launched child’s environment.
Sourcefn on_first_frame_committed(&mut self)
fn on_first_frame_committed(&mut self)
Called once, immediately after the first buffer for the main surface has been rendered and committed to the compositor. Note: this is the client-side commit, not the compositor’s present — under VT switching the actual present can be deferred (no DRM master yet), so a handoff signal that fires here is enough to tell a parent “ready to be presented as soon as my VT becomes active”.
Sourcefn on_main_frame_committed(&mut self)
fn on_main_frame_committed(&mut self)
Called every time a buffer for the main surface has been rendered and committed, before the subsurfaces are reconciled for the same iteration. Lets a host sequence a subsurface change after the main frame it depends on: a subsurface retired here goes away only once the main frame that replaces it has been sent.
Sourcefn on_overlay_frame_committed(&mut self, _id: OverlayId)
fn on_overlay_frame_committed(&mut self, _id: OverlayId)
Called every time a buffer for the overlay id has been rendered and
committed.
Sourcefn on_subsurface_committed(&mut self, _id: SubsurfaceId)
fn on_subsurface_committed(&mut self, _id: SubsurfaceId)
Called every time the content of the subsurface id has been
rasterised and committed (first raster, resize or a new
content_version), before the parent commit that maps it.
Sourcefn on_close_requested(&mut self) -> bool
fn on_close_requested(&mut self) -> bool
Called when the surface is asked to close (compositor request, titlebar button,
layer-shell closed event). Return true to allow the application to exit,
or false to cancel.
Default: true (always close).
Sourcefn on_key(&mut self, _keysym: Keysym) -> Option<Self::Message>
fn on_key(&mut self, _keysym: Keysym) -> Option<Self::Message>
Called on key press when no text input is focused.
Sourcefn on_key_with_modifiers(
&mut self,
keysym: Keysym,
_ctrl: bool,
_shift: bool,
) -> Option<Self::Message>
fn on_key_with_modifiers( &mut self, keysym: Keysym, _ctrl: bool, _shift: bool, ) -> Option<Self::Message>
Called on key press with modifier state. Override this instead of
on_key when you need Ctrl/Shift/Alt awareness.
Sourcefn on_back(&mut self) -> BackResponse<Self::Message>
fn on_back(&mut self) -> BackResponse<Self::Message>
Called on a back request — the shell’s back button or gesture
(delivered as the XF86Back key) or a mouse’s back button — once
the runtime has nothing of its own left to close.
Back peels one layer per request, top-most first:
- transient UI the runtime owns — the built-in context menu, open
xdg-popup overlays, a text selection, the top-most pressable
carrying an
on_escape(adialog’s cancel); - text-input focus — dropping it also retires the on-screen keyboard on compositors that did not close it themselves;
- this hook — the app’s own navigation state;
Self::on_key_with_modifierswithKeysym::XF86_Back, for apps that predate this hook;Self::back_at_root.
Return BackResponse::Message with the message that undoes the
top-most piece of navigation state — the part of the model that
says where the user is: the open panel, the current screen, the
position in a history. Derive the answer from the model every time
instead of keeping a separate list of things to undo: a list drifts
the first time the user leaves a screen some other way (its own
close button, a link), while the model cannot disagree with itself.
Navigation state is also what Self::save_state should persist.
Keeping the two the same is what makes back behave identically
after a session restore or a crash: the restored model yields the
same answers here, with nothing extra to serialise.
NavStack packages that pattern for the common
multi-screen app. docs/navigation.md covers the model at length.
Escape is a different request: it only runs step 1, drops the
focus and reaches Self::on_key_with_modifiers. It never
navigates and never leaves the app.
#[ derive( Clone ) ]
enum Msg { CloseSearch, Show( Screen ) }
struct Notes { screen: Screen, searching: bool }
impl App for Notes
{
fn on_back( &mut self ) -> BackResponse<Msg>
{
if self.searching { return BackResponse::Message( Msg::CloseSearch ); }
match self.screen
{
Screen::Detail => BackResponse::Message( Msg::Show( Screen::List ) ),
Screen::List => BackResponse::Unhandled,
}
}
}Sourcefn back_at_root(&self) -> BackAtRoot
fn back_at_root(&self) -> BackAtRoot
What a back request does when Self::on_back had nothing to go
back to. Default: BackAtRoot::Minimize — the window leaves the
screen and the app keeps its state, the way a root activity behaves
on Android.
Only applies to ShellMode::Window surfaces; layer-shell and
session-lock surfaces never react to back at the root.
Sourcefn on_swipe_up(&mut self) -> Option<Self::Message>
fn on_swipe_up(&mut self) -> Option<Self::Message>
Called when a sufficient upward swipe gesture is detected.
Return a message to handle the swipe (e.g., opening an overview).
The gesture is recognized when the user drags upward by at least
swipe_threshold() × screen height and then releases.
Sourcefn on_swipe_progress(&mut self, _progress: f32)
fn on_swipe_progress(&mut self, _progress: f32)
Called during an upward swipe gesture with progress ≥ 0.0.
Use this to create follow-the-finger animations. progress starts at 0.0
when the drag begins and increases as the finger moves upward, reaching 1.0
when the drag distance equals swipe_threshold() × screen height. It is
not clamped at 1.0 — the value keeps growing if the finger drags further
so that follow-the-finger panels can continue tracking the finger all the way
up the screen. Clamp inside the handler if you need a bounded [0, 1] range
for a visual indicator.
When the user releases without completing the gesture, this method is called
once more with progress = 0.0 to signal cancellation.
Sourcefn on_swipe_down(&mut self) -> Option<Self::Message>
fn on_swipe_down(&mut self) -> Option<Self::Message>
Called when a sufficient downward swipe gesture is detected.
Return a message to handle the swipe (e.g., toggling quick settings).
The gesture is recognized when the user drags downward by at least
swipe_down_threshold() × screen height and then releases.
Sourcefn on_swipe_down_progress(&mut self, _progress: f32)
fn on_swipe_down_progress(&mut self, _progress: f32)
Called during a downward swipe gesture with progress ≥ 0.0.
Use this to create follow-the-finger animations. progress starts at 0.0
when the drag begins and increases as the finger moves downward, reaching
1.0 when the drag distance equals swipe_down_threshold() × screen height.
It is not clamped at 1.0 — the value keeps growing if the finger drags
further so that follow-the-finger panels can continue tracking the finger
all the way down the screen. Clamp inside the handler if you need a
bounded [0, 1] range for a visual indicator.
When the user releases without completing the gesture, this method is called
once more with progress = 0.0 to signal cancellation.
Sourcefn swipe_threshold(&self) -> f32
fn swipe_threshold(&self) -> f32
Fraction of screen height required to trigger on_swipe_up.
Default: 0.6 (60% of screen height). Lower values make the gesture easier
to trigger; higher values require more vertical travel.
Sourcefn swipe_down_threshold(&self) -> f32
fn swipe_down_threshold(&self) -> f32
Fraction of screen height required to trigger on_swipe_down.
Default: 0.15 (15% of screen height). Typically lower than swipe_threshold()
because downward swipes are often initiated from a small UI element like a top bar.
Sourcefn swipe_down_edge(&self) -> f32
fn swipe_down_edge(&self) -> f32
Top-edge band where a downward swipe may originate, as a fraction of
screen height. Presses below this band never fire
on_swipe_down nor
on_swipe_down_progress.
Default: 1.0 (entire screen — any starting point is accepted).
Set to a small value like 0.05 to restrict the gesture to the top
edge, matching the usual system-panel pull-down UX.
Sourcefn on_overscroll_down_progress(&mut self, _progress: f32)
fn on_overscroll_down_progress(&mut self, _progress: f32)
Called while a vertical scroll is pinned at
its top and the finger keeps pulling down. progress is the
accumulated overscroll as a fraction of the surface height (≥ 0.0,
unbounded). Use it to drive a pull-from-top-to-dismiss panel that
tracks the finger.
Sourcefn on_overscroll_down(&mut self, _committed: bool) -> Option<Self::Message>
fn on_overscroll_down(&mut self, _committed: bool) -> Option<Self::Message>
Called when the finger releases after a top overscroll pull-down.
committed is true when the pull passed
overscroll_dismiss_threshold.
Sourcefn overscroll_dismiss_threshold(&self) -> f32
fn overscroll_dismiss_threshold(&self) -> f32
Fraction of surface height a top overscroll pull-down must exceed to
commit a dismiss on release. Default: 0.25.
Sourcefn on_swipe_left(&mut self) -> Option<Self::Message>
fn on_swipe_left(&mut self) -> Option<Self::Message>
Called when a sufficient leftward swipe gesture is detected.
Return a message to handle the swipe (e.g., paging to the next
homescreen). Fires on release when the user dragged left by at least
swipe_horizontal_threshold() × screen width. Unlike vertical swipes,
horizontal swipes survive starting the press on an interactive widget:
once the drag distance crosses an 8 px threshold the press is promoted
to a horizontal drag and no tap will fire at release.
Sourcefn on_swipe_right(&mut self) -> Option<Self::Message>
fn on_swipe_right(&mut self) -> Option<Self::Message>
Called when a sufficient rightward swipe gesture is detected.
Mirror of on_swipe_left for the other direction.
Sourcefn on_swipe_horizontal_progress(&mut self, _progress: f32)
fn on_swipe_horizontal_progress(&mut self, _progress: f32)
Called during a horizontal swipe with signed progress. Negative values
mean the finger has moved left, positive values mean right. The value
is dx / (threshold * width), so ±1.0 marks the commit threshold;
it is not clamped so follow-the-finger panels can keep tracking
past the threshold. When the user releases without completing the
gesture this method is called once more with 0.0 to signal
cancellation.
Sourcefn swipe_horizontal_threshold(&self) -> f32
fn swipe_horizontal_threshold(&self) -> f32
Fraction of screen width required to commit App::on_swipe_left /
App::on_swipe_right. Default: 0.5 (half the screen). A shell that
wants easier paging can lower this; one that wants to avoid
accidental pages can raise it.
Sourcefn long_press_duration(&self) -> Duration
fn long_press_duration(&self) -> Duration
Duration a press must remain stationary (within tolerance) before the
widget’s long-press message fires and the gesture transitions into
drag mode. Default: 500 ms.
Sourcefn on_drag_move(&mut self, _x: f32, _y: f32)
fn on_drag_move(&mut self, _x: f32, _y: f32)
Called on every pointer motion once a long-press has fired and the
gesture has entered drag mode. x, y are in physical pixels of the
surface that owned the original press.
Sourcefn on_drop(&mut self, _x: f32, _y: f32) -> Option<Self::Message>
fn on_drop(&mut self, _x: f32, _y: f32) -> Option<Self::Message>
Called on release once a long-press has fired. Return a message to
handle the drop (e.g., commit the drop target). x, y are in
physical pixels of the surface that owned the original press. The
regular tap / swipe handling is suppressed for this gesture.
Sourcefn on_text_input_focused(&mut self, _active: bool)
fn on_text_input_focused(&mut self, _active: bool)
Called when a text-input widget gains or loses focus.
Sourcefn external_text_input(&self) -> Option<u64>
fn external_text_input(&self) -> Option<u64>
Some( serial ) holds the input method for a text field ltk does not
own (an editable in an embedded web view) while no ltk text widget is
focused; a new serial renews the request, e.g. on a press on the field.
Sourcefn external_text_purpose(&self) -> Purpose
fn external_text_purpose(&self) -> Purpose
What the field held by Self::external_text_input is for; Terminal gives the on-screen keyboard its row of terminal keys.
Sourcefn on_external_text_commit(&mut self, _text: &str)
fn on_external_text_commit(&mut self, _text: &str)
Text committed by the input method while Self::external_text_input holds it.
Sourcefn on_external_text_delete(&mut self, _before: u32, _after: u32)
fn on_external_text_delete(&mut self, _before: u32, _after: u32)
Delete around the external field’s cursor, in UTF-8 bytes as zwp_text_input_v3 counts.
Sourcefn builtin_keyboard(&self) -> bool
fn builtin_keyboard(&self) -> bool
true to draw ltk’s own on-screen keyboard under a focused text field even when the compositor offers an input method; it is drawn regardless when none is offered, or with LTK_BUILTIN_OSK=1.
Sourcefn on_toplevel_event(&self, _event: ToplevelEvent) -> Option<Self::Message>
fn on_toplevel_event(&self, _event: ToplevelEvent) -> Option<Self::Message>
Translate a Wayland ext-foreign-toplevel-list-v1 event into an
app message. The runtime binds the protocol globally and forwards
every open / close it sees here; apps that ignore window state
leave the default (return None) and pay nothing.
The id field is the Wayland object id of the toplevel handle —
unique within the session, stable for the handle’s lifetime, the
same value coming in on Closed as the matching Opened.
app_id on Opened is the toplevel’s app_id event (may be
empty if the compositor never sent one before the first done).
Sourcefn on_files_changed(&self, _dir: &Path) -> Option<Self::Message>
fn on_files_changed(&self, _dir: &Path) -> Option<Self::Message>
A directory the app listed through crate::files::list changed: in a browser, through another client of the desktop. Natively not reported yet.
Sourcefn on_mounts_changed(&self, _mounts: &[Mount]) -> Option<Self::Message>
fn on_mounts_changed(&self, _mounts: &[Mount]) -> Option<Self::Message>
The folders of the user’s computer mounted in a browser, when the app connects and whenever one comes or goes. Natively there are none.
Sourcefn on_open_files(&self, _paths: Vec<PathBuf>) -> Option<Self::Message>
fn on_open_files(&self, _paths: Vec<PathBuf>) -> Option<Self::Message>
The files a browser’s desktop launched the app to open. Natively they come in the app’s arguments instead.
Sourcefn take_focus_request(&mut self) -> Option<WidgetId>
fn take_focus_request(&mut self) -> Option<WidgetId>
Return Some(id) once to focus the widget with that WidgetId.
The app must return None after the first call.
The runtime waits a few drawn frames for the widget to appear, so a
request made from the update that adds the widget to the view is
honoured, and a target scrolled out of a viewport is brought into
view before it is focused. A widget that never appears is dropped.
Sourcefn take_blur_request(&mut self) -> bool
fn take_blur_request(&mut self) -> bool
Return true once to drop the keyboard focus, which folds the on-screen keyboard; a take_focus_request in the same cycle wins.
Sourcefn take_clipboard_request(&mut self) -> Option<String>
fn take_clipboard_request(&mut self) -> Option<String>
Return Some( text ) once to put it in the clipboard, for other applications as well.
Sourcefn take_primary_request(&mut self) -> Option<String>
fn take_primary_request(&mut self) -> Option<String>
Return Some( text ) once to make it the primary selection, which the middle button pastes, here and in other applications.
Sourcefn take_paste_request(&mut self) -> Option<SelectionKind>
fn take_paste_request(&mut self) -> Option<SelectionKind>
Return Some( kind ) once to have Self::on_paste called with the text that selection holds.
Sourcefn on_paste(&mut self, _text: &str)
fn on_paste(&mut self, _text: &str)
The text of the selection Self::take_paste_request asked for; not called when it is empty.
Sourcefn take_text_command(&mut self) -> Option<(WidgetId, TextCommand)>
fn take_text_command(&mut self) -> Option<(WidgetId, TextCommand)>
Return Some( ( id, command ) ) once to have the text field with
that WidgetId take the focus and do
command, after the frame that lays it out is drawn. A field that
is not on screen then drops the command.
Sourcefn on_pointer_move(&mut self, _x: f32, _y: f32)
fn on_pointer_move(&mut self, _x: f32, _y: f32)
Called on every pointer motion (mouse move, button press, button
release) and on every primary-finger touch down and motion. x, y are in physical pixels of the main surface,
the same coordinate space as widget rects. Default: no-op.
Useful for embedding components that need to know the live
pointer position without going through a full
crate::widget::external::ExternalSource / WidgetHandlers
dispatch path — for example forwarding clicks into an embedded
WPE WebView.
Sourcefn on_pointer_hover(
&mut self,
_target: SurfaceTarget,
_position: Option<(f32, f32)>,
)
fn on_pointer_hover( &mut self, _target: SurfaceTarget, _position: Option<(f32, f32)>, )
Mouse motion over target, in physical pixels of that surface, or
None when the pointer leaves it. Touch never reports here.
Sourcefn on_blur_regions(&mut self, _target: SurfaceTarget, _regions: &[(Rect, f32)])
fn on_blur_regions(&mut self, _target: SurfaceTarget, _regions: &[(Rect, f32)])
The ( rect, corner radius ) of every Container::blur_behind
drawn on target, in its physical pixels, after a frame where they
changed: for a shell to tell its compositor what to blur.
Sourcefn on_pointer_axis(&mut self, _x: f32, _y: f32, _dx: f32, _dy: f32)
fn on_pointer_axis(&mut self, _x: f32, _y: f32, _dx: f32, _dy: f32)
Called on a wheel / touchpad scroll event whose position does
not fall inside any LTK scroll viewport. x,
y are in physical pixels (same coordinate space as
Self::on_pointer_move); dx, dy are scroll deltas in the
raw axis units the compositor delivered (AxisSource::Wheel
gives ~10 px ticks, touchpads give continuous values). Default:
no-op.
Useful for embeddings that take over scrolling for their own content — for example forwarding the event to a WPE view that owns a scrollable web page — or for wheel-driven view state such as a stepped carousel. The runtime rebuilds and repaints after the hook returns, so state mutated here shows immediately.
Sourcefn on_pointer_wheel(
&mut self,
_x: f32,
_y: f32,
_notches_x: f32,
_notches_y: f32,
) -> bool
fn on_pointer_wheel( &mut self, _x: f32, _y: f32, _notches_x: f32, _notches_y: f32, ) -> bool
Called before Self::on_pointer_axis for a scroll event from a
wheel or any device that reports discrete detents, with the number
of detents on each axis (fractional on high-resolution wheels;
positive is right / down). Return true to consume it; false, the
default, lets the same event reach on_pointer_axis in raw units.
Sourcefn on_touch_down(&mut self, _id: i64, _x: f32, _y: f32)
fn on_touch_down(&mut self, _id: i64, _x: f32, _y: f32)
Raw multi-touch callbacks. Default: no-op.
The first finger to land becomes the primary slot and is fed
through the regular gesture machine — on_pointer_*, swipe,
scroll, long-press, drag-and-drop all run from that slot. Every
additional finger fires on_touch_down / on_touch_move /
on_touch_up instead, with id matching the wl_touch.id
the compositor delivered.
Use this for app-defined multi-finger gestures (pinch-zoom,
two-finger pan in a canvas, parallel keyboard keys) that the
built-in single-slot machine cannot model. (x, y) are in
physical pixels, matching the coordinate space of
Self::on_pointer_move.
When Self::claims_raw_touch returns true the primary
finger arrives here as well, instead of driving the gesture
machine.
Sourcefn on_touch_move(&mut self, _id: i64, _x: f32, _y: f32)
fn on_touch_move(&mut self, _id: i64, _x: f32, _y: f32)
See Self::on_touch_down.
Sourcefn on_touch_up(&mut self, _id: i64, _x: f32, _y: f32)
fn on_touch_up(&mut self, _id: i64, _x: f32, _y: f32)
See Self::on_touch_down. x, y are the last known
position of the finger (wl_touch.up does not carry one).
Sourcefn claims_raw_touch(&self) -> bool
fn claims_raw_touch(&self) -> bool
Return true to receive the primary finger through the raw
Self::on_touch_down / move / up stream as well, bypassing
the built-in single-slot gesture machine entirely — widget
presses, taps and swipes stop working on touch. For apps whose
surface is one self-contained input consumer (an embedded
WebView, a game canvas) that needs every finger verbatim.
Sourcefn claims_raw_touch_at(&self, _x: f32, _y: f32) -> bool
fn claims_raw_touch_at(&self, _x: f32, _y: f32) -> bool
Per-press variant of Self::claims_raw_touch: return true to
take the finger landing at (x, y) (physical pixels of the main
surface) through the raw Self::on_touch_down / move / up stream,
while fingers landing elsewhere keep driving the widget gesture
machine. For apps that embed a self-contained input consumer (a
WebView) next to regular widgets. A claimed press clears the widget
focus. Only consulted for the main surface.
Sourcefn on_drop_motion(&mut self, _x: f32, _y: f32)
fn on_drop_motion(&mut self, _x: f32, _y: f32)
Pointer of a cross-application drag-and-drop entered or moved
inside the main surface. (x, y) is in logical pixels.
Sourcefn on_drop_leave(&mut self)
fn on_drop_leave(&mut self)
The drag left without dropping.
Sourcefn on_drop_received(&mut self, _x: f32, _y: f32, _mime: &str, _text: &str)
fn on_drop_received(&mut self, _x: f32, _y: f32, _mime: &str, _text: &str)
External drop payload landed on the surface. mime is the
best mime the source offered (text/uri-list, text/plain, …)
and text is the decoded payload (UTF-8). (x, y) is the
release position in logical pixels.
Called on every left-button mouse press / release, and on every
primary-finger touch down / up, before the regular gesture machine fires. pressed = true for press,
false for release. (x, y) are in physical pixels (same
coordinate space as Self::on_pointer_move). Default: no-op.
Lets embeddings see the raw button transitions without going through LTK’s tap/long-press/drag classification — needed for forwarding clicks AND drags to an embedded view, since the tap classifier collapses press+release into a single event.
Sourcefn on_pointer_secondary(&mut self, _x: f32, _y: f32)
fn on_pointer_secondary(&mut self, _x: f32, _y: f32)
A secondary-button press that no widget of ltk’s own answered, in physical pixels. Default: no-op.
Sourcefn on_pointer_middle(&mut self, _x: f32, _y: f32)
fn on_pointer_middle(&mut self, _x: f32, _y: f32)
A middle-button press, in physical pixels. Default: no-op.
Every press and release of the left, middle and right buttons, with the modifiers held, before ltk handles it: for an app that hands the mouse on, as a terminal does to a program that asks for it. Default: no-op.
Sourcefn on_modifiers(&mut self, _ctrl: bool, _shift: bool, _alt: bool)
fn on_modifiers(&mut self, _ctrl: bool, _shift: bool, _alt: bool)
The modifiers held changed, for an app that needs them with the wheel or a motion, which do not carry them. Default: no-op.
Sourcefn on_keyboard_leave(&mut self)
fn on_keyboard_leave(&mut self)
The window lost the keyboard, so no release will come for the keys held: for an app that repeats keys itself. Default: no-op.
Sourcefn on_raw_key(
&mut self,
_keysym: Keysym,
_keycode: u32,
_pressed: bool,
_ctrl: bool,
_shift: bool,
)
fn on_raw_key( &mut self, _keysym: Keysym, _keycode: u32, _pressed: bool, _ctrl: bool, _shift: bool, )
Called on every keyboard event (press and release) before the
regular focus-aware dispatch (Self::on_key /
Self::on_key_with_modifiers) runs. Default: no-op.
keycode is the raw hardware scancode straight from the
compositor (wl_keyboard.key’s key argument); keysym is
the xkb-translated keysym the user effectively pressed. Most
consumers only care about keysym, but embeddings that
forward into an inner window system (a WPE web view, an X11
emulator, …) typically need both — the inner system does its
own keycode → keysym translation for layout-aware shortcuts.
This bypass exists for those embeddings: it fires in addition to the normal callbacks; consume or ignore at will.
XF86_Back is not reported here: it is a navigation request, not
input for the embedded system, and goes through Self::on_back.
Sourcefn on_raw_key_event(&mut self, key: &RawKey)
fn on_raw_key_event(&mut self, key: &RawKey)
Self::on_raw_key with the Alt state and the typed text too; the runtime calls this one, which forwards to on_raw_key unless overridden. Override it instead when Alt or dead keys matter, as in a terminal.
Sourcefn claims_keyboard(&self) -> bool
fn claims_keyboard(&self) -> bool
true while every key belongs to Self::on_raw_key, as in a terminal: ltk then neither dispatches keys to its widgets, so Enter and Space do not press the focused or hovered one, nor repeats them. XF86_Back still goes through Self::on_back.
Sourcefn on_resize(&mut self, _width: u32, _height: u32)
fn on_resize(&mut self, _width: u32, _height: u32)
Called when the surface is (re-)configured with a new size.
width and height are in physical pixels (the Wayland surface
size multiplied by the current buffer scale). They therefore match the
coordinate space used for layout and the pointer/touch callbacks
(on_drag_move, on_drop, widget hit-testing). Also fired when the
buffer scale changes, so apps can refresh any state keyed off the old
physical dimensions.
Sourcefn on_scale_changed(&mut self, _scale: u32)
fn on_scale_changed(&mut self, _scale: u32)
Called when the compositor reports a new integer buffer scale for the
main surface. scale is the integer buffer scale (1 = standard DPI,
2 = HiDPI ×2); physical pixels equal logical pixels × scale. In a
browser the scale is the page’s devicePixelRatio, which may be
fractional; scale is then that ratio rounded, and
on_resize gives the exact physical size. The default
is inert so apps that only care about physical pixels can keep using
on_resize.
Sourcefn set_channel_sender(&mut self, _sender: ChannelSender<Self::Message>)
fn set_channel_sender(&mut self, _sender: ChannelSender<Self::Message>)
Called once at startup with a channel sender that can be used from any thread to deliver messages into the event loop. Sending a message immediately wakes the event loop — no polling delay.
Sourcefn poll_interval(&self) -> Option<Duration>
fn poll_interval(&self) -> Option<Duration>
How often the event loop should call poll_external for
periodic work such as clock ticks. Return None (the default) to disable the
timer — poll_external will still be called after every Wayland event.
Sourcefn key_repeat_delay(&self) -> Option<Duration>
fn key_repeat_delay(&self) -> Option<Duration>
Delay before the runtime starts repeating a held-down key.
Some(d) overrides whatever the compositor advertises through
wl_keyboard.repeat_info; None (the default) means “use the
compositor’s setting, or fall back to 500 ms when the compositor
did not provide one”.
Returning Some(Duration::ZERO) effectively disables the wait
before the first repeat — useful only for diagnostic builds.
Sourcefn key_repeat_interval(&self) -> Option<Duration>
fn key_repeat_interval(&self) -> Option<Duration>
Interval between successive synthetic key events while a key is
held down past the initial Self::key_repeat_delay.
Some(d) overrides the compositor’s wl_keyboard.repeat_info
rate; None (the default) means “use the compositor’s setting,
or fall back to 33 ms (~30 Hz) when the compositor did not
provide one”. Pass Some(Duration::ZERO) to disable repeats
entirely (or override the per-key gate via
Self::key_repeats).
Sourcefn cursor_override(&self) -> Option<CursorShape>
fn cursor_override(&self) -> Option<CursorShape>
Override the pointer cursor shape globally. When Some(shape),
the runtime sends that shape to the compositor regardless of
which widget the pointer is over — useful for “the app is busy”
states (return crate::CursorShape::Wait) or while the app
is doing a long synchronous operation. Returning None (the
default) lets per-widget defaults take effect.
The runtime calls this every frame, so flipping a loading
boolean in Self::update propagates to the cursor on the
next iteration without any extra wiring.
Sourcefn cursor_at(&self, _x: f32, _y: f32) -> Option<CursorShape>
fn cursor_at(&self, _x: f32, _y: f32) -> Option<CursorShape>
The cursor the app wants at ( x, y ), in physical pixels of the main surface: below the window’s resize edges and Self::cursor_override, above the cursor of the widget under it. None, the default, leaves the widget’s.
Sourcefn key_repeats(&self, keysym: Keysym) -> bool
fn key_repeats(&self, keysym: Keysym) -> bool
Decide whether a given key participates in held-key repeat.
Default: every non-modifier key repeats except Escape,
XF86_Back, Tab and ISO_Left_Tab — those drive one-shot UI
semantics (dismiss / go back / focus cycle) where a held key would
multiply the effect in surprising ways. Override to widen or
narrow the gate (a chess clock app, for example, might want even
Tab to repeat).
Sourcefn is_animating(&self) -> bool
fn is_animating(&self) -> bool
Return true while a frame-by-frame animation is running.
The event loop will keep requesting redraws at ~60 fps until this returns false.
Sourcefn needs_repaint(&mut self) -> bool
fn needs_repaint(&mut self) -> bool
Return true when the main surface’s pixels changed but its widgets did not, such as an crate::widget::external::External with a new frame: the surface is drawn again from the cached view, without calling Self::view. Asked once per iteration, after the messages are processed.
Sourcefn cap_software_animation(&self) -> bool
fn cap_software_animation(&self) -> bool
Cap Self::is_animating redraws to ~30 Hz when the software
renderer is active. Default true: 60 fps software rasterization is a
common battery sink on mobile (no GPU offload), and halving it is
usually imperceptible for the animations software fallback can afford.
The GLES backend is never capped. Return false to keep the full
display rate on software.
Sourcefn subsurface_motion_only(&self) -> bool
fn subsurface_motion_only(&self) -> bool
Return true when a finger-tracked swipe or an Self::is_animating
slide only repositions the app’s input-transparent subsurfaces
(Self::subsurfaces) while the main surface buffer stays unchanged.
The runtime then skips the per-frame main re-raster that
Self::on_swipe_progress and is_animating would otherwise force,
keeping the animation pumped (motion events during the drag, a bare
frame callback while is_animating) and letting the per-frame
subsurface reconcile carry the motion. Use it for a slide-to-reveal
panel over a static main surface.
Sourcefn background_color(&self) -> Color
fn background_color(&self) -> Color
Background color for the canvas. Override to make the surface
transparent or to deviate from the theme. Default: the active
theme’s bg token, so the window matches the rest of the
shell out of the box.
Sourcefn input_region(&self) -> Option<Vec<Rect>>
fn input_region(&self) -> Option<Vec<Rect>>
Return the interactive input region as a list of rects (logical pixels).
Only these areas receive pointer/touch input; the rest passes through.
Return None (default) to receive input everywhere.
Sourcefn overlay_opaque_region(&self, _id: OverlayId) -> Option<Vec<Rect>>
fn overlay_opaque_region(&self, _id: OverlayId) -> Option<Vec<Rect>>
Rects (physical layout pixels) of overlay id that are fully opaque
this frame, so the compositor can skip blending them and repainting
what lies underneath. None (default) declares nothing opaque.
Sourcefn window_config(&self) -> Option<(&str, &str)>
fn window_config(&self) -> Option<(&str, &str)>
Return Some(( title, app_id )) to force an XDG toplevel window instead of
layer-shell overlay. The compositor will display the title in the title bar
and use the app_id for taskbar/icon matching. Return None (default) to
use layer-shell when available. The app_id element is ignored:
app_id names the window.
Deprecated: Use shell_mode instead.
Sourcefn shell_mode(&self) -> ShellMode
fn shell_mode(&self) -> ShellMode
Specify the Wayland shell mode for this application.
ShellMode::Window: Normal application window (xdg-shell). Default.ShellMode::Layer: System component at a specific layer (layer-shell).ShellMode::SessionLock:ext-session-lock-v1lock surface (screen locker).
For regular applications, use the default Window mode.
For shell components (panels, backgrounds, overlays), use Layer.
For a screen locker, use SessionLock and request the unlock by
returning true from requested_exit.
Sourcefn secondary_view(
&self,
_width: u32,
_height: u32,
) -> Option<Element<Self::Message>>
fn secondary_view( &self, _width: u32, _height: u32, ) -> Option<Element<Self::Message>>
Content for the surfaces the runtime creates on every output beyond
the first. In ShellMode::SessionLock these are lock surfaces —
the compositor blanks any output without one, so each is covered. In
ShellMode::Layer on Layer::Background they are background
layer surfaces, so a shell’s wallpaper reaches extended outputs
(typically without the grid or any chrome). They take no input.
width / height are that output’s surface size in physical pixels.
Default None: the surface is filled with
background_color.
Sourcefn requested_exit(&self) -> bool
fn requested_exit(&self) -> bool
Return true to tear the surface down and exit the event loop. For a
ShellMode::SessionLock surface the runtime calls unlock first, so
the compositor lifts the lock instead of leaving the outputs blanked.
Polled after every batch of updates.
Sourcefn window_size_hint(&self) -> Option<(u32, u32)>
fn window_size_hint(&self) -> Option<(u32, u32)>
Suggest an initial size for an xdg-shell window in logical pixels.
Returning Some(( w, h )) makes ltk call both
xdg_toplevel.set_min_size( w, h ) and
xdg_toplevel.set_max_size( w, h ) before the first commit, which
most compositors honour as an exact size for the configure they
send back. The window is still resizable from the application’s
point of view — if the compositor sends a different configure, the
runtime adopts that size on the next frame.
A hint larger than the screen is shrunk on the first configure,
keeping its aspect ratio: to the compositor’s
xdg_toplevel.configure_bounds when it sends them, otherwise to
90 % of the output. A phone-shaped 720x1440 hint therefore opens as
486x972 on a 1080p desktop instead of running off its bottom edge.
Only applies to ShellMode::Window surfaces and to the
xdg-shell fallback path used when wlr-layer-shell is missing.
Ignored for layer-shell surfaces, which use Self::layer_size
instead.
Default: None (let the compositor pick).
Sourcefn window_title(&self) -> String
fn window_title(&self) -> String
The main window’s title, which the compositor’s title bar, task switcher and dock show; read once, when the window is made.
Only applies to ShellMode::Window surfaces and to the
xdg-shell fallback of a layer surface.
Default: the app_id.
Sourcefn window_resizable(&self) -> bool
fn window_resizable(&self) -> bool
Whether the user may resize an xdg-shell window.
When Self::window_size_hint is set, ltk pins
min_size == max_size before the first commit so the compositor’s
first configure honours the requested size, and then releases
both from the first configure so the surface becomes
user-resizable; a minimum left in place would make a mobile
compositor shrink the window’s scale to honour it. Returning
false skips that release: the pin stays
in place for the lifetime of the toplevel, declaring a fixed-size
window that compositors must not resize or restore a remembered
geometry over.
Ignored when Self::window_size_hint returns None.
Default: true.
Sourcefn start_fullscreen(&self) -> bool
fn start_fullscreen(&self) -> bool
Request fullscreen on the toplevel before its first commit.
When true, ltk calls xdg_toplevel.set_fullscreen( None ) so
the compositor picks an output and maps the surface fullscreen
from the start (no flicker through a windowed configure first).
The compositor’s own decorations are suppressed for fullscreen
surfaces; the built-in titlebar from Self::window_config is
still painted by ltk on top of the surface unless the app opts
out.
Only applies to ShellMode::Window surfaces and to the
xdg-shell fallback path used when wlr-layer-shell is missing.
Default: false.
Sourcefn fullscreen(&self) -> Option<bool>
fn fullscreen(&self) -> Option<bool>
Desired fullscreen state of the toplevel while the app runs.
Polled after every batch of updates: when the returned value
changes, ltk calls xdg_toplevel.set_fullscreen /
unset_fullscreen. While the compositor reports the window as
fullscreen the built-in titlebar is not painted. None (the
default) leaves the window state alone.
Only applies to ShellMode::Window surfaces.
Sourcefn exclusive_zone(&self) -> i32
fn exclusive_zone(&self) -> i32
Specify the exclusive zone for layer-shell surfaces.
The exclusive zone reserves screen space for this surface.
For example, a top panel with height 50 should return 50 to prevent
other windows from overlapping it.
> 0: Reserve this many pixels from the anchored edge0: No exclusive zone (default for overlays)-1: Don’t reserve space but request focus
Only applies to ShellMode::Layer surfaces. Ignored for windows.
Sourcefn layer_anchor(&self) -> Anchor
fn layer_anchor(&self) -> Anchor
Specify which screen edges the layer-shell surface is anchored to.
Anchoring determines the position and size of the surface:
Anchor::TOP: Top bar (anchored to top, left, right)Anchor::BOTTOM: Bottom bar (anchored to bottom, left, right)Anchor::LEFT: Left sidebar (anchored to left, top, bottom)Anchor::RIGHT: Right sidebar (anchored to right, top, bottom)Anchor::ALL: Full screen (anchored to all edges)
Default: Anchor::ALL (full screen)
Only applies to ShellMode::Layer surfaces. Ignored for windows.
Sourcefn layer_size(&self) -> (u32, u32)
fn layer_size(&self) -> (u32, u32)
Specify the desired size for layer-shell surfaces.
Returns (width, height) where:
0means “fill available space in that dimension”> 0means “use this exact size in pixels”
Examples:
- Top bar:
(0, 50)- full width, 50px height - Bottom bar:
(0, 40)- full width, 40px height - Side panel:
(300, 0)- 300px width, full height - Full screen:
(0, 0)- fill everything (default)
Default: (0, 0) (fill all available space)
Only applies to ShellMode::Layer surfaces. Ignored for windows.
Sourcefn keyboard_exclusive(&self) -> bool
fn keyboard_exclusive(&self) -> bool
Request exclusive keyboard focus for this layer-shell surface.
When true, the compositor sends keyboard events to this surface
without requiring a pointer click first. Useful for greeters,
lock screens, and other surfaces that must capture input immediately.
Default: false (on-demand keyboard interactivity)
Only applies to ShellMode::Layer surfaces. Ignored for windows.