1use super::{Action, View};
5#[cfg(feature = "winit")]
6use crate::Application;
7
8use iced::window;
9#[cfg(all(wayland_platform, feature = "winit"))]
10use iced_runtime::platform_specific::wayland::CornerRadius;
11#[cfg(wayland_platform)]
12use iced_runtime::platform_specific::wayland::layer_surface::IcedMargin;
13use std::any::Any;
14
15use std::sync::Arc;
16
17#[cfg(wayland_platform)]
19#[must_use]
20pub fn destroy_popup<M>(id: iced_core::window::Id) -> Action<M> {
21 Action::DestroyPopup(id)
22}
23
24#[cfg(wayland_platform)]
25#[must_use]
26pub fn destroy_subsurface<M>(id: iced_core::window::Id) -> Action<M> {
27 Action::DestroySubsurface(id)
28}
29
30#[cfg(wayland_platform)]
31#[must_use]
32pub fn destroy_window<M>(id: iced_core::window::Id) -> Action<M> {
33 Action::DestroyWindow(id)
34}
35
36#[cfg(wayland_platform)]
37#[must_use]
38pub fn destroy_layer_shell<M>(id: iced_core::window::Id) -> Action<M> {
39 Action::DestroyLayerShell(id)
40}
41
42#[derive(Debug, Default, Copy, Clone)]
43pub struct LiveSettings {
44 #[cfg(wayland_platform)]
45 pub padding: Option<IcedMargin>,
47 #[cfg(wayland_platform)]
48 pub corners: Option<CornerRadius>,
50 pub blur: Option<bool>,
52}
53
54#[cfg(wayland_platform)]
55type BoxedView<App> = Option<
56 Box<
57 dyn Fn(&App) -> crate::Element<'_, crate::Action<<App as Application>::Message>>
58 + Send
59 + Sync
60 + 'static,
61 >,
62>;
63
64#[cfg(wayland_platform)]
65#[must_use]
66pub fn app_window<App: Application>(
67 live_settings: impl Fn(&App) -> LiveSettings + Send + Sync + 'static,
68 settings: impl Fn(&mut App) -> window::Settings + Send + Sync + 'static,
69 view: BoxedView<App>,
70) -> (window::Id, Action<App::Message>) {
71 let id = window::Id::unique();
72
73 let boxed: Box<dyn Fn(&mut App) -> window::Settings + Send + Sync + 'static> =
74 Box::new(settings);
75 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
76
77 let boxed_live: Box<dyn Fn(&App) -> LiveSettings + Send + Sync + 'static> =
78 Box::new(live_settings);
79 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
80
81 (
82 id,
83 Action::AppWindow(
84 id,
85 Arc::new(boxed),
86 Arc::new(boxed_live),
87 view.map(|view| {
88 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(view);
89 Arc::new(boxed)
90 }),
91 ),
92 )
93}
94
95#[cfg(wayland_platform)]
97#[must_use]
98pub fn simple_window<Message: 'static>(
99 live_settings: impl Fn() -> LiveSettings + Send + Sync + 'static,
100 settings: impl Fn() -> window::Settings + Send + Sync + 'static,
101 view: Option<
102 impl Fn() -> crate::Element<'static, crate::Action<Message>> + Send + Sync + 'static,
103 >,
104) -> (window::Id, Action<Message>) {
105 let id = window::Id::unique();
106
107 let boxed: Box<dyn Fn() -> window::Settings + Send + Sync + 'static> = Box::new(settings);
108 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
109
110 let boxed_live: Box<dyn Fn() -> LiveSettings + Send + Sync + 'static> = Box::new(live_settings);
111 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
112
113 (
114 id,
115 Action::Window(
116 id,
117 Arc::new(boxed),
118 Arc::new(boxed_live),
119 view.map(|view| Arc::new(view) as View<Message>),
120 ),
121 )
122}
123
124#[cfg(wayland_platform)]
125#[must_use]
126pub fn app_popup<App: Application>(
127 live_settings: impl Fn(&App) -> LiveSettings + Send + Sync + 'static,
128 settings: impl Fn(&mut App) -> iced_runtime::platform_specific::wayland::popup::SctkPopupSettings
129 + Send
130 + Sync
131 + 'static,
132 view: BoxedView<App>,
133) -> Action<App::Message> {
134 let boxed: Box<
135 dyn Fn(&mut App) -> iced_runtime::platform_specific::wayland::popup::SctkPopupSettings
136 + Send
137 + Sync
138 + 'static,
139 > = Box::new(settings);
140 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
141
142 let boxed_live: Box<dyn Fn(&App) -> LiveSettings + Send + Sync + 'static> =
143 Box::new(live_settings);
144 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
145
146 Action::AppPopup(
147 Arc::new(boxed),
148 Arc::new(boxed_live),
149 view.map(|view| {
150 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(view);
151 Arc::new(boxed)
152 }),
153 )
154}
155
156#[cfg(wayland_platform)]
158#[must_use]
159pub fn simple_subsurface<Message: 'static>(
160 settings: impl Fn() -> iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings
161 + Send
162 + Sync
163 + 'static,
164 view: Option<
165 Box<dyn Fn() -> crate::Element<'static, crate::Action<Message>> + Send + Sync + 'static>,
166 >,
167) -> Action<Message> {
168 let boxed: Box<
169 dyn Fn() -> iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings
170 + Send
171 + Sync
172 + 'static,
173 > = Box::new(settings);
174 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
175
176 Action::Subsurface(
177 Arc::new(boxed),
178 Arc::new(Box::new(LiveSettings::default)),
179 view.map(|view| Arc::from(view) as View<Message>),
180 )
181}
182
183#[cfg(wayland_platform)]
185#[must_use]
186pub fn simple_popup<Message: 'static>(
187 live_settings: impl Fn() -> LiveSettings + Send + Sync + 'static,
188 settings: impl Fn() -> iced_runtime::platform_specific::wayland::popup::SctkPopupSettings
189 + Send
190 + Sync
191 + 'static,
192 view: Option<
193 impl Fn() -> crate::Element<'static, crate::Action<Message>> + Send + Sync + 'static,
194 >,
195) -> Action<Message> {
196 let boxed: Box<
197 dyn Fn() -> iced_runtime::platform_specific::wayland::popup::SctkPopupSettings
198 + Send
199 + Sync
200 + 'static,
201 > = Box::new(settings);
202 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
203
204 let boxed_live: Box<dyn Fn() -> LiveSettings + Send + Sync + 'static> = Box::new(live_settings);
205 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
206
207 Action::Popup(
208 Arc::new(boxed),
209 Arc::new(boxed_live),
210 view.map(|view| Arc::new(view) as View<Message>),
211 )
212}
213
214#[cfg(wayland_platform)]
215#[must_use]
216pub fn subsurface<App: Application>(
217 settings: impl Fn(
218 &mut App,
219 )
220 -> iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings
221 + Send
222 + Sync
223 + 'static,
224 view: BoxedView<App>,
226) -> Action<App::Message> {
227 let boxed: Box<
228 dyn Fn(
229 &mut App,
230 )
231 -> iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings
232 + Send
233 + Sync
234 + 'static,
235 > = Box::new(settings);
236 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
237
238 Action::AppSubsurface(
239 Arc::new(boxed),
240 Arc::new(Box::new(|_: &App| LiveSettings::default())),
241 view.map(|view| {
242 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(view);
243 Arc::new(boxed)
244 }),
245 )
246}
247
248#[cfg(wayland_platform)]
249#[must_use]
250pub fn simple_layer_shell<Message: 'static>(
251 live_settings: impl Fn() -> LiveSettings + Send + Sync + 'static,
252 settings: impl Fn()
253 -> iced_runtime::platform_specific::wayland::layer_surface::SctkLayerSurfaceSettings
254 + Send
255 + Sync
256 + 'static,
257 view: Option<
258 impl Fn() -> crate::Element<'static, crate::Action<Message>> + Send + Sync + 'static,
259 >,
260) -> Action<Message> {
261 let boxed: Box<
262 dyn Fn()
263 -> iced_runtime::platform_specific::wayland::layer_surface::SctkLayerSurfaceSettings
264 + Send
265 + Sync
266 + 'static,
267 > = Box::new(settings);
268 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
269 let boxed_live: Box<dyn Fn() -> LiveSettings + Send + Sync + 'static> = Box::new(live_settings);
270 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
271 Action::LayerShell(
272 Arc::new(boxed),
273 Arc::new(boxed_live),
274 view.map(|view| Arc::new(view) as View<Message>),
275 )
276}
277
278#[cfg(wayland_platform)]
279#[must_use]
280pub fn lock<Message: 'static>(
281 live_settings: impl Fn() -> LiveSettings + Send + Sync + 'static,
282 id: window::Id,
283 output: cctk::wayland_client::protocol::wl_output::WlOutput,
284 view: Option<
285 impl Fn() -> crate::Element<'static, crate::Action<Message>> + Send + Sync + 'static,
286 >,
287) -> Action<Message> {
288 let boxed_live: Box<dyn Fn() -> LiveSettings + Send + Sync + 'static> = Box::new(live_settings);
289 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
290 Action::Lock(
291 id,
292 output,
293 Arc::new(boxed_live),
294 view.map(|view| Arc::new(view) as View<Message>),
295 )
296}
297
298#[cfg(wayland_platform)]
299#[must_use]
300pub fn app_layer_shell<App: Application>(
301 live_settings: impl Fn(&App) -> LiveSettings + Send + Sync + 'static,
302 settings: impl Fn(
303 &mut App,
304 )
305 -> iced_runtime::platform_specific::wayland::layer_surface::SctkLayerSurfaceSettings
306 + Send
307 + Sync
308 + 'static,
309 view: BoxedView<App>,
311) -> Action<App::Message> {
312 let boxed: Box<
313 dyn Fn(
314 &mut App,
315 )
316 -> iced_runtime::platform_specific::wayland::layer_surface::SctkLayerSurfaceSettings
317 + Send
318 + Sync
319 + 'static,
320 > = Box::new(settings);
321 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed);
322
323 let boxed_live: Box<dyn Fn(&App) -> LiveSettings + Send + Sync + 'static> =
324 Box::new(live_settings);
325 let boxed_live: Box<dyn Any + Send + Sync + 'static> = Box::new(boxed_live);
326
327 Action::AppLayerShell(
328 Arc::new(boxed),
329 Arc::new(boxed_live),
330 view.map(|view| {
331 let boxed: Box<dyn Any + Send + Sync + 'static> = Box::new(view);
332 Arc::new(boxed)
333 }),
334 )
335}