Surface

Struct Surface 

Source
pub struct Surface { /* private fields */ }
Expand description

A type that can be drawn on, e.g. by wgpu.

A Surface represents a drawable area within a window. It provides the necessary handles for graphics APIs like wgpu to render content, and notifies about size changes.

§Creating a Surface

A Surface is created from a Window using the Window::surface() method. Only one Surface can be created per window.

use app_window::window::Window;
use app_window::coordinates::{Position, Size};

let mut window = Window::new(
    Position::new(100.0, 100.0),
    Size::new(800.0, 600.0),
    "My Window".to_string()
).await;

let surface = window.surface().await;

§Platform Implementation Details

The Surface abstraction exists for several reasons:

  1. Future flexibility: While currently limited to one surface per window, this design allows for potential multi-surface support in the future.
  2. Performance: On some platforms, creating a drawable surface is more expensive than creating a blank window. Applications that don’t need to draw can skip this cost.
  3. Compositing: Platform window decorations (title bars, borders) often require special handling when composited with the application’s rendered content.

Implementations§

Source§

impl Surface

Source

pub async fn size_scale(&self) -> (Size, f64)

Returns the size and scale factor of the surface.

The size is returned in logical pixels, which may differ from physical pixels on high-DPI displays. The scale factor indicates the ratio between logical and physical pixels.

§Returns

A tuple containing:

  • The Size of the surface in logical pixels
  • The scale factor as a f64 (e.g., 2.0 for a Retina display)
§Example
let mut surface = window.surface().await;
let (size, scale) = surface.size_scale().await;

println!("Surface size: {}x{}", size.width(), size.height());
println!("Scale factor: {}", scale);

// Calculate physical pixel dimensions
let physical_width = (size.width() * scale) as u32;
let physical_height = (size.height() * scale) as u32;
Source

pub fn size_main(&self) -> (Size, f64)

Returns the size and scale factor of the surface from the main thread.

This is the synchronous version of size_scale() that can only be called from the main thread. Use this when you’re already on the main thread and need the size without awaiting.

§Returns

A tuple containing:

  • The Size of the surface in logical pixels
  • The scale factor as a f64 (e.g., 2.0 for a Retina display)
§Panics

Panics if called from a thread other than the main thread.

§Example
#[cfg(target_arch = "wasm32")] {
    wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
}
use app_window::test_support::doctest_main;
use some_executor::task::{Configuration, Task};

doctest_main(|| {
    Task::without_notifications(
        "doctest".to_string(),
        Configuration::default(),
        async {
            use app_window::application;

            let mut window = app_window::window::Window::default().await;
            let surface = window.surface().await;

            // Only call from main thread
            if application::is_main_thread() {
                let (size, scale) = surface.size_main();
                println!("Size: {}x{} at {}x scale", size.width(), size.height(), scale);
            }
        },
    ).spawn_static_current();
});
Source

pub fn raw_window_handle(&self) -> RawWindowHandle

Returns the raw window handle for this surface.

This handle can be used with graphics APIs like wgpu to create a rendering surface. The handle is platform-specific and follows the raw-window-handle standard.

§Example
let surface = window.surface().await;
let raw_handle = surface.raw_window_handle();

// Use with wgpu (requires 'wgpu' feature)
unsafe {
    let wgpu_surface = instance.create_surface_unsafe(
        SurfaceTargetUnsafe::RawHandle {
            raw_display_handle: surface.raw_display_handle(),
            raw_window_handle: raw_handle,
        }
    );
}
Source

pub fn window_handle(&self) -> WindowHandle<'_>

Returns a borrowed window handle for this surface.

This is a safe wrapper around raw_window_handle() that provides a lifetime-bound handle following the raw-window-handle v0.6 API. This is the preferred method for passing window handles to graphics APIs that accept the newer WindowHandle type.

§Example
let surface = window.surface().await;
let handle = surface.window_handle();

// Use with graphics APIs that accept WindowHandle
// e.g., wgpu's create_surface_from_handle()
Source

pub fn raw_display_handle(&self) -> RawDisplayHandle

Returns the raw display handle for this surface.

This handle represents the display or connection that owns the window. It’s required alongside the window handle when creating graphics surfaces. The handle is platform-specific and follows the raw-window-handle standard.

§Platform Details
  • Windows: Returns a Windows display handle
  • macOS: Returns an AppKit display handle
  • Linux (Wayland): Returns a Wayland display handle
  • Web: Returns a web display handle
§Example

See raw_window_handle() for usage with graphics APIs.

Source

pub fn display_handle(&self) -> DisplayHandle<'_>

Returns a borrowed display handle for this surface.

This is a safe wrapper around raw_display_handle() that provides a lifetime-bound handle following the raw-window-handle v0.6 API. This is the preferred method for passing display handles to graphics APIs that accept the newer DisplayHandle type.

§Example
let surface = window.surface().await;
let display = surface.display_handle();
let window = surface.window_handle();

// Both handles are often used together when creating graphics surfaces
Source

pub fn size_update<F: Fn(Size) + Send + 'static>(&mut self, update: F)

Registers a callback to be invoked when the surface is resized.

The callback will be called whenever the surface size changes, such as when the user resizes the window or the window is moved between displays with different DPI settings. The callback receives the new Size in logical pixels.

§Thread Safety

The callback must be Send and 'static as it may be called from different threads depending on the platform. The callback should be efficient as it may be called frequently during resize operations.

§Example
let mut surface = window.surface().await;

surface.size_update(|new_size: Size| {
    println!("Surface resized to: {}x{}",
             new_size.width(),
             new_size.height());
     
    // Trigger a re-render or update your graphics pipeline
    // with the new dimensions
});
§Platform Behavior
  • All platforms: The callback is invoked after the resize has occurred
  • macOS: May be called multiple times during a resize drag operation
  • Windows/Linux: Typically called at the end of a resize operation

Trait Implementations§

Source§

impl Debug for Surface

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more