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, OptionU32, 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!(VirtualKeyCode, VirtualKeyCodeVec, VirtualKeyCodeVecDestructor, VirtualKeyCodeVecDestructorType, VirtualKeyCodeVecSlice, OptionVirtualKeyCode);
370impl_vec_debug!(VirtualKeyCode, VirtualKeyCodeVec);
371impl_vec_partialord!(VirtualKeyCode, VirtualKeyCodeVec);
372impl_vec_ord!(VirtualKeyCode, VirtualKeyCodeVec);
373impl_vec_clone!(
374 VirtualKeyCode,
375 VirtualKeyCodeVec,
376 VirtualKeyCodeVecDestructor
377);
378impl_vec_partialeq!(VirtualKeyCode, VirtualKeyCodeVec);
379impl_vec_eq!(VirtualKeyCode, VirtualKeyCodeVec);
380impl_vec_hash!(VirtualKeyCode, VirtualKeyCodeVec);
381
382impl_vec_as_hashmap!(VirtualKeyCode, VirtualKeyCodeVec);
383
384impl_vec!(ScanCode, ScanCodeVec, ScanCodeVecDestructor, ScanCodeVecDestructorType, ScanCodeVecSlice, OptionU32);
385impl_vec_debug!(ScanCode, ScanCodeVec);
386impl_vec_partialord!(ScanCode, ScanCodeVec);
387impl_vec_ord!(ScanCode, ScanCodeVec);
388impl_vec_clone!(ScanCode, ScanCodeVec, ScanCodeVecDestructor);
389impl_vec_partialeq!(ScanCode, ScanCodeVec);
390impl_vec_eq!(ScanCode, ScanCodeVec);
391impl_vec_hash!(ScanCode, ScanCodeVec);
392
393impl_vec_as_hashmap!(ScanCode, ScanCodeVec);
394
395#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
397#[repr(C)]
398pub struct MouseState {
399 pub mouse_cursor_type: OptionMouseCursorType,
401 pub cursor_position: CursorPosition,
404 pub is_cursor_locked: bool,
407 pub left_down: bool,
409 pub right_down: bool,
411 pub middle_down: bool,
413}
414
415impl MouseState {
416 pub fn matches(&self, context: &ContextMenuMouseButton) -> bool {
417 use self::ContextMenuMouseButton::*;
418 match context {
419 Left => self.left_down,
420 Right => self.right_down,
421 Middle => self.middle_down,
422 }
423 }
424}
425
426impl_option!(
427 MouseState,
428 OptionMouseState,
429 [Debug, Copy, Clone, PartialEq, PartialOrd]
430);
431
432impl_option!(
433 MouseCursorType,
434 OptionMouseCursorType,
435 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
436);
437
438impl Default for MouseState {
439 fn default() -> Self {
440 Self {
441 mouse_cursor_type: Some(MouseCursorType::Default).into(),
442 cursor_position: CursorPosition::default(),
443 is_cursor_locked: false,
444 left_down: false,
445 right_down: false,
446 middle_down: false,
447 }
448 }
449}
450
451#[derive(Debug, Clone, PartialEq, PartialOrd, Hash, Eq, Ord)]
452#[repr(C)]
453pub struct VirtualKeyCodeCombo {
454 pub keys: VirtualKeyCodeVec,
455}
456
457impl_option!(
458 VirtualKeyCodeCombo,
459 OptionVirtualKeyCodeCombo,
460 copy = false,
461 [Debug, Clone, PartialEq, PartialOrd, Hash, Eq, Ord]
462);
463
464#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Hash, Eq, Ord)]
465#[repr(C)]
466pub enum ContextMenuMouseButton {
467 Right,
468 Middle,
469 Left,
470}
471
472impl Default for ContextMenuMouseButton {
473 fn default() -> Self {
474 ContextMenuMouseButton::Right
475 }
476}
477
478impl MouseState {
479 pub fn mouse_down(&self) -> bool {
481 self.right_down || self.left_down || self.middle_down
482 }
483}
484
485#[derive(Debug)]
487pub struct ScrollResult {}
488
489#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
490#[repr(C, u8)]
491pub enum CursorPosition {
492 OutOfWindow(LogicalPosition),
493 Uninitialized,
494 InWindow(LogicalPosition),
495}
496
497impl Default for CursorPosition {
498 fn default() -> CursorPosition {
499 CursorPosition::Uninitialized
500 }
501}
502
503impl CursorPosition {
504 pub fn get_position(&self) -> Option<LogicalPosition> {
505 match self {
506 CursorPosition::InWindow(logical_pos) => Some(*logical_pos),
507 CursorPosition::OutOfWindow(_) | CursorPosition::Uninitialized => None,
508 }
509 }
510
511 pub fn is_inside_window(&self) -> bool {
512 self.get_position().is_some()
513 }
514}
515
516#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
519#[repr(C)]
520pub struct DebugState {
521 pub profiler_dbg: bool,
522 pub render_target_dbg: bool,
523 pub texture_cache_dbg: bool,
524 pub gpu_time_queries: bool,
525 pub gpu_sample_queries: bool,
526 pub disable_batching: bool,
527 pub epochs: bool,
528 pub echo_driver_messages: bool,
529 pub show_overdraw: bool,
530 pub gpu_cache_dbg: bool,
531 pub texture_cache_dbg_clear_evicted: bool,
532 pub picture_caching_dbg: bool,
533 pub primitive_dbg: bool,
534 pub zoom_dbg: bool,
535 pub small_screen: bool,
536 pub disable_opaque_pass: bool,
537 pub disable_alpha_pass: bool,
538 pub disable_clip_masks: bool,
539 pub disable_text_prims: bool,
540 pub disable_gradient_prims: bool,
541 pub obscure_images: bool,
542 pub glyph_flashing: bool,
543 pub smart_profiler: bool,
544 pub invalidation_dbg: bool,
545 pub tile_cache_logging_dbg: bool,
546 pub profiler_capture: bool,
547 pub force_picture_invalidation: bool,
548}
549
550fn translate_cursor(cursor: StyleCursor) -> MouseCursorType {
551 use azul_css::props::style::effects::StyleCursor;
552 match cursor {
553 StyleCursor::Default => MouseCursorType::Default,
554 StyleCursor::Crosshair => MouseCursorType::Crosshair,
555 StyleCursor::Pointer => MouseCursorType::Hand,
556 StyleCursor::Move => MouseCursorType::Move,
557 StyleCursor::Text => MouseCursorType::Text,
558 StyleCursor::Wait => MouseCursorType::Wait,
559 StyleCursor::Help => MouseCursorType::Help,
560 StyleCursor::Progress => MouseCursorType::Progress,
561 StyleCursor::ContextMenu => MouseCursorType::ContextMenu,
562 StyleCursor::Cell => MouseCursorType::Cell,
563 StyleCursor::VerticalText => MouseCursorType::VerticalText,
564 StyleCursor::Alias => MouseCursorType::Alias,
565 StyleCursor::Copy => MouseCursorType::Copy,
566 StyleCursor::Grab => MouseCursorType::Grab,
567 StyleCursor::Grabbing => MouseCursorType::Grabbing,
568 StyleCursor::AllScroll => MouseCursorType::AllScroll,
569 StyleCursor::ZoomIn => MouseCursorType::ZoomIn,
570 StyleCursor::ZoomOut => MouseCursorType::ZoomOut,
571 StyleCursor::EResize => MouseCursorType::EResize,
572 StyleCursor::NResize => MouseCursorType::NResize,
573 StyleCursor::SResize => MouseCursorType::SResize,
574 StyleCursor::SeResize => MouseCursorType::SeResize,
575 StyleCursor::WResize => MouseCursorType::WResize,
576 StyleCursor::EwResize => MouseCursorType::EwResize,
577 StyleCursor::NsResize => MouseCursorType::NsResize,
578 StyleCursor::NeswResize => MouseCursorType::NeswResize,
579 StyleCursor::NwseResize => MouseCursorType::NwseResize,
580 StyleCursor::ColResize => MouseCursorType::ColResize,
581 StyleCursor::RowResize => MouseCursorType::RowResize,
582 StyleCursor::Unset => MouseCursorType::Default,
583 }
584}
585
586#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Hash, Ord, Eq)]
587#[repr(C)]
588pub struct TouchState {
589 pub num_touches: usize,
591}
592
593#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
595#[repr(C)]
596pub struct TouchPoint {
597 pub id: u64,
599 pub position: LogicalPosition,
601 pub force: f32,
604}
605
606impl_option!(
607 TouchPoint,
608 OptionTouchPoint,
609 [Debug, Copy, Clone, PartialEq, PartialOrd]
610);
611
612impl_vec!(TouchPoint, TouchPointVec, TouchPointVecDestructor, TouchPointVecDestructorType, TouchPointVecSlice, OptionTouchPoint);
613impl_vec_debug!(TouchPoint, TouchPointVec);
614impl_vec_clone!(TouchPoint, TouchPointVec, TouchPointVecDestructor);
615impl_vec_partialeq!(TouchPoint, TouchPointVec);
616
617#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Hash, Ord, Eq)]
619#[repr(C)]
620pub enum WindowTheme {
621 DarkMode,
622 LightMode,
623}
624
625impl Default for WindowTheme {
626 fn default() -> WindowTheme {
627 WindowTheme::LightMode }
629}
630
631impl_option!(
632 WindowTheme,
633 OptionWindowTheme,
634 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
635);
636
637#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
648#[repr(C)]
649pub struct MonitorId {
650 pub index: usize,
652 pub hash: u64,
654}
655
656impl MonitorId {
657 pub const PRIMARY: MonitorId = MonitorId { index: 0, hash: 0 };
659
660 pub const fn new(index: usize) -> Self {
662 Self { index, hash: 0 }
663 }
664
665 pub const fn from_index_and_hash(index: usize, hash: u64) -> Self {
667 Self { index, hash }
668 }
669
670 pub fn from_properties(
676 index: usize,
677 name: &str,
678 position: LayoutPoint,
679 size: LayoutSize,
680 ) -> Self {
681 use core::hash::{Hash, Hasher};
682
683 struct FnvHasher(u64);
685
686 impl Hasher for FnvHasher {
687 fn write(&mut self, bytes: &[u8]) {
688 const FNV_PRIME: u64 = 0x100000001b3;
689 for &byte in bytes {
690 self.0 ^= byte as u64;
691 self.0 = self.0.wrapping_mul(FNV_PRIME);
692 }
693 }
694
695 fn finish(&self) -> u64 {
696 self.0
697 }
698 }
699
700 const FNV_OFFSET_BASIS: u64 = 0xcbf29ce484222325;
701 let mut hasher = FnvHasher(FNV_OFFSET_BASIS);
702
703 name.hash(&mut hasher);
705 (position.x as i64).hash(&mut hasher);
706 (position.y as i64).hash(&mut hasher);
707 (size.width as i64).hash(&mut hasher);
708 (size.height as i64).hash(&mut hasher);
709
710 Self {
711 index,
712 hash: hasher.finish(),
713 }
714 }
715}
716
717impl_option!(
718 MonitorId,
719 OptionMonitorId,
720 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
721);
722
723#[derive(Debug, PartialEq, PartialOrd, Clone)]
725#[repr(C)]
726pub struct Monitor {
727 pub monitor_id: MonitorId,
729 pub monitor_name: OptionString,
731 pub size: LayoutSize,
733 pub position: LayoutPoint,
735 pub scale_factor: f64,
737 pub work_area: LayoutRect,
739 pub video_modes: VideoModeVec,
741 pub is_primary_monitor: bool,
743}
744
745impl_option!(
746 Monitor,
747 OptionMonitor,
748 copy = false,
749 [Debug, PartialEq, PartialOrd, Clone]
750);
751
752impl_vec!(Monitor, MonitorVec, MonitorVecDestructor, MonitorVecDestructorType, MonitorVecSlice, OptionMonitor);
753impl_vec_debug!(Monitor, MonitorVec);
754impl_vec_clone!(Monitor, MonitorVec, MonitorVecDestructor);
755impl_vec_partialeq!(Monitor, MonitorVec);
756impl_vec_partialord!(Monitor, MonitorVec);
757
758impl core::hash::Hash for Monitor {
759 fn hash<H>(&self, state: &mut H)
760 where
761 H: core::hash::Hasher,
762 {
763 self.monitor_id.hash(state)
764 }
765}
766
767impl Default for Monitor {
768 fn default() -> Self {
769 Monitor {
770 monitor_id: MonitorId::PRIMARY,
771 monitor_name: OptionString::None,
772 size: LayoutSize::zero(),
773 position: LayoutPoint::zero(),
774 scale_factor: 1.0,
775 work_area: LayoutRect::zero(),
776 video_modes: Vec::new().into(),
777 is_primary_monitor: false,
778 }
779 }
780}
781#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
782#[repr(C)]
783pub struct VideoMode {
784 pub size: LayoutSize,
785 pub bit_depth: u16,
786 pub refresh_rate: u16,
787}
788
789impl_option!(
790 VideoMode,
791 OptionVideoMode,
792 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
793);
794
795impl_vec!(VideoMode, VideoModeVec, VideoModeVecDestructor, VideoModeVecDestructorType, VideoModeVecSlice, OptionVideoMode);
796impl_vec_clone!(VideoMode, VideoModeVec, VideoModeVecDestructor);
797impl_vec_debug!(VideoMode, VideoModeVec);
798impl_vec_partialeq!(VideoMode, VideoModeVec);
799impl_vec_partialord!(VideoMode, VideoModeVec);
800
801#[derive(Debug, Copy, Clone, PartialEq)]
802#[repr(C, u8)]
803pub enum WindowPosition {
804 Uninitialized,
805 Initialized(PhysicalPositionI32),
806}
807
808impl Default for WindowPosition {
809 fn default() -> WindowPosition {
810 WindowPosition::Uninitialized
811 }
812}
813
814#[derive(Debug, Copy, Clone, PartialEq)]
815#[repr(C, u8)]
816pub enum ImePosition {
818 Uninitialized,
819 Initialized(LogicalRect),
820}
821
822impl Default for ImePosition {
823 fn default() -> ImePosition {
824 ImePosition::Uninitialized
825 }
826}
827
828#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
829#[repr(C)]
830pub struct WindowFlags {
831 pub frame: WindowFrame,
833 pub close_requested: bool,
836 pub decorations: WindowDecorations,
838 pub is_visible: bool,
840 pub is_always_on_top: bool,
842 pub is_resizable: bool,
844 pub has_focus: bool,
846 pub background_material: WindowBackgroundMaterial,
848 pub smooth_scroll_enabled: bool,
850 pub autotab_enabled: bool,
852 pub window_type: WindowType,
854 pub has_decorations: bool,
857 pub use_native_menus: bool,
860 pub use_native_context_menus: bool,
863 pub is_top_level: bool,
867 pub prevent_system_sleep: bool,
871}
872
873impl_option!(
874 WindowFlags,
875 OptionWindowFlags,
876 copy = false,
877 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
878);
879
880#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
882#[repr(C)]
883pub enum WindowType {
884 Normal,
886 Menu,
888 Tooltip,
890 Dialog,
892}
893
894impl Default for WindowType {
895 fn default() -> Self {
896 Self::Normal
897 }
898}
899
900#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
901#[repr(C)]
902pub enum WindowFrame {
903 Normal,
904 Minimized,
905 Maximized,
906 Fullscreen,
907}
908
909#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
911#[repr(C)]
912pub enum WindowDecorations {
913 Normal,
915 NoTitle,
918 NoTitleAutoInject,
926 NoControls,
928 None,
930}
931
932impl Default for WindowDecorations {
933 fn default() -> Self {
934 Self::Normal
935 }
936}
937
938#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
940#[repr(C)]
941pub enum WindowBackgroundMaterial {
942 Opaque,
944 Transparent,
946 Sidebar,
948 Menu,
950 HUD,
952 Titlebar,
954 MicaAlt,
956}
957
958impl Default for WindowBackgroundMaterial {
959 fn default() -> Self {
960 Self::Opaque
961 }
962}
963
964impl Default for WindowFlags {
965 fn default() -> Self {
966 Self {
967 frame: WindowFrame::Normal,
968 close_requested: false,
969 decorations: WindowDecorations::Normal,
970 is_visible: true,
971 is_always_on_top: false,
972 is_resizable: true,
973 has_focus: true,
974 background_material: WindowBackgroundMaterial::Opaque,
975 smooth_scroll_enabled: true,
976 autotab_enabled: true,
977 window_type: WindowType::Normal,
978 has_decorations: false,
979 use_native_menus: cfg!(any(target_os = "windows", target_os = "macos")),
982 use_native_context_menus: cfg!(any(target_os = "windows", target_os = "macos")),
983 is_top_level: false,
984 prevent_system_sleep: false,
985 }
986 }
987}
988
989impl WindowFlags {
990 #[inline]
992 pub fn is_menu_window(&self) -> bool {
993 self.window_type == WindowType::Menu
994 }
995
996 #[inline]
998 pub fn is_tooltip_window(&self) -> bool {
999 self.window_type == WindowType::Tooltip
1000 }
1001
1002 #[inline]
1004 pub fn is_dialog_window(&self) -> bool {
1005 self.window_type == WindowType::Dialog
1006 }
1007
1008 #[inline]
1010 pub fn window_has_focus(&self) -> bool {
1011 self.has_focus
1012 }
1013
1014 #[inline]
1016 pub fn is_close_requested(&self) -> bool {
1017 self.close_requested
1018 }
1019
1020 #[inline]
1022 pub fn has_csd(&self) -> bool {
1023 self.has_decorations
1024 }
1025
1026 #[inline]
1028 pub fn use_native_menus(&self) -> bool {
1029 self.use_native_menus
1030 }
1031
1032 #[inline]
1034 pub fn use_native_context_menus(&self) -> bool {
1035 self.use_native_context_menus
1036 }
1037}
1038
1039#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
1040#[repr(C)]
1041pub struct PlatformSpecificOptions {
1042 pub windows_options: WindowsWindowOptions,
1043 pub linux_options: LinuxWindowOptions,
1044 pub mac_options: MacWindowOptions,
1045 pub wasm_options: WasmWindowOptions,
1046}
1047
1048unsafe impl Sync for PlatformSpecificOptions {}
1049unsafe impl Send for PlatformSpecificOptions {}
1050
1051#[derive(Debug, Clone, PartialEq, PartialOrd)]
1052#[repr(C)]
1053pub struct WindowsWindowOptions {
1054 pub allow_drag_and_drop: bool,
1056 pub no_redirection_bitmap: bool,
1058 pub window_icon: OptionWindowIcon,
1060 pub taskbar_icon: OptionTaskBarIcon,
1064 pub parent_window: OptionHwndHandle,
1066}
1067
1068impl Default for WindowsWindowOptions {
1069 fn default() -> WindowsWindowOptions {
1070 WindowsWindowOptions {
1071 allow_drag_and_drop: true,
1072 no_redirection_bitmap: false,
1073 window_icon: OptionWindowIcon::None,
1074 taskbar_icon: OptionTaskBarIcon::None,
1075 parent_window: OptionHwndHandle::None,
1076 }
1077 }
1078}
1079
1080pub type HwndHandle = *mut c_void;
1082
1083impl_option!(
1084 HwndHandle,
1085 OptionHwndHandle,
1086 copy = false,
1087 [Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1088);
1089
1090#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1093#[repr(C)]
1094pub enum XWindowType {
1095 Desktop,
1099 Dock,
1102 Toolbar,
1104 Menu,
1106 Utility,
1108 Splash,
1110 Dialog,
1112 DropdownMenu,
1115 PopupMenu,
1118 Tooltip,
1121 Notification,
1124 Combo,
1127 Dnd,
1130 Normal,
1132}
1133
1134impl_option!(
1135 XWindowType,
1136 OptionXWindowType,
1137 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1138);
1139
1140impl Default for XWindowType {
1141 fn default() -> Self {
1142 XWindowType::Normal
1143 }
1144}
1145
1146#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1147#[repr(C)]
1148pub enum UserAttentionType {
1149 None,
1150 Critical,
1151 Informational,
1152}
1153
1154impl Default for UserAttentionType {
1155 fn default() -> UserAttentionType {
1156 UserAttentionType::None
1157 }
1158}
1159
1160#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1162#[repr(C)]
1163pub struct LinuxDecorationsState {
1164 pub is_dragging_titlebar: bool,
1165 pub close_button_hover: bool,
1166 pub maximize_button_hover: bool,
1167 pub minimize_button_hover: bool,
1168}
1169
1170impl_option!(
1171 LinuxDecorationsState,
1172 OptionLinuxDecorationsState,
1173 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
1174);
1175
1176#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
1177#[repr(C)]
1178pub struct LinuxWindowOptions {
1179 pub x11_visual: OptionX11Visual,
1181 pub x11_screen: OptionI32,
1183 pub x11_wm_classes: StringPairVec,
1186 pub x11_override_redirect: bool,
1189 pub x11_window_types: XWindowTypeVec,
1192 pub x11_gtk_theme_variant: OptionString,
1195 pub x11_resize_increments: OptionLogicalSize,
1198 pub x11_base_size: OptionLogicalSize,
1201 pub wayland_app_id: OptionString,
1208 pub wayland_theme: OptionWaylandTheme,
1209 pub request_user_attention: UserAttentionType,
1210 pub window_icon: OptionWindowIcon,
1211 pub x11_decorations_state: OptionLinuxDecorationsState,
1213}
1214
1215pub type X11Visual = *const c_void;
1216impl_option!(
1217 X11Visual,
1218 OptionX11Visual,
1219 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
1220);
1221
1222#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1223#[repr(C)]
1224pub struct AzStringPair {
1225 pub key: AzString,
1226 pub value: AzString,
1227}
1228
1229impl_option!(
1230 AzStringPair,
1231 OptionStringPair,
1232 copy = false,
1233 [Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash]
1234);
1235
1236impl_vec!(AzStringPair, StringPairVec, StringPairVecDestructor, StringPairVecDestructorType, StringPairVecSlice, OptionStringPair);
1237impl_vec_mut!(AzStringPair, StringPairVec);
1238impl_vec_debug!(AzStringPair, StringPairVec);
1239impl_vec_partialord!(AzStringPair, StringPairVec);
1240impl_vec_ord!(AzStringPair, StringPairVec);
1241impl_vec_clone!(AzStringPair, StringPairVec, StringPairVecDestructor);
1242impl_vec_partialeq!(AzStringPair, StringPairVec);
1243impl_vec_eq!(AzStringPair, StringPairVec);
1244impl_vec_hash!(AzStringPair, StringPairVec);
1245
1246impl_option!(
1247 StringPairVec,
1248 OptionStringPairVec,
1249 copy = false,
1250 [Debug, Clone, PartialOrd, PartialEq, Ord, Eq, Hash]
1251);
1252
1253impl StringPairVec {
1254 pub fn get_key(&self, search_key: &str) -> Option<&AzString> {
1255 self.as_ref().iter().find_map(|v| {
1256 if v.key.as_str() == search_key {
1257 Some(&v.value)
1258 } else {
1259 None
1260 }
1261 })
1262 }
1263 pub fn get_key_mut(&mut self, search_key: &str) -> Option<&mut AzStringPair> {
1264 self.as_mut()
1265 .iter_mut()
1266 .find(|v| v.key.as_str() == search_key)
1267 }
1268 pub fn insert_kv<I: Into<AzString>>(&mut self, key: I, value: I) {
1269 let key = key.into();
1270 let value = value.into();
1271 match self.get_key_mut(key.as_str()) {
1272 None => {}
1273 Some(s) => {
1274 s.value = value;
1275 return;
1276 }
1277 }
1278 self.push(AzStringPair { key, value });
1279 }
1280}
1281
1282impl_vec!(XWindowType, XWindowTypeVec, XWindowTypeVecDestructor, XWindowTypeVecDestructorType, XWindowTypeVecSlice, OptionXWindowType);
1283impl_vec_debug!(XWindowType, XWindowTypeVec);
1284impl_vec_partialord!(XWindowType, XWindowTypeVec);
1285impl_vec_ord!(XWindowType, XWindowTypeVec);
1286impl_vec_clone!(XWindowType, XWindowTypeVec, XWindowTypeVecDestructor);
1287impl_vec_partialeq!(XWindowType, XWindowTypeVec);
1288impl_vec_eq!(XWindowType, XWindowTypeVec);
1289impl_vec_hash!(XWindowType, XWindowTypeVec);
1290
1291impl_option!(
1292 WaylandTheme,
1293 OptionWaylandTheme,
1294 copy = false,
1295 [Debug, Clone, PartialEq, PartialOrd]
1296);
1297
1298#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1299#[repr(C)]
1300pub struct MacWindowOptions {
1301 pub _reserved: u8,
1303}
1304
1305#[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1306#[repr(C)]
1307pub struct WasmWindowOptions {
1308 pub _reserved: u8,
1310}
1311
1312#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1313#[repr(C)]
1314pub enum FullScreenMode {
1315 SlowFullScreen,
1318 FastFullScreen,
1321 SlowWindowed,
1324 FastWindowed,
1327}
1328
1329#[derive(Debug, Clone, PartialEq, PartialOrd)]
1332#[repr(C)]
1333pub struct WaylandTheme {
1334 pub title_bar_active_background_color: ColorU,
1335 pub title_bar_active_separator_color: ColorU,
1336 pub title_bar_active_text_color: ColorU,
1337 pub title_bar_inactive_background_color: ColorU,
1338 pub title_bar_inactive_separator_color: ColorU,
1339 pub title_bar_inactive_text_color: ColorU,
1340 pub maximize_idle_foreground_inactive_color: ColorU,
1341 pub minimize_idle_foreground_inactive_color: ColorU,
1342 pub close_idle_foreground_inactive_color: ColorU,
1343 pub maximize_hovered_foreground_inactive_color: ColorU,
1344 pub minimize_hovered_foreground_inactive_color: ColorU,
1345 pub close_hovered_foreground_inactive_color: ColorU,
1346 pub maximize_disabled_foreground_inactive_color: ColorU,
1347 pub minimize_disabled_foreground_inactive_color: ColorU,
1348 pub close_disabled_foreground_inactive_color: ColorU,
1349 pub maximize_idle_background_inactive_color: ColorU,
1350 pub minimize_idle_background_inactive_color: ColorU,
1351 pub close_idle_background_inactive_color: ColorU,
1352 pub maximize_hovered_background_inactive_color: ColorU,
1353 pub minimize_hovered_background_inactive_color: ColorU,
1354 pub close_hovered_background_inactive_color: ColorU,
1355 pub maximize_disabled_background_inactive_color: ColorU,
1356 pub minimize_disabled_background_inactive_color: ColorU,
1357 pub close_disabled_background_inactive_color: ColorU,
1358 pub maximize_idle_foreground_active_color: ColorU,
1359 pub minimize_idle_foreground_active_color: ColorU,
1360 pub close_idle_foreground_active_color: ColorU,
1361 pub maximize_hovered_foreground_active_color: ColorU,
1362 pub minimize_hovered_foreground_active_color: ColorU,
1363 pub close_hovered_foreground_active_color: ColorU,
1364 pub maximize_disabled_foreground_active_color: ColorU,
1365 pub minimize_disabled_foreground_active_color: ColorU,
1366 pub close_disabled_foreground_active_color: ColorU,
1367 pub maximize_idle_background_active_color: ColorU,
1368 pub minimize_idle_background_active_color: ColorU,
1369 pub close_idle_background_active_color: ColorU,
1370 pub maximize_hovered_background_active_color: ColorU,
1371 pub minimize_hovered_background_active_color: ColorU,
1372 pub close_hovered_background_active_color: ColorU,
1373 pub maximize_disabled_background_active_color: ColorU,
1374 pub minimize_disabled_background_active_color: ColorU,
1375 pub close_disabled_background_active_color: ColorU,
1376 pub title_bar_font: AzString,
1377 pub title_bar_font_size: f32,
1378}
1379
1380#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
1381#[repr(C)]
1382pub struct WindowSize {
1383 pub dimensions: LogicalSize,
1386 pub dpi: u32,
1388 pub min_dimensions: OptionLogicalSize,
1390 pub max_dimensions: OptionLogicalSize,
1392}
1393
1394impl WindowSize {
1395 pub fn get_layout_size(&self) -> LayoutSize {
1396 LayoutSize::new(
1397 libm::roundf(self.dimensions.width) as isize,
1398 libm::roundf(self.dimensions.height) as isize,
1399 )
1400 }
1401
1402 pub fn get_logical_size(&self) -> LogicalSize {
1404 self.dimensions
1405 }
1406
1407 pub fn get_physical_size(&self) -> PhysicalSize<u32> {
1408 self.dimensions
1409 .to_physical(self.get_hidpi_factor().inner.get())
1410 }
1411
1412 pub fn get_hidpi_factor(&self) -> DpiScaleFactor {
1413 DpiScaleFactor {
1414 inner: FloatValue::new(self.dpi as f32 / 96.0),
1415 }
1416 }
1417}
1418
1419impl Default for WindowSize {
1420 fn default() -> Self {
1421 Self {
1422 #[cfg(not(feature = "glow"))]
1423 dimensions: LogicalSize::new(640.0, 480.0),
1424 dpi: 96,
1425 min_dimensions: None.into(),
1426 max_dimensions: None.into(),
1427 }
1428 }
1429}
1430
1431#[repr(C)]
1432#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1433pub enum RendererType {
1434 Hardware,
1436 Software,
1438}
1439
1440impl_option!(
1441 RendererType,
1442 OptionRendererType,
1443 [Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash]
1444);
1445
1446#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
1447pub enum UpdateFocusWarning {
1448 FocusInvalidDomId(DomId),
1449 FocusInvalidNodeId(NodeHierarchyItemId),
1450 CouldNotFindFocusNode(CssPath),
1451}
1452
1453impl ::core::fmt::Display for UpdateFocusWarning {
1454 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1455 use self::UpdateFocusWarning::*;
1456 match self {
1457 FocusInvalidDomId(dom_id) => write!(f, "Focusing on DOM with invalid ID: {:?}", dom_id),
1458 FocusInvalidNodeId(node_id) => {
1459 write!(f, "Focusing on node with invalid ID: {}", node_id)
1460 }
1461 CouldNotFindFocusNode(css_path) => {
1462 write!(f, "Could not find focus node for path: {}", css_path)
1463 }
1464 }
1465 }
1466}
1467
1468#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1470#[repr(C, u8)]
1471pub enum AcceleratorKey {
1472 Ctrl,
1473 Alt,
1474 Shift,
1475 Key(VirtualKeyCode),
1476}
1477
1478impl AcceleratorKey {
1479 pub fn matches(&self, keyboard_state: &KeyboardState) -> bool {
1483 use self::AcceleratorKey::*;
1484 match self {
1485 Ctrl => keyboard_state.ctrl_down(),
1486 Alt => keyboard_state.alt_down(),
1487 Shift => keyboard_state.shift_down(),
1488 Key(k) => keyboard_state.is_key_down(*k),
1489 }
1490 }
1491}
1492
1493#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1495#[repr(C)]
1496pub enum VirtualKeyCode {
1497 Key1,
1498 Key2,
1499 Key3,
1500 Key4,
1501 Key5,
1502 Key6,
1503 Key7,
1504 Key8,
1505 Key9,
1506 Key0,
1507 A,
1508 B,
1509 C,
1510 D,
1511 E,
1512 F,
1513 G,
1514 H,
1515 I,
1516 J,
1517 K,
1518 L,
1519 M,
1520 N,
1521 O,
1522 P,
1523 Q,
1524 R,
1525 S,
1526 T,
1527 U,
1528 V,
1529 W,
1530 X,
1531 Y,
1532 Z,
1533 Escape,
1534 F1,
1535 F2,
1536 F3,
1537 F4,
1538 F5,
1539 F6,
1540 F7,
1541 F8,
1542 F9,
1543 F10,
1544 F11,
1545 F12,
1546 F13,
1547 F14,
1548 F15,
1549 F16,
1550 F17,
1551 F18,
1552 F19,
1553 F20,
1554 F21,
1555 F22,
1556 F23,
1557 F24,
1558 Snapshot,
1559 Scroll,
1560 Pause,
1561 Insert,
1562 Home,
1563 Delete,
1564 End,
1565 PageDown,
1566 PageUp,
1567 Left,
1568 Up,
1569 Right,
1570 Down,
1571 Back,
1572 Return,
1573 Space,
1574 Compose,
1575 Caret,
1576 Numlock,
1577 Numpad0,
1578 Numpad1,
1579 Numpad2,
1580 Numpad3,
1581 Numpad4,
1582 Numpad5,
1583 Numpad6,
1584 Numpad7,
1585 Numpad8,
1586 Numpad9,
1587 NumpadAdd,
1588 NumpadDivide,
1589 NumpadDecimal,
1590 NumpadComma,
1591 NumpadEnter,
1592 NumpadEquals,
1593 NumpadMultiply,
1594 NumpadSubtract,
1595 AbntC1,
1596 AbntC2,
1597 Apostrophe,
1598 Apps,
1599 Asterisk,
1600 At,
1601 Ax,
1602 Backslash,
1603 Calculator,
1604 Capital,
1605 Colon,
1606 Comma,
1607 Convert,
1608 Equals,
1609 Grave,
1610 Kana,
1611 Kanji,
1612 LAlt,
1613 LBracket,
1614 LControl,
1615 LShift,
1616 LWin,
1617 Mail,
1618 MediaSelect,
1619 MediaStop,
1620 Minus,
1621 Mute,
1622 MyComputer,
1623 NavigateForward,
1624 NavigateBackward,
1625 NextTrack,
1626 NoConvert,
1627 OEM102,
1628 Period,
1629 PlayPause,
1630 Plus,
1631 Power,
1632 PrevTrack,
1633 RAlt,
1634 RBracket,
1635 RControl,
1636 RShift,
1637 RWin,
1638 Semicolon,
1639 Slash,
1640 Sleep,
1641 Stop,
1642 Sysrq,
1643 Tab,
1644 Underline,
1645 Unlabeled,
1646 VolumeDown,
1647 VolumeUp,
1648 Wake,
1649 WebBack,
1650 WebFavorites,
1651 WebForward,
1652 WebHome,
1653 WebRefresh,
1654 WebSearch,
1655 WebStop,
1656 Yen,
1657 Copy,
1658 Paste,
1659 Cut,
1660}
1661
1662impl VirtualKeyCode {
1663 pub fn get_lowercase(&self) -> Option<char> {
1664 use self::VirtualKeyCode::*;
1665 match self {
1666 A => Some('a'),
1667 B => Some('b'),
1668 C => Some('c'),
1669 D => Some('d'),
1670 E => Some('e'),
1671 F => Some('f'),
1672 G => Some('g'),
1673 H => Some('h'),
1674 I => Some('i'),
1675 J => Some('j'),
1676 K => Some('k'),
1677 L => Some('l'),
1678 M => Some('m'),
1679 N => Some('n'),
1680 O => Some('o'),
1681 P => Some('p'),
1682 Q => Some('q'),
1683 R => Some('r'),
1684 S => Some('s'),
1685 T => Some('t'),
1686 U => Some('u'),
1687 V => Some('v'),
1688 W => Some('w'),
1689 X => Some('x'),
1690 Y => Some('y'),
1691 Z => Some('z'),
1692 Key0 | Numpad0 => Some('0'),
1693 Key1 | Numpad1 => Some('1'),
1694 Key2 | Numpad2 => Some('2'),
1695 Key3 | Numpad3 => Some('3'),
1696 Key4 | Numpad4 => Some('4'),
1697 Key5 | Numpad5 => Some('5'),
1698 Key6 | Numpad6 => Some('6'),
1699 Key7 | Numpad7 => Some('7'),
1700 Key8 | Numpad8 => Some('8'),
1701 Key9 | Numpad9 => Some('9'),
1702 Minus => Some('-'),
1703 Asterisk => Some('´'),
1704 At => Some('@'),
1705 Period => Some('.'),
1706 Semicolon => Some(';'),
1707 Slash => Some('/'),
1708 Caret => Some('^'),
1709 _ => None,
1710 }
1711 }
1712}
1713
1714#[derive(Debug, Clone)]
1716#[repr(C)]
1717pub struct SmallWindowIconBytes {
1718 pub key: IconKey,
1719 pub rgba_bytes: U8Vec,
1720}
1721
1722#[derive(Debug, Clone)]
1724#[repr(C)]
1725pub struct LargeWindowIconBytes {
1726 pub key: IconKey,
1727 pub rgba_bytes: U8Vec,
1728}
1729
1730#[derive(Debug, Clone)]
1732#[repr(C, u8)]
1733pub enum WindowIcon {
1734 Small(SmallWindowIconBytes),
1735 Large(LargeWindowIconBytes),
1737}
1738
1739impl_option!(
1740 WindowIcon,
1741 OptionWindowIcon,
1742 copy = false,
1743 [Debug, Clone, PartialOrd, PartialEq, Eq, Hash, Ord]
1744);
1745
1746impl WindowIcon {
1747 pub fn get_key(&self) -> IconKey {
1748 match &self {
1749 WindowIcon::Small(SmallWindowIconBytes { key, .. }) => *key,
1750 WindowIcon::Large(LargeWindowIconBytes { key, .. }) => *key,
1751 }
1752 }
1753}
1754impl PartialEq for WindowIcon {
1757 fn eq(&self, rhs: &Self) -> bool {
1758 self.get_key() == rhs.get_key()
1759 }
1760}
1761
1762impl PartialOrd for WindowIcon {
1763 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1764 Some((self.get_key()).cmp(&rhs.get_key()))
1765 }
1766}
1767
1768impl Eq for WindowIcon {}
1769
1770impl Ord for WindowIcon {
1771 fn cmp(&self, rhs: &Self) -> Ordering {
1772 (self.get_key()).cmp(&rhs.get_key())
1773 }
1774}
1775
1776impl Hash for WindowIcon {
1777 fn hash<H>(&self, state: &mut H)
1778 where
1779 H: Hasher,
1780 {
1781 self.get_key().hash(state);
1782 }
1783}
1784
1785#[derive(Debug, Clone)]
1787#[repr(C)]
1788pub struct TaskBarIcon {
1789 pub key: IconKey,
1790 pub rgba_bytes: U8Vec,
1791}
1792
1793impl_option!(
1794 TaskBarIcon,
1795 OptionTaskBarIcon,
1796 copy = false,
1797 [Debug, Clone, PartialOrd, PartialEq, Eq, Hash, Ord]
1798);
1799
1800impl PartialEq for TaskBarIcon {
1801 fn eq(&self, rhs: &Self) -> bool {
1802 self.key == rhs.key
1803 }
1804}
1805
1806impl PartialOrd for TaskBarIcon {
1807 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
1808 Some((self.key).cmp(&rhs.key))
1809 }
1810}
1811
1812impl Eq for TaskBarIcon {}
1813
1814impl Ord for TaskBarIcon {
1815 fn cmp(&self, rhs: &Self) -> Ordering {
1816 (self.key).cmp(&rhs.key)
1817 }
1818}
1819
1820impl Hash for TaskBarIcon {
1821 fn hash<H>(&self, state: &mut H)
1822 where
1823 H: Hasher,
1824 {
1825 self.key.hash(state);
1826 }
1827}