1 #![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
2
3 use std::os::raw;
4 #[cfg(feature = "x11")]
5 use std::{ptr, sync::Arc};
6
7 #[cfg(feature = "wayland")]
8 use smithay_client_toolkit::window::{ButtonState as SCTKButtonState, Theme as SCTKTheme};
9
10 use crate::{
11 event_loop::{EventLoop, EventLoopWindowTarget},
12 monitor::MonitorHandle,
13 window::{Window, WindowBuilder},
14 };
15
16 #[cfg(feature = "x11")]
17 use crate::dpi::Size;
18 #[cfg(feature = "x11")]
19 use crate::platform_impl::x11::{ffi::XVisualInfo, XConnection};
20 use crate::platform_impl::{
21 EventLoop as LinuxEventLoop, EventLoopWindowTarget as LinuxEventLoopWindowTarget,
22 Window as LinuxWindow,
23 };
24
25 // TODO: stupid hack so that glutin can do its work
26 #[doc(hidden)]
27 #[cfg(feature = "x11")]
28 pub use crate::platform_impl::x11;
29 #[cfg(feature = "x11")]
30 pub use crate::platform_impl::{x11::util::WindowType as XWindowType, XNotSupported};
31
32 /// Additional methods on `EventLoopWindowTarget` that are specific to Unix.
33 pub trait EventLoopWindowTargetExtUnix {
34 /// True if the `EventLoopWindowTarget` uses Wayland.
35 #[cfg(feature = "wayland")]
is_wayland(&self) -> bool36 fn is_wayland(&self) -> bool;
37
38 /// True if the `EventLoopWindowTarget` uses X11.
39 #[cfg(feature = "x11")]
is_x11(&self) -> bool40 fn is_x11(&self) -> bool;
41
42 #[doc(hidden)]
43 #[cfg(feature = "x11")]
xlib_xconnection(&self) -> Option<Arc<XConnection>>44 fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
45
46 /// Returns a pointer to the `wl_display` object of wayland that is used by this
47 /// `EventLoopWindowTarget`.
48 ///
49 /// Returns `None` if the `EventLoop` doesn't use wayland (if it uses xlib for example).
50 ///
51 /// The pointer will become invalid when the winit `EventLoop` is destroyed.
52 #[cfg(feature = "wayland")]
wayland_display(&self) -> Option<*mut raw::c_void>53 fn wayland_display(&self) -> Option<*mut raw::c_void>;
54 }
55
56 impl<T> EventLoopWindowTargetExtUnix for EventLoopWindowTarget<T> {
57 #[inline]
58 #[cfg(feature = "wayland")]
is_wayland(&self) -> bool59 fn is_wayland(&self) -> bool {
60 self.p.is_wayland()
61 }
62
63 #[inline]
64 #[cfg(feature = "x11")]
is_x11(&self) -> bool65 fn is_x11(&self) -> bool {
66 !self.p.is_wayland()
67 }
68
69 #[inline]
70 #[doc(hidden)]
71 #[cfg(feature = "x11")]
xlib_xconnection(&self) -> Option<Arc<XConnection>>72 fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
73 match self.p {
74 LinuxEventLoopWindowTarget::X(ref e) => Some(e.x_connection().clone()),
75 #[cfg(feature = "wayland")]
76 _ => None,
77 }
78 }
79
80 #[inline]
81 #[cfg(feature = "wayland")]
wayland_display(&self) -> Option<*mut raw::c_void>82 fn wayland_display(&self) -> Option<*mut raw::c_void> {
83 match self.p {
84 LinuxEventLoopWindowTarget::Wayland(ref p) => {
85 Some(p.display().get_display_ptr() as *mut _)
86 }
87 #[cfg(feature = "x11")]
88 _ => None,
89 }
90 }
91 }
92
93 /// Additional methods on `EventLoop` that are specific to Unix.
94 pub trait EventLoopExtUnix {
95 /// Builds a new `EventLoop` that is forced to use X11.
96 ///
97 /// # Panics
98 ///
99 /// If called outside the main thread. To initialize an X11 event loop outside
100 /// the main thread, use [`new_x11_any_thread`](#tymethod.new_x11_any_thread).
101 #[cfg(feature = "x11")]
new_x11() -> Result<Self, XNotSupported> where Self: Sized102 fn new_x11() -> Result<Self, XNotSupported>
103 where
104 Self: Sized;
105
106 /// Builds a new `EventLoop` that is forced to use Wayland.
107 ///
108 /// # Panics
109 ///
110 /// If called outside the main thread. To initialize a Wayland event loop outside
111 /// the main thread, use [`new_wayland_any_thread`](#tymethod.new_wayland_any_thread).
112 #[cfg(feature = "wayland")]
new_wayland() -> Self where Self: Sized113 fn new_wayland() -> Self
114 where
115 Self: Sized;
116
117 /// Builds a new `EventLoop` on any thread.
118 ///
119 /// This method bypasses the cross-platform compatibility requirement
120 /// that `EventLoop` be created on the main thread.
new_any_thread() -> Self where Self: Sized121 fn new_any_thread() -> Self
122 where
123 Self: Sized;
124
125 /// Builds a new X11 `EventLoop` on any thread.
126 ///
127 /// This method bypasses the cross-platform compatibility requirement
128 /// that `EventLoop` be created on the main thread.
129 #[cfg(feature = "x11")]
new_x11_any_thread() -> Result<Self, XNotSupported> where Self: Sized130 fn new_x11_any_thread() -> Result<Self, XNotSupported>
131 where
132 Self: Sized;
133
134 /// Builds a new Wayland `EventLoop` on any thread.
135 ///
136 /// This method bypasses the cross-platform compatibility requirement
137 /// that `EventLoop` be created on the main thread.
138 #[cfg(feature = "wayland")]
new_wayland_any_thread() -> Self where Self: Sized139 fn new_wayland_any_thread() -> Self
140 where
141 Self: Sized;
142 }
143
wrap_ev<T>(event_loop: LinuxEventLoop<T>) -> EventLoop<T>144 fn wrap_ev<T>(event_loop: LinuxEventLoop<T>) -> EventLoop<T> {
145 EventLoop {
146 event_loop,
147 _marker: std::marker::PhantomData,
148 }
149 }
150
151 impl<T> EventLoopExtUnix for EventLoop<T> {
152 #[inline]
new_any_thread() -> Self153 fn new_any_thread() -> Self {
154 wrap_ev(LinuxEventLoop::new_any_thread())
155 }
156
157 #[inline]
158 #[cfg(feature = "x11")]
new_x11_any_thread() -> Result<Self, XNotSupported>159 fn new_x11_any_thread() -> Result<Self, XNotSupported> {
160 LinuxEventLoop::new_x11_any_thread().map(wrap_ev)
161 }
162
163 #[inline]
164 #[cfg(feature = "wayland")]
new_wayland_any_thread() -> Self165 fn new_wayland_any_thread() -> Self {
166 wrap_ev(
167 LinuxEventLoop::new_wayland_any_thread()
168 // TODO: propagate
169 .expect("failed to open Wayland connection"),
170 )
171 }
172
173 #[inline]
174 #[cfg(feature = "x11")]
new_x11() -> Result<Self, XNotSupported>175 fn new_x11() -> Result<Self, XNotSupported> {
176 LinuxEventLoop::new_x11().map(wrap_ev)
177 }
178
179 #[inline]
180 #[cfg(feature = "wayland")]
new_wayland() -> Self181 fn new_wayland() -> Self {
182 wrap_ev(
183 LinuxEventLoop::new_wayland()
184 // TODO: propagate
185 .expect("failed to open Wayland connection"),
186 )
187 }
188 }
189
190 /// Additional methods on `Window` that are specific to Unix.
191 pub trait WindowExtUnix {
192 /// Returns the ID of the `Window` xlib object that is used by this window.
193 ///
194 /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
195 #[cfg(feature = "x11")]
xlib_window(&self) -> Option<raw::c_ulong>196 fn xlib_window(&self) -> Option<raw::c_ulong>;
197
198 /// Returns a pointer to the `Display` object of xlib that is used by this window.
199 ///
200 /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
201 ///
202 /// The pointer will become invalid when the glutin `Window` is destroyed.
203 #[cfg(feature = "x11")]
xlib_display(&self) -> Option<*mut raw::c_void>204 fn xlib_display(&self) -> Option<*mut raw::c_void>;
205
206 #[cfg(feature = "x11")]
xlib_screen_id(&self) -> Option<raw::c_int>207 fn xlib_screen_id(&self) -> Option<raw::c_int>;
208
209 #[doc(hidden)]
210 #[cfg(feature = "x11")]
xlib_xconnection(&self) -> Option<Arc<XConnection>>211 fn xlib_xconnection(&self) -> Option<Arc<XConnection>>;
212
213 /// Set window urgency hint (`XUrgencyHint`). Only relevant on X.
214 #[cfg(feature = "x11")]
set_urgent(&self, is_urgent: bool)215 fn set_urgent(&self, is_urgent: bool);
216
217 /// This function returns the underlying `xcb_connection_t` of an xlib `Display`.
218 ///
219 /// Returns `None` if the window doesn't use xlib (if it uses wayland for example).
220 ///
221 /// The pointer will become invalid when the glutin `Window` is destroyed.
222 #[cfg(feature = "x11")]
xcb_connection(&self) -> Option<*mut raw::c_void>223 fn xcb_connection(&self) -> Option<*mut raw::c_void>;
224
225 /// Returns a pointer to the `wl_surface` object of wayland that is used by this window.
226 ///
227 /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
228 ///
229 /// The pointer will become invalid when the glutin `Window` is destroyed.
230 #[cfg(feature = "wayland")]
wayland_surface(&self) -> Option<*mut raw::c_void>231 fn wayland_surface(&self) -> Option<*mut raw::c_void>;
232
233 /// Returns a pointer to the `wl_display` object of wayland that is used by this window.
234 ///
235 /// Returns `None` if the window doesn't use wayland (if it uses xlib for example).
236 ///
237 /// The pointer will become invalid when the glutin `Window` is destroyed.
238 #[cfg(feature = "wayland")]
wayland_display(&self) -> Option<*mut raw::c_void>239 fn wayland_display(&self) -> Option<*mut raw::c_void>;
240
241 /// Sets the color theme of the client side window decorations on wayland
242 #[cfg(feature = "wayland")]
set_wayland_theme<T: Theme>(&self, theme: T)243 fn set_wayland_theme<T: Theme>(&self, theme: T);
244
245 /// Check if the window is ready for drawing
246 ///
247 /// It is a remnant of a previous implementation detail for the
248 /// wayland backend, and is no longer relevant.
249 ///
250 /// Always return true.
251 #[deprecated]
is_ready(&self) -> bool252 fn is_ready(&self) -> bool;
253 }
254
255 impl WindowExtUnix for Window {
256 #[inline]
257 #[cfg(feature = "x11")]
xlib_window(&self) -> Option<raw::c_ulong>258 fn xlib_window(&self) -> Option<raw::c_ulong> {
259 match self.window {
260 LinuxWindow::X(ref w) => Some(w.xlib_window()),
261 #[cfg(feature = "wayland")]
262 _ => None,
263 }
264 }
265
266 #[inline]
267 #[cfg(feature = "x11")]
xlib_display(&self) -> Option<*mut raw::c_void>268 fn xlib_display(&self) -> Option<*mut raw::c_void> {
269 match self.window {
270 LinuxWindow::X(ref w) => Some(w.xlib_display()),
271 #[cfg(feature = "wayland")]
272 _ => None,
273 }
274 }
275
276 #[inline]
277 #[cfg(feature = "x11")]
xlib_screen_id(&self) -> Option<raw::c_int>278 fn xlib_screen_id(&self) -> Option<raw::c_int> {
279 match self.window {
280 LinuxWindow::X(ref w) => Some(w.xlib_screen_id()),
281 #[cfg(feature = "wayland")]
282 _ => None,
283 }
284 }
285
286 #[inline]
287 #[doc(hidden)]
288 #[cfg(feature = "x11")]
xlib_xconnection(&self) -> Option<Arc<XConnection>>289 fn xlib_xconnection(&self) -> Option<Arc<XConnection>> {
290 match self.window {
291 LinuxWindow::X(ref w) => Some(w.xlib_xconnection()),
292 #[cfg(feature = "wayland")]
293 _ => None,
294 }
295 }
296
297 #[inline]
298 #[cfg(feature = "x11")]
set_urgent(&self, is_urgent: bool)299 fn set_urgent(&self, is_urgent: bool) {
300 match self.window {
301 LinuxWindow::X(ref w) => w.set_urgent(is_urgent),
302 #[cfg(feature = "wayland")]
303 _ => (),
304 }
305 }
306
307 #[inline]
308 #[cfg(feature = "x11")]
xcb_connection(&self) -> Option<*mut raw::c_void>309 fn xcb_connection(&self) -> Option<*mut raw::c_void> {
310 match self.window {
311 LinuxWindow::X(ref w) => Some(w.xcb_connection()),
312 #[cfg(feature = "wayland")]
313 _ => None,
314 }
315 }
316
317 #[inline]
318 #[cfg(feature = "wayland")]
wayland_surface(&self) -> Option<*mut raw::c_void>319 fn wayland_surface(&self) -> Option<*mut raw::c_void> {
320 match self.window {
321 LinuxWindow::Wayland(ref w) => Some(w.surface().as_ref().c_ptr() as *mut _),
322 #[cfg(feature = "x11")]
323 _ => None,
324 }
325 }
326
327 #[inline]
328 #[cfg(feature = "wayland")]
wayland_display(&self) -> Option<*mut raw::c_void>329 fn wayland_display(&self) -> Option<*mut raw::c_void> {
330 match self.window {
331 LinuxWindow::Wayland(ref w) => Some(w.display().as_ref().c_ptr() as *mut _),
332 #[cfg(feature = "x11")]
333 _ => None,
334 }
335 }
336
337 #[inline]
338 #[cfg(feature = "wayland")]
set_wayland_theme<T: Theme>(&self, theme: T)339 fn set_wayland_theme<T: Theme>(&self, theme: T) {
340 match self.window {
341 LinuxWindow::Wayland(ref w) => w.set_theme(WaylandTheme(theme)),
342 #[cfg(feature = "x11")]
343 _ => {}
344 }
345 }
346
347 #[inline]
is_ready(&self) -> bool348 fn is_ready(&self) -> bool {
349 true
350 }
351 }
352
353 /// Additional methods on `WindowBuilder` that are specific to Unix.
354 pub trait WindowBuilderExtUnix {
355 #[cfg(feature = "x11")]
with_x11_visual<T>(self, visual_infos: *const T) -> Self356 fn with_x11_visual<T>(self, visual_infos: *const T) -> Self;
357 #[cfg(feature = "x11")]
with_x11_screen(self, screen_id: i32) -> Self358 fn with_x11_screen(self, screen_id: i32) -> Self;
359
360 /// Build window with `WM_CLASS` hint; defaults to the name of the binary. Only relevant on X11.
361 #[cfg(feature = "x11")]
with_class(self, class: String, instance: String) -> Self362 fn with_class(self, class: String, instance: String) -> Self;
363 /// Build window with override-redirect flag; defaults to false. Only relevant on X11.
364 #[cfg(feature = "x11")]
with_override_redirect(self, override_redirect: bool) -> Self365 fn with_override_redirect(self, override_redirect: bool) -> Self;
366 /// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`. Only relevant on X11.
367 #[cfg(feature = "x11")]
with_x11_window_type(self, x11_window_type: Vec<XWindowType>) -> Self368 fn with_x11_window_type(self, x11_window_type: Vec<XWindowType>) -> Self;
369 /// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11.
370 #[cfg(feature = "x11")]
with_gtk_theme_variant(self, variant: String) -> Self371 fn with_gtk_theme_variant(self, variant: String) -> Self;
372 /// Build window with resize increment hint. Only implemented on X11.
373 #[cfg(feature = "x11")]
with_resize_increments<S: Into<Size>>(self, increments: S) -> Self374 fn with_resize_increments<S: Into<Size>>(self, increments: S) -> Self;
375 /// Build window with base size hint. Only implemented on X11.
376 #[cfg(feature = "x11")]
with_base_size<S: Into<Size>>(self, base_size: S) -> Self377 fn with_base_size<S: Into<Size>>(self, base_size: S) -> Self;
378
379 /// Build window with a given application ID. It should match the `.desktop` file distributed with
380 /// your program. Only relevant on Wayland.
381 ///
382 /// For details about application ID conventions, see the
383 /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id)
384 #[cfg(feature = "wayland")]
with_app_id(self, app_id: String) -> Self385 fn with_app_id(self, app_id: String) -> Self;
386 }
387
388 impl WindowBuilderExtUnix for WindowBuilder {
389 #[inline]
390 #[cfg(feature = "x11")]
with_x11_visual<T>(mut self, visual_infos: *const T) -> Self391 fn with_x11_visual<T>(mut self, visual_infos: *const T) -> Self {
392 {
393 self.platform_specific.visual_infos =
394 Some(unsafe { ptr::read(visual_infos as *const XVisualInfo) });
395 }
396 self
397 }
398
399 #[inline]
400 #[cfg(feature = "x11")]
with_x11_screen(mut self, screen_id: i32) -> Self401 fn with_x11_screen(mut self, screen_id: i32) -> Self {
402 self.platform_specific.screen_id = Some(screen_id);
403 self
404 }
405
406 #[inline]
407 #[cfg(feature = "x11")]
with_class(mut self, instance: String, class: String) -> Self408 fn with_class(mut self, instance: String, class: String) -> Self {
409 self.platform_specific.class = Some((instance, class));
410 self
411 }
412
413 #[inline]
414 #[cfg(feature = "x11")]
with_override_redirect(mut self, override_redirect: bool) -> Self415 fn with_override_redirect(mut self, override_redirect: bool) -> Self {
416 self.platform_specific.override_redirect = override_redirect;
417 self
418 }
419
420 #[inline]
421 #[cfg(feature = "x11")]
with_x11_window_type(mut self, x11_window_types: Vec<XWindowType>) -> Self422 fn with_x11_window_type(mut self, x11_window_types: Vec<XWindowType>) -> Self {
423 self.platform_specific.x11_window_types = x11_window_types;
424 self
425 }
426
427 #[inline]
428 #[cfg(feature = "x11")]
with_gtk_theme_variant(mut self, variant: String) -> Self429 fn with_gtk_theme_variant(mut self, variant: String) -> Self {
430 self.platform_specific.gtk_theme_variant = Some(variant);
431 self
432 }
433
434 #[inline]
435 #[cfg(feature = "x11")]
with_resize_increments<S: Into<Size>>(mut self, increments: S) -> Self436 fn with_resize_increments<S: Into<Size>>(mut self, increments: S) -> Self {
437 self.platform_specific.resize_increments = Some(increments.into());
438 self
439 }
440
441 #[inline]
442 #[cfg(feature = "x11")]
with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self443 fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
444 self.platform_specific.base_size = Some(base_size.into());
445 self
446 }
447
448 #[inline]
449 #[cfg(feature = "wayland")]
with_app_id(mut self, app_id: String) -> Self450 fn with_app_id(mut self, app_id: String) -> Self {
451 self.platform_specific.app_id = Some(app_id);
452 self
453 }
454 }
455
456 /// Additional methods on `MonitorHandle` that are specific to Linux.
457 pub trait MonitorHandleExtUnix {
458 /// Returns the inner identifier of the monitor.
native_id(&self) -> u32459 fn native_id(&self) -> u32;
460 }
461
462 impl MonitorHandleExtUnix for MonitorHandle {
463 #[inline]
native_id(&self) -> u32464 fn native_id(&self) -> u32 {
465 self.inner.native_identifier()
466 }
467 }
468
469 /// Wrapper for implementing SCTK's theme trait.
470 #[cfg(feature = "wayland")]
471 struct WaylandTheme<T: Theme>(T);
472
473 pub trait Theme: Send + 'static {
474 /// Primary color of the scheme.
primary_color(&self, window_active: bool) -> [u8; 4]475 fn primary_color(&self, window_active: bool) -> [u8; 4];
476
477 /// Secondary color of the scheme.
secondary_color(&self, window_active: bool) -> [u8; 4]478 fn secondary_color(&self, window_active: bool) -> [u8; 4];
479
480 /// Color for the close button.
close_button_color(&self, status: ButtonState) -> [u8; 4]481 fn close_button_color(&self, status: ButtonState) -> [u8; 4];
482
483 /// Icon color for the close button, defaults to the secondary color.
484 #[allow(unused_variables)]
close_button_icon_color(&self, status: ButtonState) -> [u8; 4]485 fn close_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
486 self.secondary_color(true)
487 }
488
489 /// Background color for the maximize button.
maximize_button_color(&self, status: ButtonState) -> [u8; 4]490 fn maximize_button_color(&self, status: ButtonState) -> [u8; 4];
491
492 /// Icon color for the maximize button, defaults to the secondary color.
493 #[allow(unused_variables)]
maximize_button_icon_color(&self, status: ButtonState) -> [u8; 4]494 fn maximize_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
495 self.secondary_color(true)
496 }
497
498 /// Background color for the minimize button.
minimize_button_color(&self, status: ButtonState) -> [u8; 4]499 fn minimize_button_color(&self, status: ButtonState) -> [u8; 4];
500
501 /// Icon color for the minimize button, defaults to the secondary color.
502 #[allow(unused_variables)]
minimize_button_icon_color(&self, status: ButtonState) -> [u8; 4]503 fn minimize_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
504 self.secondary_color(true)
505 }
506 }
507
508 #[cfg(feature = "wayland")]
509 impl<T: Theme> SCTKTheme for WaylandTheme<T> {
get_primary_color(&self, active: bool) -> [u8; 4]510 fn get_primary_color(&self, active: bool) -> [u8; 4] {
511 self.0.primary_color(active)
512 }
513
get_secondary_color(&self, active: bool) -> [u8; 4]514 fn get_secondary_color(&self, active: bool) -> [u8; 4] {
515 self.0.secondary_color(active)
516 }
517
get_close_button_color(&self, status: SCTKButtonState) -> [u8; 4]518 fn get_close_button_color(&self, status: SCTKButtonState) -> [u8; 4] {
519 self.0.close_button_color(ButtonState::from_sctk(status))
520 }
521
get_close_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4]522 fn get_close_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4] {
523 self.0
524 .close_button_icon_color(ButtonState::from_sctk(status))
525 }
526
get_maximize_button_color(&self, status: SCTKButtonState) -> [u8; 4]527 fn get_maximize_button_color(&self, status: SCTKButtonState) -> [u8; 4] {
528 self.0.maximize_button_color(ButtonState::from_sctk(status))
529 }
530
get_maximize_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4]531 fn get_maximize_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4] {
532 self.0
533 .maximize_button_icon_color(ButtonState::from_sctk(status))
534 }
535
get_minimize_button_color(&self, status: SCTKButtonState) -> [u8; 4]536 fn get_minimize_button_color(&self, status: SCTKButtonState) -> [u8; 4] {
537 self.0.minimize_button_color(ButtonState::from_sctk(status))
538 }
539
get_minimize_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4]540 fn get_minimize_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4] {
541 self.0
542 .minimize_button_icon_color(ButtonState::from_sctk(status))
543 }
544 }
545
546 pub enum ButtonState {
547 /// Button is being hovered over by pointer.
548 Hovered,
549 /// Button is not being hovered over by pointer.
550 Idle,
551 /// Button is disabled.
552 Disabled,
553 }
554
555 #[cfg(feature = "wayland")]
556 impl ButtonState {
from_sctk(button_state: SCTKButtonState) -> Self557 fn from_sctk(button_state: SCTKButtonState) -> Self {
558 match button_state {
559 SCTKButtonState::Hovered => Self::Hovered,
560 SCTKButtonState::Idle => Self::Idle,
561 SCTKButtonState::Disabled => Self::Disabled,
562 }
563 }
564 }
565