Skip to main content

fret_runtime/capabilities/
platform.rs

1use super::keys;
2use super::{
3    ClipboardCapabilities, ClipboardTextCapabilities, DndCapabilities, ExecCapabilities,
4    FsCapabilities, GfxCapabilities, ImeCapabilities, ShellCapabilities, UiCapabilities,
5};
6use super::{
7    ExternalDragPayloadKind, ExternalDragPositionQuality, WindowHoverDetectionQuality,
8    WindowSetOuterPositionQuality, WindowZLevelQuality,
9};
10
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(default)]
15pub struct PlatformCapabilities {
16    pub exec: ExecCapabilities,
17    pub ui: UiCapabilities,
18    pub clipboard: ClipboardCapabilities,
19    pub dnd: DndCapabilities,
20    pub ime: ImeCapabilities,
21    pub fs: FsCapabilities,
22    pub shell: ShellCapabilities,
23    pub gfx: GfxCapabilities,
24}
25
26impl Default for PlatformCapabilities {
27    fn default() -> Self {
28        Self {
29            exec: ExecCapabilities::default(),
30            ui: UiCapabilities {
31                multi_window: true,
32                window_tear_off: true,
33                cursor_icons: true,
34                window_hover_detection: WindowHoverDetectionQuality::Reliable,
35                window_set_outer_position: WindowSetOuterPositionQuality::Reliable,
36                window_z_level: WindowZLevelQuality::Reliable,
37                window_decorations: true,
38                window_resizable: true,
39                window_transparent: true,
40                window_skip_taskbar: true,
41                window_non_activating: true,
42                window_hit_test_passthrough_all: true,
43                window_hit_test_passthrough_regions: false,
44                window_set_visible: true,
45                window_begin_drag: true,
46                window_begin_resize: true,
47                window_background_material_system_default: true,
48                window_background_material_mica: true,
49                window_background_material_acrylic: true,
50                window_background_material_vibrancy: true,
51                native_window_handle: false,
52            },
53            clipboard: ClipboardCapabilities {
54                text: ClipboardTextCapabilities {
55                    read: true,
56                    write: true,
57                },
58                files: false,
59                primary_text: cfg!(all(
60                    unix,
61                    not(any(
62                        target_os = "macos",
63                        target_os = "android",
64                        target_os = "emscripten",
65                        target_arch = "wasm32"
66                    ))
67                )),
68            },
69            dnd: DndCapabilities {
70                external: true,
71                external_payload: ExternalDragPayloadKind::FileToken,
72                external_position: ExternalDragPositionQuality::Continuous,
73            },
74            ime: ImeCapabilities {
75                enabled: true,
76                set_cursor_area: true,
77            },
78            fs: FsCapabilities {
79                real_paths: true,
80                file_dialogs: true,
81            },
82            shell: ShellCapabilities {
83                open_url: true,
84                share_sheet: false,
85                incoming_open: false,
86            },
87            gfx: GfxCapabilities {
88                webgpu: false,
89                native_gpu: true,
90            },
91        }
92    }
93}
94
95impl PlatformCapabilities {
96    pub fn bool_key(&self, key: &str) -> Option<bool> {
97        match key {
98            keys::UI_MULTI_WINDOW => Some(self.ui.multi_window),
99            keys::UI_WINDOW_TEAR_OFF => Some(self.ui.window_tear_off),
100            keys::UI_CURSOR_ICONS => Some(self.ui.cursor_icons),
101            keys::UI_WINDOW_DECORATIONS => Some(self.ui.window_decorations),
102            keys::UI_WINDOW_RESIZABLE => Some(self.ui.window_resizable),
103            keys::UI_WINDOW_TRANSPARENT => Some(self.ui.window_transparent),
104            keys::UI_WINDOW_ALWAYS_ON_TOP => Some(!matches!(
105                self.ui.window_z_level,
106                super::WindowZLevelQuality::None
107            )),
108            keys::UI_WINDOW_SKIP_TASKBAR => Some(self.ui.window_skip_taskbar),
109            keys::UI_WINDOW_NON_ACTIVATING => Some(self.ui.window_non_activating),
110            keys::UI_WINDOW_HIT_TEST_PASSTHROUGH_ALL => {
111                Some(self.ui.window_hit_test_passthrough_all)
112            }
113            keys::UI_WINDOW_HIT_TEST_PASSTHROUGH_REGIONS => {
114                Some(self.ui.window_hit_test_passthrough_regions)
115            }
116            keys::UI_WINDOW_SET_VISIBLE => Some(self.ui.window_set_visible),
117            keys::UI_WINDOW_BEGIN_DRAG => Some(self.ui.window_begin_drag),
118            keys::UI_WINDOW_BEGIN_RESIZE => Some(self.ui.window_begin_resize),
119            keys::UI_WINDOW_BACKGROUND_MATERIAL_SYSTEM_DEFAULT => {
120                Some(self.ui.window_background_material_system_default)
121            }
122            keys::UI_WINDOW_BACKGROUND_MATERIAL_MICA => {
123                Some(self.ui.window_background_material_mica)
124            }
125            keys::UI_WINDOW_BACKGROUND_MATERIAL_ACRYLIC => {
126                Some(self.ui.window_background_material_acrylic)
127            }
128            keys::UI_WINDOW_BACKGROUND_MATERIAL_VIBRANCY => {
129                Some(self.ui.window_background_material_vibrancy)
130            }
131            keys::UI_NATIVE_WINDOW_HANDLE => Some(self.ui.native_window_handle),
132            keys::CLIPBOARD_TEXT => Some(self.clipboard.text.read && self.clipboard.text.write),
133            keys::CLIPBOARD_TEXT_READ => Some(self.clipboard.text.read),
134            keys::CLIPBOARD_TEXT_WRITE => Some(self.clipboard.text.write),
135            keys::CLIPBOARD_FILES => Some(self.clipboard.files),
136            keys::CLIPBOARD_PRIMARY_TEXT => Some(self.clipboard.primary_text),
137            keys::DND_EXTERNAL => Some(self.dnd.external),
138            keys::IME | keys::IME_ENABLED => Some(self.ime.enabled),
139            keys::IME_SET_CURSOR_AREA => Some(self.ime.set_cursor_area),
140            keys::FS_REAL_PATHS => Some(self.fs.real_paths),
141            keys::FS_FILE_DIALOGS => Some(self.fs.file_dialogs),
142            keys::SHELL_OPEN_URL => Some(self.shell.open_url),
143            keys::SHELL_SHARE_SHEET => Some(self.shell.share_sheet),
144            keys::SHELL_INCOMING_OPEN => Some(self.shell.incoming_open),
145            keys::GFX_WEBGPU => Some(self.gfx.webgpu),
146            keys::GFX_NATIVE_GPU => Some(self.gfx.native_gpu),
147            _ => None,
148        }
149    }
150
151    pub fn str_key(&self, key: &str) -> Option<&'static str> {
152        match key {
153            keys::EXEC_BACKGROUND_WORK => Some(self.exec.background_work.as_str()),
154            keys::EXEC_WAKE => Some(self.exec.wake.as_str()),
155            keys::EXEC_TIMERS => Some(self.exec.timers.as_str()),
156            keys::UI_WINDOW_HOVER_DETECTION => Some(self.ui.window_hover_detection.as_str()),
157            keys::UI_WINDOW_SET_OUTER_POSITION => Some(self.ui.window_set_outer_position.as_str()),
158            keys::UI_WINDOW_Z_LEVEL => Some(self.ui.window_z_level.as_str()),
159            keys::DND_EXTERNAL_PAYLOAD => Some(self.dnd.external_payload.as_str()),
160            keys::DND_EXTERNAL_POSITION => Some(self.dnd.external_position.as_str()),
161            _ => None,
162        }
163    }
164}