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