window.rs

   1use crate::{
   2    px, size, AnyBox, AnyView, AppContext, AsyncWindowContext, AvailableSpace, BorrowAppContext,
   3    Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId, Edges, Effect, Element, EntityId,
   4    EventEmitter, FocusEvent, FontId, GlobalElementId, GlyphId, Handle, Hsla, ImageData,
   5    InputEvent, IsZero, KeyDownEvent, KeyDownListener, KeyUpEvent, KeyUpListener, LayoutId,
   6    MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, Path, Pixels, Platform,
   7    PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
   8    RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size,
   9    Style, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle,
  10    WindowOptions, SUBPIXEL_VARIANTS,
  11};
  12use anyhow::Result;
  13use collections::{HashMap, HashSet};
  14use derive_more::{Deref, DerefMut};
  15use smallvec::SmallVec;
  16use std::{
  17    any::{Any, TypeId},
  18    borrow::Cow,
  19    fmt::Debug,
  20    future::Future,
  21    marker::PhantomData,
  22    mem,
  23    sync::Arc,
  24};
  25use util::{post_inc, ResultExt};
  26
  27#[derive(Deref, DerefMut, Ord, PartialOrd, Eq, PartialEq, Clone, Default)]
  28pub struct StackingOrder(pub(crate) SmallVec<[u32; 16]>);
  29
  30#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
  31pub enum DispatchPhase {
  32    /// After the capture phase comes the bubble phase, in which event handlers are
  33    /// invoked front to back. This is the phase you'll usually want to use for event handlers.
  34    #[default]
  35    Bubble,
  36    /// During the initial capture phase, event handlers are invoked back to front. This phase
  37    /// is used for special purposes such as clearing the "pressed" state for click events. If
  38    /// you stop event propagation during this phase, you need to know what you're doing. Handlers
  39    /// outside of the immediate region may rely on detecting non-local events during this phase.
  40    Capture,
  41}
  42
  43type AnyMouseEventListener =
  44    Box<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
  45type AnyFocusChangeListener = Box<dyn Fn(&FocusEvent, &mut WindowContext) + Send + Sync + 'static>;
  46type AnyKeyDownListener =
  47    Box<dyn Fn(&KeyDownEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
  48type AnyKeyUpListener =
  49    Box<dyn Fn(&KeyUpEvent, DispatchPhase, &mut WindowContext) + Send + Sync + 'static>;
  50
  51#[derive(Copy, Clone, PartialEq, Eq, Hash)]
  52pub struct FocusId(usize);
  53
  54#[derive(Clone)]
  55pub struct FocusHandle {
  56    pub(crate) id: FocusId,
  57}
  58
  59impl FocusHandle {
  60    pub(crate) fn new(id: FocusId) -> Self {
  61        Self { id }
  62    }
  63
  64    pub fn is_focused(&self, cx: &WindowContext) -> bool {
  65        cx.window.focus == Some(self.id)
  66    }
  67
  68    pub fn contains_focused(&self, cx: &WindowContext) -> bool {
  69        cx.window.containing_focus.contains(&self.id)
  70    }
  71
  72    pub fn within_focused(&self, cx: &WindowContext) -> bool {
  73        let mut ancestor = Some(self.id);
  74        while let Some(ancestor_id) = ancestor {
  75            if cx.window.focus == Some(ancestor_id) {
  76                return true;
  77            } else {
  78                ancestor = cx.window.focus_parents_by_child.get(&ancestor_id).copied();
  79            }
  80        }
  81        false
  82    }
  83}
  84
  85pub struct Window {
  86    handle: AnyWindowHandle,
  87    platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
  88    display_id: DisplayId,
  89    sprite_atlas: Arc<dyn PlatformAtlas>,
  90    rem_size: Pixels,
  91    content_size: Size<Pixels>,
  92    layout_engine: TaffyLayoutEngine,
  93    pub(crate) root_view: Option<AnyView>,
  94    pub(crate) element_id_stack: GlobalElementId,
  95    prev_element_states: HashMap<GlobalElementId, AnyBox>,
  96    element_states: HashMap<GlobalElementId, AnyBox>,
  97    z_index_stack: StackingOrder,
  98    content_mask_stack: Vec<ContentMask<Pixels>>,
  99    mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyMouseEventListener)>>,
 100    focus_stack: Vec<FocusStackFrame>,
 101    focus_parents_by_child: HashMap<FocusId, FocusId>,
 102    containing_focus: HashSet<FocusId>,
 103    pub(crate) focus_change_listeners: Vec<AnyFocusChangeListener>,
 104    key_down_listeners: Vec<AnyKeyDownListener>,
 105    key_up_listeners: Vec<AnyKeyUpListener>,
 106    propagate_event: bool,
 107    mouse_position: Point<Pixels>,
 108    scale_factor: f32,
 109    pub(crate) scene_builder: SceneBuilder,
 110    pub(crate) dirty: bool,
 111    pub(crate) last_blur: Option<Option<FocusId>>,
 112    pub(crate) focus: Option<FocusId>,
 113    next_focus_id: FocusId,
 114}
 115
 116impl Window {
 117    pub fn new(
 118        handle: AnyWindowHandle,
 119        options: WindowOptions,
 120        cx: &mut MainThread<AppContext>,
 121    ) -> Self {
 122        let platform_window = cx.platform().open_window(handle, options);
 123        let display_id = platform_window.display().id();
 124        let sprite_atlas = platform_window.sprite_atlas();
 125        let mouse_position = platform_window.mouse_position();
 126        let content_size = platform_window.content_size();
 127        let scale_factor = platform_window.scale_factor();
 128        platform_window.on_resize(Box::new({
 129            let cx = cx.to_async();
 130            move |content_size, scale_factor| {
 131                cx.update_window(handle, |cx| {
 132                    cx.window.scale_factor = scale_factor;
 133                    cx.window.scene_builder = SceneBuilder::new();
 134                    cx.window.content_size = content_size;
 135                    cx.window.display_id = cx
 136                        .window
 137                        .platform_window
 138                        .borrow_on_main_thread()
 139                        .display()
 140                        .id();
 141                    cx.window.dirty = true;
 142                })
 143                .log_err();
 144            }
 145        }));
 146
 147        platform_window.on_event({
 148            let cx = cx.to_async();
 149            Box::new(move |event| {
 150                cx.update_window(handle, |cx| cx.dispatch_event(event))
 151                    .log_err()
 152                    .unwrap_or(true)
 153            })
 154        });
 155
 156        let platform_window = MainThreadOnly::new(Arc::new(platform_window), cx.executor.clone());
 157
 158        Window {
 159            handle,
 160            platform_window,
 161            display_id,
 162            sprite_atlas,
 163            rem_size: px(16.),
 164            content_size,
 165            layout_engine: TaffyLayoutEngine::new(),
 166            root_view: None,
 167            element_id_stack: GlobalElementId::default(),
 168            prev_element_states: HashMap::default(),
 169            element_states: HashMap::default(),
 170            z_index_stack: StackingOrder(SmallVec::new()),
 171            content_mask_stack: Vec::new(),
 172            focus_stack: Vec::new(),
 173            focus_parents_by_child: HashMap::default(),
 174            containing_focus: HashSet::default(),
 175            mouse_listeners: HashMap::default(),
 176            focus_change_listeners: Vec::new(),
 177            key_down_listeners: Vec::new(),
 178            key_up_listeners: Vec::new(),
 179            propagate_event: true,
 180            mouse_position,
 181            scale_factor,
 182            scene_builder: SceneBuilder::new(),
 183            dirty: true,
 184            last_blur: None,
 185            focus: None,
 186            next_focus_id: FocusId(0),
 187        }
 188    }
 189}
 190
 191#[derive(Clone, Debug, Default, PartialEq, Eq)]
 192#[repr(C)]
 193pub struct ContentMask<P: Clone + Default + Debug> {
 194    pub bounds: Bounds<P>,
 195}
 196
 197impl ContentMask<Pixels> {
 198    pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
 199        ContentMask {
 200            bounds: self.bounds.scale(factor),
 201        }
 202    }
 203
 204    pub fn intersect(&self, other: &Self) -> Self {
 205        let bounds = self.bounds.intersect(&other.bounds);
 206        ContentMask { bounds }
 207    }
 208}
 209
 210struct FocusStackFrame {
 211    handle: FocusHandle,
 212    key_down_listeners: SmallVec<[AnyKeyDownListener; 2]>,
 213    key_up_listeners: SmallVec<[AnyKeyUpListener; 2]>,
 214}
 215
 216pub struct WindowContext<'a, 'w> {
 217    app: Reference<'a, AppContext>,
 218    pub(crate) window: Reference<'w, Window>,
 219}
 220
 221impl<'a, 'w> WindowContext<'a, 'w> {
 222    pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self {
 223        Self {
 224            app: Reference::Mutable(app),
 225            window: Reference::Mutable(window),
 226        }
 227    }
 228
 229    pub fn notify(&mut self) {
 230        self.window.dirty = true;
 231    }
 232
 233    pub fn focus_handle(&mut self) -> FocusHandle {
 234        let id = FocusId(post_inc(&mut self.window.next_focus_id.0));
 235        FocusHandle { id }
 236    }
 237
 238    pub fn focus(&mut self, handle: &FocusHandle) {
 239        if self.window.last_blur.is_none() {
 240            self.window.last_blur = Some(self.window.focus);
 241        }
 242
 243        let window_id = self.window.handle.id;
 244        self.window.focus = Some(handle.id);
 245        self.push_effect(Effect::FocusChanged {
 246            window_id,
 247            focused: Some(handle.id),
 248        });
 249        self.notify();
 250    }
 251
 252    pub fn blur(&mut self) {
 253        if self.window.last_blur.is_none() {
 254            self.window.last_blur = Some(self.window.focus);
 255        }
 256
 257        let window_id = self.window.handle.id;
 258        self.window.focus = None;
 259        self.push_effect(Effect::FocusChanged {
 260            window_id,
 261            focused: None,
 262        });
 263        self.notify();
 264    }
 265
 266    pub fn run_on_main<R>(
 267        &mut self,
 268        f: impl FnOnce(&mut MainThread<WindowContext<'_, '_>>) -> R + Send + 'static,
 269    ) -> Task<Result<R>>
 270    where
 271        R: Send + 'static,
 272    {
 273        if self.executor.is_main_thread() {
 274            Task::ready(Ok(f(unsafe {
 275                mem::transmute::<&mut Self, &mut MainThread<Self>>(self)
 276            })))
 277        } else {
 278            let id = self.window.handle.id;
 279            self.app.run_on_main(move |cx| cx.update_window(id, f))
 280        }
 281    }
 282
 283    pub fn to_async(&self) -> AsyncWindowContext {
 284        AsyncWindowContext::new(self.app.to_async(), self.window.handle)
 285    }
 286
 287    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
 288        let f = Box::new(f);
 289        let display_id = self.window.display_id;
 290        self.run_on_main(move |cx| {
 291            if let Some(callbacks) = cx.next_frame_callbacks.get_mut(&display_id) {
 292                callbacks.push(f);
 293                // If there was already a callback, it means that we already scheduled a frame.
 294                if callbacks.len() > 1 {
 295                    return;
 296                }
 297            } else {
 298                let async_cx = cx.to_async();
 299                cx.next_frame_callbacks.insert(display_id, vec![f]);
 300                cx.platform().set_display_link_output_callback(
 301                    display_id,
 302                    Box::new(move |_current_time, _output_time| {
 303                        let _ = async_cx.update(|cx| {
 304                            let callbacks = cx
 305                                .next_frame_callbacks
 306                                .get_mut(&display_id)
 307                                .unwrap()
 308                                .drain(..)
 309                                .collect::<Vec<_>>();
 310                            for callback in callbacks {
 311                                callback(cx);
 312                            }
 313
 314                            cx.run_on_main(move |cx| {
 315                                if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
 316                                    cx.platform().stop_display_link(display_id);
 317                                }
 318                            })
 319                            .detach();
 320                        });
 321                    }),
 322                );
 323            }
 324
 325            cx.platform().start_display_link(display_id);
 326        })
 327        .detach();
 328    }
 329
 330    pub fn spawn<Fut, R>(
 331        &mut self,
 332        f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static,
 333    ) -> Task<R>
 334    where
 335        R: Send + 'static,
 336        Fut: Future<Output = R> + Send + 'static,
 337    {
 338        let window = self.window.handle;
 339        self.app.spawn(move |app| {
 340            let cx = AsyncWindowContext::new(app, window);
 341            let future = f(window, cx);
 342            async move { future.await }
 343        })
 344    }
 345
 346    pub fn request_layout(
 347        &mut self,
 348        style: &Style,
 349        children: impl IntoIterator<Item = LayoutId>,
 350    ) -> LayoutId {
 351        self.app.layout_id_buffer.clear();
 352        self.app.layout_id_buffer.extend(children.into_iter());
 353        let rem_size = self.rem_size();
 354
 355        self.window
 356            .layout_engine
 357            .request_layout(style, rem_size, &self.app.layout_id_buffer)
 358    }
 359
 360    pub fn request_measured_layout<
 361        F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync + 'static,
 362    >(
 363        &mut self,
 364        style: Style,
 365        rem_size: Pixels,
 366        measure: F,
 367    ) -> LayoutId {
 368        self.window
 369            .layout_engine
 370            .request_measured_layout(style, rem_size, measure)
 371    }
 372
 373    pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
 374        self.window
 375            .layout_engine
 376            .layout_bounds(layout_id)
 377            .map(Into::into)
 378    }
 379
 380    pub fn scale_factor(&self) -> f32 {
 381        self.window.scale_factor
 382    }
 383
 384    pub fn rem_size(&self) -> Pixels {
 385        self.window.rem_size
 386    }
 387
 388    pub fn stop_propagation(&mut self) {
 389        self.window.propagate_event = false;
 390    }
 391
 392    pub fn on_mouse_event<Event: 'static>(
 393        &mut self,
 394        handler: impl Fn(&Event, DispatchPhase, &mut WindowContext) + Send + Sync + 'static,
 395    ) {
 396        let order = self.window.z_index_stack.clone();
 397        self.window
 398            .mouse_listeners
 399            .entry(TypeId::of::<Event>())
 400            .or_default()
 401            .push((
 402                order,
 403                Box::new(move |event: &dyn Any, phase, cx| {
 404                    handler(event.downcast_ref().unwrap(), phase, cx)
 405                }),
 406            ))
 407    }
 408
 409    pub fn mouse_position(&self) -> Point<Pixels> {
 410        self.window.mouse_position
 411    }
 412
 413    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
 414        self.window.z_index_stack.push(order);
 415        let result = f(self);
 416        self.window.z_index_stack.pop();
 417        result
 418    }
 419
 420    pub fn paint_shadows(
 421        &mut self,
 422        bounds: Bounds<Pixels>,
 423        corner_radii: Corners<Pixels>,
 424        shadows: &[BoxShadow],
 425    ) {
 426        let scale_factor = self.scale_factor();
 427        let content_mask = self.content_mask();
 428        let window = &mut *self.window;
 429        for shadow in shadows {
 430            let mut shadow_bounds = bounds;
 431            shadow_bounds.origin += shadow.offset;
 432            shadow_bounds.dilate(shadow.spread_radius);
 433            window.scene_builder.insert(
 434                &window.z_index_stack,
 435                Shadow {
 436                    order: 0,
 437                    bounds: shadow_bounds.scale(scale_factor),
 438                    content_mask: content_mask.scale(scale_factor),
 439                    corner_radii: corner_radii.scale(scale_factor),
 440                    color: shadow.color,
 441                    blur_radius: shadow.blur_radius.scale(scale_factor),
 442                },
 443            );
 444        }
 445    }
 446
 447    pub fn paint_quad(
 448        &mut self,
 449        bounds: Bounds<Pixels>,
 450        corner_radii: Corners<Pixels>,
 451        background: impl Into<Hsla>,
 452        border_widths: Edges<Pixels>,
 453        border_color: impl Into<Hsla>,
 454    ) {
 455        let scale_factor = self.scale_factor();
 456        let content_mask = self.content_mask();
 457
 458        let window = &mut *self.window;
 459        window.scene_builder.insert(
 460            &window.z_index_stack,
 461            Quad {
 462                order: 0,
 463                bounds: bounds.scale(scale_factor),
 464                content_mask: content_mask.scale(scale_factor),
 465                background: background.into(),
 466                border_color: border_color.into(),
 467                corner_radii: corner_radii.scale(scale_factor),
 468                border_widths: border_widths.scale(scale_factor),
 469            },
 470        );
 471    }
 472
 473    pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
 474        let scale_factor = self.scale_factor();
 475        let content_mask = self.content_mask();
 476        path.content_mask = content_mask;
 477        path.color = color.into();
 478        let window = &mut *self.window;
 479        window
 480            .scene_builder
 481            .insert(&window.z_index_stack, path.scale(scale_factor));
 482    }
 483
 484    pub fn paint_underline(
 485        &mut self,
 486        origin: Point<Pixels>,
 487        width: Pixels,
 488        style: &UnderlineStyle,
 489    ) -> Result<()> {
 490        let scale_factor = self.scale_factor();
 491        let height = if style.wavy {
 492            style.thickness * 3.
 493        } else {
 494            style.thickness
 495        };
 496        let bounds = Bounds {
 497            origin,
 498            size: size(width, height),
 499        };
 500        let content_mask = self.content_mask();
 501        let window = &mut *self.window;
 502        window.scene_builder.insert(
 503            &window.z_index_stack,
 504            Underline {
 505                order: 0,
 506                bounds: bounds.scale(scale_factor),
 507                content_mask: content_mask.scale(scale_factor),
 508                thickness: style.thickness.scale(scale_factor),
 509                color: style.color.unwrap_or_default(),
 510                wavy: style.wavy,
 511            },
 512        );
 513        Ok(())
 514    }
 515
 516    pub fn paint_glyph(
 517        &mut self,
 518        origin: Point<Pixels>,
 519        font_id: FontId,
 520        glyph_id: GlyphId,
 521        font_size: Pixels,
 522        color: Hsla,
 523    ) -> Result<()> {
 524        let scale_factor = self.scale_factor();
 525        let glyph_origin = origin.scale(scale_factor);
 526        let subpixel_variant = Point {
 527            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 528            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
 529        };
 530        let params = RenderGlyphParams {
 531            font_id,
 532            glyph_id,
 533            font_size,
 534            subpixel_variant,
 535            scale_factor,
 536            is_emoji: false,
 537        };
 538
 539        let raster_bounds = self.text_system().raster_bounds(&params)?;
 540        if !raster_bounds.is_zero() {
 541            let tile =
 542                self.window
 543                    .sprite_atlas
 544                    .get_or_insert_with(&params.clone().into(), &mut || {
 545                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 546                        Ok((size, Cow::Owned(bytes)))
 547                    })?;
 548            let bounds = Bounds {
 549                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 550                size: tile.bounds.size.map(Into::into),
 551            };
 552            let content_mask = self.content_mask().scale(scale_factor);
 553            let window = &mut *self.window;
 554            window.scene_builder.insert(
 555                &window.z_index_stack,
 556                MonochromeSprite {
 557                    order: 0,
 558                    bounds,
 559                    content_mask,
 560                    color,
 561                    tile,
 562                },
 563            );
 564        }
 565        Ok(())
 566    }
 567
 568    pub fn paint_emoji(
 569        &mut self,
 570        origin: Point<Pixels>,
 571        font_id: FontId,
 572        glyph_id: GlyphId,
 573        font_size: Pixels,
 574    ) -> Result<()> {
 575        let scale_factor = self.scale_factor();
 576        let glyph_origin = origin.scale(scale_factor);
 577        let params = RenderGlyphParams {
 578            font_id,
 579            glyph_id,
 580            font_size,
 581            // We don't render emojis with subpixel variants.
 582            subpixel_variant: Default::default(),
 583            scale_factor,
 584            is_emoji: true,
 585        };
 586
 587        let raster_bounds = self.text_system().raster_bounds(&params)?;
 588        if !raster_bounds.is_zero() {
 589            let tile =
 590                self.window
 591                    .sprite_atlas
 592                    .get_or_insert_with(&params.clone().into(), &mut || {
 593                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
 594                        Ok((size, Cow::Owned(bytes)))
 595                    })?;
 596            let bounds = Bounds {
 597                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
 598                size: tile.bounds.size.map(Into::into),
 599            };
 600            let content_mask = self.content_mask().scale(scale_factor);
 601            let window = &mut *self.window;
 602
 603            window.scene_builder.insert(
 604                &window.z_index_stack,
 605                PolychromeSprite {
 606                    order: 0,
 607                    bounds,
 608                    corner_radii: Default::default(),
 609                    content_mask,
 610                    tile,
 611                    grayscale: false,
 612                },
 613            );
 614        }
 615        Ok(())
 616    }
 617
 618    pub fn paint_svg(
 619        &mut self,
 620        bounds: Bounds<Pixels>,
 621        path: SharedString,
 622        color: Hsla,
 623    ) -> Result<()> {
 624        let scale_factor = self.scale_factor();
 625        let bounds = bounds.scale(scale_factor);
 626        // Render the SVG at twice the size to get a higher quality result.
 627        let params = RenderSvgParams {
 628            path,
 629            size: bounds
 630                .size
 631                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
 632        };
 633
 634        let tile =
 635            self.window
 636                .sprite_atlas
 637                .get_or_insert_with(&params.clone().into(), &mut || {
 638                    let bytes = self.svg_renderer.render(&params)?;
 639                    Ok((params.size, Cow::Owned(bytes)))
 640                })?;
 641        let content_mask = self.content_mask().scale(scale_factor);
 642
 643        let window = &mut *self.window;
 644        window.scene_builder.insert(
 645            &window.z_index_stack,
 646            MonochromeSprite {
 647                order: 0,
 648                bounds,
 649                content_mask,
 650                color,
 651                tile,
 652            },
 653        );
 654
 655        Ok(())
 656    }
 657
 658    pub fn paint_image(
 659        &mut self,
 660        bounds: Bounds<Pixels>,
 661        corner_radii: Corners<Pixels>,
 662        data: Arc<ImageData>,
 663        grayscale: bool,
 664    ) -> Result<()> {
 665        let scale_factor = self.scale_factor();
 666        let bounds = bounds.scale(scale_factor);
 667        let params = RenderImageParams { image_id: data.id };
 668
 669        let tile = self
 670            .window
 671            .sprite_atlas
 672            .get_or_insert_with(&params.clone().into(), &mut || {
 673                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
 674            })?;
 675        let content_mask = self.content_mask().scale(scale_factor);
 676        let corner_radii = corner_radii.scale(scale_factor);
 677
 678        let window = &mut *self.window;
 679        window.scene_builder.insert(
 680            &window.z_index_stack,
 681            PolychromeSprite {
 682                order: 0,
 683                bounds,
 684                content_mask,
 685                corner_radii,
 686                tile,
 687                grayscale,
 688            },
 689        );
 690        Ok(())
 691    }
 692
 693    pub(crate) fn draw(&mut self) {
 694        let unit_entity = self.unit_entity.clone();
 695        self.update_entity(&unit_entity, |view, cx| {
 696            cx.start_frame();
 697
 698            let mut root_view = cx.window.root_view.take().unwrap();
 699
 700            if let Some(element_id) = root_view.id() {
 701                cx.with_element_state(element_id, |element_state, cx| {
 702                    let element_state = draw_with_element_state(&mut root_view, element_state, cx);
 703                    ((), element_state)
 704                });
 705            } else {
 706                draw_with_element_state(&mut root_view, None, cx);
 707            };
 708
 709            cx.window.root_view = Some(root_view);
 710            let scene = cx.window.scene_builder.build();
 711            cx.end_frame();
 712
 713            cx.run_on_main(view, |_, cx| {
 714                cx.window
 715                    .platform_window
 716                    .borrow_on_main_thread()
 717                    .draw(scene);
 718                cx.window.dirty = false;
 719            })
 720            .detach();
 721        });
 722
 723        fn draw_with_element_state(
 724            root_view: &mut AnyView,
 725            element_state: Option<AnyBox>,
 726            cx: &mut ViewContext<()>,
 727        ) -> AnyBox {
 728            let mut element_state = root_view.initialize(&mut (), element_state, cx);
 729            let layout_id = root_view.layout(&mut (), &mut element_state, cx);
 730            let available_space = cx.window.content_size.map(Into::into);
 731            cx.window
 732                .layout_engine
 733                .compute_layout(layout_id, available_space);
 734            let bounds = cx.window.layout_engine.layout_bounds(layout_id);
 735            root_view.paint(bounds, &mut (), &mut element_state, cx);
 736            element_state
 737        }
 738    }
 739
 740    fn start_frame(&mut self) {
 741        // Make the current element states the previous, and then clear the current.
 742        // The empty element states map will be populated for any element states we
 743        // reference during the upcoming frame.
 744        let window = &mut *self.window;
 745        mem::swap(&mut window.element_states, &mut window.prev_element_states);
 746        window.element_states.clear();
 747
 748        // Clear mouse event listeners, because elements add new element listeners
 749        // when the upcoming frame is painted.
 750        window.mouse_listeners.values_mut().for_each(Vec::clear);
 751
 752        // Clear focus state, because we determine what is focused when the new elements
 753        // in the upcoming frame are initialized.
 754        window.focus_change_listeners.clear();
 755        window.key_down_listeners.clear();
 756        window.key_up_listeners.clear();
 757        window.containing_focus.clear();
 758        window.focus_parents_by_child.clear();
 759    }
 760
 761    fn end_frame(&mut self) {
 762        self.text_system().end_frame();
 763    }
 764
 765    fn dispatch_event(&mut self, event: InputEvent) -> bool {
 766        if let Some(any_mouse_event) = event.mouse_event() {
 767            if let Some(MouseMoveEvent { position, .. }) = any_mouse_event.downcast_ref() {
 768                self.window.mouse_position = *position;
 769            }
 770
 771            if let Some(mut handlers) = self
 772                .window
 773                .mouse_listeners
 774                .remove(&any_mouse_event.type_id())
 775            {
 776                // Because handlers may add other handlers, we sort every time.
 777                handlers.sort_by(|(a, _), (b, _)| a.cmp(b));
 778
 779                // Handlers may set this to false by calling `stop_propagation`
 780                self.window.propagate_event = true;
 781
 782                // Capture phase, events bubble from back to front. Handlers for this phase are used for
 783                // special purposes, such as detecting events outside of a given Bounds.
 784                for (_, handler) in &handlers {
 785                    handler(any_mouse_event, DispatchPhase::Capture, self);
 786                    if !self.window.propagate_event {
 787                        break;
 788                    }
 789                }
 790
 791                // Bubble phase, where most normal handlers do their work.
 792                if self.window.propagate_event {
 793                    for (_, handler) in handlers.iter().rev() {
 794                        handler(any_mouse_event, DispatchPhase::Bubble, self);
 795                        if !self.window.propagate_event {
 796                            break;
 797                        }
 798                    }
 799                }
 800
 801                // Just in case any handlers added new handlers, which is weird, but possible.
 802                handlers.extend(
 803                    self.window
 804                        .mouse_listeners
 805                        .get_mut(&any_mouse_event.type_id())
 806                        .into_iter()
 807                        .flat_map(|handlers| handlers.drain(..)),
 808                );
 809                self.window
 810                    .mouse_listeners
 811                    .insert(any_mouse_event.type_id(), handlers);
 812            }
 813        }
 814
 815        true
 816    }
 817}
 818
 819impl<'a, 'w> MainThread<WindowContext<'a, 'w>> {
 820    fn platform(&self) -> &dyn Platform {
 821        self.platform.borrow_on_main_thread()
 822    }
 823}
 824
 825impl Context for WindowContext<'_, '_> {
 826    type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
 827    type Result<T> = T;
 828
 829    fn entity<T: Send + Sync + 'static>(
 830        &mut self,
 831        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 832    ) -> Handle<T> {
 833        let slot = self.app.entities.reserve();
 834        let entity = build_entity(&mut ViewContext::mutable(
 835            &mut *self.app,
 836            &mut self.window,
 837            slot.id,
 838        ));
 839        self.entities.insert(slot, entity)
 840    }
 841
 842    fn update_entity<T: Send + Sync + 'static, R>(
 843        &mut self,
 844        handle: &Handle<T>,
 845        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 846    ) -> R {
 847        let mut entity = self.entities.lease(handle);
 848        let result = update(
 849            &mut *entity,
 850            &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id),
 851        );
 852        self.entities.end_lease(entity);
 853        result
 854    }
 855}
 856
 857impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
 858    type Target = AppContext;
 859
 860    fn deref(&self) -> &Self::Target {
 861        &self.app
 862    }
 863}
 864
 865impl<'a, 'w> std::ops::DerefMut for WindowContext<'a, 'w> {
 866    fn deref_mut(&mut self) -> &mut Self::Target {
 867        &mut self.app
 868    }
 869}
 870
 871impl BorrowAppContext for WindowContext<'_, '_> {
 872    fn app_mut(&mut self) -> &mut AppContext {
 873        &mut *self.app
 874    }
 875}
 876
 877pub trait BorrowWindow: BorrowAppContext {
 878    fn window(&self) -> &Window;
 879    fn window_mut(&mut self) -> &mut Window;
 880
 881    fn with_element_id<R>(
 882        &mut self,
 883        id: impl Into<ElementId>,
 884        f: impl FnOnce(&mut Self) -> R,
 885    ) -> R {
 886        self.window_mut().element_id_stack.push(id.into());
 887        let result = f(self);
 888        self.window_mut().element_id_stack.pop();
 889        result
 890    }
 891
 892    fn with_content_mask<R>(
 893        &mut self,
 894        mask: ContentMask<Pixels>,
 895        f: impl FnOnce(&mut Self) -> R,
 896    ) -> R {
 897        let mask = mask.intersect(&self.content_mask());
 898        self.window_mut().content_mask_stack.push(mask);
 899        let result = f(self);
 900        self.window_mut().content_mask_stack.pop();
 901        result
 902    }
 903
 904    fn with_element_state<S: 'static + Send + Sync, R>(
 905        &mut self,
 906        id: ElementId,
 907        f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
 908    ) -> R {
 909        self.with_element_id(id, |cx| {
 910            let global_id = cx.window_mut().element_id_stack.clone();
 911            if let Some(any) = cx
 912                .window_mut()
 913                .element_states
 914                .remove(&global_id)
 915                .or_else(|| cx.window_mut().prev_element_states.remove(&global_id))
 916            {
 917                // Using the extra inner option to avoid needing to reallocate a new box.
 918                let mut state_box = any
 919                    .downcast::<Option<S>>()
 920                    .expect("invalid element state type for id");
 921                let state = state_box
 922                    .take()
 923                    .expect("element state is already on the stack");
 924                let (result, state) = f(Some(state), cx);
 925                state_box.replace(state);
 926                cx.window_mut().element_states.insert(global_id, state_box);
 927                result
 928            } else {
 929                let (result, state) = f(None, cx);
 930                cx.window_mut()
 931                    .element_states
 932                    .insert(global_id, Box::new(Some(state)));
 933                result
 934            }
 935        })
 936    }
 937
 938    fn content_mask(&self) -> ContentMask<Pixels> {
 939        self.window()
 940            .content_mask_stack
 941            .last()
 942            .cloned()
 943            .unwrap_or_else(|| ContentMask {
 944                bounds: Bounds {
 945                    origin: Point::default(),
 946                    size: self.window().content_size,
 947                },
 948            })
 949    }
 950
 951    fn rem_size(&self) -> Pixels {
 952        self.window().rem_size
 953    }
 954}
 955
 956impl BorrowWindow for WindowContext<'_, '_> {
 957    fn window(&self) -> &Window {
 958        &*self.window
 959    }
 960
 961    fn window_mut(&mut self) -> &mut Window {
 962        &mut *self.window
 963    }
 964}
 965
 966pub struct ViewContext<'a, 'w, S> {
 967    window_cx: WindowContext<'a, 'w>,
 968    entity_type: PhantomData<S>,
 969    entity_id: EntityId,
 970}
 971
 972impl<S> BorrowAppContext for ViewContext<'_, '_, S> {
 973    fn app_mut(&mut self) -> &mut AppContext {
 974        &mut *self.window_cx.app
 975    }
 976}
 977
 978impl<S> BorrowWindow for ViewContext<'_, '_, S> {
 979    fn window(&self) -> &Window {
 980        &self.window_cx.window
 981    }
 982
 983    fn window_mut(&mut self) -> &mut Window {
 984        &mut *self.window_cx.window
 985    }
 986}
 987
 988impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
 989    fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
 990        Self {
 991            window_cx: WindowContext::mutable(app, window),
 992            entity_id,
 993            entity_type: PhantomData,
 994        }
 995    }
 996
 997    pub fn handle(&self) -> WeakHandle<V> {
 998        self.entities.weak_handle(self.entity_id)
 999    }
1000
1001    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
1002        self.window.z_index_stack.push(order);
1003        let result = f(self);
1004        self.window.z_index_stack.pop();
1005        result
1006    }
1007
1008    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + Send + 'static) {
1009        let entity = self.handle();
1010        self.window_cx.on_next_frame(move |cx| {
1011            entity.update(cx, f).ok();
1012        });
1013    }
1014
1015    pub fn observe<E: Send + Sync + 'static>(
1016        &mut self,
1017        handle: &Handle<E>,
1018        on_notify: impl Fn(&mut V, Handle<E>, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
1019    ) -> Subscription {
1020        let this = self.handle();
1021        let handle = handle.downgrade();
1022        let window_handle = self.window.handle;
1023        self.app.observers.insert(
1024            handle.id,
1025            Box::new(move |cx| {
1026                cx.update_window(window_handle.id, |cx| {
1027                    if let Some(handle) = handle.upgrade(cx) {
1028                        this.update(cx, |this, cx| on_notify(this, handle, cx))
1029                            .is_ok()
1030                    } else {
1031                        false
1032                    }
1033                })
1034                .unwrap_or(false)
1035            }),
1036        )
1037    }
1038
1039    pub fn subscribe<E: EventEmitter + Send + Sync + 'static>(
1040        &mut self,
1041        handle: &Handle<E>,
1042        on_event: impl Fn(&mut V, Handle<E>, &E::Event, &mut ViewContext<'_, '_, V>)
1043            + Send
1044            + Sync
1045            + 'static,
1046    ) -> Subscription {
1047        let this = self.handle();
1048        let handle = handle.downgrade();
1049        let window_handle = self.window.handle;
1050        self.app.event_handlers.insert(
1051            handle.id,
1052            Box::new(move |event, cx| {
1053                cx.update_window(window_handle.id, |cx| {
1054                    if let Some(handle) = handle.upgrade(cx) {
1055                        let event = event.downcast_ref().expect("invalid event type");
1056                        this.update(cx, |this, cx| on_event(this, handle, event, cx))
1057                            .is_ok()
1058                    } else {
1059                        false
1060                    }
1061                })
1062                .unwrap_or(false)
1063            }),
1064        )
1065    }
1066
1067    pub fn on_release(
1068        &mut self,
1069        on_release: impl Fn(&mut V, &mut WindowContext) + Send + Sync + 'static,
1070    ) -> Subscription {
1071        let window_handle = self.window.handle;
1072        self.app.release_handlers.insert(
1073            self.entity_id,
1074            Box::new(move |this, cx| {
1075                let this = this.downcast_mut().expect("invalid entity type");
1076                // todo!("are we okay with silently swallowing the error?")
1077                let _ = cx.update_window(window_handle.id, |cx| on_release(this, cx));
1078            }),
1079        )
1080    }
1081
1082    pub fn observe_release<E: Send + Sync + 'static>(
1083        &mut self,
1084        handle: &Handle<E>,
1085        on_release: impl Fn(&mut V, &mut E, &mut ViewContext<'_, '_, V>) + Send + Sync + 'static,
1086    ) -> Subscription {
1087        let this = self.handle();
1088        let window_handle = self.window.handle;
1089        self.app.release_handlers.insert(
1090            handle.id,
1091            Box::new(move |entity, cx| {
1092                let entity = entity.downcast_mut().expect("invalid entity type");
1093                // todo!("are we okay with silently swallowing the error?")
1094                let _ = cx.update_window(window_handle.id, |cx| {
1095                    this.update(cx, |this, cx| on_release(this, entity, cx))
1096                });
1097            }),
1098        )
1099    }
1100
1101    pub fn notify(&mut self) {
1102        self.window_cx.notify();
1103        self.window_cx.app.push_effect(Effect::Notify {
1104            emitter: self.entity_id,
1105        });
1106    }
1107
1108    pub fn with_focus<R>(
1109        &mut self,
1110        focus_handle: Option<FocusHandle>,
1111        key_down: impl IntoIterator<Item = KeyDownListener<V>>,
1112        key_up: impl IntoIterator<Item = KeyUpListener<V>>,
1113        f: impl FnOnce(&mut Self) -> R,
1114    ) -> R {
1115        let Some(focus_handle) = focus_handle else {
1116            return f(self);
1117        };
1118
1119        let handle = self.handle();
1120        let window = &mut *self.window;
1121        if let Some(parent_frame) = window.focus_stack.last() {
1122            window
1123                .focus_parents_by_child
1124                .insert(focus_handle.id, parent_frame.handle.id);
1125        }
1126
1127        let mut frame = FocusStackFrame {
1128            handle: focus_handle.clone(),
1129            key_down_listeners: SmallVec::new(),
1130            key_up_listeners: SmallVec::new(),
1131        };
1132
1133        for listener in key_down {
1134            let handle = handle.clone();
1135            frame
1136                .key_down_listeners
1137                .push(Box::new(move |event, phase, cx| {
1138                    handle
1139                        .update(cx, |view, cx| listener(view, event, phase, cx))
1140                        .log_err();
1141                }));
1142        }
1143        for listener in key_up {
1144            let handle = handle.clone();
1145            frame
1146                .key_up_listeners
1147                .push(Box::new(move |event, phase, cx| {
1148                    handle
1149                        .update(cx, |view, cx| listener(view, event, phase, cx))
1150                        .log_err();
1151                }));
1152        }
1153
1154        window.focus_stack.push(frame);
1155
1156        if Some(focus_handle.id) == window.focus {
1157            for frame in &mut window.focus_stack {
1158                window.containing_focus.insert(frame.handle.id);
1159                window
1160                    .key_down_listeners
1161                    .extend(frame.key_down_listeners.drain(..));
1162                window
1163                    .key_up_listeners
1164                    .extend(frame.key_up_listeners.drain(..));
1165            }
1166        }
1167
1168        let result = f(self);
1169        self.window.focus_stack.pop();
1170        result
1171    }
1172
1173    pub fn run_on_main<R>(
1174        &mut self,
1175        view: &mut V,
1176        f: impl FnOnce(&mut V, &mut MainThread<ViewContext<'_, '_, V>>) -> R + Send + 'static,
1177    ) -> Task<Result<R>>
1178    where
1179        R: Send + 'static,
1180    {
1181        if self.executor.is_main_thread() {
1182            let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
1183            Task::ready(Ok(f(view, cx)))
1184        } else {
1185            let handle = self.handle().upgrade(self).unwrap();
1186            self.window_cx.run_on_main(move |cx| handle.update(cx, f))
1187        }
1188    }
1189
1190    pub fn spawn<Fut, R>(
1191        &mut self,
1192        f: impl FnOnce(WeakHandle<V>, AsyncWindowContext) -> Fut + Send + 'static,
1193    ) -> Task<R>
1194    where
1195        R: Send + 'static,
1196        Fut: Future<Output = R> + Send + 'static,
1197    {
1198        let handle = self.handle();
1199        self.window_cx.spawn(move |_, cx| {
1200            let result = f(handle, cx);
1201            async move { result.await }
1202        })
1203    }
1204
1205    pub fn on_mouse_event<Event: 'static>(
1206        &mut self,
1207        handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static,
1208    ) {
1209        let handle = self.handle().upgrade(self).unwrap();
1210        self.window_cx.on_mouse_event(move |event, phase, cx| {
1211            handle.update(cx, |view, cx| {
1212                handler(view, event, phase, cx);
1213            })
1214        });
1215    }
1216}
1217
1218impl<'a, 'w, S: EventEmitter + Send + Sync + 'static> ViewContext<'a, 'w, S> {
1219    pub fn emit(&mut self, event: S::Event) {
1220        self.window_cx.app.push_effect(Effect::Emit {
1221            emitter: self.entity_id,
1222            event: Box::new(event),
1223        });
1224    }
1225}
1226
1227impl<'a, 'w, S> Context for ViewContext<'a, 'w, S> {
1228    type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
1229    type Result<U> = U;
1230
1231    fn entity<T2: Send + Sync + 'static>(
1232        &mut self,
1233        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
1234    ) -> Handle<T2> {
1235        self.window_cx.entity(build_entity)
1236    }
1237
1238    fn update_entity<U: Send + Sync + 'static, R>(
1239        &mut self,
1240        handle: &Handle<U>,
1241        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
1242    ) -> R {
1243        self.window_cx.update_entity(handle, update)
1244    }
1245}
1246
1247impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
1248    type Target = WindowContext<'a, 'w>;
1249
1250    fn deref(&self) -> &Self::Target {
1251        &self.window_cx
1252    }
1253}
1254
1255impl<'a, 'w, S: 'static> std::ops::DerefMut for ViewContext<'a, 'w, S> {
1256    fn deref_mut(&mut self) -> &mut Self::Target {
1257        &mut self.window_cx
1258    }
1259}
1260
1261// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
1262slotmap::new_key_type! { pub struct WindowId; }
1263
1264#[derive(PartialEq, Eq)]
1265pub struct WindowHandle<S> {
1266    id: WindowId,
1267    state_type: PhantomData<S>,
1268}
1269
1270impl<S> Copy for WindowHandle<S> {}
1271
1272impl<S> Clone for WindowHandle<S> {
1273    fn clone(&self) -> Self {
1274        WindowHandle {
1275            id: self.id,
1276            state_type: PhantomData,
1277        }
1278    }
1279}
1280
1281impl<S> WindowHandle<S> {
1282    pub fn new(id: WindowId) -> Self {
1283        WindowHandle {
1284            id,
1285            state_type: PhantomData,
1286        }
1287    }
1288}
1289
1290impl<S: 'static> Into<AnyWindowHandle> for WindowHandle<S> {
1291    fn into(self) -> AnyWindowHandle {
1292        AnyWindowHandle {
1293            id: self.id,
1294            state_type: TypeId::of::<S>(),
1295        }
1296    }
1297}
1298
1299#[derive(Copy, Clone, PartialEq, Eq)]
1300pub struct AnyWindowHandle {
1301    pub(crate) id: WindowId,
1302    state_type: TypeId,
1303}
1304
1305#[cfg(any(test, feature = "test"))]
1306impl From<SmallVec<[u32; 16]>> for StackingOrder {
1307    fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
1308        StackingOrder(small_vec)
1309    }
1310}
1311
1312#[derive(Clone, Debug, Eq, PartialEq, Hash)]
1313pub enum ElementId {
1314    View(EntityId),
1315    Number(usize),
1316    Name(SharedString),
1317}
1318
1319impl From<EntityId> for ElementId {
1320    fn from(id: EntityId) -> Self {
1321        ElementId::View(id)
1322    }
1323}
1324
1325impl From<usize> for ElementId {
1326    fn from(id: usize) -> Self {
1327        ElementId::Number(id)
1328    }
1329}
1330
1331impl From<i32> for ElementId {
1332    fn from(id: i32) -> Self {
1333        Self::Number(id as usize)
1334    }
1335}
1336
1337impl From<SharedString> for ElementId {
1338    fn from(name: SharedString) -> Self {
1339        ElementId::Name(name)
1340    }
1341}
1342
1343impl From<&'static str> for ElementId {
1344    fn from(name: &'static str) -> Self {
1345        ElementId::Name(name.into())
1346    }
1347}