Skip to content

Commit

Permalink
implement WinitVirtualDevice::output() to the one single virtual output
Browse files Browse the repository at this point in the history
  • Loading branch information
sodiboo committed Nov 23, 2024
1 parent 2febcdc commit 9e8a5de
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
5 changes: 5 additions & 0 deletions src/backend/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,9 @@ impl Winit {
pub fn ipc_outputs(&self) -> Arc<Mutex<IpcOutputMap>> {
self.ipc_outputs.clone()
}

// FIXME: If/when the winit backend supports multiple outputs, then this method makes no sense.
pub fn single_output(&self) -> &Output {
&self.output
}
}
26 changes: 16 additions & 10 deletions src/input/backend_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use smithay::backend::input;
use smithay::backend::winit::WinitVirtualDevice;
use smithay::output::Output;

use crate::backend::Backend;
use crate::niri::State;
use crate::protocols::virtual_pointer::VirtualPointer;

pub trait NiriInputBackend: input::InputBackend<Device = Self::NiriDevice> {
Expand All @@ -16,29 +18,33 @@ where
}

pub trait NiriInputDevice: input::Device {
// FIXME: should this be per-event? logically yes,
// but right now we only use it for virtual pointers, which have static outputs.
fn output(&self) -> Option<Output>;
// FIXME: this should maybe be per-event, not per-device,
// but it's not clear that this matters in practice?
// it might be more obvious once we implement it for libinput
fn output(&self, state: &State) -> Option<Output>;
}

impl NiriInputDevice for libinput::Device {
fn output(&self) -> Option<Output> {
fn output(&self, _state: &State) -> Option<Output> {
// FIXME: Allow specifying the output per-device?
// In that case, change the method to take a reference to our state or config or something
// (because we can't easily change the libinput Device struct)
None
}
}

impl NiriInputDevice for WinitVirtualDevice {
fn output(&self) -> Option<Output> {
// here it's actually *correct* to return None, because there is only one output.
None
fn output(&self, state: &State) -> Option<Output> {
match state.backend {
Backend::Winit(ref winit) => Some(winit.single_output().clone()),
// returning None over panicking here because it's not worth panicking over
// and also, foreseeably, someone might want to, at some point, use `WinitInputBackend`
// for dirty hacks or mocking or whatever, in which case this will be useful.
_ => None,
}
}
}

impl NiriInputDevice for VirtualPointer {
fn output(&self) -> Option<Output> {
fn output(&self, _: &State) -> Option<Output> {
self.output().cloned()
}
}
4 changes: 2 additions & 2 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl State {
where
I::Device: 'static,
{
let device_output = event.device().output();
let device_output = event.device().output(self);
let device_output = device_output.as_ref();
let (target_geo, keep_ratio, px, transform) =
if let Some(output) = device_output.or_else(|| self.niri.output_for_tablet()) {
Expand Down Expand Up @@ -2375,7 +2375,7 @@ impl State {
evt: &impl AbsolutePositionEvent<I>,
fallback_output: Option<&Output>,
) -> Option<Point<f64, Logical>> {
let output = evt.device().output();
let output = evt.device().output(self);
let output = output.as_ref().or(fallback_output)?;
let output_geo = self.niri.global_space.output_geometry(output).unwrap();
let transform = output.current_transform();
Expand Down

0 comments on commit 9e8a5de

Please sign in to comment.