1 //! SCTK environment setup. 2 3 use sctk::reexports::client::protocol::wl_compositor::WlCompositor; 4 use sctk::reexports::client::protocol::wl_output::WlOutput; 5 use sctk::reexports::protocols::unstable::xdg_shell::v6::client::zxdg_shell_v6::ZxdgShellV6; 6 use sctk::reexports::client::protocol::wl_seat::WlSeat; 7 use sctk::reexports::protocols::unstable::xdg_decoration::v1::client::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1; 8 use sctk::reexports::client::protocol::wl_shell::WlShell; 9 use sctk::reexports::client::protocol::wl_subcompositor::WlSubcompositor; 10 use sctk::reexports::client::{Attached, DispatchData}; 11 use sctk::reexports::client::protocol::wl_shm::WlShm; 12 use sctk::reexports::protocols::xdg_shell::client::xdg_wm_base::XdgWmBase; 13 use sctk::reexports::protocols::unstable::relative_pointer::v1::client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1; 14 use sctk::reexports::protocols::unstable::pointer_constraints::v1::client::zwp_pointer_constraints_v1::ZwpPointerConstraintsV1; 15 use sctk::reexports::protocols::unstable::text_input::v3::client::zwp_text_input_manager_v3::ZwpTextInputManagerV3; 16 17 use sctk::environment::{Environment, SimpleGlobal}; 18 use sctk::output::{OutputHandler, OutputHandling, OutputInfo, OutputStatusListener}; 19 use sctk::seat::{SeatData, SeatHandler, SeatHandling, SeatListener}; 20 use sctk::shell::{Shell, ShellHandler, ShellHandling}; 21 use sctk::shm::ShmHandler; 22 23 /// Set of extra features that are supported by the compositor. 24 #[derive(Debug, Clone, Copy)] 25 pub struct WindowingFeatures { 26 cursor_grab: bool, 27 } 28 29 impl WindowingFeatures { 30 /// Create `WindowingFeatures` based on the presented interfaces. new(env: &Environment<WinitEnv>) -> Self31 pub fn new(env: &Environment<WinitEnv>) -> Self { 32 let cursor_grab = env.get_global::<ZwpPointerConstraintsV1>().is_some(); 33 Self { cursor_grab } 34 } 35 cursor_grab(&self) -> bool36 pub fn cursor_grab(&self) -> bool { 37 self.cursor_grab 38 } 39 } 40 41 sctk::environment!(WinitEnv, 42 singles = [ 43 WlShm => shm, 44 WlCompositor => compositor, 45 WlSubcompositor => subcompositor, 46 WlShell => shell, 47 XdgWmBase => shell, 48 ZxdgShellV6 => shell, 49 ZxdgDecorationManagerV1 => decoration_manager, 50 ZwpRelativePointerManagerV1 => relative_pointer_manager, 51 ZwpPointerConstraintsV1 => pointer_constraints, 52 ZwpTextInputManagerV3 => text_input_manager, 53 ], 54 multis = [ 55 WlSeat => seats, 56 WlOutput => outputs, 57 ] 58 ); 59 60 /// The environment that we utilize. 61 pub struct WinitEnv { 62 seats: SeatHandler, 63 64 outputs: OutputHandler, 65 66 shm: ShmHandler, 67 68 compositor: SimpleGlobal<WlCompositor>, 69 70 subcompositor: SimpleGlobal<WlSubcompositor>, 71 72 shell: ShellHandler, 73 74 relative_pointer_manager: SimpleGlobal<ZwpRelativePointerManagerV1>, 75 76 pointer_constraints: SimpleGlobal<ZwpPointerConstraintsV1>, 77 78 text_input_manager: SimpleGlobal<ZwpTextInputManagerV3>, 79 80 decoration_manager: SimpleGlobal<ZxdgDecorationManagerV1>, 81 } 82 83 impl WinitEnv { new() -> Self84 pub fn new() -> Self { 85 // Output tracking for available_monitors, etc. 86 let outputs = OutputHandler::new(); 87 88 // Keyboard/Pointer/Touch input. 89 let seats = SeatHandler::new(); 90 91 // Essential globals. 92 let shm = ShmHandler::new(); 93 let compositor = SimpleGlobal::new(); 94 let subcompositor = SimpleGlobal::new(); 95 96 // Gracefully handle shell picking, since SCTK automatically supports multiple 97 // backends. 98 let shell = ShellHandler::new(); 99 100 // Server side decorations. 101 let decoration_manager = SimpleGlobal::new(); 102 103 // Device events for pointer. 104 let relative_pointer_manager = SimpleGlobal::new(); 105 106 // Pointer grab functionality. 107 let pointer_constraints = SimpleGlobal::new(); 108 109 // IME handling. 110 let text_input_manager = SimpleGlobal::new(); 111 112 Self { 113 seats, 114 outputs, 115 shm, 116 compositor, 117 subcompositor, 118 shell, 119 decoration_manager, 120 relative_pointer_manager, 121 pointer_constraints, 122 text_input_manager, 123 } 124 } 125 } 126 127 impl ShellHandling for WinitEnv { get_shell(&self) -> Option<Shell>128 fn get_shell(&self) -> Option<Shell> { 129 self.shell.get_shell() 130 } 131 } 132 133 impl SeatHandling for WinitEnv { listen<F: FnMut(Attached<WlSeat>, &SeatData, DispatchData<'_>) + 'static>( &mut self, f: F, ) -> SeatListener134 fn listen<F: FnMut(Attached<WlSeat>, &SeatData, DispatchData<'_>) + 'static>( 135 &mut self, 136 f: F, 137 ) -> SeatListener { 138 self.seats.listen(f) 139 } 140 } 141 142 impl OutputHandling for WinitEnv { listen<F: FnMut(WlOutput, &OutputInfo, DispatchData<'_>) + 'static>( &mut self, f: F, ) -> OutputStatusListener143 fn listen<F: FnMut(WlOutput, &OutputInfo, DispatchData<'_>) + 'static>( 144 &mut self, 145 f: F, 146 ) -> OutputStatusListener { 147 self.outputs.listen(f) 148 } 149 } 150