Skip to main content

Seat

Struct Seat 

Source
pub struct Seat { /* private fields */ }
Available on crate feature libinput only.
Expand description

Every input device on one seat.

Poll AsFd, call dispatch when it is readable, and act on what comes back. Nothing is delivered through a callback: an event loop that has to reason about what a handler might re-enter is harder than one that gets a list.

Implementations§

Source§

impl Seat

Source

pub fn open(options: &SeatOptions) -> Result<Self, InputError>

Open the seat, opening its devices directly.

Needs read access to /dev/input/event*, which outside a login session means root or the input group. For devices that survive a VT switch, use Seat::open_with and route through a session instead.

Everything typed on this machine comes through here, including into other applications: an evdev reader is a keylogger that happens to be asked politely. That is inherent to the interface – it is why the permission is restricted – and it is worth being deliberate about where the events go.

§Errors

InputError::Seat if libinput cannot enumerate the seat through udev. An unknown seat name is not an error; see SeatOptions::seat.

Examples found in repository?
examples/input.rs (line 29)
28fn main() {
29    let mut seat = match Seat::open(&SeatOptions::default()) {
30        Ok(seat) => seat,
31        Err(error) => {
32            eprintln!("{error}");
33            std::process::exit(1);
34        }
35    };
36    let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37    let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39    let started = Instant::now();
40    let mut events = Vec::new();
41    let mut repeats: Vec<KeyEvent> = Vec::new();
42    let mut leds = keyboard.leds();
43
44    loop {
45        {
46            let seat_fd = seat.as_fd();
47            let timer_fd = repeater.fd();
48            let mut fds = [
49                PollFd::new(&seat_fd, PollFlags::IN),
50                PollFd::new(&timer_fd, PollFlags::IN),
51            ];
52            let timeout = Duration::from_secs(30).try_into().expect("timeout");
53            if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54                println!("nothing for thirty seconds");
55                return;
56            }
57        }
58
59        let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61        events.clear();
62        seat.dispatch(&mut events).expect("dispatch");
63        for event in &mut events {
64            match event {
65                InputEvent::Key(key) => {
66                    keyboard.process_key(key);
67                    repeater.on_key(key, keyboard.should_repeat(key.key));
68                    if report(key) {
69                        return;
70                    }
71                }
72                other => println!("{other:?}"),
73            }
74        }
75
76        repeats.clear();
77        repeater.dispatch(now, &mut repeats).expect("repeat");
78        for key in &mut repeats {
79            // Resolved, not replayed: a Shift pressed since the key went down
80            // changes what this types.
81            keyboard.resolve(key);
82            report(key);
83        }
84
85        let current = keyboard.leds();
86        if current != leds {
87            seat.set_leds(current);
88            leds = current;
89        }
90    }
91}
Source

pub fn open_with( options: &SeatOptions, opener: impl LibinputInterface + 'static, ) -> Result<Self, InputError>

Open the seat, opening its devices through opener.

The hook libinput calls for every privileged open and its matching close. Implement LibinputInterface over a drmkit_session::Session and every /dev/input/event* libinput touches gets the same revocable lifetime as the DRM device – which is what makes a VT switch give the keyboard back.

§Errors

As Seat::open.

Source

pub fn dispatch(&mut self, out: &mut Vec<InputEvent>) -> Result<(), InputError>

Read whatever the devices have to say, appending to out.

Device arrivals and departures are handled here and not reported: they are this type’s bookkeeping, and a consumer that wants to know which devices exist has udev for it.

§Errors

InputError::Dispatch if libinput cannot read its descriptor.

Examples found in repository?
examples/input.rs (line 62)
28fn main() {
29    let mut seat = match Seat::open(&SeatOptions::default()) {
30        Ok(seat) => seat,
31        Err(error) => {
32            eprintln!("{error}");
33            std::process::exit(1);
34        }
35    };
36    let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37    let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39    let started = Instant::now();
40    let mut events = Vec::new();
41    let mut repeats: Vec<KeyEvent> = Vec::new();
42    let mut leds = keyboard.leds();
43
44    loop {
45        {
46            let seat_fd = seat.as_fd();
47            let timer_fd = repeater.fd();
48            let mut fds = [
49                PollFd::new(&seat_fd, PollFlags::IN),
50                PollFd::new(&timer_fd, PollFlags::IN),
51            ];
52            let timeout = Duration::from_secs(30).try_into().expect("timeout");
53            if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54                println!("nothing for thirty seconds");
55                return;
56            }
57        }
58
59        let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61        events.clear();
62        seat.dispatch(&mut events).expect("dispatch");
63        for event in &mut events {
64            match event {
65                InputEvent::Key(key) => {
66                    keyboard.process_key(key);
67                    repeater.on_key(key, keyboard.should_repeat(key.key));
68                    if report(key) {
69                        return;
70                    }
71                }
72                other => println!("{other:?}"),
73            }
74        }
75
76        repeats.clear();
77        repeater.dispatch(now, &mut repeats).expect("repeat");
78        for key in &mut repeats {
79            // Resolved, not replayed: a Shift pressed since the key went down
80            // changes what this types.
81            keyboard.resolve(key);
82            report(key);
83        }
84
85        let current = keyboard.leds();
86        if current != leds {
87            seat.set_leds(current);
88            leds = current;
89        }
90    }
91}
Source

pub fn suspend(&mut self)

Close every device, keeping the seat.

For a session pause. The descriptors are about to stop working, and libinput reading a revoked one produces a stream of errors rather than events.

Source

pub fn resume(&mut self) -> Result<(), InputError>

Reopen everything after a suspend.

Devices arrive as ordinary additions on the next dispatch, and the lights are restored with them.

§Errors

InputError::Seat if libinput cannot re-enumerate.

Source

pub fn set_leds(&mut self, leds: Leds)

Drive the lock lights on every keyboard.

xkb owns the latch and the device owns the light; this is the wire between them. Read Keyboard::leds after a key and push it here when it has changed.

Examples found in repository?
examples/input.rs (line 87)
28fn main() {
29    let mut seat = match Seat::open(&SeatOptions::default()) {
30        Ok(seat) => seat,
31        Err(error) => {
32            eprintln!("{error}");
33            std::process::exit(1);
34        }
35    };
36    let mut keyboard = Keyboard::from_names(&KeymapNames::default()).expect("keymap");
37    let mut repeater = KeyRepeater::new(RepeatConfig::default()).expect("timer");
38
39    let started = Instant::now();
40    let mut events = Vec::new();
41    let mut repeats: Vec<KeyEvent> = Vec::new();
42    let mut leds = keyboard.leds();
43
44    loop {
45        {
46            let seat_fd = seat.as_fd();
47            let timer_fd = repeater.fd();
48            let mut fds = [
49                PollFd::new(&seat_fd, PollFlags::IN),
50                PollFd::new(&timer_fd, PollFlags::IN),
51            ];
52            let timeout = Duration::from_secs(30).try_into().expect("timeout");
53            if poll(&mut fds, Some(&timeout)).expect("poll") == 0 {
54                println!("nothing for thirty seconds");
55                return;
56            }
57        }
58
59        let now = u32::try_from(started.elapsed().as_millis()).unwrap_or(u32::MAX);
60
61        events.clear();
62        seat.dispatch(&mut events).expect("dispatch");
63        for event in &mut events {
64            match event {
65                InputEvent::Key(key) => {
66                    keyboard.process_key(key);
67                    repeater.on_key(key, keyboard.should_repeat(key.key));
68                    if report(key) {
69                        return;
70                    }
71                }
72                other => println!("{other:?}"),
73            }
74        }
75
76        repeats.clear();
77        repeater.dispatch(now, &mut repeats).expect("repeat");
78        for key in &mut repeats {
79            // Resolved, not replayed: a Shift pressed since the key went down
80            // changes what this types.
81            keyboard.resolve(key);
82            report(key);
83        }
84
85        let current = keyboard.leds();
86        if current != leds {
87            seat.set_leds(current);
88            leds = current;
89        }
90    }
91}
Source

pub fn keyboard_count(&self) -> usize

How many keyboard-capable devices are on the seat.

Trait Implementations§

Source§

impl AsFd for Seat

Source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
Source§

impl Debug for Seat

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Seat

§

impl !Send for Seat

§

impl !Sync for Seat

§

impl !UnwindSafe for Seat

§

impl Freeze for Seat

§

impl Unpin for Seat

§

impl UnsafeUnpin for Seat

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsFilelike for T
where T: AsFd,

Source§

fn as_filelike(&self) -> BorrowedFd<'_>

Borrows the reference. Read more
Source§

fn as_filelike_view<Target>(&self) -> FilelikeView<'_, Target>
where Target: FilelikeViewType,

Return a borrowing view of a resource which dereferences to a &Target. Read more
Source§

impl<T> AsSocketlike for T
where T: AsFd,

Source§

fn as_socketlike(&self) -> BorrowedFd<'_>

Borrows the reference.
Source§

fn as_socketlike_view<Target>(&self) -> SocketlikeView<'_, Target>
where Target: SocketlikeViewType,

Return a borrowing view of a resource which dereferences to a &Target. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.