1#[doc = include_str!("../docs/generate_widgets.md")]
2#[macro_export]
3macro_rules! generate_widgets {
4 ($($slint_win:ty),+) => {
5 use $crate::wayland_adapter::{WinHandle, SpellWin};
6 $crate::macro_internal::paste! {
7 $(
8 struct [<$slint_win Spell>] {
9 ui: $slint_win ,
10 way: SpellWin,
11 }
12
13 impl std::fmt::Debug for [<$slint_win Spell>] {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 f.debug_struct("Spell")
16 .field("wayland_side:", &self.way) .finish() }
19 }
20
21 impl [<$slint_win Spell>] {
22 pub fn invoke_spell(name: &str, window_conf: WindowConf) -> Self {
23 let way_win = SpellWin::invoke_spell(name, window_conf);
24 [<$slint_win Spell>] {
25 ui: $slint_win::new().unwrap(),
26 way: way_win
27 }
28 }
29 pub fn hide(&self) {
31 self.way.hide();
32 }
33
34 pub fn show_again(&mut self) {
36 self.way.show_again();
37 }
38
39 pub fn toggle(&mut self) {
41 self.way.toggle();
42 }
43
44 pub fn grab_focus(&self) {
46 self.way.grab_focus();
47 }
48
49 pub fn remove_focus(&self) {
51 self.way.remove_focus();
52 }
53
54 pub fn add_input_region(&self, x: i32, y: i32, width: i32, height: i32) {
56 self.way.add_input_region(x, y, width, height);
57 }
58
59 pub fn subtract_input_region(&self, x: i32, y: i32, width: i32, height: i32) {
61 self.way.subtract_input_region(x, y, width, height);
62 }
63
64 pub fn add_opaque_region(&self, x: i32, y: i32, width: i32, height: i32) {
66 self.way.add_opaque_region(x, y, width, height);
67 }
68
69 pub fn subtract_opaque_region(&self, x: i32, y: i32, width: i32, height: i32) {
71 self.way.subtract_opaque_region(x, y, width, height);
72 }
73
74 pub fn set_exclusive_zone(&mut self, val: i32) {
76 self.way.set_exclusive_zone(val);
77 }
78 pub fn get_handler(&self) -> WinHandle {
80 WinHandle(self.way.loop_handle.clone())
81 }
82
83 pub fn parts(self) -> ($slint_win, SpellWin) {
84 let [<$slint_win Spell>] { ui, way } = self;
85 (ui, way)
86 }
87 }
88
89 impl $crate::SpellAssociatedNew for [<$slint_win Spell>] {
90 fn on_call(
91 &mut self,
92 ) -> Result<(), Box<dyn std::error::Error>> {
93 let event_loop = self.way.event_loop.clone();
94 event_loop
95 .borrow_mut()
96 .dispatch(std::time::Duration::from_millis(1), &mut self.way)
97 .unwrap();
98 Ok(())
99 }
100
101 fn get_span(&self) -> $crate::macro_internal::Span {
102 self.way.span.clone()
103 }
104 }
105
106 impl std::ops::Deref for [<$slint_win Spell>] {
107 type Target = [<$slint_win>];
108 fn deref(&self) -> &Self::Target {
109 &self.ui
110 }
111 }
112 )+
113 }
114 };
115}
116
117#[doc = include_str!("../docs/cast_spell.md")]
118#[macro_export]
119macro_rules! cast_spell {
120 (
122 $win:expr
123 $(, notification: $noti:expr)?
124 $(,)?
125 ) => {{
126 $(
127 $crate::cast_spell!(@notification $noti);
128 )?
129 let (x,_y) = $crate::cast_spell!(@expand entry: $win);
130 $crate::cast_spell!(@run x)
131 }};
132 (
134 ($win:expr, ipc)
135 $(, notification: $noti:expr)?
136 $(,)?
137 ) => {{
138 $(
139 $crate::cast_spell!(@notification $noti);
140 )?
141 let (x, _y) = $crate::cast_spell!(@expand entry: ($win, ipc));
142 $crate::cast_spell!(@run x)
143 }};
144
145 (
147 windows: [ $($entry:tt),+ $(,)? ]
148 $(, notification: $noti:expr)?
149 $(,)?
150 ) => {{
151 $(
152 $crate::cast_spell!(@notification $noti);
153 )?
154 let mut windows = Vec::new();
155 $(
156 let (way, $crate::cast_spell!(@name $entry)) = $crate::cast_spell!(@expand entry: $entry);
158 $crate::cast_spell!(@vector_add windows, way);
159 )+
160 $crate::cast_spells_new(windows)
161 }};
162
163 (
166 windows: $windows:expr
167 $(, windows_ipc: $windows_ipc:expr)?
168 $(, Notification: $noti:expr)?
169 $(,)?
170 ) => {{
171 $(
172 $crate::cast_spell!(@notification $noti);
173 )?
174 $crate::cast_spells_new(windows)
175 }};
176
177 (
182 @expand
183 entry: ($waywindow:expr, ipc)
184 ) => {{
185 let socket_path = format!("/tmp/{}_ipc.sock", $waywindow.way.layer_name);
186 let _ = std::fs::remove_file(&socket_path); let listener = std::os::unix::net::UnixListener::bind(&socket_path)?;
188 let listener_clone = listener.try_clone().unwrap();
189 listener.set_nonblocking(true)?;
190 let (ui, mut way) = $waywindow.parts();
191 way.ipc_handler = Some(listener_clone);
192 let _ = way.loop_handle.clone().insert_source(
193 $crate::macro_internal::Generic::new(listener, $crate::macro_internal::Interest::READ, $crate::macro_internal::Mode::Level),
194 move |_, meta, data| {
195 loop {
196 match data.ipc_handler.as_ref().unwrap().accept() {
197 Ok((mut stream, _addr)) => {
198 let mut request = String::new();
199 if let Err(err) = std::io::Read::read_to_string(&mut stream, &mut request) {
201 $crate::macro_internal::warn!("Couldn't read CLI stream");
202 }
203 let (operation, command_args) = request.split_once(" ").unwrap_or((request.trim(), ""));
204 let (command, args) = command_args.split_once(" ").unwrap_or((command_args.trim(), ""));
205 match operation {
206 "hide" => data.hide(),
207 "show" => data.show_again(),
208 "update" => {
209 let returned_type = IpcController::get_type(&ui,command);
210 if let Err(_) = stream.write_all(returned_type.as_bytes()) {
211 }
213 }
214 "look"=> IpcController::change_val(&mut ui, command, args),
215 _=> {}
218 }
219 }
220 Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {
221 break; }
223 Err(e) => {
224 break;
226 }
227 }
228 }
229 Ok($crate::macro_internal::PostAction::Continue)
230 },
231 );
232 (way, ui)
233 }};
234 (
236 @expand
237 entry: $waywindow:expr
238 ) => {{
239 let socket_path = format!("/tmp/{}_ipc.sock", $waywindow.way.layer_name);
241 let _ = std::fs::remove_file(&socket_path); let listener = std::os::unix::net::UnixListener::bind(&socket_path)?;
243 let listener_clone = listener.try_clone().unwrap();
244 listener.set_nonblocking(true)?;
245 let (ui, mut way) = $waywindow.parts();
248 way.ipc_handler = Some(listener_clone);
249 let _ = way.loop_handle.clone().insert_source(
250 $crate::macro_internal::Generic::new(listener, $crate::macro_internal::Interest::READ, $crate::macro_internal::Mode::Level),
251 move |_, _, data| {
252 loop {
253 match data.ipc_handler.as_ref().unwrap().accept() {
254 Ok((mut stream, _addr)) => {
255 let mut request = String::new();
256 if let Err(err) = std::io::Read::read_to_string(&mut stream, &mut request) {
258 $crate::macro_internal::warn!("Couldn't read CLI stream");
259 }
260 println!("\n\n GIven request {}", request);
261 let (operation, command_args) = request.split_once(" ").unwrap_or((request.trim(), ""));
262 println!("Operation:{}, command_args:{}", operation, command_args);
263 let (command, args) = command_args.split_once(" ").unwrap_or((command_args.trim(), ""));
264 println!("Operation:{}, Command {}, args: {}",operation, command, args);
265 match operation {
266 "hide" => data.hide(),
267 "show" => data.show_again(),
268 "update" => {}
269 "look"=> {}
270 _=> {}
271 }
272 }
273 Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => {
274 break; }
276 Err(e) => {
277 panic!("Following error occured.{}",e);
278 }
279 }
280 }
281
282 Ok($crate::macro_internal::PostAction::Continue)
287 },
288 );
289 (way, ui)
290 }};
291 (@vector_add $wins:expr, ($waywindow:expr, ipc)) => {
292 $wins.push(Box::new($waywindow) as Box<dyn $crate::SpellAssociatedNew>)
293 };
294 (@vector_add $wins:expr, $waywindow:expr) => {
295 $wins.push(Box::new($waywindow) as Box<dyn $crate::SpellAssociatedNew>)
296 };
297
298 (@name ($win:expr,ipc)) => {
299 $crate::macro_internal::paste! {
300 [<$win _var>]
301 }
302 };
303
304 (@name $win:expr) => {
305 $crate::macro_internal::paste! {
306 [<$win _var>]
307 }
308 };
309 (@notification $noti:expr) => {
311 let _notification = &$noti;
313 };
314
315 (@run $way:expr) => {
316 $crate::cast_spell_inner($way)
317 };
318
319 (lock: $lock:expr) => {
321 $crate::cast_spell!(@run $lock)
322 };
323}