1#[cfg(not(feature = "std"))]
2use alloc::string::{String, ToString};
3use alloc::{
4 boxed::Box,
5 collections::{btree_map::BTreeMap, btree_set::BTreeSet},
6 vec::Vec,
7};
8use core::{
9 cmp::Ordering,
10 ffi::c_void,
11 hash::{Hash, Hasher},
12 ops,
13 sync::atomic::{AtomicI64, AtomicUsize, Ordering as AtomicOrdering},
14};
15
16use azul_css::{
17 css::CssPath,
18 props::{
19 basic::{ColorU, FloatValue, LayoutPoint, LayoutRect, LayoutSize},
20 property::CssProperty,
21 style::StyleCursor,
22 },
23 AzString, LayoutDebugMessage, OptionF32, OptionI32, OptionString, U8Vec,
24};
25use rust_fontconfig::FcFontCache;
26
27use crate::{
28 callbacks::{LayoutCallback, LayoutCallbackType, Update},
29 dom::{DomId, DomNodeId, NodeHierarchy},
30 geom::{
31 LogicalPosition, LogicalRect, LogicalSize, OptionLogicalSize, PhysicalPositionI32,
32 PhysicalSize,
33 },
34 gl::OptionGlContextPtr,
35 hit_test::{ExternalScrollId, OverflowingScrollNode},
36 id::{NodeDataContainer, NodeId},
37 refany::OptionRefAny,
38 resources::{
39 DpiScaleFactor, Epoch, GlTextureCache, IdNamespace, ImageCache, ImageMask, ImageRef,
40 RendererResources, ResourceUpdate,
41 },
42 selection::SelectionState,
43 styled_dom::NodeHierarchyItemId,
44 task::{Instant, ThreadId, TimerId},
45 FastBTreeSet, FastHashMap,
46};
47
48pub const DEFAULT_TITLE: &str = "Azul App";
49
50static LAST_WINDOW_ID: AtomicI64 = AtomicI64::new(0);
51
52#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
55#[repr(transparent)]
56pub struct WindowId {
57 pub id: i64,
58}
59
60impl WindowId {
61 pub fn new() -> Self {
62 WindowId {
63 id: LAST_WINDOW_ID.fetch_add(1, AtomicOrdering::SeqCst),
64 }
65 }
66}
67
68static LAST_ICON_KEY: AtomicUsize = AtomicUsize::new(0);
69
70#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
74#[repr(C)]
75pub struct IconKey {
76 icon_id: usize,
77}
78
79impl IconKey {
80 pub fn new() -> Self {
81 Self {
82 icon_id: LAST_ICON_KEY.fetch_add(1, AtomicOrdering::SeqCst),
83 }
84 }
85}
86
87#[repr(C)]
88#[derive(PartialEq, Copy, Clone, Debug, PartialOrd, Ord, Eq, Hash)]
89pub struct RendererOptions {
90 pub vsync: Vsync,
91 pub srgb: Srgb,
92 pub hw_accel: HwAcceleration,
93}
94
95impl_option!(
96 RendererOptions,
97 OptionRendererOptions,
98 [PartialEq, Copy, Clone, Debug, PartialOrd, Ord, Eq, Hash]
99);
100
101impl Default for RendererOptions {
102 fn default() -> Self {
103 Self {
104 vsync: Vsync::Enabled,
105 srgb: Srgb::Disabled,
106 hw_accel: HwAcceleration::Enabled,
107 }
108 }
109}
110
111impl RendererOptions {
112 pub const fn new(vsync: Vsync, srgb: Srgb, hw_accel: HwAcceleration) -> Self {
113 Self {
114 vsync,
115 srgb,
116 hw_accel,
117 }
118 }
119}
120
121#[repr(C)]
122#[derive(PartialEq, Copy, Clone, Debug, PartialOrd, Ord, Eq, Hash)]
123pub enum Vsync {
124 Enabled,
125 Disabled,
126 DontCare,
127}
128
129impl Vsync {
130 pub const fn is_enabled(&self) -> bool {
131 match self {
132 Vsync::Enabled => true,
133 _ => false,
134 }
135 }
136}
137
138#[repr(C)]
139#[derive(PartialEq, Copy, Clone, Debug, PartialOrd, Ord, Eq, Hash)]
140pub enum Srgb {
141 Enabled,
142 Disabled,
143 DontCare,
144}
145impl Srgb {
146 pub const fn is_enabled(&self) -> bool {
147 match self {
148 Srgb::Enabled => true,
149 _ => false,
150 }
151 }
152}
153
154#[repr(C)]
155#[derive(PartialEq, Copy, Clone, Debug, PartialOrd, Ord, Eq, Hash)]
156pub enum HwAcceleration {
157 Enabled,
158 Disabled,
159 DontCare,
160}
161impl HwAcceleration {
162 pub const fn is_enabled(&self) -> bool {
163 match self {
164 HwAcceleration::Enabled => true,
165 _ => false,
166 }
167 }
168}
169
170#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
171#[repr(C, u8)]
172pub enum RawWindowHandle {
173 IOS(IOSHandle),
174 MacOS(MacOSHandle),
175 Xlib(XlibHandle),
176 Xcb(XcbHandle),
177 Wayland(WaylandHandle),
178 Windows(WindowsHandle),
179 Web(WebHandle),
180 Android(AndroidHandle),
181 Unsupported,
182}
183
184unsafe impl Send for RawWindowHandle {}
185
186#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
187#[repr(C)]
188pub struct IOSHandle {
189 pub ui_window: *mut c_void,
190 pub ui_view: *mut c_void,
191 pub ui_view_controller: *mut c_void,
192}
193
194#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
195#[repr(C)]
196pub struct MacOSHandle {
197 pub ns_window: *mut c_void,
198 pub ns_view: *mut c_void,
199}
200
201#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
202#[repr(C)]
203pub struct XlibHandle {
204 pub window: u64,
206 pub display: *mut c_void,
207}
208
209#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
210#[repr(C)]
211pub struct XcbHandle {
212 pub window: u32,
214 pub connection: *mut c_void,
216}
217
218#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
219#[repr(C)]
220pub struct WaylandHandle {
221 pub surface: *mut c_void,
223 pub display: *mut c_void,
225}
226
227#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
228#[repr(C)]
229pub struct WindowsHandle {
230 pub hwnd: *mut c_void,
232 pub hinstance: *mut c_void,
234}
235
236#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
237#[repr(C)]
238pub struct WebHandle {
239 pub id: u32,
245}
246
247#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
248#[repr(C)]
249pub struct AndroidHandle {
250 pub a_native_window: *mut c_void,
252}
253
254#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
255#[repr(C)]
256pub enum MouseCursorType {
257 Default,
258 Crosshair,
259 Hand,
260 Arrow,
261 Move,
262 Text,
263 Wait,
264 Help,
265 Progress,
266 NotAllowed,
267 ContextMenu,
268 Cell,
269 VerticalText,
270 Alias,
271 Copy,
272 NoDrop,
273 Grab,
274 Grabbing,
275 AllScroll,
276 ZoomIn,
277 ZoomOut,
278 EResize,
279 NResize,
280 NeResize,
281 NwResize,
282 SResize,
283 SeResize,
284 SwResize,
285 WResize,
286 EwResize,
287 NsResize,
288 NeswResize,
289 NwseResize,
290 ColResize,
291 RowResize,
292}
293
294impl Default for MouseCursorType {
295 fn default() -> Self {
296 MouseCursorType::Default
297 }
298}
299
300pub type ScanCode = u32;
302
303#[derive(Default, Debug, Clone, PartialEq)]
305#[repr(C)]
306pub struct KeyboardState {
307 pub current_virtual_keycode: OptionVirtualKeyCode,
313 pub pressed_virtual_keycodes: VirtualKeyCodeVec,
324 pub pressed_scancodes: ScanCodeVec,
330}
331
332impl KeyboardState {
333 pub fn shift_down(&self) -> bool {
334 self.is_key_down(VirtualKeyCode::LShift) || self.is_key_down(VirtualKeyCode::RShift)
335 }
336 pub fn ctrl_down(&self) -> bool {
337 self.is_key_down(VirtualKeyCode::LControl) || self.is_key_down(VirtualKeyCode::RControl)
338 }
339 pub fn alt_down(&self) -> bool {
340 self.is_key_down(VirtualKeyCode::LAlt) || self.is_key_down(VirtualKeyCode::RAlt)
341 }
342 pub fn super_down(&self) -> bool {
343 self.is_key_down(VirtualKeyCode::LWin) || self.is_key_down(VirtualKeyCode::RWin)
344 }
345 pub fn is_key_down(&self, key: VirtualKeyCode) -> bool {
346 self.pressed_virtual_keycodes.iter().any(|k| *k == key)
347 }
348}
349
350impl_option!(
351 KeyboardState,
352 OptionKeyboardState,
353 copy = false,
354 [Debug, Clone, PartialEq]
355);
356
357impl_option!(
359 u32,
360 OptionChar,
361 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
362);
363impl_option!(
364 VirtualKeyCode,
365 OptionVirtualKeyCode,
366 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
367);
368
369impl_vec!(
370 VirtualKeyCode,
371 VirtualKeyCodeVec,
372 VirtualKeyCodeVecDestructor,
373 VirtualKeyCodeVecDestructorType
374);
375impl_vec_debug!(VirtualKeyCode, VirtualKeyCodeVec);
376impl_vec_partialord!(VirtualKeyCode, VirtualKeyCodeVec);
377impl_vec_ord!(VirtualKeyCode, VirtualKeyCodeVec);
378impl_vec_clone!(
379 VirtualKeyCode,
380 VirtualKeyCodeVec,
381 VirtualKeyCodeVecDestructor
382);
383impl_vec_partialeq!(VirtualKeyCode, VirtualKeyCodeVec);
384impl_vec_eq!(VirtualKeyCode, VirtualKeyCodeVec);
385impl_vec_hash!(VirtualKeyCode, VirtualKeyCodeVec);
386
387impl_vec_as_hashmap!(VirtualKeyCode, VirtualKeyCodeVec);
388
389impl_vec!(
390 ScanCode,
391 ScanCodeVec,
392 ScanCodeVecDestructor,
393 ScanCodeVecDestructorType
394);
395impl_vec_debug!(ScanCode, ScanCodeVec);
396impl_vec_partialord!(ScanCode, ScanCodeVec);
397impl_vec_ord!(ScanCode, ScanCodeVec);
398impl_vec_clone!(ScanCode, ScanCodeVec, ScanCodeVecDestructor);
399impl_vec_partialeq!(ScanCode, ScanCodeVec);
400impl_vec_eq!(ScanCode, ScanCodeVec);
401impl_vec_hash!(ScanCode, ScanCodeVec);
402
403impl_vec_as_hashmap!(ScanCode, ScanCodeVec);
404
405#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
407#[repr(C)]
408pub struct MouseState {
409 pub mouse_cursor_type: OptionMouseCursorType,
411 pub cursor_position: CursorPosition,
414 pub is_cursor_locked: bool,
417 pub left_down: bool,
419 pub right_down: bool,
421 pub middle_down: bool,
423}
424
425impl MouseState {
426 pub fn matches(&self, context: &ContextMenuMouseButton) -> bool {
427 use self::ContextMenuMouseButton::*;
428 match context {
429 Left => self.left_down,
430 Right => self.right_down,
431 Middle => self.middle_down,
432 }
433 }
434}
435
436impl_option!(
437 MouseState,
438 OptionMouseState,
439 [Debug, Copy, Clone, PartialEq, PartialOrd]
440);
441
442impl_option!(
443 MouseCursorType,
444 OptionMouseCursorType,
445 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
446);
447
448impl Default for MouseState {
449 fn default() -> Self {
450 Self {
451 mouse_cursor_type: Some(MouseCursorType::Default).into(),
452 cursor_position: CursorPosition::default(),
453 is_cursor_locked: false,
454 left_down: false,
455 right_down: false,
456 middle_down: false,
457 }
458 }
459}
460
461#[derive(Debug, Clone, PartialEq, PartialOrd, Hash, Eq, Ord)]
462#[repr(C)]
463pub struct VirtualKeyCodeCombo {
464 pub keys: VirtualKeyCodeVec,
465}
466
467impl_option!(
468 VirtualKeyCodeCombo,
469 OptionVirtualKeyCodeCombo,
470 copy = false,
471 [Debug, Clone, PartialEq, PartialOrd, Hash, Eq, Ord]
472);
473
474#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Hash, Eq, Ord)]
475#[repr(C)]
476pub enum ContextMenuMouseButton {
477 Right,
478 Middle,
479 Left,
480}
481
482impl Default for ContextMenuMouseButton {
483 fn default() -> Self {
484 ContextMenuMouseButton::Right
485 }
486}
487
488impl MouseState {
489 pub fn mouse_down(&self) -> bool {
491 self.right_down || self.left_down || self.middle_down
492 }
493}
494
495#[derive(Debug)]
497pub struct ScrollResult {}
498
499#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
500#[repr(C, u8)]
501pub enum CursorPosition {
502 OutOfWindow(LogicalPosition),
503 Uninitialized,
504 InWindow(LogicalPosition),
505}
506
507impl Default for CursorPosition {
508 fn default() -> CursorPosition {
509 CursorPosition::Uninitialized
510 }
511}
512
513impl CursorPosition {
514 pub fn get_position(&self) -> Option<LogicalPosition> {
515 match self {
516 CursorPosition::InWindow(logical_pos) => Some(*logical_pos),
517 CursorPosition::OutOfWindow(_) | CursorPosition::Uninitialized => None,
518 }
519 }
520
521 pub fn is_inside_window(&self) -> bool {
522 self.get_position().is_some()
523 }
524}
525
526#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
529#[repr(C)]
530pub struct DebugState {
531 pub profiler_dbg: bool,
532 pub render_target_dbg: bool,
533 pub texture_cache_dbg: bool,
534 pub gpu_time_queries: bool,
535 pub gpu_sample_queries: bool,
536 pub disable_batching: bool,
537 pub epochs: bool,
538 pub echo_driver_messages: bool,
539 pub show_overdraw: bool,
540 pub gpu_cache_dbg: bool,
541 pub texture_cache_dbg_clear_evicted: bool,
542 pub picture_caching_dbg: bool,
543 pub primitive_dbg: bool,
544 pub zoom_dbg: bool,
545 pub small_screen: bool,
546 pub disable_opaque_pass: bool,
547 pub disable_alpha_pass: bool,
548 pub disable_clip_masks: bool,
549 pub disable_text_prims: bool,
550 pub disable_gradient_prims: bool,
551 pub obscure_images: bool,
552 pub glyph_flashing: bool,
553 pub smart_profiler: bool,
554 pub invalidation_dbg: bool,
555 pub tile_cache_logging_dbg: bool,
556 pub profiler_capture: bool,
557 pub force_picture_invalidation: bool,
558}
559
560fn translate_cursor(cursor: StyleCursor) -> MouseCursorType {
561 use azul_css::props::style::effects::StyleCursor;
562 match cursor {
563 StyleCursor::Default => MouseCursorType::Default,
564 StyleCursor::Crosshair => MouseCursorType::Crosshair,
565 StyleCursor::Pointer => MouseCursorType::Hand,
566 StyleCursor::Move => MouseCursorType::Move,
567 StyleCursor::Text => MouseCursorType::Text,
568 StyleCursor::Wait => MouseCursorType::Wait,
569 StyleCursor::Help => MouseCursorType::Help,
570 StyleCursor::Progress => MouseCursorType::Progress,
571 StyleCursor::ContextMenu => MouseCursorType::ContextMenu,
572 StyleCursor::Cell => MouseCursorType::Cell,
573 StyleCursor::VerticalText => MouseCursorType::VerticalText,
574 StyleCursor::Alias => MouseCursorType::Alias,
575 StyleCursor::Copy => MouseCursorType::Copy,
576 StyleCursor::Grab => MouseCursorType::Grab,
577 StyleCursor::Grabbing => MouseCursorType::Grabbing,
578 StyleCursor::AllScroll => MouseCursorType::AllScroll,
579 StyleCursor::ZoomIn => MouseCursorType::ZoomIn,
580 StyleCursor::ZoomOut => MouseCursorType::ZoomOut,
581 StyleCursor::EResize => MouseCursorType::EResize,
582 StyleCursor::NResize => MouseCursorType::NResize,
583 StyleCursor::SResize => MouseCursorType::SResize,
584 StyleCursor::SeResize => MouseCursorType::SeResize,
585 StyleCursor::WResize => MouseCursorType::WResize,
586 StyleCursor::EwResize => MouseCursorType::EwResize,
587 StyleCursor::NsResize => MouseCursorType::NsResize,
588 StyleCursor::NeswResize => MouseCursorType::NeswResize,
589 StyleCursor::NwseResize => MouseCursorType::NwseResize,
590 StyleCursor::ColResize => MouseCursorType::ColResize,
591 StyleCursor::RowResize => MouseCursorType::RowResize,
592 StyleCursor::Unset => MouseCursorType::Default,
593 }
594}
595
596#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Hash, Ord, Eq)]
597#[repr(C)]
598pub struct TouchState {
599 pub num_touches: usize,
601}
602
603#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
605#[repr(C)]
606pub struct TouchPoint {
607 pub id: u64,
609 pub position: LogicalPosition,
611 pub force: f32,
614}
615
616impl_vec!(
617 TouchPoint,
618 TouchPointVec,
619 TouchPointVecDestructor,
620 TouchPointVecDestructorType
621);
622impl_vec_debug!(TouchPoint, TouchPointVec);
623impl_vec_clone!(TouchPoint, TouchPointVec, TouchPointVecDestructor);
624impl_vec_partialeq!(TouchPoint, TouchPointVec);
625
626#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Hash, Ord, Eq)]
628#[repr(C)]
629pub enum WindowTheme {
630 DarkMode,
631 LightMode,
632}
633
634impl Default for WindowTheme {
635 fn default() -> WindowTheme {
636 WindowTheme::LightMode }
638}
639
640impl_option!(
641 WindowTheme,
642 OptionWindowTheme,
643 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
644);
645
646#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
657#[repr(C)]
658pub struct MonitorId {
659 pub index: usize,
661 pub hash: u64,
663}
664
665impl MonitorId {
666 pub const PRIMARY: MonitorId = MonitorId { index: 0, hash: 0 };
668
669 pub const fn new(index: usize) -> Self {
671 Self { index, hash: 0 }
672 }
673
674 pub const fn from_index_and_hash(index: usize, hash: u64) -> Self {
676 Self { index, hash }
677 }
678
679 pub fn from_properties(
685 index: usize,
686 name: &str,
687 position: LayoutPoint,
688 size: LayoutSize,
689 ) -> Self {
690 use core::hash::{Hash, Hasher};
691
692 struct FnvHasher(u64);
694
695 impl Hasher for FnvHasher {
696 fn write(&mut self, bytes: &[u8]) {
697 const FNV_PRIME: u64 = 0x100000001b3;
698 for &byte in bytes {
699 self.0 ^= byte as u64;
700 self.0 = self.0.wrapping_mul(FNV_PRIME);
701 }
702 }
703
704 fn finish(&self) -> u64 {
705 self.0
706 }
707 }
708
709 const FNV_OFFSET_BASIS: u64 = 0xcbf29ce484222325;
710 let mut hasher = FnvHasher(FNV_OFFSET_BASIS);
711
712 name.hash(&mut hasher);
714 (position.x as i64).hash(&mut hasher);
715 (position.y as i64).hash(&mut hasher);
716 (size.width as i64).hash(&mut hasher);
717 (size.height as i64).hash(&mut hasher);
718
719 Self {
720 index,
721 hash: hasher.finish(),
722 }
723 }
724}
725
726impl_option!(
727 MonitorId,
728 OptionMonitorId,
729 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
730);
731
732#[derive(Debug, PartialEq, PartialOrd, Clone)]
734#[repr(C)]
735pub struct Monitor {
736 pub monitor_id: MonitorId,
738 pub monitor_name: OptionString,
740 pub size: LayoutSize,
742 pub position: LayoutPoint,
744 pub scale_factor: f64,
746 pub work_area: LayoutRect,
748 pub video_modes: VideoModeVec,
750 pub is_primary_monitor: bool,
752}
753
754impl_vec!(
755 Monitor,
756 MonitorVec,
757 MonitorVecDestructor,
758 MonitorVecDestructorType
759);
760impl_vec_debug!(Monitor, MonitorVec);
761impl_vec_clone!(Monitor, MonitorVec, MonitorVecDestructor);
762impl_vec_partialeq!(Monitor, MonitorVec);
763impl_vec_partialord!(Monitor, MonitorVec);
764
765impl core::hash::Hash for Monitor {
766 fn hash<H>(&self, state: &mut H)
767 where
768 H: core::hash::Hasher,
769 {
770 self.monitor_id.hash(state)
771 }
772}
773
774impl Default for Monitor {
775 fn default() -> Self {
776 Monitor {
777 monitor_id: MonitorId::PRIMARY,
778 monitor_name: OptionString::None,
779 size: LayoutSize::zero(),
780 position: LayoutPoint::zero(),
781 scale_factor: 1.0,
782 work_area: LayoutRect::zero(),
783 video_modes: Vec::new().into(),
784 is_primary_monitor: false,
785 }
786 }
787}
788#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
789#[repr(C)]
790pub struct VideoMode {
791 pub size: LayoutSize,
792 pub bit_depth: u16,
793 pub refresh_rate: u16,
794}
795
796impl_vec!(
797 VideoMode,
798 VideoModeVec,
799 VideoModeVecDestructor,
800 VideoModeVecDestructorType
801);
802impl_vec_clone!(VideoMode, VideoModeVec, VideoModeVecDestructor);
803impl_vec_debug!(VideoMode, VideoModeVec);
804impl_vec_partialeq!(VideoMode, VideoModeVec);
805impl_vec_partialord!(VideoMode, VideoModeVec);
806
807#[derive(Debug, Copy, Clone, PartialEq)]
808#[repr(C, u8)]
809pub enum WindowPosition {
810 Uninitialized,
811 Initialized(PhysicalPositionI32),
812}
813
814impl Default for WindowPosition {
815 fn default() -> WindowPosition {
816 WindowPosition::Uninitialized
817 }
818}
819
820#[derive(Debug, Copy, Clone, PartialEq)]
821#[repr(C, u8)]
822pub enum ImePosition {
824 Uninitialized,
825 Initialized(LogicalRect),
826}
827
828impl Default for ImePosition {
829 fn default() -> ImePosition {
830 ImePosition::Uninitialized
831 }
832}
833
834#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
835#[repr(C)]
836pub struct WindowFlags {
837 pub frame: WindowFrame,
839 pub close_requested: bool,
842 pub decorations: WindowDecorations,
844 pub is_visible: bool,
846 pub is_always_on_top: bool,
848 pub is_resizable: bool,
850 pub has_focus: bool,
852 pub background_material: WindowBackgroundMaterial,
854 pub smooth_scroll_enabled: bool,
856 pub autotab_enabled: bool,
858 pub window_type: WindowType,
860 pub has_decorations: bool,
863 pub use_native_menus: bool,
866 pub use_native_context_menus: bool,
869 pub is_top_level: bool,
873 pub prevent_system_sleep: bool,
877}
878
879impl_option!(
880 WindowFlags,
881 OptionWindowFlags,
882 copy = false,
883 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
884);
885
886#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
888#[repr(C)]
889pub enum WindowType {
890 Normal,
892 Menu,
894 Tooltip,
896 Dialog,
898}
899
900impl Default for WindowType {
901 fn default() -> Self {
902 Self::Normal
903 }
904}
905
906#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
907#[repr(C)]
908pub enum WindowFrame {
909 Normal,
910 Minimized,
911 Maximized,
912 Fullscreen,
913}
914
915#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
917#[repr(C)]
918pub enum WindowDecorations {
919 Normal,
921 NoTitle,
923 NoControls,
925 None,
927}
928
929impl Default for WindowDecorations {
930 fn default() -> Self {
931 Self::Normal
932 }
933}
934
935#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
937#[repr(C)]
938pub enum WindowBackgroundMaterial {
939 Opaque,
941 Transparent,
943 Sidebar,
945 Menu,
947 HUD,
949 Titlebar,
951 MicaAlt,
953}
954
955impl Default for WindowBackgroundMaterial {
956 fn default() -> Self {
957 Self::Opaque
958 }
959}
960
961impl Default for WindowFlags {
962 fn default() -> Self {
963 Self {
964 frame: WindowFrame::Normal,
965 close_requested: false,
966 decorations: WindowDecorations::Normal,
967 is_visible: true,
968 is_always_on_top: false,
969 is_resizable: true,
970 has_focus: true,
971 background_material: WindowBackgroundMaterial::Opaque,
972 smooth_scroll_enabled: true,
973 autotab_enabled: true,
974 window_type: WindowType::Normal,
975 has_decorations: false,
976 use_native_menus: cfg!(any(target_os = "windows", target_os = "macos")),
979 use_native_context_menus: cfg!(any(target_os = "windows", target_os = "macos")),
980 is_top_level: false,
981 prevent_system_sleep: false,
982 }
983 }
984}
985
986impl WindowFlags {
987 #[inline]
989 pub fn is_menu_window(&self) -> bool {
990 self.window_type == WindowType::Menu
991 }
992
993 #[inline]
995 pub fn is_tooltip_window(&self) -> bool {
996 self.window_type == WindowType::Tooltip
997 }
998
999 #[inline]
1001 pub fn is_dialog_window(&self) -> bool {
1002 self.window_type == WindowType::Dialog
1003 }
1004
1005 #[inline]
1007 pub fn window_has_focus(&self) -> bool {
1008 self.has_focus
1009 }
1010
1011 #[inline]
1013 pub fn is_close_requested(&self) -> bool {
1014 self.close_requested
1015 }
1016
1017 #[inline]
1019 pub fn has_csd(&self) -> bool {
1020 self.has_decorations
1021 }
1022
1023 #[inline]
1025 pub fn use_native_menus(&self) -> bool {
1026 self.use_native_menus
1027 }
1028
1029 #[inline]
1031 pub fn use_native_context_menus(&self) -> bool {
1032 self.use_native_context_menus
1033 }
1034}
1035
1036#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
1037#[repr(C)]
1038pub struct PlatformSpecificOptions {
1039 pub windows_options: WindowsWindowOptions,
1040 pub linux_options: LinuxWindowOptions,
1041 pub mac_options: MacWindowOptions,
1042 pub wasm_options: WasmWindowOptions,
1043}
1044
1045unsafe impl Sync for PlatformSpecificOptions {}
1046unsafe impl Send for PlatformSpecificOptions {}
1047
1048#[derive(Debug, Clone, PartialEq, PartialOrd)]
1049#[repr(C)]
1050pub struct WindowsWindowOptions {
1051 pub allow_drag_and_drop: bool,
1053 pub no_redirection_bitmap: bool,
1055 pub window_icon: OptionWindowIcon,
1057 pub taskbar_icon: OptionTaskBarIcon,
1061 pub parent_window: OptionHwndHandle,
1063}
1064
1065impl Default for WindowsWindowOptions {
1066 fn default() -> WindowsWindowOptions {
1067 WindowsWindowOptions {
1068 allow_drag_and_drop: true,
1069 no_redirection_bitmap: false,
1070 window_icon: OptionWindowIcon::None,
1071 taskbar_icon: OptionTaskBarIcon::None,
1072 parent_window: OptionHwndHandle::None,
1073 }
1074 }
1075}
1076
1077pub type HwndHandle = *mut c_void;
1079
1080impl_option!(
1081 HwndHandle,
1082 OptionHwndHandle,
1083 copy = false,
1084 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1085);
1086
1087#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1090#[repr(C)]
1091pub enum XWindowType {
1092 Desktop,
1096 Dock,
1099 Toolbar,
1101 Menu,
1103 Utility,
1105 Splash,
1107 Dialog,
1109 DropdownMenu,
1112 PopupMenu,
1115 Tooltip,
1118 Notification,
1121 Combo,
1124 Dnd,
1127 Normal,
1129}
1130
1131impl Default for XWindowType {
1132 fn default() -> Self {
1133 XWindowType::Normal
1134 }
1135}
1136
1137#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1138#[repr(C)]
1139pub enum UserAttentionType {
1140 None,
1141 Critical,
1142 Informational,
1143}
1144
1145impl Default for UserAttentionType {
1146 fn default() -> UserAttentionType {
1147 UserAttentionType::None
1148 }
1149}
1150
1151#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1153#[repr(C)]
1154pub struct LinuxDecorationsState {
1155 pub is_dragging_titlebar: bool,
1156 pub close_button_hover: bool,
1157 pub maximize_button_hover: bool,
1158 pub minimize_button_hover: bool,
1159}
1160
1161impl_option!(
1162 LinuxDecorationsState,
1163 OptionLinuxDecorationsState,
1164 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
1165);
1166
1167#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
1168#[repr(C)]
1169pub struct LinuxWindowOptions {
1170 pub x11_visual: OptionX11Visual,
1172 pub x11_screen: OptionI32,
1174 pub x11_wm_classes: StringPairVec,
1177 pub x11_override_redirect: bool,
1180 pub x11_window_types: XWindowTypeVec,
1183 pub x11_gtk_theme_variant: OptionString,
1186 pub x11_resize_increments: OptionLogicalSize,
1189 pub x11_base_size: OptionLogicalSize,
1192 pub wayland_app_id: OptionString,
1199 pub wayland_theme: OptionWaylandTheme,
1200 pub request_user_attention: UserAttentionType,
1201 pub window_icon: OptionWindowIcon,
1202 pub x11_decorations_state: OptionLinuxDecorationsState,
1204}
1205
1206pub type X11Visual = *const c_void;
1207impl_option!(
1208 X11Visual,
1209 OptionX11Visual,
1210 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1211);
1212
1213#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1214#[repr(C)]
1215pub struct AzStringPair {
1216 pub key: AzString,
1217 pub value: AzString,
1218}
1219
1220impl_vec!(
1221 AzStringPair,
1222 StringPairVec,
1223 StringPairVecDestructor,
1224 StringPairVecDestructorType
1225);
1226impl_vec_mut!(AzStringPair, StringPairVec);
1227impl_vec_debug!(AzStringPair, StringPairVec);
1228impl_vec_partialord!(AzStringPair, StringPairVec);
1229impl_vec_ord!(AzStringPair, StringPairVec);
1230impl_vec_clone!(AzStringPair, StringPairVec, StringPairVecDestructor);
1231impl_vec_partialeq!(AzStringPair, StringPairVec);
1232impl_vec_eq!(AzStringPair, StringPairVec);
1233impl_vec_hash!(AzStringPair, StringPairVec);
1234
1235impl_option!(
1236 StringPairVec,
1237 OptionStringPairVec,
1238 copy = false,
1239 [Debug, Clone, PartialOrd, PartialEq, Ord, Eq, Hash]
1240);
1241
1242impl StringPairVec {
1243 pub fn get_key(&self, search_key: &str) -> Option<&AzString> {
1244 self.as_ref().iter().find_map(|v| {
1245 if v.key.as_str() == search_key {
1246 Some(&v.value)
1247 } else {
1248 None
1249 }
1250 })
1251 }
1252 pub fn get_key_mut(&mut self, search_key: &str) -> Option<&mut AzStringPair> {
1253 self.as_mut()
1254 .iter_mut()
1255 .find(|v| v.key.as_str() == search_key)
1256 }
1257 pub fn insert_kv<I: Into<AzString>>(&mut self, key: I, value: I) {
1258 let key = key.into();
1259 let value = value.into();
1260 match self.get_key_mut(key.as_str()) {
1261 None => {}
1262 Some(s) => {
1263 s.value = value;
1264 return;
1265 }
1266 }
1267 self.push(AzStringPair { key, value });
1268 }
1269}
1270
1271impl_vec!(
1272 XWindowType,
1273 XWindowTypeVec,
1274 XWindowTypeVecDestructor,
1275 XWindowTypeVecDestructorType
1276);
1277impl_vec_debug!(XWindowType, XWindowTypeVec);
1278impl_vec_partialord!(XWindowType, XWindowTypeVec);
1279impl_vec_ord!(XWindowType, XWindowTypeVec);
1280impl_vec_clone!(XWindowType, XWindowTypeVec, XWindowTypeVecDestructor);
1281impl_vec_partialeq!(XWindowType, XWindowTypeVec);
1282impl_vec_eq!(XWindowType, XWindowTypeVec);
1283impl_vec_hash!(XWindowType, XWindowTypeVec);
1284
1285impl_option!(
1286 WaylandTheme,
1287 OptionWaylandTheme,
1288 copy = false,
1289 [Debug, Clone, PartialEq, PartialOrd]
1290);
1291
1292#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1293#[repr(C)]
1294pub struct MacWindowOptions {
1295 pub _reserved: u8,
1297}
1298
1299#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1300#[repr(C)]
1301pub struct WasmWindowOptions {
1302 pub _reserved: u8,
1304}
1305
1306#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1307#[repr(C)]
1308pub enum FullScreenMode {
1309 SlowFullScreen,
1312 FastFullScreen,
1315 SlowWindowed,
1318 FastWindowed,
1321}
1322
1323#[derive(Debug, Clone, PartialEq, PartialOrd)]
1326#[repr(C)]
1327pub struct WaylandTheme {
1328 pub title_bar_active_background_color: ColorU,
1329 pub title_bar_active_separator_color: ColorU,
1330 pub title_bar_active_text_color: ColorU,
1331 pub title_bar_inactive_background_color: ColorU,
1332 pub title_bar_inactive_separator_color: ColorU,
1333 pub title_bar_inactive_text_color: ColorU,
1334 pub maximize_idle_foreground_inactive_color: ColorU,
1335 pub minimize_idle_foreground_inactive_color: ColorU,
1336 pub close_idle_foreground_inactive_color: ColorU,
1337 pub maximize_hovered_foreground_inactive_color: ColorU,
1338 pub minimize_hovered_foreground_inactive_color: ColorU,
1339 pub close_hovered_foreground_inactive_color: ColorU,
1340 pub maximize_disabled_foreground_inactive_color: ColorU,
1341 pub minimize_disabled_foreground_inactive_color: ColorU,
1342 pub close_disabled_foreground_inactive_color: ColorU,
1343 pub maximize_idle_background_inactive_color: ColorU,
1344 pub minimize_idle_background_inactive_color: ColorU,
1345 pub close_idle_background_inactive_color: ColorU,
1346 pub maximize_hovered_background_inactive_color: ColorU,
1347 pub minimize_hovered_background_inactive_color: ColorU,
1348 pub close_hovered_background_inactive_color: ColorU,
1349 pub maximize_disabled_background_inactive_color: ColorU,
1350 pub minimize_disabled_background_inactive_color: ColorU,
1351 pub close_disabled_background_inactive_color: ColorU,
1352 pub maximize_idle_foreground_active_color: ColorU,
1353 pub minimize_idle_foreground_active_color: ColorU,
1354 pub close_idle_foreground_active_color: ColorU,
1355 pub maximize_hovered_foreground_active_color: ColorU,
1356 pub minimize_hovered_foreground_active_color: ColorU,
1357 pub close_hovered_foreground_active_color: ColorU,
1358 pub maximize_disabled_foreground_active_color: ColorU,
1359 pub minimize_disabled_foreground_active_color: ColorU,
1360 pub close_disabled_foreground_active_color: ColorU,
1361 pub maximize_idle_background_active_color: ColorU,
1362 pub minimize_idle_background_active_color: ColorU,
1363 pub close_idle_background_active_color: ColorU,
1364 pub maximize_hovered_background_active_color: ColorU,
1365 pub minimize_hovered_background_active_color: ColorU,
1366 pub close_hovered_background_active_color: ColorU,
1367 pub maximize_disabled_background_active_color: ColorU,
1368 pub minimize_disabled_background_active_color: ColorU,
1369 pub close_disabled_background_active_color: ColorU,
1370 pub title_bar_font: AzString,
1371 pub title_bar_font_size: f32,
1372}
1373
1374#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
1375#[repr(C)]
1376pub struct WindowSize {
1377 pub dimensions: LogicalSize,
1380 pub dpi: u32,
1382 pub min_dimensions: OptionLogicalSize,
1384 pub max_dimensions: OptionLogicalSize,
1386}
1387
1388impl WindowSize {
1389 pub fn get_layout_size(&self) -> LayoutSize {
1390 LayoutSize::new(
1391 libm::roundf(self.dimensions.width) as isize,
1392 libm::roundf(self.dimensions.height) as isize,
1393 )
1394 }
1395
1396 pub fn get_logical_size(&self) -> LogicalSize {
1398 self.dimensions
1399 }
1400
1401 pub fn get_physical_size(&self) -> PhysicalSize<u32> {
1402 self.dimensions
1403 .to_physical(self.get_hidpi_factor().inner.get())
1404 }
1405
1406 pub fn get_hidpi_factor(&self) -> DpiScaleFactor {
1407 DpiScaleFactor {
1408 inner: FloatValue::new(self.dpi as f32 / 96.0),
1409 }
1410 }
1411}
1412
1413impl Default for WindowSize {
1414 fn default() -> Self {
1415 Self {
1416 #[cfg(not(feature = "glow"))]
1417 dimensions: LogicalSize::new(640.0, 480.0),
1418 dpi: 96,
1419 min_dimensions: None.into(),
1420 max_dimensions: None.into(),
1421 }
1422 }
1423}
1424
1425#[repr(C)]
1426#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1427pub enum RendererType {
1428 Hardware,
1430 Software,
1432}
1433
1434impl_option!(
1435 RendererType,
1436 OptionRendererType,
1437 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
1438);
1439
1440#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1441pub enum UpdateFocusWarning {
1442 FocusInvalidDomId(DomId),
1443 FocusInvalidNodeId(NodeHierarchyItemId),
1444 CouldNotFindFocusNode(CssPath),
1445}
1446
1447impl ::core::fmt::Display for UpdateFocusWarning {
1448 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1449 use self::UpdateFocusWarning::*;
1450 match self {
1451 FocusInvalidDomId(dom_id) => write!(f, "Focusing on DOM with invalid ID: {:?}", dom_id),
1452 FocusInvalidNodeId(node_id) => {
1453 write!(f, "Focusing on node with invalid ID: {}", node_id)
1454 }
1455 CouldNotFindFocusNode(css_path) => {
1456 write!(f, "Could not find focus node for path: {}", css_path)
1457 }
1458 }
1459 }
1460}
1461
1462#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1464#[repr(C, u8)]
1465pub enum AcceleratorKey {
1466 Ctrl,
1467 Alt,
1468 Shift,
1469 Key(VirtualKeyCode),
1470}
1471
1472impl AcceleratorKey {
1473 pub fn matches(&self, keyboard_state: &KeyboardState) -> bool {
1477 use self::AcceleratorKey::*;
1478 match self {
1479 Ctrl => keyboard_state.ctrl_down(),
1480 Alt => keyboard_state.alt_down(),
1481 Shift => keyboard_state.shift_down(),
1482 Key(k) => keyboard_state.is_key_down(*k),
1483 }
1484 }
1485}
1486
1487#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1489#[repr(C)]
1490pub enum VirtualKeyCode {
1491 Key1,
1492 Key2,
1493 Key3,
1494 Key4,
1495 Key5,
1496 Key6,
1497 Key7,
1498 Key8,
1499 Key9,
1500 Key0,
1501 A,
1502 B,
1503 C,
1504 D,
1505 E,
1506 F,
1507 G,
1508 H,
1509 I,
1510 J,
1511 K,
1512 L,
1513 M,
1514 N,
1515 O,
1516 P,
1517 Q,
1518 R,
1519 S,
1520 T,
1521 U,
1522 V,
1523 W,
1524 X,
1525 Y,
1526 Z,
1527 Escape,
1528 F1,
1529 F2,
1530 F3,
1531 F4,
1532 F5,
1533 F6,
1534 F7,
1535 F8,
1536 F9,
1537 F10,
1538 F11,
1539 F12,
1540 F13,
1541 F14,
1542 F15,
1543 F16,
1544 F17,
1545 F18,
1546 F19,
1547 F20,
1548 F21,
1549 F22,
1550 F23,
1551 F24,
1552 Snapshot,
1553 Scroll,
1554 Pause,
1555 Insert,
1556 Home,
1557 Delete,
1558 End,
1559 PageDown,
1560 PageUp,
1561 Left,
1562 Up,
1563 Right,
1564 Down,
1565 Back,
1566 Return,
1567 Space,
1568 Compose,
1569 Caret,
1570 Numlock,
1571 Numpad0,
1572 Numpad1,
1573 Numpad2,
1574 Numpad3,
1575 Numpad4,
1576 Numpad5,
1577 Numpad6,
1578 Numpad7,
1579 Numpad8,
1580 Numpad9,
1581 NumpadAdd,
1582 NumpadDivide,
1583 NumpadDecimal,
1584 NumpadComma,
1585 NumpadEnter,
1586 NumpadEquals,
1587 NumpadMultiply,
1588 NumpadSubtract,
1589 AbntC1,
1590 AbntC2,
1591 Apostrophe,
1592 Apps,
1593 Asterisk,
1594 At,
1595 Ax,
1596 Backslash,
1597 Calculator,
1598 Capital,
1599 Colon,
1600 Comma,
1601 Convert,
1602 Equals,
1603 Grave,
1604 Kana,
1605 Kanji,
1606 LAlt,
1607 LBracket,
1608 LControl,
1609 LShift,
1610 LWin,
1611 Mail,
1612 MediaSelect,
1613 MediaStop,
1614 Minus,
1615 Mute,
1616 MyComputer,
1617 NavigateForward,
1618 NavigateBackward,
1619 NextTrack,
1620 NoConvert,
1621 OEM102,
1622 Period,
1623 PlayPause,
1624 Plus,
1625 Power,
1626 PrevTrack,
1627 RAlt,
1628 RBracket,
1629 RControl,
1630 RShift,
1631 RWin,
1632 Semicolon,
1633 Slash,
1634 Sleep,
1635 Stop,
1636 Sysrq,
1637 Tab,
1638 Underline,
1639 Unlabeled,
1640 VolumeDown,
1641 VolumeUp,
1642 Wake,
1643 WebBack,
1644 WebFavorites,
1645 WebForward,
1646 WebHome,
1647 WebRefresh,
1648 WebSearch,
1649 WebStop,
1650 Yen,
1651 Copy,
1652 Paste,
1653 Cut,
1654}
1655
1656impl VirtualKeyCode {
1657 pub fn get_lowercase(&self) -> Option<char> {
1658 use self::VirtualKeyCode::*;
1659 match self {
1660 A => Some('a'),
1661 B => Some('b'),
1662 C => Some('c'),
1663 D => Some('d'),
1664 E => Some('e'),
1665 F => Some('f'),
1666 G => Some('g'),
1667 H => Some('h'),
1668 I => Some('i'),
1669 J => Some('j'),
1670 K => Some('k'),
1671 L => Some('l'),
1672 M => Some('m'),
1673 N => Some('n'),
1674 O => Some('o'),
1675 P => Some('p'),
1676 Q => Some('q'),
1677 R => Some('r'),
1678 S => Some('s'),
1679 T => Some('t'),
1680 U => Some('u'),
1681 V => Some('v'),
1682 W => Some('w'),
1683 X => Some('x'),
1684 Y => Some('y'),
1685 Z => Some('z'),
1686 Key0 | Numpad0 => Some('0'),
1687 Key1 | Numpad1 => Some('1'),
1688 Key2 | Numpad2 => Some('2'),
1689 Key3 | Numpad3 => Some('3'),
1690 Key4 | Numpad4 => Some('4'),
1691 Key5 | Numpad5 => Some('5'),
1692 Key6 | Numpad6 => Some('6'),
1693 Key7 | Numpad7 => Some('7'),
1694 Key8 | Numpad8 => Some('8'),
1695 Key9 | Numpad9 => Some('9'),
1696 Minus => Some('-'),
1697 Asterisk => Some('´'),
1698 At => Some('@'),
1699 Period => Some('.'),
1700 Semicolon => Some(';'),
1701 Slash => Some('/'),
1702 Caret => Some('^'),
1703 _ => None,
1704 }
1705 }
1706}
1707
1708#[derive(Debug, Clone)]
1710#[repr(C)]
1711pub struct SmallWindowIconBytes {
1712 pub key: IconKey,
1713 pub rgba_bytes: U8Vec,
1714}
1715
1716#[derive(Debug, Clone)]
1718#[repr(C)]
1719pub struct LargeWindowIconBytes {
1720 pub key: IconKey,
1721 pub rgba_bytes: U8Vec,
1722}
1723
1724#[derive(Debug, Clone)]
1726#[repr(C, u8)]
1727pub enum WindowIcon {
1728 Small(SmallWindowIconBytes),
1729 Large(LargeWindowIconBytes),
1731}
1732
1733impl_option!(
1734 WindowIcon,
1735 OptionWindowIcon,
1736 copy = false,
1737 [Debug, Clone, PartialOrd, PartialEq, Eq, Hash, Ord]
1738);
1739
1740impl WindowIcon {
1741 pub fn get_key(&self) -> IconKey {
1742 match &self {
1743 WindowIcon::Small(SmallWindowIconBytes { key, .. }) => *key,
1744 WindowIcon::Large(LargeWindowIconBytes { key, .. }) => *key,
1745 }
1746 }
1747}
1748impl PartialEq for WindowIcon {
1751 fn eq(&self, rhs: &Self) -> bool {
1752 self.get_key() == rhs.get_key()
1753 }
1754}
1755
1756impl PartialOrd for WindowIcon {
1757 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1758 Some((self.get_key()).cmp(&rhs.get_key()))
1759 }
1760}
1761
1762impl Eq for WindowIcon {}
1763
1764impl Ord for WindowIcon {
1765 fn cmp(&self, rhs: &Self) -> Ordering {
1766 (self.get_key()).cmp(&rhs.get_key())
1767 }
1768}
1769
1770impl Hash for WindowIcon {
1771 fn hash<H>(&self, state: &mut H)
1772 where
1773 H: Hasher,
1774 {
1775 self.get_key().hash(state);
1776 }
1777}
1778
1779#[derive(Debug, Clone)]
1781#[repr(C)]
1782pub struct TaskBarIcon {
1783 pub key: IconKey,
1784 pub rgba_bytes: U8Vec,
1785}
1786
1787impl_option!(
1788 TaskBarIcon,
1789 OptionTaskBarIcon,
1790 copy = false,
1791 [Debug, Clone, PartialOrd, PartialEq, Eq, Hash, Ord]
1792);
1793
1794impl PartialEq for TaskBarIcon {
1795 fn eq(&self, rhs: &Self) -> bool {
1796 self.key == rhs.key
1797 }
1798}
1799
1800impl PartialOrd for TaskBarIcon {
1801 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1802 Some((self.key).cmp(&rhs.key))
1803 }
1804}
1805
1806impl Eq for TaskBarIcon {}
1807
1808impl Ord for TaskBarIcon {
1809 fn cmp(&self, rhs: &Self) -> Ordering {
1810 (self.key).cmp(&rhs.key)
1811 }
1812}
1813
1814impl Hash for TaskBarIcon {
1815 fn hash<H>(&self, state: &mut H)
1816 where
1817 H: Hasher,
1818 {
1819 self.key.hash(state);
1820 }
1821}