window.rs

  1use crate::{
  2    image_cache::RenderImageParams, px, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
  3    BorrowAppContext, Bounds, Context, Corners, DevicePixels, DisplayId, Effect, Element, EntityId,
  4    FontId, GlyphId, Handle, Hsla, ImageData, IsZero, LayoutId, MainThread, MainThreadOnly,
  5    MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Reference,
  6    RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene, SharedString, Size, StackingOrder,
  7    Style, TaffyLayoutEngine, Task, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
  8};
  9use anyhow::Result;
 10use smallvec::SmallVec;
 11use std::{any::TypeId, borrow::Cow, future::Future, marker::PhantomData, mem, sync::Arc};
 12use util::ResultExt;
 13
 14pub struct AnyWindow {}
 15
 16pub struct Window {
 17    handle: AnyWindowHandle,
 18    platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
 19    pub(crate) display_id: DisplayId, // todo!("make private again?")
 20    sprite_atlas: Arc<dyn PlatformAtlas>,
 21    rem_size: Pixels,
 22    content_size: Size<Pixels>,
 23    layout_engine: TaffyLayoutEngine,
 24    pub(crate) root_view: Option<AnyView<()>>,
 25    mouse_position: Point<Pixels>,
 26    current_stacking_order: StackingOrder,
 27    content_mask_stack: Vec<ContentMask>,
 28    pub(crate) scene: Scene,
 29    pub(crate) dirty: bool,
 30}
 31
 32impl Window {
 33    pub fn new(
 34        handle: AnyWindowHandle,
 35        options: WindowOptions,
 36        cx: &mut MainThread<AppContext>,
 37    ) -> Self {
 38        let platform_window = cx.platform().open_window(handle, options);
 39        let display_id = platform_window.display().id();
 40        let sprite_atlas = platform_window.sprite_atlas();
 41        let mouse_position = platform_window.mouse_position();
 42        let content_size = platform_window.content_size();
 43        let scale_factor = platform_window.scale_factor();
 44        platform_window.on_resize(Box::new({
 45            let handle = handle;
 46            let cx = cx.to_async();
 47            move |content_size, scale_factor| {
 48                cx.update_window(handle, |cx| {
 49                    cx.window.scene = Scene::new(scale_factor);
 50                    cx.window.content_size = content_size;
 51                    cx.window.display_id = cx
 52                        .window
 53                        .platform_window
 54                        .borrow_on_main_thread()
 55                        .display()
 56                        .id();
 57                    cx.window.dirty = true;
 58                })
 59                .log_err();
 60            }
 61        }));
 62
 63        let platform_window = MainThreadOnly::new(Arc::new(platform_window), cx.executor.clone());
 64
 65        Window {
 66            handle,
 67            platform_window,
 68            display_id,
 69            sprite_atlas,
 70            rem_size: px(16.),
 71            content_size,
 72            layout_engine: TaffyLayoutEngine::new(),
 73            root_view: None,
 74            mouse_position,
 75            current_stacking_order: SmallVec::new(),
 76            content_mask_stack: Vec::new(),
 77            scene: Scene::new(scale_factor),
 78            dirty: true,
 79        }
 80    }
 81}
 82
 83#[derive(Clone, Debug)]
 84pub struct ContentMask {
 85    pub bounds: Bounds<Pixels>,
 86}
 87
 88impl ContentMask {
 89    pub fn scale(&self, factor: f32) -> ScaledContentMask {
 90        ScaledContentMask {
 91            bounds: self.bounds.scale(factor),
 92        }
 93    }
 94
 95    pub fn intersect(&self, other: &Self) -> Self {
 96        let bounds = self.bounds.intersect(&other.bounds);
 97        ContentMask { bounds }
 98    }
 99}
100
101#[derive(Default, Clone, Debug, PartialEq, Eq)]
102#[repr(C)]
103pub struct ScaledContentMask {
104    bounds: Bounds<ScaledPixels>,
105}
106
107pub struct WindowContext<'a, 'w> {
108    app: Reference<'a, AppContext>,
109    window: Reference<'w, Window>,
110}
111
112impl<'a, 'w> WindowContext<'a, 'w> {
113    pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self {
114        Self {
115            app: Reference::Mutable(app),
116            window: Reference::Mutable(window),
117        }
118    }
119
120    pub fn notify(&mut self) {
121        self.window.dirty = true;
122    }
123
124    pub fn run_on_main<R>(
125        &mut self,
126        f: impl FnOnce(&mut MainThread<WindowContext<'_, '_>>) -> R + Send + 'static,
127    ) -> Task<Result<R>>
128    where
129        R: Send + 'static,
130    {
131        if self.executor.is_main_thread() {
132            Task::ready(Ok(f(unsafe {
133                mem::transmute::<&mut Self, &mut MainThread<Self>>(self)
134            })))
135        } else {
136            let id = self.window.handle.id;
137            self.app.run_on_main(move |cx| cx.update_window(id, f))
138        }
139    }
140
141    pub fn to_async(&self) -> AsyncWindowContext {
142        AsyncWindowContext::new(self.app.to_async(), self.window.handle)
143    }
144
145    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut WindowContext) + Send + 'static) {
146        let f = Box::new(f);
147        let display_id = self.window.display_id;
148        let async_cx = self.to_async();
149        let app_cx = self.app_mut();
150        match app_cx.next_frame_callbacks.entry(display_id) {
151            collections::hash_map::Entry::Occupied(mut entry) => {
152                if entry.get().is_empty() {
153                    app_cx.display_linker.start(display_id);
154                }
155                entry.get_mut().push(f);
156            }
157            collections::hash_map::Entry::Vacant(entry) => {
158                app_cx.display_linker.set_output_callback(
159                    display_id,
160                    Box::new(move |_current_time, _output_time| {
161                        let _ = async_cx.update(|cx| {
162                            let callbacks = cx
163                                .next_frame_callbacks
164                                .get_mut(&display_id)
165                                .unwrap()
166                                .drain(..)
167                                .collect::<Vec<_>>();
168                            for callback in callbacks {
169                                callback(cx);
170                            }
171
172                            if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
173                                cx.display_linker.stop(display_id);
174                            }
175                        });
176                    }),
177                );
178                app_cx.display_linker.start(display_id);
179                entry.insert(vec![f]);
180            }
181        }
182    }
183
184    pub fn spawn<Fut, R>(
185        &mut self,
186        f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut + Send + 'static,
187    ) -> Task<R>
188    where
189        R: Send + 'static,
190        Fut: Future<Output = R> + Send + 'static,
191    {
192        let window = self.window.handle;
193        self.app.spawn(move |app| {
194            let cx = AsyncWindowContext::new(app, window);
195            let future = f(window, cx);
196            async move { future.await }
197        })
198    }
199
200    pub fn request_layout(
201        &mut self,
202        style: Style,
203        children: impl IntoIterator<Item = LayoutId>,
204    ) -> Result<LayoutId> {
205        self.app.layout_id_buffer.clear();
206        self.app.layout_id_buffer.extend(children.into_iter());
207        let rem_size = self.rem_size();
208
209        self.window
210            .layout_engine
211            .request_layout(style, rem_size, &self.app.layout_id_buffer)
212    }
213
214    pub fn request_measured_layout<
215        F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync + 'static,
216    >(
217        &mut self,
218        style: Style,
219        rem_size: Pixels,
220        measure: F,
221    ) -> Result<LayoutId> {
222        self.window
223            .layout_engine
224            .request_measured_layout(style, rem_size, measure)
225    }
226
227    pub fn layout(&mut self, layout_id: LayoutId) -> Result<Layout> {
228        Ok(self
229            .window
230            .layout_engine
231            .layout(layout_id)
232            .map(Into::into)?)
233    }
234
235    pub fn scale_factor(&self) -> f32 {
236        self.window.scene.scale_factor
237    }
238
239    pub fn rem_size(&self) -> Pixels {
240        self.window.rem_size
241    }
242
243    pub fn mouse_position(&self) -> Point<Pixels> {
244        self.window.mouse_position
245    }
246
247    pub fn scene(&mut self) -> &mut Scene {
248        &mut self.window.scene
249    }
250
251    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
252        self.window.current_stacking_order.push(order);
253        let result = f(self);
254        self.window.current_stacking_order.pop();
255        result
256    }
257
258    pub fn current_stacking_order(&self) -> StackingOrder {
259        self.window.current_stacking_order.clone()
260    }
261
262    pub fn paint_glyph(
263        &mut self,
264        origin: Point<Pixels>,
265        order: u32,
266        font_id: FontId,
267        glyph_id: GlyphId,
268        font_size: Pixels,
269        color: Hsla,
270    ) -> Result<()> {
271        let scale_factor = self.scale_factor();
272        let glyph_origin = origin.scale(scale_factor);
273        let subpixel_variant = Point {
274            x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
275            y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
276        };
277        let params = RenderGlyphParams {
278            font_id,
279            glyph_id,
280            font_size,
281            subpixel_variant,
282            scale_factor,
283            is_emoji: false,
284        };
285
286        let raster_bounds = self.text_system().raster_bounds(&params)?;
287        if !raster_bounds.is_zero() {
288            let layer_id = self.current_stacking_order();
289            let tile =
290                self.window
291                    .sprite_atlas
292                    .get_or_insert_with(&params.clone().into(), &mut || {
293                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
294                        Ok((size, Cow::Owned(bytes)))
295                    })?;
296            let bounds = Bounds {
297                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
298                size: tile.bounds.size.map(Into::into),
299            };
300            let content_mask = self.content_mask().scale(scale_factor);
301
302            self.window.scene.insert(
303                layer_id,
304                MonochromeSprite {
305                    order,
306                    bounds,
307                    content_mask,
308                    color,
309                    tile,
310                },
311            );
312        }
313        Ok(())
314    }
315
316    pub fn paint_emoji(
317        &mut self,
318        origin: Point<Pixels>,
319        order: u32,
320        font_id: FontId,
321        glyph_id: GlyphId,
322        font_size: Pixels,
323    ) -> Result<()> {
324        let scale_factor = self.scale_factor();
325        let glyph_origin = origin.scale(scale_factor);
326        let params = RenderGlyphParams {
327            font_id,
328            glyph_id,
329            font_size,
330            // We don't render emojis with subpixel variants.
331            subpixel_variant: Default::default(),
332            scale_factor,
333            is_emoji: true,
334        };
335
336        let raster_bounds = self.text_system().raster_bounds(&params)?;
337        if !raster_bounds.is_zero() {
338            let layer_id = self.current_stacking_order();
339            let tile =
340                self.window
341                    .sprite_atlas
342                    .get_or_insert_with(&params.clone().into(), &mut || {
343                        let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
344                        Ok((size, Cow::Owned(bytes)))
345                    })?;
346            let bounds = Bounds {
347                origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
348                size: tile.bounds.size.map(Into::into),
349            };
350            let content_mask = self.content_mask().scale(scale_factor);
351
352            self.window.scene.insert(
353                layer_id,
354                PolychromeSprite {
355                    order,
356                    bounds,
357                    corner_radii: Default::default(),
358                    content_mask,
359                    tile,
360                    grayscale: false,
361                },
362            );
363        }
364        Ok(())
365    }
366
367    pub fn paint_svg(
368        &mut self,
369        bounds: Bounds<Pixels>,
370        order: u32,
371        path: SharedString,
372        color: Hsla,
373    ) -> Result<()> {
374        let scale_factor = self.scale_factor();
375        let bounds = bounds.scale(scale_factor);
376        // Render the SVG at twice the size to get a higher quality result.
377        let params = RenderSvgParams {
378            path,
379            size: bounds
380                .size
381                .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
382        };
383
384        let layer_id = self.current_stacking_order();
385        let tile =
386            self.window
387                .sprite_atlas
388                .get_or_insert_with(&params.clone().into(), &mut || {
389                    let bytes = self.svg_renderer.render(&params)?;
390                    Ok((params.size, Cow::Owned(bytes)))
391                })?;
392        let content_mask = self.content_mask().scale(scale_factor);
393
394        self.window.scene.insert(
395            layer_id,
396            MonochromeSprite {
397                order,
398                bounds,
399                content_mask,
400                color,
401                tile,
402            },
403        );
404
405        Ok(())
406    }
407
408    pub fn paint_image(
409        &mut self,
410        bounds: Bounds<Pixels>,
411        corner_radii: Corners<Pixels>,
412        order: u32,
413        data: Arc<ImageData>,
414        grayscale: bool,
415    ) -> Result<()> {
416        let scale_factor = self.scale_factor();
417        let bounds = bounds.scale(scale_factor);
418        let params = RenderImageParams { image_id: data.id };
419
420        let order = self.current_stacking_order();
421        let tile = self
422            .window
423            .sprite_atlas
424            .get_or_insert_with(&params.clone().into(), &mut || {
425                Ok((data.size(), Cow::Borrowed(data.as_bytes())))
426            })?;
427        let content_mask = self.content_mask().scale(scale_factor);
428        let corner_radii = corner_radii.scale(scale_factor);
429
430        self.window.scene.insert(
431            order,
432            PolychromeSprite {
433                order: 0, // Used in in Scene::batches. 0 has no meaning.
434                bounds,
435                content_mask,
436                corner_radii,
437                tile,
438                grayscale,
439            },
440        );
441
442        Ok(())
443    }
444
445    pub(crate) fn draw(&mut self) -> Result<()> {
446        let unit_entity = self.unit_entity.clone();
447        self.update_entity(&unit_entity, |view, cx| {
448            let mut root_view = cx.window.root_view.take().unwrap();
449            let (root_layout_id, mut frame_state) = root_view.layout(&mut (), cx)?;
450            let available_space = cx.window.content_size.map(Into::into);
451
452            cx.window
453                .layout_engine
454                .compute_layout(root_layout_id, available_space)?;
455            let layout = cx.window.layout_engine.layout(root_layout_id)?;
456
457            root_view.paint(layout, &mut (), &mut frame_state, cx)?;
458            cx.window.root_view = Some(root_view);
459            let scene = cx.window.scene.take();
460
461            cx.run_on_main(view, |_, cx| {
462                cx.window
463                    .platform_window
464                    .borrow_on_main_thread()
465                    .draw(scene);
466                cx.window.dirty = false;
467            })
468            .detach();
469
470            Ok(())
471        })
472    }
473}
474
475impl Context for WindowContext<'_, '_> {
476    type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
477    type Result<T> = T;
478
479    fn entity<T: Send + Sync + 'static>(
480        &mut self,
481        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
482    ) -> Handle<T> {
483        let slot = self.app.entities.reserve();
484        let entity = build_entity(&mut ViewContext::mutable(
485            &mut *self.app,
486            &mut self.window,
487            slot.id,
488        ));
489        self.entities.insert(slot, entity)
490    }
491
492    fn update_entity<T: Send + Sync + 'static, R>(
493        &mut self,
494        handle: &Handle<T>,
495        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
496    ) -> R {
497        let mut entity = self.entities.lease(handle);
498        let result = update(
499            &mut *entity,
500            &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id),
501        );
502        self.entities.end_lease(entity);
503        result
504    }
505}
506
507impl<'a, 'w> std::ops::Deref for WindowContext<'a, 'w> {
508    type Target = AppContext;
509
510    fn deref(&self) -> &Self::Target {
511        &self.app
512    }
513}
514
515impl<'a, 'w> std::ops::DerefMut for WindowContext<'a, 'w> {
516    fn deref_mut(&mut self) -> &mut Self::Target {
517        &mut self.app
518    }
519}
520
521impl BorrowAppContext for WindowContext<'_, '_> {
522    fn app_mut(&mut self) -> &mut AppContext {
523        &mut *self.app
524    }
525}
526
527pub trait BorrowWindow: BorrowAppContext {
528    fn window(&self) -> &Window;
529    fn window_mut(&mut self) -> &mut Window;
530
531    fn with_content_mask<R>(&mut self, mask: ContentMask, f: impl FnOnce(&mut Self) -> R) -> R {
532        let mask = mask.intersect(&self.content_mask());
533        self.window_mut().content_mask_stack.push(mask);
534        let result = f(self);
535        self.window_mut().content_mask_stack.pop();
536        result
537    }
538
539    fn content_mask(&self) -> ContentMask {
540        self.window()
541            .content_mask_stack
542            .last()
543            .cloned()
544            .unwrap_or_else(|| ContentMask {
545                bounds: Bounds {
546                    origin: Point::default(),
547                    size: self.window().content_size,
548                },
549            })
550    }
551
552    fn rem_size(&self) -> Pixels {
553        self.window().rem_size
554    }
555}
556
557impl BorrowWindow for WindowContext<'_, '_> {
558    fn window(&self) -> &Window {
559        &*self.window
560    }
561
562    fn window_mut(&mut self) -> &mut Window {
563        &mut *self.window
564    }
565}
566
567pub struct ViewContext<'a, 'w, S> {
568    window_cx: WindowContext<'a, 'w>,
569    entity_type: PhantomData<S>,
570    entity_id: EntityId,
571}
572
573impl<S> BorrowAppContext for ViewContext<'_, '_, S> {
574    fn app_mut(&mut self) -> &mut AppContext {
575        &mut *self.window_cx.app
576    }
577
578    fn with_text_style<F, R>(&mut self, style: crate::TextStyleRefinement, f: F) -> R
579    where
580        F: FnOnce(&mut Self) -> R,
581    {
582        self.window_cx.app.push_text_style(style);
583        let result = f(self);
584        self.window_cx.app.pop_text_style();
585        result
586    }
587
588    fn with_state<T: Send + Sync + 'static, F, R>(&mut self, state: T, f: F) -> R
589    where
590        F: FnOnce(&mut Self) -> R,
591    {
592        self.window_cx.app.push_state(state);
593        let result = f(self);
594        self.window_cx.app.pop_state::<T>();
595        result
596    }
597}
598
599impl<S> BorrowWindow for ViewContext<'_, '_, S> {
600    fn window(&self) -> &Window {
601        &self.window_cx.window
602    }
603
604    fn window_mut(&mut self) -> &mut Window {
605        &mut *self.window_cx.window
606    }
607}
608
609impl<'a, 'w, S: Send + Sync + 'static> ViewContext<'a, 'w, S> {
610    fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
611        Self {
612            window_cx: WindowContext::mutable(app, window),
613            entity_id,
614            entity_type: PhantomData,
615        }
616    }
617
618    pub fn handle(&self) -> WeakHandle<S> {
619        self.entities.weak_handle(self.entity_id)
620    }
621
622    pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
623        self.window.current_stacking_order.push(order);
624        let result = f(self);
625        self.window.current_stacking_order.pop();
626        result
627    }
628
629    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut S, &mut ViewContext<S>) + Send + 'static) {
630        let entity = self.handle();
631        self.window_cx.on_next_frame(move |cx| {
632            entity.update(cx, f).ok();
633        });
634    }
635
636    pub fn observe<E: Send + Sync + 'static>(
637        &mut self,
638        handle: &Handle<E>,
639        on_notify: impl Fn(&mut S, Handle<E>, &mut ViewContext<'_, '_, S>) + Send + Sync + 'static,
640    ) {
641        let this = self.handle();
642        let handle = handle.downgrade();
643        let window_handle = self.window.handle;
644        self.app
645            .observers
646            .entry(handle.id)
647            .or_default()
648            .push(Arc::new(move |cx| {
649                cx.update_window(window_handle.id, |cx| {
650                    if let Some(handle) = handle.upgrade(cx) {
651                        this.update(cx, |this, cx| on_notify(this, handle, cx))
652                            .is_ok()
653                    } else {
654                        false
655                    }
656                })
657                .unwrap_or(false)
658            }));
659    }
660
661    pub fn notify(&mut self) {
662        self.window_cx.notify();
663        self.window_cx
664            .app
665            .pending_effects
666            .push_back(Effect::Notify(self.entity_id));
667    }
668
669    pub fn run_on_main<R>(
670        &mut self,
671        view: &mut S,
672        f: impl FnOnce(&mut S, &mut MainThread<ViewContext<'_, '_, S>>) -> R + Send + 'static,
673    ) -> Task<Result<R>>
674    where
675        R: Send + 'static,
676    {
677        if self.executor.is_main_thread() {
678            let cx = unsafe { mem::transmute::<&mut Self, &mut MainThread<Self>>(self) };
679            Task::ready(Ok(f(view, cx)))
680        } else {
681            let handle = self.handle().upgrade(self).unwrap();
682            self.window_cx.run_on_main(move |cx| handle.update(cx, f))
683        }
684    }
685
686    pub fn spawn<Fut, R>(
687        &mut self,
688        f: impl FnOnce(WeakHandle<S>, AsyncWindowContext) -> Fut + Send + 'static,
689    ) -> Task<R>
690    where
691        R: Send + 'static,
692        Fut: Future<Output = R> + Send + 'static,
693    {
694        let handle = self.handle();
695        self.window_cx.spawn(move |_, cx| {
696            let result = f(handle, cx);
697            async move { result.await }
698        })
699    }
700
701    pub(crate) fn erase_state<R>(&mut self, f: impl FnOnce(&mut ViewContext<()>) -> R) -> R {
702        let entity_id = self.unit_entity.id;
703        let mut cx = ViewContext::mutable(
704            &mut *self.window_cx.app,
705            &mut *self.window_cx.window,
706            entity_id,
707        );
708        f(&mut cx)
709    }
710}
711
712impl<'a, 'w, S> Context for ViewContext<'a, 'w, S> {
713    type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
714    type Result<U> = U;
715
716    fn entity<T2: Send + Sync + 'static>(
717        &mut self,
718        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
719    ) -> Handle<T2> {
720        self.window_cx.entity(build_entity)
721    }
722
723    fn update_entity<U: Send + Sync + 'static, R>(
724        &mut self,
725        handle: &Handle<U>,
726        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
727    ) -> R {
728        self.window_cx.update_entity(handle, update)
729    }
730}
731
732impl<'a, 'w, S: 'static> std::ops::Deref for ViewContext<'a, 'w, S> {
733    type Target = WindowContext<'a, 'w>;
734
735    fn deref(&self) -> &Self::Target {
736        &self.window_cx
737    }
738}
739
740impl<'a, 'w, S: 'static> std::ops::DerefMut for ViewContext<'a, 'w, S> {
741    fn deref_mut(&mut self) -> &mut Self::Target {
742        &mut self.window_cx
743    }
744}
745
746// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
747slotmap::new_key_type! { pub struct WindowId; }
748
749#[derive(PartialEq, Eq)]
750pub struct WindowHandle<S> {
751    id: WindowId,
752    state_type: PhantomData<S>,
753}
754
755impl<S> Copy for WindowHandle<S> {}
756
757impl<S> Clone for WindowHandle<S> {
758    fn clone(&self) -> Self {
759        WindowHandle {
760            id: self.id,
761            state_type: PhantomData,
762        }
763    }
764}
765
766impl<S> WindowHandle<S> {
767    pub fn new(id: WindowId) -> Self {
768        WindowHandle {
769            id,
770            state_type: PhantomData,
771        }
772    }
773}
774
775impl<S: 'static> Into<AnyWindowHandle> for WindowHandle<S> {
776    fn into(self) -> AnyWindowHandle {
777        AnyWindowHandle {
778            id: self.id,
779            state_type: TypeId::of::<S>(),
780        }
781    }
782}
783
784#[derive(Copy, Clone, PartialEq, Eq)]
785pub struct AnyWindowHandle {
786    pub(crate) id: WindowId,
787    state_type: TypeId,
788}
789
790#[derive(Clone)]
791pub struct Layout {
792    pub order: u32,
793    pub bounds: Bounds<Pixels>,
794}