diff --git a/Cargo.toml b/Cargo.toml index 4a60477..1af9476 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,30 +10,31 @@ repository = "https://github.com/pinnacle-comp/pinnacle/" keywords = ["wayland", "compositor", "smithay", "lua"] [dependencies] -tracing = { git = "https://github.com/tokio-rs/tracing", rev = "b8c45cc" } -tracing-subscriber = { git = "https://github.com/tokio-rs/tracing", rev = "b8c45cc", features = ["env-filter"] } -tracing-appender = { git = "https://github.com/tokio-rs/tracing", rev = "b8c45cc" } -smithay = { git = "https://github.com/Smithay/smithay", rev = "1a61e1c", features = ["desktop", "wayland_frontend"] } -smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "1a61e1c", optional = true } +tracing = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60" } +tracing-subscriber = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60", features = ["env-filter"] } +tracing-appender = { git = "https://github.com/tokio-rs/tracing", rev = "84f0a60" } +smithay = { git = "https://github.com/Smithay/smithay", rev = "4e41ab0" } +smithay-drm-extras = { git = "https://github.com/Smithay/smithay", rev = "4e41ab0", optional = true } thiserror = "1.0.48" xcursor = { version = "0.3.4", optional = true } image = { version = "0.24.7", default-features = false, optional = true } serde = { version = "1.0.188", features = ["derive"] } rmp = { version = "0.8.12" } rmp-serde = { version = "1.1.2" } -calloop = { version = "0.10.1", features = ["executor", "futures-io"] } +calloop = { version = "0.12.2", features = ["executor", "futures-io"] } futures-lite = { version = "1.13.0" } async-process = { version = "1.7.0" } async-channel = "1.9.0" x11rb = { version = "0.12.0", default-features = false, features = ["composite"], optional = true } shellexpand = "3.1.0" -toml = "0.7.7" +toml = "0.8.2" anyhow = { version = "1.0.75", features = ["backtrace"] } clap = { version = "4.4.2", features = ["derive"] } xkbcommon = "0.6.0" xdg = "2.5.2" lazy_static = "1.4.0" sysinfo = "0.29.10" +nix = { version = "0.27.1", features = ["user", "resource"] } [features] default = ["egl", "winit", "udev", "xwayland"] diff --git a/src/backend/udev.rs b/src/backend/udev.rs index cb68a73..2d2320f 100644 --- a/src/backend/udev.rs +++ b/src/backend/udev.rs @@ -73,10 +73,7 @@ use smithay::{ }, }, utils::{Clock, DeviceFd, IsAlive, Logical, Monotonic, Point, Transform}, - wayland::{ - dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufState}, - input_method::{InputMethodHandle, InputMethodSeat}, - }, + wayland::dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufState}, xwayland::X11Surface, }; use smithay_drm_extras::{ @@ -159,8 +156,8 @@ impl BackendData for Udev { } pub fn run_udev() -> anyhow::Result<()> { - let mut event_loop = EventLoop::try_new_high_precision()?; - let mut display = Display::new()?; + let mut event_loop = EventLoop::try_new()?; + let display = Display::new()?; // Initialize session let (session, notifier) = LibSeatSession::new()?; @@ -198,9 +195,11 @@ pub fn run_udev() -> anyhow::Result<()> { pointer_element: PointerElement::default(), }; + let display_handle = display.handle(); + let mut state = State::init( Backend::Udev(data), - &mut display, + display, event_loop.get_signal(), event_loop.handle(), )?; @@ -377,7 +376,8 @@ pub fn run_udev() -> anyhow::Result<()> { ?primary_gpu, "Trying to initialize EGL Hardware Acceleration", ); - match renderer.bind_wl_display(&display.handle()) { + + match renderer.bind_wl_display(&display_handle) { Ok(_) => tracing::info!("EGL hardware-acceleration enabled"), Err(err) => tracing::error!(?err, "Failed to initialize EGL hardware-acceleration"), } @@ -389,7 +389,7 @@ pub fn run_udev() -> anyhow::Result<()> { .expect("failed to create dmabuf feedback"); let mut dmabuf_state = DmabufState::new(); let global = dmabuf_state - .create_global_with_default_feedback::(&display.handle(), &default_feedback); + .create_global_with_default_feedback::(&display_handle, &default_feedback); udev.dmabuf_state = Some((dmabuf_state, global)); let gpu_manager = &mut udev.gpu_manager; @@ -419,11 +419,14 @@ pub fn run_udev() -> anyhow::Result<()> { event_loop.run( Some(Duration::from_micros(((1.0 / 144.0) * 1000000.0) as u64)), - &mut CalloopData { state, display }, + &mut CalloopData { + state, + display_handle, + }, |data| { data.state.space.refresh(); data.state.popup_manager.cleanup(); - data.display + data.display_handle .flush_clients() .expect("failed to flush_clients"); }, @@ -1244,7 +1247,7 @@ impl State { surface, &mut renderer, &output, - self.seat.input_method(), + // self.seat.input_method(), &pointer_image, &mut udev.pointer_element, self.pointer_location, @@ -1361,7 +1364,7 @@ fn render_surface<'a>( surface: &'a mut SurfaceData, renderer: &mut UdevRenderer<'a, '_>, output: &Output, - input_method: &InputMethodHandle, + // input_method: &InputMethodHandle, pointer_image: &TextureBuffer, pointer_element: &mut PointerElement, pointer_location: Point, @@ -1416,7 +1419,7 @@ fn render_surface<'a>( pointer_location, cursor_status, dnd_icon, - input_method, + // input_method, pointer_element, Some(pointer_image), ); diff --git a/src/backend/winit.rs b/src/backend/winit.rs index cb65710..0e82e85 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -27,10 +27,7 @@ use smithay::{ wayland_server::{protocol::wl_surface::WlSurface, Display}, }, utils::{IsAlive, Transform}, - wayland::{ - dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufState}, - input_method::InputMethodSeat, - }, + wayland::dmabuf::{DmabufFeedback, DmabufFeedbackBuilder, DmabufGlobal, DmabufState}, }; use crate::{ @@ -62,9 +59,9 @@ impl BackendData for Winit { /// Start Pinnacle as a window in a graphical environment. pub fn run_winit() -> anyhow::Result<()> { - let mut event_loop: EventLoop = EventLoop::try_new_high_precision()?; + let mut event_loop: EventLoop = EventLoop::try_new()?; - let mut display: Display = Display::new()?; + let display: Display = Display::new()?; let display_handle = display.handle(); let evt_loop_handle = event_loop.handle(); @@ -84,8 +81,7 @@ pub fn run_winit() -> anyhow::Result<()> { size: (0, 0).into(), subpixel: Subpixel::Unknown, make: "Pinnacle".to_string(), - model: "69LongMonitorNameXQ83VGX Super Ultra Pro Max XTX Ti Plus with Max-Q Design (and Knuckles)" - .to_string(), + model: "Winit Window".to_string(), }; let output = Output::new("Pinnacle window".to_string(), physical_properties); @@ -160,7 +156,7 @@ pub fn run_winit() -> anyhow::Result<()> { dmabuf_state, full_redraw: 0, }), - &mut display, + display, event_loop.get_signal(), evt_loop_handle, )?; @@ -193,7 +189,7 @@ pub fn run_winit() -> anyhow::Result<()> { state .loop_handle .insert_source(Timer::immediate(), move |_instant, _metadata, data| { - let display = &mut data.display; + let display_handle = &mut data.display_handle; let state = &mut data.state; let result = winit_evt_loop.dispatch_new_events(|event| match event { @@ -230,7 +226,7 @@ pub fn run_winit() -> anyhow::Result<()> { if let CursorImageStatus::Surface(surface) = &state.cursor_status { if !surface.alive() { - state.cursor_status = CursorImageStatus::Default; + state.cursor_status = CursorImageStatus::default_named(); } } @@ -277,7 +273,7 @@ pub fn run_winit() -> anyhow::Result<()> { state.space.refresh(); state.popup_manager.cleanup(); - display + display_handle .flush_clients() .expect("failed to flush client buffers"); @@ -303,7 +299,7 @@ pub fn run_winit() -> anyhow::Result<()> { state.pointer_location, &mut state.cursor_status, state.dnd_icon.as_ref(), - state.seat.input_method(), + // state.seat.input_method(), &mut pointer_element, None, ); @@ -387,7 +383,7 @@ pub fn run_winit() -> anyhow::Result<()> { state.space.refresh(); state.popup_manager.cleanup(); - display + display_handle .flush_clients() .expect("failed to flush client buffers"); @@ -400,7 +396,10 @@ pub fn run_winit() -> anyhow::Result<()> { event_loop.run( Some(Duration::from_micros(((1.0 / 144.0) * 1000000.0) as u64)), - &mut CalloopData { display, state }, + &mut CalloopData { + display_handle, + state, + }, |_data| { // println!("{}", _data.state.space.elements().count()); }, diff --git a/src/config.rs b/src/config.rs index 5a60f94..ba4d1a8 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,6 +19,7 @@ use smithay::{ use toml::Table; use api::msg::Modifier; +use xkbcommon::xkb::Keysym; use crate::{ state::{State, WithState}, @@ -286,8 +287,8 @@ impl State { let reload_mask = ModifierMask::from(reload_keybind.modifiers); let kill_mask = ModifierMask::from(kill_keybind.modifiers); - let reload_keybind = (reload_mask, reload_keybind.key as u32); - let kill_keybind = (kill_mask, kill_keybind.key as u32); + let reload_keybind = (reload_mask, Keysym::from(reload_keybind.key as u32)); + let kill_keybind = (kill_mask, Keysym::from(kill_keybind.key as u32)); let socket_token = self .loop_handle diff --git a/src/focus.rs b/src/focus.rs index 399b8f6..a12b07e 100644 --- a/src/focus.rs +++ b/src/focus.rs @@ -112,6 +112,14 @@ impl TryFrom for WlSurface { } impl PointerTarget for FocusTarget { + fn frame(&self, seat: &Seat, data: &mut State) { + match self { + FocusTarget::Window(window) => window.frame(seat, data), + FocusTarget::Popup(popup) => popup.wl_surface().frame(seat, data), + FocusTarget::LayerSurface(surf) => surf.frame(seat, data), + } + } + fn enter(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { match self { FocusTarget::Window(window) => PointerTarget::enter(window, seat, data, event), diff --git a/src/grab/move_grab.rs b/src/grab/move_grab.rs index 38e2aaa..9adea0e 100644 --- a/src/grab/move_grab.rs +++ b/src/grab/move_grab.rs @@ -32,6 +32,10 @@ pub struct MoveSurfaceGrab { } impl PointerGrab for MoveSurfaceGrab { + fn frame(&mut self, data: &mut State, handle: &mut PointerInnerHandle<'_, State>) { + handle.frame(data); + } + fn motion( &mut self, state: &mut State, diff --git a/src/grab/resize_grab.rs b/src/grab/resize_grab.rs index 4f40247..2780d37 100644 --- a/src/grab/resize_grab.rs +++ b/src/grab/resize_grab.rs @@ -83,6 +83,10 @@ impl ResizeSurfaceGrab { } impl PointerGrab for ResizeSurfaceGrab { + fn frame(&mut self, data: &mut State, handle: &mut PointerInnerHandle<'_, State>) { + handle.frame(data); + } + fn motion( &mut self, data: &mut State, diff --git a/src/handlers.rs b/src/handlers.rs index cb35741..5bcb42e 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -3,6 +3,8 @@ mod xdg_shell; mod xwayland; +use std::os::fd::OwnedFd; + use smithay::{ backend::renderer::utils, delegate_compositor, delegate_data_device, delegate_fractional_scale, delegate_layer_shell, @@ -13,7 +15,6 @@ use smithay::{ output::Output, reexports::{ calloop::Interest, - wayland_protocols::wp::primary_selection::zv1::server::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1, wayland_server::{ protocol::{ wl_buffer::WlBuffer, wl_data_source::WlDataSource, wl_output::WlOutput, @@ -28,23 +29,26 @@ use smithay::{ self, BufferAssignment, CompositorClientState, CompositorHandler, CompositorState, SurfaceAttributes, }, - data_device::{ - self, set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, - ServerDndGrabHandler, - }, dmabuf, fractional_scale::{self, FractionalScaleHandler}, - primary_selection::{ - self, set_primary_focus, PrimarySelectionHandler, PrimarySelectionState, - }, seat::WaylandFocus, + selection::data_device::{ + set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, + ServerDndGrabHandler, + }, + selection::{ + primary_selection::{ + set_primary_focus, PrimarySelectionHandler, PrimarySelectionState, + }, + SelectionHandler, SelectionSource, SelectionTarget, + }, shell::{ wlr_layer::{self, Layer, LayerSurfaceData, WlrLayerShellHandler, WlrLayerShellState}, xdg::{XdgPopupSurfaceData, XdgToplevelSurfaceData}, }, shm::{ShmHandler, ShmState}, }, - xwayland::{xwm::SelectionType, X11Wm, XWaylandClientData}, + xwayland::{X11Wm, XWaylandClientData}, }; use crate::{ @@ -83,7 +87,7 @@ impl CompositorHandler for State { let res = state.loop_handle.insert_source(source, move |_, _, data| { data.state .client_compositor_state(&client) - .blocker_cleared(&mut data.state, &data.display.handle()); + .blocker_cleared(&mut data.state, &data.display_handle); Ok(()) }); if res.is_ok() { @@ -164,7 +168,7 @@ fn ensure_initial_configure(surface: &WlSurface, state: &mut State) { } if let Some(popup) = state.popup_manager.find_popup(surface) { - let PopupKind::Xdg(popup) = &popup; + let PopupKind::Xdg(popup) = &popup else { return }; let initial_configure_sent = compositor::with_states(surface, |states| { states .data_map @@ -227,87 +231,49 @@ impl ClientDndGrabHandler for State { impl ServerDndGrabHandler for State {} -impl DataDeviceHandler for State { +impl SelectionHandler for State { type SelectionUserData = (); - fn data_device_state(&self) -> &DataDeviceState { - &self.data_device_state - } - - fn new_selection(&mut self, source: Option, _seat: Seat) { + fn new_selection( + &mut self, + ty: SelectionTarget, + source: Option, + _seat: Seat, + ) { if let Some(xwm) = self.xwm.as_mut() { - if let Some(source) = source { - if let Ok(Err(err)) = data_device::with_source_metadata(&source, |metadata| { - xwm.new_selection(SelectionType::Clipboard, Some(metadata.mime_types.clone())) - }) { - tracing::warn!(?err, "Failed to set Xwayland clipboard selection"); - } - } else if let Err(err) = xwm.new_selection(SelectionType::Clipboard, None) { - tracing::warn!(?err, "Failed to clear Xwayland clipboard selection"); + if let Err(err) = xwm.new_selection(ty, source.map(|source| source.mime_types())) { + tracing::warn!(?err, ?ty, "Failed to set Xwayland selection"); } } } fn send_selection( &mut self, + ty: SelectionTarget, mime_type: String, - fd: std::os::fd::OwnedFd, + fd: OwnedFd, _seat: Seat, - _user_data: &Self::SelectionUserData, + _user_data: &(), ) { if let Some(xwm) = self.xwm.as_mut() { - if let Err(err) = xwm.send_selection( - SelectionType::Clipboard, - mime_type, - fd, - self.loop_handle.clone(), - ) { - tracing::warn!(?err, "Failed to send clipboard (X11 -> Wayland)"); + if let Err(err) = xwm.send_selection(ty, mime_type, fd, self.loop_handle.clone()) { + tracing::warn!(?err, "Failed to send primary (X11 -> Wayland)"); } } } } + +impl DataDeviceHandler for State { + fn data_device_state(&self) -> &DataDeviceState { + &self.data_device_state + } +} delegate_data_device!(State); impl PrimarySelectionHandler for State { - type SelectionUserData = (); - fn primary_selection_state(&self) -> &PrimarySelectionState { &self.primary_selection_state } - - fn new_selection(&mut self, source: Option, _seat: Seat) { - if let Some(xwm) = self.xwm.as_mut() { - if let Some(source) = source { - if let Ok(Err(err)) = primary_selection::with_source_metadata(&source, |metadata| { - xwm.new_selection(SelectionType::Primary, Some(metadata.mime_types.clone())) - }) { - tracing::warn!(?err, "Failed to set Xwayland primary selection"); - } - } else if let Err(err) = xwm.new_selection(SelectionType::Primary, None) { - tracing::warn!(?err, "Failed to clear Xwayland primary selection"); - } - } - } - - fn send_selection( - &mut self, - mime_type: String, - fd: std::os::fd::OwnedFd, - _seat: Seat, - _user_data: &Self::SelectionUserData, - ) { - if let Some(xwm) = self.xwm.as_mut() { - if let Err(err) = xwm.send_selection( - SelectionType::Primary, - mime_type, - fd, - self.loop_handle.clone(), - ) { - tracing::warn!(?err, "Failed to send primary (X11 -> Wayland)"); - } - } - } } delegate_primary_selection!(State); diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index a24e0d5..6d7398d 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -197,7 +197,7 @@ impl XdgShellHandler for State { if let Some(popup) = self.popup_manager.find_popup(s) { // popup.geometry() doesn't return the right location, so we dive into the // PopupSurface's state to grab it. - let PopupKind::Xdg(popup_surf) = &popup; + let PopupKind::Xdg(popup_surf) = &popup else { return }; // TODO: let l = popup_surf.with_pending_state(|state| state.geometry.loc); tracing::debug!(loc = ?l, "parent is popup"); loc += l; diff --git a/src/handlers/xwayland.rs b/src/handlers/xwayland.rs index e82dd5b..d991e82 100644 --- a/src/handlers/xwayland.rs +++ b/src/handlers/xwayland.rs @@ -3,17 +3,20 @@ use smithay::{ utils::{Logical, Point, Rectangle, SERIAL_COUNTER}, wayland::{ - data_device::{ + selection::data_device::{ clear_data_device_selection, current_data_device_selection_userdata, request_data_device_client_selection, set_data_device_selection, }, - primary_selection::{ - clear_primary_selection, current_primary_selection_userdata, - request_primary_client_selection, set_primary_selection, + selection::{ + primary_selection::{ + clear_primary_selection, current_primary_selection_userdata, + request_primary_client_selection, set_primary_selection, + }, + SelectionTarget, }, }, xwayland::{ - xwm::{Reorder, SelectionType, WmWindowType, XwmId}, + xwm::{Reorder, WmWindowType, XwmId}, X11Surface, X11Wm, XwmHandler, }, }; @@ -403,7 +406,7 @@ impl XwmHandler for CalloopData { ); } - fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionType) -> bool { + fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionTarget) -> bool { self.state .seat .get_keyboard() @@ -420,12 +423,12 @@ impl XwmHandler for CalloopData { fn send_selection( &mut self, _xwm: XwmId, - selection: SelectionType, + selection: SelectionTarget, mime_type: String, fd: std::os::fd::OwnedFd, ) { match selection { - SelectionType::Clipboard => { + SelectionTarget::Clipboard => { if let Err(err) = request_data_device_client_selection(&self.state.seat, mime_type, fd) { @@ -435,7 +438,7 @@ impl XwmHandler for CalloopData { ); } } - SelectionType::Primary => { + SelectionTarget::Primary => { if let Err(err) = request_primary_client_selection(&self.state.seat, mime_type, fd) { tracing::error!( @@ -447,9 +450,9 @@ impl XwmHandler for CalloopData { } } - fn new_selection(&mut self, _xwm: XwmId, selection: SelectionType, mime_types: Vec) { + fn new_selection(&mut self, _xwm: XwmId, selection: SelectionTarget, mime_types: Vec) { match selection { - SelectionType::Clipboard => { + SelectionTarget::Clipboard => { set_data_device_selection( &self.state.display_handle, &self.state.seat, @@ -457,20 +460,20 @@ impl XwmHandler for CalloopData { (), ); } - SelectionType::Primary => { + SelectionTarget::Primary => { set_primary_selection(&self.state.display_handle, &self.state.seat, mime_types, ()); } } } - fn cleared_selection(&mut self, _xwm: XwmId, selection: SelectionType) { + fn cleared_selection(&mut self, _xwm: XwmId, selection: SelectionTarget) { match selection { - SelectionType::Clipboard => { + SelectionTarget::Clipboard => { if current_data_device_selection_userdata(&self.state.seat).is_some() { clear_data_device_selection(&self.state.display_handle, &self.state.seat); } } - SelectionType::Primary => { + SelectionTarget::Primary => { if current_primary_selection_userdata(&self.state.seat).is_some() { clear_primary_selection(&self.state.display_handle, &self.state.seat); } diff --git a/src/input.rs b/src/input.rs index 5634cae..49f9dd3 100644 --- a/src/input.rs +++ b/src/input.rs @@ -27,17 +27,18 @@ use smithay::{ utils::{Logical, Point, SERIAL_COUNTER}, wayland::{seat::WaylandFocus, shell::wlr_layer}, }; +use xkbcommon::xkb::Keysym; use crate::state::State; #[derive(Default, Debug)] pub struct InputState { /// A hashmap of modifier keys and keycodes to callback IDs - pub keybinds: HashMap<(ModifierMask, u32), CallbackId>, + pub keybinds: HashMap<(ModifierMask, Keysym), CallbackId>, /// A hashmap of modifier keys and mouse button codes to callback IDs pub mousebinds: HashMap<(ModifierMask, u32, MouseEdge), CallbackId>, - pub reload_keybind: Option<(ModifierMask, u32)>, - pub kill_keybind: Option<(ModifierMask, u32)>, + pub reload_keybind: Option<(ModifierMask, Keysym)>, + pub kill_keybind: Option<(ModifierMask, Keysym)>, pub libinput_settings: Vec, pub libinput_devices: Vec, } @@ -337,7 +338,7 @@ impl State { } else if Some((modifier_mask, mod_sym)) == reload_keybind { return FilterResult::Intercept(KeyAction::ReloadConfig); } else if let mut vt @ keysyms::KEY_XF86Switch_VT_1 - ..=keysyms::KEY_XF86Switch_VT_12 = keysym.modified_sym() + ..=keysyms::KEY_XF86Switch_VT_12 = keysym.modified_sym().raw() { vt = vt - keysyms::KEY_XF86Switch_VT_1 + 1; tracing::info!("Switching to vt {vt}"); @@ -345,7 +346,7 @@ impl State { } } - if keysym.modified_sym() == keysyms::KEY_Control_L { + if keysym.modified_sym() == Keysym::Control_L { match press_state { KeyState::Pressed => { move_mode = true; diff --git a/src/render.rs b/src/render.rs index c4098bf..c44e4f1 100644 --- a/src/render.rs +++ b/src/render.rs @@ -12,7 +12,7 @@ use smithay::{ }, desktop::{ layer_map_for_output, - space::{SpaceElement, SpaceRenderElements, SurfaceTree}, + space::{SpaceElement, SpaceRenderElements}, utils::{ surface_presentation_feedback_flags_from_states, surface_primary_scanout_output, OutputPresentationFeedback, @@ -27,7 +27,7 @@ use smithay::{ }, render_elements, utils::{IsAlive, Logical, Physical, Point, Scale}, - wayland::{compositor, input_method::InputMethodHandle, shell::wlr_layer}, + wayland::{compositor, shell::wlr_layer}, xwayland::X11Surface, }; @@ -181,7 +181,7 @@ pub fn generate_render_elements( pointer_location: Point, cursor_status: &mut CursorImageStatus, dnd_icon: Option<&WlSurface>, - input_method: &InputMethodHandle, + // input_method: &InputMethodHandle, pointer_element: &mut PointerElement, pointer_image: Option<&TextureBuffer>, ) -> Vec>> @@ -196,21 +196,21 @@ where let scale = Scale::from(output.current_scale().fractional_scale()); let mut custom_render_elements: Vec> = Vec::new(); - // draw input method surface if any - let rectangle = input_method.coordinates(); - let position = Point::from(( - rectangle.loc.x + rectangle.size.w, - rectangle.loc.y + rectangle.size.h, - )); - input_method.with_surface(|surface| { - custom_render_elements.extend(AsRenderElements::::render_elements( - &SurfaceTree::from_surface(surface), - renderer, - position.to_physical_precise_round(scale), - scale, - 1.0, - )); - }); + // // draw input method surface if any + // let rectangle = input_method.coordinates(); + // let position = Point::from(( + // rectangle.loc.x + rectangle.size.w, + // rectangle.loc.y + rectangle.size.h, + // )); + // input_method.with_surface(|surface| { + // custom_render_elements.extend(AsRenderElements::::render_elements( + // &SurfaceTree::from_surface(surface), + // renderer, + // position.to_physical_precise_round(scale), + // scale, + // 1.0, + // )); + // }); if output_geometry.to_f64().contains(pointer_location) { let cursor_hotspot = if let CursorImageStatus::Surface(ref surface) = cursor_status { @@ -238,7 +238,7 @@ where // reset the cursor if the surface is no longer alive if let CursorImageStatus::Surface(surface) = &*cursor_status { if !surface.alive() { - *cursor_status = CursorImageStatus::Default; + *cursor_status = CursorImageStatus::default_named(); } } diff --git a/src/render/pointer.rs b/src/render/pointer.rs index ad08ed2..3cf6a94 100644 --- a/src/render/pointer.rs +++ b/src/render/pointer.rs @@ -3,13 +3,14 @@ use smithay::{ backend::renderer::{ element::{ + self, surface::{self, WaylandSurfaceRenderElement}, texture::{TextureBuffer, TextureRenderElement}, AsRenderElements, }, ImportAll, Renderer, Texture, }, - input::pointer::CursorImageStatus, + input::pointer::{CursorIcon, CursorImageStatus}, render_elements, utils::{Physical, Point, Scale}, }; @@ -23,7 +24,7 @@ impl Default for PointerElement { fn default() -> Self { Self { texture: Default::default(), - status: CursorImageStatus::Default, + status: CursorImageStatus::default_named(), } } } @@ -64,7 +65,7 @@ where ) -> Vec { match &self.status { CursorImageStatus::Hidden => vec![], - CursorImageStatus::Default => { + CursorImageStatus::Named(CursorIcon::Default) => { if let Some(texture) = self.texture.as_ref() { vec![PointerRenderElement::::from( TextureRenderElement::from_texture_buffer( @@ -73,6 +74,7 @@ where None, None, None, + element::Kind::Cursor, ), ) .into()] @@ -80,10 +82,16 @@ where vec![] } } + CursorImageStatus::Named(_) => vec![], CursorImageStatus::Surface(surface) => { let elements: Vec> = surface::render_elements_from_surface_tree( - renderer, surface, location, scale, alpha, + renderer, + surface, + location, + scale, + alpha, + element::Kind::Cursor, ); elements.into_iter().map(C::from).collect() } diff --git a/src/state.rs b/src/state.rs index 95b9b26..e4141dd 100644 --- a/src/state.rs +++ b/src/state.rs @@ -2,7 +2,7 @@ mod api_handlers; -use std::{cell::RefCell, os::fd::AsRawFd, sync::Arc, time::Duration}; +use std::{cell::RefCell, sync::Arc, time::Duration}; use crate::{ backend::Backend, @@ -33,11 +33,11 @@ use smithay::{ utils::{Clock, Logical, Monotonic, Point, Size}, wayland::{ compositor::{self, CompositorClientState, CompositorState}, - data_device::DataDeviceState, dmabuf::DmabufFeedback, fractional_scale::FractionalScaleManagerState, output::OutputManagerState, - primary_selection::PrimarySelectionState, + selection::data_device::DataDeviceState, + selection::primary_selection::PrimarySelectionState, shell::{wlr_layer::WlrLayerShellState, xdg::XdgShellState}, shm::ShmState, socket::ListeningSocketSource, @@ -103,7 +103,7 @@ impl State { /// Creates the central state and starts the config and xwayland pub fn init( backend: Backend, - display: &mut Display, + display: Display, loop_signal: LoopSignal, loop_handle: LoopHandle<'static, CalloopData>, ) -> anyhow::Result { @@ -134,20 +134,23 @@ impl State { } loop_handle.insert_source(socket, |stream, _metadata, data| { - data.display - .handle() + data.display_handle .insert_client(stream, Arc::new(ClientState::default())) .expect("Could not insert client into loop handle"); })?; + let display_handle = display.handle(); + loop_handle.insert_source( - Generic::new( - display.backend().poll_fd().as_raw_fd(), - Interest::READ, - Mode::Level, - ), - |_readiness, _metadata, data| { - data.display.dispatch_clients(&mut data.state)?; + Generic::new(display, Interest::READ, Mode::Level), + |_readiness, display, data| { + // Safety: we don't drop the display + unsafe { + display + .get_mut() + .dispatch_clients(&mut data.state) + .expect("failed to dispatch clients"); + } Ok(PostAction::Continue) }, )?; @@ -166,7 +169,6 @@ impl State { anyhow::bail!("Failed to insert async executor into event loop: {err}"); } - let display_handle = display.handle(); let mut seat_state = SeatState::new(); let mut seat = seat_state.new_wl_seat(&display_handle, backend.seat_name()); @@ -241,7 +243,7 @@ impl State { pointer_location: (0.0, 0.0).into(), shm_state: ShmState::new::(&display_handle, vec![]), space: Space::::default(), - cursor_status: CursorImageStatus::Default, + cursor_status: CursorImageStatus::default_named(), output_manager_state: OutputManagerState::new_with_xdg_output::(&display_handle), xdg_shell_state: XdgShellState::new::(&display_handle), viewporter_state: ViewporterState::new::(&display_handle), @@ -313,7 +315,7 @@ impl State { } pub struct CalloopData { - pub display: Display, + pub display_handle: DisplayHandle, pub state: State, } diff --git a/src/state/api_handlers.rs b/src/state/api_handlers.rs index 8cc3299..d2f1f77 100644 --- a/src/state/api_handlers.rs +++ b/src/state/api_handlers.rs @@ -58,7 +58,7 @@ impl State { self.input_state .keybinds - .insert((modifiers.into(), key), callback_id); + .insert((modifiers.into(), key.into()), callback_id); } Msg::SetMousebind { modifiers, diff --git a/src/window.rs b/src/window.rs index 8d1c765..9c29da8 100644 --- a/src/window.rs +++ b/src/window.rs @@ -290,6 +290,13 @@ impl IsAlive for WindowElement { } impl PointerTarget for WindowElement { + fn frame(&self, seat: &Seat, data: &mut State) { + match self { + WindowElement::Wayland(window) => window.frame(seat, data), + WindowElement::X11(surface) => surface.frame(seat, data), + } + } + fn enter(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { // TODO: ssd match self {