App: claim raw touch per press with claims_raw_touch_at, and toggle fullscreen at runtime with fullscreen
Two additions to the `App` trait, both needed by an application that embeds a self-contained input consumer next to regular widgets. The case at hand is trust, the Eydos browser: an ltk-webkit `WebView` below a toolbar built from stock widgets, with an F11 fullscreen toggle. Raw touch per press. `App::claims_raw_touch` is all or nothing: once it returns `true` every finger, the primary included, bypasses the gesture machine, so widget presses, taps and swipes stop working on touch. That suits an app whose whole surface is one WebView (the eydos-settings portal), but not one that shows the view under its own chrome: claiming raw touch made the address box and the toolbar buttons dead to the finger, and not claiming it fed the page a mouse-like primary slot, so a drag selected text instead of scrolling and pinch-zoom was impossible. The new `App::claims_raw_touch_at( x, y )` is consulted on `wl_touch.down` with the press position in physical pixels of the main surface; a finger landing where it returns `true` goes through the raw `on_touch_down` / `on_touch_move` / `on_touch_up` stream while fingers landing elsewhere keep driving the gesture machine. The default is `false`, so existing apps are unaffected, and it is only consulted for the main surface: overlays have their own coordinate space and the hook carries no surface argument. The implementation reuses the auxiliary-slot path instead of adding a second notion of raw ownership. In `TouchHandler::down` the position is now resolved before the takeover check; a claimed finger is recorded in `touch_slots` without becoming `primary_touch_id`, which is precisely the state of a second finger today, so `motion`, `up` and `reset_touch_state` already route it to the app and report its release point with no change. A claimed press skips the plain-press takeover (it must not commit a tap in progress on the chrome) and calls `set_focus( focus, None, qh )`, mirroring what a pointer press outside any widget does: without it a focused text field would keep the text-input protocol, the on-screen keyboard and the key stream after the user had moved on to the page. `pointer_pos` is still assigned after the takeover, since `release_primary` uses it as the release point of the finger being committed. Runtime fullscreen. `App::start_fullscreen` only covers the first commit; there was no way to enter or leave fullscreen afterwards. `App::fullscreen() -> Option<bool>` declares the desired state and is polled after every batch of `update`s, next to `requested_exit`. `AppData::sync_fullscreen` compares it with `applied_fullscreen`, the last value sent, and calls `xdg_toplevel.set_fullscreen( None )` or `unset_fullscreen` only on a change; `None`, the default, leaves the window state alone. `applied_fullscreen` is seeded with `start_fullscreen()`, so an app that starts fullscreen and reports `Some( true )` does not send a redundant request, and one that reports `Some( false )` is not pushed out of a fullscreen it asked for a moment earlier. It is a no-op for layer-shell and session-lock surfaces, which have no toplevel. The `configure` handler now also zeroes `titlebar_height` while `WindowConfigure::is_fullscreen()` holds, as it already did for server-side decorations. The built-in titlebar was otherwise painted over a fullscreen surface, which is what the `start_fullscreen` doc comment described as happening "unless the app opts out" without there being a way to opt out. The height follows the compositor's reported state rather than the app's request, so it stays correct when the compositor refuses the request or leaves fullscreen on its own. Both hooks are documented on the trait and listed in the changelog under Unreleased.
This commit is contained in:
+20
@@ -811,6 +811,15 @@ pub trait App: 'static
|
||||
/// WebView, a game canvas) that needs every finger verbatim.
|
||||
fn claims_raw_touch( &self ) -> bool { false }
|
||||
|
||||
/// 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.
|
||||
fn claims_raw_touch_at( &self, _x: f32, _y: f32 ) -> bool { false }
|
||||
|
||||
/// Pointer of a cross-application drag-and-drop entered or moved
|
||||
/// inside the main surface. `(x, y)` is in logical pixels.
|
||||
fn on_drop_motion( &mut self, _x: f32, _y: f32 ) {}
|
||||
@@ -1058,6 +1067,17 @@ pub trait App: 'static
|
||||
/// **Default**: `false`.
|
||||
fn start_fullscreen( &self ) -> bool { false }
|
||||
|
||||
/// Desired fullscreen state of the toplevel while the app runs.
|
||||
///
|
||||
/// Polled after every batch of `update`s: 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.
|
||||
fn fullscreen( &self ) -> Option<bool> { None }
|
||||
|
||||
/// Specify the exclusive zone for layer-shell surfaces.
|
||||
///
|
||||
/// The exclusive zone reserves screen space for this surface.
|
||||
|
||||
Reference in New Issue
Block a user