input: add a default seat
This commit is contained in:
parent
8a73779cbd
commit
355a9eb240
10 changed files with 58 additions and 14 deletions
|
|
@ -62,3 +62,5 @@ impl WireMode {
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct PollableId(pub u64);
|
||||
|
||||
pub const DEFAULT_SEAT_NAME: &str = "default";
|
||||
|
|
|
|||
|
|
@ -576,6 +576,10 @@ impl Client {
|
|||
self.send(&ClientMessage::SetDoubleClickDistance { dist });
|
||||
}
|
||||
|
||||
pub fn disable_default_seat(&self) {
|
||||
self.send(&ClientMessage::DisableDefaultSeat);
|
||||
}
|
||||
|
||||
pub fn connector_set_position(&self, connector: Connector, x: i32, y: i32) {
|
||||
self.send(&ClientMessage::ConnectorSetPosition { connector, x, y });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,6 +381,7 @@ pub enum ClientMessage<'a> {
|
|||
env: Vec<(String, String)>,
|
||||
fds: Vec<(i32, i32)>,
|
||||
},
|
||||
DisableDefaultSeat,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use {
|
|||
input::{acceleration::AccelProfile, capability::Capability},
|
||||
keyboard::Keymap,
|
||||
Axis, Direction, ModifiedKeySym, Workspace,
|
||||
_private::DEFAULT_SEAT_NAME,
|
||||
},
|
||||
serde::{Deserialize, Serialize},
|
||||
std::time::Duration,
|
||||
|
|
@ -319,10 +320,20 @@ pub fn input_devices() -> Vec<InputDevice> {
|
|||
/// Returns or creates a seat.
|
||||
///
|
||||
/// Seats are identified by their name. If no seat with the name exists, a new seat will be created.
|
||||
///
|
||||
/// NOTE: You should prefer [`get_default_seat`] instead. Most applications cannot handle more than
|
||||
/// one seat and will only process input from one of the seats.
|
||||
pub fn get_seat(name: &str) -> Seat {
|
||||
get!(Seat(0)).get_seat(name)
|
||||
}
|
||||
|
||||
/// Returns or creates the default seat.
|
||||
///
|
||||
/// This is equivalent to `get_seat("default")`.
|
||||
pub fn get_default_seat() -> Seat {
|
||||
get_seat(DEFAULT_SEAT_NAME)
|
||||
}
|
||||
|
||||
/// Sets a closure to run when a new seat has been created.
|
||||
pub fn on_new_seat<F: FnMut(Seat) + 'static>(f: F) {
|
||||
get!().on_new_seat(f)
|
||||
|
|
@ -357,3 +368,14 @@ pub fn set_double_click_time(duration: Duration) {
|
|||
pub fn set_double_click_distance(distance: i32) {
|
||||
get!().set_double_click_distance(distance)
|
||||
}
|
||||
|
||||
/// Disables the creation of a default seat.
|
||||
///
|
||||
/// Unless this function is called at startup of the compositor, a seat called `default`
|
||||
/// will automatically be created.
|
||||
///
|
||||
/// When a new input device is attached and a seat called `default` exists, the input
|
||||
/// device is initially attached to this seat.
|
||||
pub fn disable_default_seat() {
|
||||
get!().disable_default_seat();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,23 +12,19 @@
|
|||
//! config!(configure);
|
||||
//! ```
|
||||
//!
|
||||
//! This configuration will not allow you to interact with the compositor at all nor exit it.
|
||||
//! This configuration will not allow you to exit the compositor.
|
||||
//! To add at least that much functionality, add the following code to `configure`:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use jay_config::{config, quit};
|
||||
//! use jay_config::input::{get_seat, input_devices, on_new_input_device};
|
||||
//! use jay_config::input::{get_default_seat, input_devices, on_new_input_device};
|
||||
//! use jay_config::keyboard::mods::ALT;
|
||||
//! use jay_config::keyboard::syms::SYM_q;
|
||||
//!
|
||||
//! fn configure() {
|
||||
//! // Create a seat.
|
||||
//! let seat = get_seat("default");
|
||||
//! let seat = get_default_seat();
|
||||
//! // Create a key binding to exit the compositor.
|
||||
//! seat.bind(ALT | SYM_q, || quit());
|
||||
//! // Assign all current and future input devices to this seat.
|
||||
//! input_devices().into_iter().for_each(move |d| d.set_seat(seat));
|
||||
//! on_new_input_device(move |d| d.set_seat(seat));
|
||||
//! }
|
||||
//!
|
||||
//! config!(configure);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ use {
|
|||
},
|
||||
ahash::AHashSet,
|
||||
forker::ForkerProxy,
|
||||
jay_config::video::GfxApi,
|
||||
jay_config::{_private::DEFAULT_SEAT_NAME, video::GfxApi},
|
||||
std::{cell::Cell, env, future::Future, ops::Deref, rc::Rc, sync::Arc, time::Duration},
|
||||
thiserror::Error,
|
||||
uapi::c,
|
||||
|
|
@ -207,6 +207,7 @@ fn start_compositor2(
|
|||
output_transforms: Default::default(),
|
||||
double_click_interval_usec: Cell::new(400 * 1000),
|
||||
double_click_distance: Cell::new(5),
|
||||
create_default_seat: Cell::new(true),
|
||||
});
|
||||
state.tracker.register(ClientId::from_raw(0));
|
||||
create_dummy_output(&state);
|
||||
|
|
@ -254,6 +255,10 @@ async fn start_compositor3(state: Rc<State>, test_future: Option<TestFuture>) {
|
|||
config.configure(false);
|
||||
state.config.set(Some(Rc::new(config)));
|
||||
|
||||
if state.create_default_seat.get() && state.globals.seats.is_empty() {
|
||||
state.create_seat(DEFAULT_SEAT_NAME);
|
||||
}
|
||||
|
||||
let _geh = start_global_event_handlers(&state, &backend);
|
||||
state.start_xwayland();
|
||||
|
||||
|
|
|
|||
|
|
@ -164,9 +164,7 @@ impl ConfigProxyHandler {
|
|||
return;
|
||||
}
|
||||
}
|
||||
let global_name = self.state.globals.name();
|
||||
let seat = WlSeatGlobal::new(global_name, name, &self.state);
|
||||
self.state.globals.add_global(&self.state, &seat);
|
||||
let seat = self.state.create_seat(name);
|
||||
self.respond(Response::GetSeat {
|
||||
seat: Seat(seat.id().raw() as _),
|
||||
});
|
||||
|
|
@ -1516,6 +1514,7 @@ impl ConfigProxyHandler {
|
|||
env,
|
||||
fds,
|
||||
} => self.handle_run(prog, args, env, fds).wrn("run")?,
|
||||
ClientMessage::DisableDefaultSeat => self.state.create_default_seat.set(false),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ testcase!();
|
|||
async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
|
||||
let client = run.create_client().await?;
|
||||
|
||||
tassert!(client.registry.seats.is_empty());
|
||||
tassert_eq!(client.registry.seats.len(), 1);
|
||||
|
||||
let seat = run.get_seat("default")?;
|
||||
let seat = run.get_seat("new-seat")?;
|
||||
|
||||
client.sync().await;
|
||||
|
||||
tassert_eq!(client.registry.seats.len(), 1);
|
||||
tassert_eq!(client.registry.seats.len(), 2);
|
||||
|
||||
let client_seat = client.registry.seats.get(&seat.name());
|
||||
tassert!(client_seat.is_some());
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ pub struct State {
|
|||
pub output_transforms: RefCell<AHashMap<Rc<OutputId>, Transform>>,
|
||||
pub double_click_interval_usec: Cell<u64>,
|
||||
pub double_click_distance: Cell<i32>,
|
||||
pub create_default_seat: Cell<bool>,
|
||||
}
|
||||
|
||||
// impl Drop for State {
|
||||
|
|
@ -924,4 +925,11 @@ impl State {
|
|||
capture.send_failed();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_seat(self: &Rc<Self>, name: &str) -> Rc<WlSeatGlobal> {
|
||||
let global_name = self.globals.name();
|
||||
let seat = WlSeatGlobal::new(global_name, name, self);
|
||||
self.globals.add_global(self, &seat);
|
||||
seat
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use {
|
|||
tasks::udev_utils::{udev_props, UdevProps},
|
||||
utils::asyncevent::AsyncEvent,
|
||||
},
|
||||
jay_config::_private::DEFAULT_SEAT_NAME,
|
||||
std::{cell::Cell, rc::Rc},
|
||||
};
|
||||
|
||||
|
|
@ -53,6 +54,12 @@ impl DeviceHandler {
|
|||
let ae = self.ae.clone();
|
||||
self.dev.on_change(Rc::new(move || ae.trigger()));
|
||||
}
|
||||
for seat in self.state.globals.seats.lock().values() {
|
||||
if seat.seat_name() == DEFAULT_SEAT_NAME {
|
||||
self.data.seat.set(Some(seat.clone()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(config) = self.state.config.get() {
|
||||
config.new_input_device(self.dev.id());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue