Skip to content

Commit

Permalink
niri msg pick-window: Use a pointer grab
Browse files Browse the repository at this point in the history
  • Loading branch information
bbb651 committed Feb 19, 2025
1 parent 15bec65 commit 8e9b56b
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 26 deletions.
27 changes: 11 additions & 16 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ use crate::niri::State;
use crate::ui::screenshot_ui::ScreenshotUi;
use crate::utils::spawning::spawn;
use crate::utils::{center, get_monotonic_time, ResizeEdge};
use crate::window::Mapped;

pub mod backend_ext;
pub mod move_grab;
pub mod pick_window_grab;
pub mod resize_grab;
pub mod scroll_tracker;
pub mod spatial_movement_grab;
Expand Down Expand Up @@ -383,14 +383,16 @@ impl State {
}
}

if pressed && raw == Some(Keysym::Escape) {
if let Some(tx) = this.niri.pick_window.take() {
this.niri.suppressed_keys.insert(key_code);
let _ = tx.send_blocking(None);
// Redraw to update the cursor.
this.niri.queue_redraw_all();
return FilterResult::Intercept(None);
}
if pressed && raw == Some(Keysym::Escape) && this.niri.pick_window.is_some() {
// We window picking state so the pick window grab must be active.
// Unsetting it cancels window picking.
this.niri
.seat
.get_pointer()
.unwrap()
.unset_grab(this, serial, time);
this.niri.suppressed_keys.insert(key_code);
return FilterResult::Intercept(None);
}

let bindings = &this.niri.config.borrow().binds;
Expand Down Expand Up @@ -2032,13 +2034,6 @@ impl State {
self.niri.pointer_hidden = false;
self.niri.tablet_cursor_location = None;

if let Some(tx) = self.niri.pick_window.take() {
let _ = tx.send_blocking(self.niri.window_under_cursor().map(Mapped::id));
// Redraw to update the cursor.
self.niri.queue_redraw_all();
return;
}

if let Some(mapped) = self.niri.window_under_cursor() {
let window = mapped.window.clone();

Expand Down
172 changes: 172 additions & 0 deletions src/input/pick_window_grab.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use smithay::backend::input::ButtonState;
use smithay::input::pointer::{
CursorImageStatus, GrabStartData as PointerGrabStartData, PointerGrab,
};

use crate::niri::State;
use crate::window::Mapped;

pub struct PickWindowGrab {
start_data: PointerGrabStartData<State>,
}

impl PickWindowGrab {
pub fn new(start_data: PointerGrabStartData<State>) -> Self {
Self { start_data }
}

fn on_ungrab(&mut self, state: &mut State) {
if let Some(tx) = state.niri.pick_window.take() {
let _ = tx.send_blocking(None);
}
state
.niri
.cursor_manager
.set_cursor_image(CursorImageStatus::default_named());
// Redraw to update the cursor.
state.niri.queue_redraw_all();
}
}

impl PointerGrab<State> for PickWindowGrab {
fn motion(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
_focus: Option<(
<State as smithay::input::SeatHandler>::PointerFocus,
smithay::utils::Point<f64, smithay::utils::Logical>,
)>,
event: &smithay::input::pointer::MotionEvent,
) {
handle.motion(data, None, event);
}

fn relative_motion(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
_focus: Option<(
<State as smithay::input::SeatHandler>::PointerFocus,
smithay::utils::Point<f64, smithay::utils::Logical>,
)>,
event: &smithay::input::pointer::RelativeMotionEvent,
) {
handle.relative_motion(data, None, event);
}

fn button(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::ButtonEvent,
) {
if event.state == ButtonState::Pressed {
if let Some(tx) = data.niri.pick_window.take() {
let _ = tx.send_blocking(
data.niri
.window_under(handle.current_location())
.map(Mapped::id),
);
}
handle.unset_grab(self, data, event.serial, event.time, true);
}
}

fn axis(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
details: smithay::input::pointer::AxisFrame,
) {
handle.axis(data, details);
}

fn frame(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
) {
handle.frame(data);
}

fn gesture_swipe_begin(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GestureSwipeBeginEvent,
) {
handle.gesture_swipe_begin(data, event);
}

fn gesture_swipe_update(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GestureSwipeUpdateEvent,
) {
handle.gesture_swipe_update(data, event);
}

fn gesture_swipe_end(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GestureSwipeEndEvent,
) {
handle.gesture_swipe_end(data, event);
}

fn gesture_pinch_begin(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GesturePinchBeginEvent,
) {
handle.gesture_pinch_begin(data, event);
}

fn gesture_pinch_update(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GesturePinchUpdateEvent,
) {
handle.gesture_pinch_update(data, event);
}

fn gesture_pinch_end(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GesturePinchEndEvent,
) {
handle.gesture_pinch_end(data, event);
}

fn gesture_hold_begin(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GestureHoldBeginEvent,
) {
handle.gesture_hold_begin(data, event);
}

fn gesture_hold_end(
&mut self,
data: &mut State,
handle: &mut smithay::input::pointer::PointerInnerHandle<'_, State>,
event: &smithay::input::pointer::GestureHoldEndEvent,
) {
handle.gesture_hold_end(data, event);
}

fn start_data(&self) -> &smithay::input::pointer::GrabStartData<State> {
&self.start_data
}

fn unset(&mut self, data: &mut State) {
self.on_ungrab(data);
}
}
25 changes: 21 additions & 4 deletions src/ipc/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ use niri_config::OutputName;
use niri_ipc::state::{EventStreamState, EventStreamStatePart as _};
use niri_ipc::{Event, KeyboardLayouts, OutputConfigChanged, Reply, Request, Response, Workspace};
use smithay::desktop::layer_map_for_output;
use smithay::input::pointer::{
CursorIcon, CursorImageStatus, Focus, GrabStartData as PointerGrabStartData,
};
use smithay::reexports::calloop::generic::Generic;
use smithay::reexports::calloop::{Interest, LoopHandle, Mode, PostAction};
use smithay::reexports::rustix::fs::unlink;
use smithay::utils::SERIAL_COUNTER;
use smithay::wayland::shell::wlr_layer::{KeyboardInteractivity, Layer};

use crate::backend::IpcOutputMap;
use crate::input::pick_window_grab::PickWindowGrab;
use crate::layout::workspace::WorkspaceId;
use crate::niri::State;
use crate::utils::{version, with_toplevel_role};
Expand Down Expand Up @@ -325,11 +330,23 @@ async fn process(ctx: &ClientCtx, request: Request) -> Reply {
Request::PickWindow => {
let (tx, rx) = async_channel::bounded(1);
ctx.event_loop.insert_idle(move |state| {
if let Some(tx) = state.niri.pick_window.replace(tx) {
// Cancel previous ongoing pick, if any.
let Some(pointer) = state.niri.seat.get_pointer() else {
let _ = tx.send_blocking(None);
}

return;
};
let start_data = PointerGrabStartData {
focus: None,
button: 0,
location: pointer.current_location(),
};
let grab = PickWindowGrab::new(start_data);
// The `WindowPickGrab` ungrab handler will cancel the previous ongoing pick, if any.
pointer.set_grab(state, grab, SERIAL_COUNTER.next_serial(), Focus::Keep);
state.niri.pick_window = Some(tx);
state
.niri
.cursor_manager
.set_cursor_image(CursorImageStatus::Named(CursorIcon::Crosshair));
// Redraw to update the cursor.
state.niri.queue_redraw_all();
});
Expand Down
7 changes: 1 addition & 6 deletions src/niri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3012,12 +3012,7 @@ impl Niri {

// Get the render cursor to draw.
let cursor_scale = output_scale.integer_scale();
let render_cursor = if self.pick_window.is_some() {
self.cursor_manager
.get_render_cursor_named(CursorIcon::Crosshair, cursor_scale)
} else {
self.cursor_manager.get_render_cursor(cursor_scale)
};
let render_cursor = self.cursor_manager.get_render_cursor(cursor_scale);

let output_scale = Scale::from(output.current_scale().fractional_scale());

Expand Down

0 comments on commit 8e9b56b

Please sign in to comment.