aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grabs/mod.rs5
-rw-r--r--src/grabs/move_grab.rs78
-rw-r--r--src/grabs/resize_grab.rs288
-rw-r--r--src/handlers/compositor.rs2
-rw-r--r--src/handlers/xdg_shell.rs144
-rw-r--r--src/layout.rs2
-rw-r--r--src/main.rs1
7 files changed, 19 insertions, 501 deletions
diff --git a/src/grabs/mod.rs b/src/grabs/mod.rs
deleted file mode 100644
index 5756e1be..00000000
--- a/src/grabs/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub mod move_grab;
-pub use move_grab::MoveSurfaceGrab;
-
-pub mod resize_grab;
-pub use resize_grab::ResizeSurfaceGrab;
diff --git a/src/grabs/move_grab.rs b/src/grabs/move_grab.rs
deleted file mode 100644
index 67a1f285..00000000
--- a/src/grabs/move_grab.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-use smithay::desktop::Window;
-use smithay::input::pointer::{
- AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
- PointerInnerHandle, RelativeMotionEvent,
-};
-use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
-use smithay::utils::{Logical, Point};
-use smithay::wayland::seat::WaylandFocus;
-
-use crate::Niri;
-
-pub struct MoveSurfaceGrab {
- pub start_data: PointerGrabStartData<Niri>,
- pub window: Window,
- pub initial_window_location: Point<i32, Logical>,
-}
-
-impl PointerGrab<Niri> for MoveSurfaceGrab {
- fn motion(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- _focus: Option<(WlSurface, Point<i32, Logical>)>,
- event: &MotionEvent,
- ) {
- // While the grab is active, no client has pointer focus
- handle.motion(data, None, event);
-
- // let delta = event.location - self.start_data.location;
- // let new_location = self.initial_window_location.to_f64() + delta;
- // let (window, space) = data
- // .monitor_set
- // .find_window_and_space(self.window.wl_surface().as_ref().unwrap())
- // .unwrap();
- // space.map_element(window.clone(), new_location.to_i32_round(), true);
- }
-
- fn relative_motion(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- focus: Option<(WlSurface, Point<i32, Logical>)>,
- event: &RelativeMotionEvent,
- ) {
- handle.relative_motion(data, focus, event);
- }
-
- fn button(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- event: &ButtonEvent,
- ) {
- handle.button(data, event);
-
- // The button is a button code as defined in the
- // Linux kernel's linux/input-event-codes.h header file, e.g. BTN_LEFT.
- const BTN_LEFT: u32 = 0x110;
-
- if !handle.current_pressed().contains(&BTN_LEFT) {
- // No more buttons are pressed, release the grab.
- handle.unset_grab(data, event.serial, event.time);
- }
- }
-
- fn axis(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- details: AxisFrame,
- ) {
- handle.axis(data, details)
- }
-
- fn start_data(&self) -> &PointerGrabStartData<Niri> {
- &self.start_data
- }
-}
diff --git a/src/grabs/resize_grab.rs b/src/grabs/resize_grab.rs
deleted file mode 100644
index 819e0b6a..00000000
--- a/src/grabs/resize_grab.rs
+++ /dev/null
@@ -1,288 +0,0 @@
-use std::cell::RefCell;
-
-use smithay::desktop::Window;
-use smithay::input::pointer::{
- AxisFrame, ButtonEvent, GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab,
- PointerInnerHandle, RelativeMotionEvent,
-};
-use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
-use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
-use smithay::utils::{Logical, Point, Rectangle, Size};
-use smithay::wayland::compositor;
-use smithay::wayland::shell::xdg::SurfaceCachedState;
-
-use crate::Niri;
-
-bitflags::bitflags! {
- #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
- pub struct ResizeEdge: u32 {
- const TOP = 0b0001;
- const BOTTOM = 0b0010;
- const LEFT = 0b0100;
- const RIGHT = 0b1000;
-
- const TOP_LEFT = Self::TOP.bits() | Self::LEFT.bits();
- const BOTTOM_LEFT = Self::BOTTOM.bits() | Self::LEFT.bits();
-
- const TOP_RIGHT = Self::TOP.bits() | Self::RIGHT.bits();
- const BOTTOM_RIGHT = Self::BOTTOM.bits() | Self::RIGHT.bits();
- }
-}
-
-impl From<xdg_toplevel::ResizeEdge> for ResizeEdge {
- #[inline]
- fn from(x: xdg_toplevel::ResizeEdge) -> Self {
- Self::from_bits(x as u32).unwrap()
- }
-}
-
-pub struct ResizeSurfaceGrab {
- start_data: PointerGrabStartData<Niri>,
- window: Window,
-
- edges: ResizeEdge,
-
- initial_rect: Rectangle<i32, Logical>,
- last_window_size: Size<i32, Logical>,
-}
-
-impl ResizeSurfaceGrab {
- pub fn start(
- start_data: PointerGrabStartData<Niri>,
- window: Window,
- edges: ResizeEdge,
- initial_window_rect: Rectangle<i32, Logical>,
- ) -> Self {
- let initial_rect = initial_window_rect;
-
- ResizeSurfaceState::with(window.toplevel().wl_surface(), |state| {
- *state = ResizeSurfaceState::Resizing {
- edges,
- initial_rect,
- };
- });
-
- Self {
- start_data,
- window,
- edges,
- initial_rect,
- last_window_size: initial_rect.size,
- }
- }
-}
-
-impl PointerGrab<Niri> for ResizeSurfaceGrab {
- fn motion(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- _focus: Option<(WlSurface, Point<i32, Logical>)>,
- event: &MotionEvent,
- ) {
- // While the grab is active, no client has pointer focus
- handle.motion(data, None, event);
-
- let mut delta = event.location - self.start_data.location;
-
- let mut new_window_width = self.initial_rect.size.w;
- let mut new_window_height = self.initial_rect.size.h;
-
- if self.edges.intersects(ResizeEdge::LEFT | ResizeEdge::RIGHT) {
- if self.edges.intersects(ResizeEdge::LEFT) {
- delta.x = -delta.x;
- }
-
- new_window_width = (self.initial_rect.size.w as f64 + delta.x) as i32;
- }
-
- if self.edges.intersects(ResizeEdge::TOP | ResizeEdge::BOTTOM) {
- if self.edges.intersects(ResizeEdge::TOP) {
- delta.y = -delta.y;
- }
-
- new_window_height = (self.initial_rect.size.h as f64 + delta.y) as i32;
- }
-
- let (min_size, max_size) =
- compositor::with_states(self.window.toplevel().wl_surface(), |states| {
- let data = states.cached_state.current::<SurfaceCachedState>();
- (data.min_size, data.max_size)
- });
-
- let min_width = min_size.w.max(1);
- let min_height = min_size.h.max(1);
-
- let max_width = (max_size.w == 0).then(i32::max_value).unwrap_or(max_size.w);
- let max_height = (max_size.h == 0).then(i32::max_value).unwrap_or(max_size.h);
-
- self.last_window_size = Size::from((
- new_window_width.max(min_width).min(max_width),
- new_window_height.max(min_height).min(max_height),
- ));
-
- let xdg = self.window.toplevel();
- xdg.with_pending_state(|state| {
- state.states.set(xdg_toplevel::State::Resizing);
- state.size = Some(self.last_window_size);
- });
-
- xdg.send_pending_configure();
- }
-
- fn relative_motion(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- focus: Option<(WlSurface, Point<i32, Logical>)>,
- event: &RelativeMotionEvent,
- ) {
- handle.relative_motion(data, focus, event);
- }
-
- fn button(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- event: &ButtonEvent,
- ) {
- handle.button(data, event);
-
- // The button is a button code as defined in the
- // Linux kernel's linux/input-event-codes.h header file, e.g. BTN_LEFT.
- const BTN_LEFT: u32 = 0x110;
-
- if !handle.current_pressed().contains(&BTN_LEFT) {
- // No more buttons are pressed, release the grab.
- handle.unset_grab(data, event.serial, event.time);
-
- let xdg = self.window.toplevel();
- xdg.with_pending_state(|state| {
- state.states.unset(xdg_toplevel::State::Resizing);
- state.size = Some(self.last_window_size);
- });
-
- xdg.send_pending_configure();
-
- ResizeSurfaceState::with(xdg.wl_surface(), |state| {
- *state = ResizeSurfaceState::WaitingForLastCommit {
- edges: self.edges,
- initial_rect: self.initial_rect,
- };
- });
- }
- }
-
- fn axis(
- &mut self,
- data: &mut Niri,
- handle: &mut PointerInnerHandle<'_, Niri>,
- details: AxisFrame,
- ) {
- handle.axis(data, details)
- }
-
- fn start_data(&self) -> &PointerGrabStartData<Niri> {
- &self.start_data
- }
-}
-
-/// State of the resize operation.
-///
-/// It is stored inside of WlSurface,
-/// and can be accessed using [`ResizeSurfaceState::with`]
-#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
-enum ResizeSurfaceState {
- #[default]
- Idle,
- Resizing {
- edges: ResizeEdge,
- /// The initial window size and location.
- initial_rect: Rectangle<i32, Logical>,
- },
- /// Resize is done, we are now waiting for last commit, to do the final move
- WaitingForLastCommit {
- edges: ResizeEdge,
- /// The initial window size and location.
- initial_rect: Rectangle<i32, Logical>,
- },
-}
-
-impl ResizeSurfaceState {
- fn with<F, T>(surface: &WlSurface, cb: F) -> T
- where
- F: FnOnce(&mut Self) -> T,
- {
- compositor::with_states(surface, |states| {
- states.data_map.insert_if_missing(RefCell::<Self>::default);
- let state = states.data_map.get::<RefCell<Self>>().unwrap();
-
- cb(&mut state.borrow_mut())
- })
- }
-
- fn commit(&mut self) -> Option<(ResizeEdge, Rectangle<i32, Logical>)> {
- match *self {
- Self::Resizing {
- edges,
- initial_rect,
- } => Some((edges, initial_rect)),
- Self::WaitingForLastCommit {
- edges,
- initial_rect,
- } => {
- // The resize is done, let's go back to idle
- *self = Self::Idle;
-
- Some((edges, initial_rect))
- }
- Self::Idle => None,
- }
- }
-}
-
-pub fn handle_commit(window: &Window) -> Option<()> {
- // FIXME
- let surface = window.toplevel().wl_surface();
- ResizeSurfaceState::with(surface, |state| {
- state.commit();
- });
-
- // let mut window_loc = space.element_location(&window)?;
- // let geometry = window.geometry();
-
- // let new_loc: Point<Option<i32>, Logical> = ResizeSurfaceState::with(surface, |state| {
- // state
- // .commit()
- // .and_then(|(edges, initial_rect)| {
- // // If the window is being resized by top or left, its location must be adjusted
- // // accordingly.
- // edges.intersects(ResizeEdge::TOP_LEFT).then(|| {
- // let new_x = edges
- // .intersects(ResizeEdge::LEFT)
- // .then_some(initial_rect.loc.x + (initial_rect.size.w - geometry.size.w));
-
- // let new_y = edges
- // .intersects(ResizeEdge::TOP)
- // .then_some(initial_rect.loc.y + (initial_rect.size.h - geometry.size.h));
-
- // (new_x, new_y).into()
- // })
- // })
- // .unwrap_or_default()
- // });
-
- // if let Some(new_x) = new_loc.x {
- // window_loc.x = new_x;
- // }
- // if let Some(new_y) = new_loc.y {
- // window_loc.y = new_y;
- // }
-
- // if new_loc.x.is_some() || new_loc.y.is_some() {
- // // If TOP or LEFT side of the window got resized, we have to move it
- // space.map_element(window, window_loc, false);
- // }
-
- Some(())
-}
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs
index 18082460..e126f9df 100644
--- a/src/handlers/compositor.rs
+++ b/src/handlers/compositor.rs
@@ -13,7 +13,6 @@ 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;
@@ -81,7 +80,6 @@ impl CompositorHandler for Niri {
}
// The toplevel remains mapped.
- resize_grab::handle_commit(&window);
self.monitor_set.update_window(&window);
self.queue_redraw(output);
diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs
index f472047a..2f4448a4 100644
--- a/src/handlers/xdg_shell.rs
+++ b/src/handlers/xdg_shell.rs
@@ -1,20 +1,17 @@
use smithay::delegate_xdg_shell;
use smithay::desktop::{find_popup_root_surface, PopupKind, Window};
-use smithay::input::pointer::{Focus, GrabStartData as PointerGrabStartData};
-use smithay::input::Seat;
use smithay::output::Output;
-use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
+use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge};
+use smithay::reexports::wayland_server::protocol::wl_output;
+use smithay::reexports::wayland_server::protocol::wl_seat::WlSeat;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
-use smithay::reexports::wayland_server::protocol::{wl_output, wl_seat};
-use smithay::reexports::wayland_server::Resource;
-use smithay::utils::{Rectangle, Serial};
+use smithay::utils::Serial;
use smithay::wayland::compositor::with_states;
use smithay::wayland::shell::xdg::{
PopupSurface, PositionerState, ToplevelSurface, XdgPopupSurfaceData, XdgShellHandler,
XdgShellState, XdgToplevelSurfaceData,
};
-use crate::grabs::{MoveSurfaceGrab, ResizeSurfaceGrab};
use crate::layout::{configure_new_window, output_size};
use crate::Niri;
@@ -36,77 +33,26 @@ impl XdgShellHandler for Niri {
assert!(existing.is_none());
}
- 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();
- });
+ fn new_popup(&mut self, surface: PopupSurface, _positioner: PositionerState) {
+ // FIXME: adjust the geometry so the popup doesn't overflow at least off the top and bottom
+ // screen edges, and ideally off the view size.
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) {
+ fn move_request(&mut self, _surface: ToplevelSurface, _seat: WlSeat, _serial: Serial) {
// FIXME
-
- // let seat = Seat::from_resource(&seat).unwrap();
-
- // let wl_surface = surface.wl_surface();
-
- // if let Some(start_data) = check_grab(&seat, wl_surface, serial) {
- // let pointer = seat.get_pointer().unwrap();
-
- // let (window, space) = self.monitor_set.find_window_and_space(wl_surface).unwrap();
- // let initial_window_location = space.element_location(&window).unwrap();
-
- // let grab = MoveSurfaceGrab {
- // start_data,
- // window: window.clone(),
- // initial_window_location,
- // };
-
- // pointer.set_grab(self, grab, serial, Focus::Clear);
- // }
}
fn resize_request(
&mut self,
- surface: ToplevelSurface,
- seat: wl_seat::WlSeat,
- serial: Serial,
- edges: xdg_toplevel::ResizeEdge,
+ _surface: ToplevelSurface,
+ _seat: WlSeat,
+ _serial: Serial,
+ _edges: ResizeEdge,
) {
// FIXME
-
- // let seat = Seat::from_resource(&seat).unwrap();
-
- // let wl_surface = surface.wl_surface();
-
- // if let Some(start_data) = check_grab(&seat, wl_surface, serial) {
- // let pointer = seat.get_pointer().unwrap();
-
- // let (window, space) = self.monitor_set.find_window_and_space(wl_surface).unwrap();
- // let initial_window_location = space.element_location(&window).unwrap();
- // let initial_window_size = window.geometry().size;
-
- // surface.with_pending_state(|state| {
- // state.states.set(xdg_toplevel::State::Resizing);
- // });
-
- // surface.send_pending_configure();
-
- // let grab = ResizeSurfaceGrab::start(
- // start_data,
- // window.clone(),
- // edges.into(),
- // Rectangle::from_loc_and_size(initial_window_location, initial_window_size),
- // );
-
- // pointer.set_grab(self, grab, serial, Focus::Clear);
- // }
}
fn reposition_request(
@@ -115,11 +61,9 @@ impl XdgShellHandler for Niri {
positioner: PositionerState,
token: u32,
) {
+ // FIXME: adjust the geometry so the popup doesn't overflow at least off the top and bottom
+ // screen edges, and ideally off the view size.
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;
@@ -127,48 +71,20 @@ impl XdgShellHandler for Niri {
surface.send_repositioned(token);
}
- fn grab(&mut self, _surface: PopupSurface, _seat: wl_seat::WlSeat, _serial: Serial) {
+ fn grab(&mut self, _surface: PopupSurface, _seat: WlSeat, _serial: Serial) {
// FIXME popup grabs
}
fn maximize_request(&mut self, surface: ToplevelSurface) {
- if surface
- .current_state()
- .capabilities
- .contains(xdg_toplevel::WmCapabilities::Maximize)
- {
- // let wl_surface = surface.wl_surface();
- // let (window, space) = self.monitor_set.find_window_and_space(wl_surface).unwrap();
- // let geometry = space
- // .output_geometry(space.outputs().next().unwrap())
- // .unwrap();
-
- // surface.with_pending_state(|state| {
- // state.states.set(xdg_toplevel::State::Maximized);
- // state.size = Some(geometry.size);
- // });
- // space.map_element(window.clone(), geometry.loc, true);
- }
+ // FIXME
// The protocol demands us to always reply with a configure,
// regardless of we fulfilled the request or not
surface.send_configure();
}
- fn unmaximize_request(&mut self, surface: ToplevelSurface) {
- if !surface
- .current_state()
- .states
- .contains(xdg_toplevel::State::Maximized)
- {
- return;
- }
-
- surface.with_pending_state(|state| {
- state.states.unset(xdg_toplevel::State::Maximized);
- state.size = None;
- });
- surface.send_pending_configure();
+ fn unmaximize_request(&mut self, _surface: ToplevelSurface) {
+ // FIXME
}
fn fullscreen_request(
@@ -237,32 +153,8 @@ impl XdgShellHandler for Niri {
}
}
-// Xdg Shell
delegate_xdg_shell!(Niri);
-fn check_grab(
- seat: &Seat<Niri>,
- surface: &WlSurface,
- serial: Serial,
-) -> Option<PointerGrabStartData<Niri>> {
- let pointer = seat.get_pointer()?;
-
- // Check that this surface has a click grab.
- if !pointer.has_grab(serial) {
- return None;
- }
-
- let start_data = pointer.grab_start_data()?;
-
- let (focus, _) = start_data.focus.as_ref()?;
- // If the focus was for a different surface, ignore the request.
- if !focus.id().same_client_as(&surface.id()) {
- return None;
- }
-
- Some(start_data)
-}
-
pub fn send_initial_configure_if_needed(window: &Window) {
let initial_configure_sent = with_states(window.toplevel().wl_surface(), |states| {
states
diff --git a/src/layout.rs b/src/layout.rs
index d47ff1be..fbb0e801 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -1847,7 +1847,7 @@ impl<W: LayoutElement> Column<W> {
fn toggle_full_width(&mut self, view_size: Size<i32, Logical>) {
let width = match self.width {
- ColumnWidth::Proportion(1.) => {
+ ColumnWidth::Proportion(x) if x == 1. => {
// FIXME: would be good to restore to previous width here.
ColumnWidth::default()
}
diff --git a/src/main.rs b/src/main.rs
index c69a9e81..40953348 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,7 +6,6 @@ mod handlers;
mod animation;
mod backend;
mod frame_clock;
-mod grabs;
mod input;
mod layout;
mod niri;