pytauri_core/ext_mod_impl/
window.rs1use pyo3::{
2 prelude::*,
3 types::{PyDict, PyFloat, PyString},
4};
5use pyo3_utils::{
6 from_py_dict::{derive_from_py_dict, FromPyDict as _, NotRequired},
7 py_wrapper::{PyWrapper, PyWrapperT0},
8};
9use tauri::window;
10
11use crate::{
12 ext_mod::{webview::Color, PhysicalPositionI32, PhysicalRect, PhysicalSizeU32},
13 tauri_runtime::Runtime,
14 utils::non_exhaustive_panic,
15};
16
17type TauriWindow = window::Window<Runtime>;
18
19#[pyclass(frozen)]
21#[non_exhaustive]
22pub struct Window(pub PyWrapper<PyWrapperT0<TauriWindow>>);
23
24impl Window {
25 pub(crate) fn new(window: TauriWindow) -> Self {
26 Self(PyWrapper::new0(window))
27 }
28}
29
30#[pyclass(frozen)]
32#[non_exhaustive]
33pub struct Monitor {
34 #[pyo3(get)]
35 name: Option<Py<PyString>>,
36 #[pyo3(get)]
37 size: PhysicalSizeU32,
38 #[pyo3(get)]
39 position: PhysicalPositionI32,
40 #[pyo3(get)]
41 work_area: Py<PhysicalRect>,
42 #[pyo3(get)]
43 scale_factor: Py<PyFloat>,
44}
45
46impl Monitor {
47 pub(crate) fn from_tauri(py: Python<'_>, monitor: window::Monitor) -> PyResult<Self> {
48 let name = monitor.name().map(|n| PyString::new(py, n).into());
49 let size = PhysicalSizeU32::from_tauri(py, *monitor.size())?;
50 let position = PhysicalPositionI32::from_tauri(py, *monitor.position())?;
51 let work_area = Py::new(py, PhysicalRect::from_tauri(py, *monitor.work_area())?)?;
52 let scale_factor = PyFloat::new(py, monitor.scale_factor()).into();
53 Ok(Self {
54 name,
55 size,
56 position,
57 work_area,
58 scale_factor,
59 })
60 }
61}
62
63macro_rules! effect_impl {
64 ($ident:ident => : $($variant:ident),*) => {
65 #[pyclass(frozen, eq, eq_int)]
67 #[derive(PartialEq, Clone, Copy)]
68 #[non_exhaustive]
69 pub enum $ident {
70 $($variant,)*
71 }
72
73 impl From<tauri::window::Effect> for $ident {
74 fn from(val: tauri::window::Effect) -> Self {
75 #[expect(deprecated)]
76 match val {
77 $(tauri::window::Effect::$variant => $ident::$variant,)*
78 }
79 }
80 }
81
82 impl From<$ident> for tauri::window::Effect {
83 fn from(val: $ident) -> Self {
84 #[expect(deprecated)]
85 match val {
86 $($ident::$variant => tauri::window::Effect::$variant,)*
87 }
88 }
89 }
90 };
91}
92
93effect_impl!(
94 Effect => :
95 AppearanceBased,
96 Light,
97 Dark,
98 MediumLight,
99 UltraDark,
100 Titlebar,
101 Selection,
102 Menu,
103 Popover,
104 Sidebar,
105 HeaderView,
106 Sheet,
107 WindowBackground,
108 HudWindow,
109 FullScreenUI,
110 Tooltip,
111 ContentBackground,
112 UnderWindowBackground,
113 UnderPageBackground,
114 Mica,
115 MicaDark,
116 MicaLight,
117 Tabbed,
118 TabbedDark,
119 TabbedLight,
120 Blur,
121 Acrylic
122);
123
124macro_rules! effect_state_impl {
125 ($ident:ident => : $($variant:ident),*) => {
126 #[pyclass(frozen, eq, eq_int)]
128 #[derive(PartialEq, Clone, Copy)]
129 #[non_exhaustive]
130 pub enum $ident {
131 $($variant,)*
132 }
133
134 impl From<tauri::window::EffectState> for $ident {
135 fn from(val: tauri::window::EffectState) -> Self {
136 match val {
137 $(tauri::window::EffectState::$variant => $ident::$variant,)*
138 }
139 }
140 }
141
142 impl From<$ident> for tauri::window::EffectState {
143 fn from(val: $ident) -> Self {
144 match val {
145 $($ident::$variant => tauri::window::EffectState::$variant,)*
146 }
147 }
148 }
149 };
150}
151
152effect_state_impl!(EffectState => : FollowsWindowActiveState, Active, Inactive);
153
154pub struct Effects {
156 effects: NotRequired<Vec<Effect>>,
157 state: NotRequired<EffectState>,
158 radius: NotRequired<f64>,
159 color: NotRequired<Color>,
160}
161
162derive_from_py_dict!(Effects {
163 #[pyo3(default)]
164 effects,
165 #[pyo3(default)]
166 state,
167 #[pyo3(default)]
168 radius,
169 #[pyo3(default)]
170 color,
171});
172
173impl<'py> FromPyObject<'py> for Effects {
174 fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
175 let dict = ob.downcast::<PyDict>()?;
176 Self::from_py_dict(dict)
177 }
178}
179
180impl Effects {
181 pub(crate) fn into_tauri(self) -> window::EffectsBuilder {
184 let mut builder = window::EffectsBuilder::new();
185 let Self {
186 effects,
187 state,
188 radius,
189 color,
190 } = self;
191
192 if let Some(effects) = effects.0 {
193 let effects = effects.into_iter().map(Into::into);
194 builder = builder.effects(effects);
195 }
196 if let Some(state) = state.0 {
197 builder = builder.state(state.into());
198 }
199 if let Some(radius) = radius.0 {
200 builder = builder.radius(radius);
201 }
202 if let Some(color) = color.0 {
203 builder = builder.color(color.0);
204 }
205 builder
206 }
207}
208
209macro_rules! progress_bar_status_impl {
210 ($ident:ident => : $( $(#[$meta:meta])* $variant:ident ),*) => {
211 #[pyclass(frozen, eq, eq_int)]
213 #[derive(PartialEq, Clone, Copy)]
214 #[non_exhaustive]
215 pub enum $ident {
216 $(
217 $(#[$meta])*
218 $variant,
219 )*
220 }
221
222 impl From<tauri::window::ProgressBarStatus> for $ident {
223 fn from(val: tauri::window::ProgressBarStatus) -> Self {
224 match val {
225 $(tauri::window::ProgressBarStatus::$variant => $ident::$variant,)*
226 }
227 }
228 }
229
230 impl From<$ident> for tauri::window::ProgressBarStatus {
231 fn from(val: $ident) -> Self {
232 match val {
233 $($ident::$variant => tauri::window::ProgressBarStatus::$variant,)*
234 }
235 }
236 }
237 };
238}
239
240progress_bar_status_impl!(
242 ProgressBarStatus => :
243 #[pyo3(name = "None_")]
244 None,
245 Normal,
246 Indeterminate,
247 Paused,
248 Error
249);
250
251pub struct ProgressBarState {
253 status: NotRequired<ProgressBarStatus>,
254 progress: NotRequired<u64>,
255}
256
257derive_from_py_dict!(ProgressBarState {
258 #[pyo3(default)]
259 status,
260 #[pyo3(default)]
261 progress,
262});
263
264impl<'py> FromPyObject<'py> for ProgressBarState {
265 fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
266 let dict = ob.downcast::<PyDict>()?;
267 Self::from_py_dict(dict)
268 }
269}
270
271impl ProgressBarState {
272 pub(crate) fn into_tauri(self) -> window::ProgressBarState {
273 let Self { status, progress } = self;
274
275 let status = status.0.map(Into::into);
276 let progress = progress.0;
277
278 window::ProgressBarState { status, progress }
279 }
280}
281
282macro_rules! title_bar_style_impl {
283 ($ident:ident => : $($variant:ident),*) => {
284 #[pyclass(frozen, eq, eq_int)]
286 #[derive(PartialEq, Clone, Copy)]
287 #[non_exhaustive]
288 pub enum $ident {
289 $($variant,)*
290 _NonExhaustive,
291 }
292
293 impl From<tauri::TitleBarStyle> for $ident {
294 fn from(val: tauri::TitleBarStyle) -> Self {
295 match val {
296 $(tauri::TitleBarStyle::$variant => $ident::$variant,)*
297 _ => { $ident::_NonExhaustive }
298 }
299 }
300 }
301
302 impl From<$ident> for tauri::TitleBarStyle {
303 fn from(val: $ident) -> Self {
304 match val {
305 $($ident::$variant => tauri::TitleBarStyle::$variant,)*
306 $ident::_NonExhaustive => non_exhaustive_panic(),
307 }
308 }
309 }
310 };
311}
312
313title_bar_style_impl!(
314 TitleBarStyle => :
315 Visible,
316 Transparent,
317 Overlay
318);