diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2023-08-11 08:22:34 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2023-08-11 08:22:34 +0400 |
| commit | 3959d1eaa10f97f2377f8174b711c8c30a2f3949 (patch) | |
| tree | 3a314d442a5a535a5047f2f9ac9511ef3ef829d1 | |
| parent | 91c7763aabf47217c6ec5587b0aae23fdaa6ecaa (diff) | |
| download | niri-3959d1eaa10f97f2377f8174b711c8c30a2f3949.tar.gz niri-3959d1eaa10f97f2377f8174b711c8c30a2f3949.tar.bz2 niri-3959d1eaa10f97f2377f8174b711c8c30a2f3949.zip | |
Add draft popup implementation
Missing grabs and positioning but gets the job sufficiently done for now.
| -rw-r--r-- | src/handlers/compositor.rs | 3 | ||||
| -rw-r--r-- | src/handlers/xdg_shell.rs | 101 | ||||
| -rw-r--r-- | src/niri.rs | 5 |
3 files changed, 80 insertions, 29 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs index 1cd781f6..f5a955e1 100644 --- a/src/handlers/compositor.rs +++ b/src/handlers/compositor.rs @@ -9,7 +9,6 @@ use smithay::wayland::compositor::{ use smithay::wayland::shm::{ShmHandler, ShmState}; use smithay::{delegate_compositor, delegate_shm}; -use super::xdg_shell; use crate::grabs::resize_grab; use crate::niri::ClientState; use crate::Niri; @@ -43,7 +42,7 @@ impl CompositorHandler for Niri { } }; - xdg_shell::handle_commit(&self.space, surface); + self.xdg_handle_commit(surface); resize_grab::handle_commit(&mut self.space, surface); self.queue_redraw(); diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 686c5525..6a12d4e9 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -1,5 +1,5 @@ use smithay::delegate_xdg_shell; -use smithay::desktop::{Space, Window}; +use smithay::desktop::{PopupKind, Window}; use smithay::input::pointer::{Focus, GrabStartData as PointerGrabStartData}; use smithay::input::Seat; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; @@ -9,8 +9,8 @@ use smithay::reexports::wayland_server::Resource; use smithay::utils::{Rectangle, Serial}; use smithay::wayland::compositor::with_states; use smithay::wayland::shell::xdg::{ - PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState, - XdgToplevelSurfaceData, + PopupSurface, PositionerState, ToplevelSurface, XdgPopupSurfaceData, XdgShellHandler, + XdgShellState, XdgToplevelSurfaceData, }; use crate::grabs::{MoveSurfaceGrab, ResizeSurfaceGrab}; @@ -26,8 +26,17 @@ impl XdgShellHandler for Niri { self.space.map_element(window, (0, 0), false); } - fn new_popup(&mut self, _surface: PopupSurface, _positioner: PositionerState) { - // TODO: Popup handling using PopupManager + fn new_popup(&mut self, surface: PopupSurface, positioner: PositionerState) { + surface.with_pending_state(|state| { + // NOTE: This is not really necessary as the default geometry + // is already set the same way, but for demonstrating how + // to set the initial popup geometry this code is left as + // an example + state.geometry = positioner.get_geometry(); + }); + if let Err(err) = self.popups.track_popup(PopupKind::Xdg(surface)) { + warn!("error tracking popup: {err:?}"); + } } fn move_request(&mut self, surface: ToplevelSurface, seat: wl_seat::WlSeat, serial: Serial) { @@ -96,6 +105,24 @@ impl XdgShellHandler for Niri { } } + fn reposition_request( + &mut self, + surface: PopupSurface, + positioner: PositionerState, + token: u32, + ) { + surface.with_pending_state(|state| { + // NOTE: This is again a simplification, a proper compositor would + // calculate the geometry of the popup here. For simplicity we just + // use the default implementation here that does not take the + // window position and output constraints into account. + let geometry = positioner.get_geometry(); + state.geometry = geometry; + state.positioner = positioner; + }); + surface.send_repositioned(token); + } + fn grab(&mut self, _surface: PopupSurface, _seat: wl_seat::WlSeat, _serial: Serial) { // TODO popup grabs } @@ -181,26 +208,48 @@ fn check_grab( Some(start_data) } -/// Should be called on `WlSurface::commit` -pub fn handle_commit(space: &Space<Window>, surface: &WlSurface) -> Option<()> { - let window = space - .elements() - .find(|w| w.toplevel().wl_surface() == surface) - .cloned()?; - - let initial_configure_sent = with_states(surface, |states| { - states - .data_map - .get::<XdgToplevelSurfaceData>() - .unwrap() - .lock() - .unwrap() - .initial_configure_sent - }); - - if !initial_configure_sent { - window.toplevel().send_configure(); - } +impl Niri { + /// Should be called on `WlSurface::commit` + pub fn xdg_handle_commit(&mut self, surface: &WlSurface) { + self.popups.commit(surface); - Some(()) + if let Some(window) = self + .space + .elements() + .find(|w| w.toplevel().wl_surface() == surface) + .cloned() + { + let initial_configure_sent = with_states(surface, |states| { + states + .data_map + .get::<XdgToplevelSurfaceData>() + .unwrap() + .lock() + .unwrap() + .initial_configure_sent + }); + + if !initial_configure_sent { + window.toplevel().send_configure(); + } + } + + if let Some(popup) = self.popups.find_popup(surface) { + let PopupKind::Xdg(ref popup) = popup; + let initial_configure_sent = with_states(surface, |states| { + states + .data_map + .get::<XdgPopupSurfaceData>() + .unwrap() + .lock() + .unwrap() + .initial_configure_sent + }); + if !initial_configure_sent { + // NOTE: This should never fail as the initial configure is always + // allowed. + popup.send_configure().expect("initial configure failed"); + } + } + } } diff --git a/src/niri.rs b/src/niri.rs index ac5cba43..0fbd49f5 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -6,7 +6,7 @@ use smithay::backend::renderer::element::render_elements; use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement}; use smithay::backend::renderer::ImportAll; use smithay::desktop::space::{space_render_elements, SpaceRenderElements}; -use smithay::desktop::{Space, Window, WindowSurfaceType}; +use smithay::desktop::{PopupManager, Space, Window, WindowSurfaceType}; use smithay::input::keyboard::XkbConfig; use smithay::input::{Seat, SeatState}; use smithay::output::Output; @@ -42,6 +42,7 @@ pub struct Niri { pub output_manager_state: OutputManagerState, pub seat_state: SeatState<Self>, pub data_device_state: DataDeviceState, + pub popups: PopupManager, pub seat: Seat<Self>, pub output: Option<Output>, @@ -137,6 +138,7 @@ impl Niri { output_manager_state, seat_state, data_device_state, + popups: PopupManager::default(), seat, output: None, @@ -225,6 +227,7 @@ impl Niri { }); self.space.refresh(); + self.popups.cleanup(); } } |
