Merge pull request #12 from kchibisov/tty-switch
Fix clipboard dying after keyboard capability is removed from the seat and then re-added.
This commit is contained in:
commit
b0b1d427f9
2 changed files with 287 additions and 235 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
- Fix crash when receiving non-utf8 data
|
- Fix crash when receiving non-utf8 data
|
||||||
- **Breaking** `load` and `load_primary` now return `Result<String>` to indicate errors
|
- **Breaking** `load` and `load_primary` now return `Result<String>` to indicate errors
|
||||||
|
- Fix clipboard dying after TTY switch
|
||||||
|
|
||||||
## 0.3.7 -- 2020-02-27
|
## 0.3.7 -- 2020-02-27
|
||||||
|
|
||||||
|
|
|
||||||
521
src/threaded.rs
521
src/threaded.rs
|
|
@ -13,9 +13,13 @@ use nix::unistd::{close, pipe2};
|
||||||
use sctk::data_device::{DataDevice, DataSource, DataSourceEvent};
|
use sctk::data_device::{DataDevice, DataSource, DataSourceEvent};
|
||||||
use sctk::keyboard::{map_keyboard_auto, Event as KbEvent};
|
use sctk::keyboard::{map_keyboard_auto, Event as KbEvent};
|
||||||
use sctk::reexports::client::protocol::{
|
use sctk::reexports::client::protocol::{
|
||||||
wl_data_device_manager, wl_display::WlDisplay, wl_pointer::Event as PtrEvent, wl_registry,
|
wl_data_device_manager,
|
||||||
wl_seat,
|
wl_display::WlDisplay,
|
||||||
|
wl_pointer::Event as PtrEvent,
|
||||||
|
wl_registry,
|
||||||
|
wl_seat::{self, Capability},
|
||||||
};
|
};
|
||||||
|
|
||||||
use sctk::reexports::client::{Display, EventQueue, GlobalEvent, GlobalManager, NewProxy};
|
use sctk::reexports::client::{Display, EventQueue, GlobalEvent, GlobalManager, NewProxy};
|
||||||
use sctk::reexports::protocols::misc::gtk_primary_selection::client::{
|
use sctk::reexports::protocols::misc::gtk_primary_selection::client::{
|
||||||
gtk_primary_selection_device::Event as GtkPrimarySelectionDeviceEvent,
|
gtk_primary_selection_device::Event as GtkPrimarySelectionDeviceEvent,
|
||||||
|
|
@ -38,7 +42,7 @@ use sctk::wayland_client::sys::client::wl_display;
|
||||||
type SeatMap = HashMap<
|
type SeatMap = HashMap<
|
||||||
String,
|
String,
|
||||||
(
|
(
|
||||||
Arc<Mutex<DataDevice>>,
|
Arc<Mutex<Option<DataDevice>>>,
|
||||||
u32,
|
u32,
|
||||||
Arc<Mutex<Option<PrimarySelectionDevice>>>,
|
Arc<Mutex<Option<PrimarySelectionDevice>>>,
|
||||||
Arc<Mutex<Option<PrimarySelectionOffer>>>,
|
Arc<Mutex<Option<PrimarySelectionOffer>>>,
|
||||||
|
|
@ -298,20 +302,25 @@ fn clipboard_thread(
|
||||||
.get(&seat_name.unwrap_or_else(|| last_seat_name.lock().unwrap().clone()))
|
.get(&seat_name.unwrap_or_else(|| last_seat_name.lock().unwrap().clone()))
|
||||||
.map_or(Ok(String::new()), |seat| {
|
.map_or(Ok(String::new()), |seat| {
|
||||||
let mut reader = None;
|
let mut reader = None;
|
||||||
seat.0.lock().unwrap().with_selection(|offer| {
|
if let Some(device) = seat.0.lock().unwrap().as_ref() {
|
||||||
if let Some(offer) = offer {
|
device.with_selection(|offer| {
|
||||||
offer.with_mime_types(|types| {
|
if let Some(offer) = offer {
|
||||||
if types.contains(&"text/plain;charset=utf-8".to_string()) {
|
offer.with_mime_types(|types| {
|
||||||
reader = Some(
|
if types
|
||||||
offer
|
.contains(&"text/plain;charset=utf-8".to_string())
|
||||||
.receive("text/plain;charset=utf-8".into())
|
{
|
||||||
.unwrap(),
|
reader = Some(
|
||||||
);
|
offer
|
||||||
}
|
.receive("text/plain;charset=utf-8".into())
|
||||||
});
|
.unwrap(),
|
||||||
}
|
);
|
||||||
});
|
}
|
||||||
event_queue.sync_roundtrip().unwrap();
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
event_queue.sync_roundtrip().unwrap();
|
||||||
|
}
|
||||||
reader.map_or(Ok(String::new()), |mut reader| {
|
reader.map_or(Ok(String::new()), |mut reader| {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
if let Err(err) = reader.read_to_string(&mut contents) {
|
if let Err(err) = reader.read_to_string(&mut contents) {
|
||||||
|
|
@ -335,21 +344,21 @@ fn clipboard_thread(
|
||||||
if let Some((device, enter_serial, _, _, _, _)) = seat_map
|
if let Some((device, enter_serial, _, _, _, _)) = seat_map
|
||||||
.get(&seat_name.unwrap_or_else(|| last_seat_name.lock().unwrap().clone()))
|
.get(&seat_name.unwrap_or_else(|| last_seat_name.lock().unwrap().clone()))
|
||||||
{
|
{
|
||||||
let data_source = DataSource::new(
|
if let Some(device) = device.lock().unwrap().as_ref() {
|
||||||
data_device_manager.lock().unwrap().as_ref().unwrap(),
|
let data_source = DataSource::new(
|
||||||
&["text/plain;charset=utf-8"],
|
data_device_manager.lock().unwrap().as_ref().unwrap(),
|
||||||
move |source_event| {
|
&["text/plain;charset=utf-8"],
|
||||||
if let DataSourceEvent::Send { mut pipe, .. } = source_event {
|
move |source_event| {
|
||||||
write!(pipe, "{}", contents).unwrap();
|
if let DataSourceEvent::Send { mut pipe, .. } = source_event {
|
||||||
}
|
write!(pipe, "{}", contents).unwrap();
|
||||||
},
|
}
|
||||||
);
|
},
|
||||||
device
|
);
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.set_selection(&Some(data_source), *enter_serial);
|
|
||||||
|
|
||||||
event_queue.sync_roundtrip().unwrap();
|
device.set_selection(&Some(data_source), *enter_serial);
|
||||||
|
|
||||||
|
event_queue.sync_roundtrip().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Load text from primary clipboard
|
// Load text from primary clipboard
|
||||||
|
|
@ -539,17 +548,197 @@ fn implement_seat(
|
||||||
primary_device_manager: Arc<Mutex<Option<PrimarySelectionDeviceMgr>>>,
|
primary_device_manager: Arc<Mutex<Option<PrimarySelectionDeviceMgr>>>,
|
||||||
gtk_primary_device_manager: Arc<Mutex<Option<GtkPrimarySelectionDeviceManager>>>,
|
gtk_primary_device_manager: Arc<Mutex<Option<GtkPrimarySelectionDeviceManager>>>,
|
||||||
) {
|
) {
|
||||||
|
let device = Arc::new(Mutex::new(None));
|
||||||
|
let device_clone = device.clone();
|
||||||
let seat_name = Arc::new(Mutex::new(String::new()));
|
let seat_name = Arc::new(Mutex::new(String::new()));
|
||||||
let seat_name_clone = seat_name.clone();
|
let seat_name_clone = seat_name.clone();
|
||||||
|
let seat_map_clone = seat_map.clone();
|
||||||
|
|
||||||
|
let primary_device = Arc::new(Mutex::new(None));
|
||||||
|
let primary_offer = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
|
let primary_device_clone = primary_device.clone();
|
||||||
|
let primary_offer_clone = primary_offer.clone();
|
||||||
|
|
||||||
|
let gtk_primary_device = Arc::new(Mutex::new(None));
|
||||||
|
let gtk_primary_offer = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
|
let gtk_primary_device_clone = gtk_primary_device.clone();
|
||||||
|
let gtk_primary_offer_clone = gtk_primary_offer.clone();
|
||||||
|
|
||||||
|
let mut pointer = None;
|
||||||
|
let mut keyboard = None;
|
||||||
|
|
||||||
// Register the seat
|
// Register the seat
|
||||||
let seat = reg
|
let seat = reg
|
||||||
.bind::<wl_seat::WlSeat, _>(version, id, move |proxy| {
|
.bind::<wl_seat::WlSeat, _>(version, id, move |proxy| {
|
||||||
proxy.implement_closure(
|
proxy.implement_closure(
|
||||||
move |event, _| {
|
move |event, seat| match event {
|
||||||
if let wl_seat::Event::Name { name } = event {
|
wl_seat::Event::Name { name } => *seat_name_clone.lock().unwrap() = name,
|
||||||
*seat_name_clone.lock().unwrap() = name
|
wl_seat::Event::Capabilities { capabilities } => {
|
||||||
|
if capabilities.contains(Capability::Pointer) {
|
||||||
|
if pointer.is_none() {
|
||||||
|
let device_clone = device_clone.clone();
|
||||||
|
|
||||||
|
let primary_device_clone = primary_device_clone.clone();
|
||||||
|
let primary_offer_clone = primary_offer_clone.clone();
|
||||||
|
|
||||||
|
let gtk_primary_device_clone = gtk_primary_device_clone.clone();
|
||||||
|
let gtk_primary_offer_clone = gtk_primary_offer_clone.clone();
|
||||||
|
|
||||||
|
let last_seat_name_clone = last_seat_name.clone();
|
||||||
|
let seat_map_clone = seat_map_clone.clone();
|
||||||
|
let seat_name_clone = seat_name_clone.clone();
|
||||||
|
pointer = Some(
|
||||||
|
seat.get_pointer(move |pointer| {
|
||||||
|
pointer.implement_closure(
|
||||||
|
move |evt, _| {
|
||||||
|
// Set this seat as the last to send an event
|
||||||
|
*last_seat_name_clone.lock().unwrap() =
|
||||||
|
seat_name_clone.lock().unwrap().clone();
|
||||||
|
|
||||||
|
// Get serials from recieved events from the seat
|
||||||
|
// pointer
|
||||||
|
match evt {
|
||||||
|
PtrEvent::Enter { serial, .. } => {
|
||||||
|
if let Some(seat) =
|
||||||
|
seat_map_clone.lock().unwrap().get_mut(
|
||||||
|
&seat_name_clone
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Update serial if "seat" is already
|
||||||
|
// presented
|
||||||
|
seat.1 = serial;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
seat_map_clone.lock().unwrap().insert(
|
||||||
|
seat_name_clone.lock().unwrap().clone(),
|
||||||
|
(
|
||||||
|
device_clone.clone(),
|
||||||
|
serial,
|
||||||
|
primary_device_clone.clone(),
|
||||||
|
primary_offer_clone.clone(),
|
||||||
|
gtk_primary_device_clone.clone(),
|
||||||
|
gtk_primary_offer_clone.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PtrEvent::Button { serial, .. } => {
|
||||||
|
if let Some(seat) =
|
||||||
|
seat_map_clone.lock().unwrap().get_mut(
|
||||||
|
&seat_name_clone
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Update serial if seat is already
|
||||||
|
// presented
|
||||||
|
seat.1 = serial;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is for consistency with
|
||||||
|
// `PtrEvent::Enter`
|
||||||
|
seat_map_clone.lock().unwrap().insert(
|
||||||
|
seat_name_clone.lock().unwrap().clone(),
|
||||||
|
(
|
||||||
|
device_clone.clone(),
|
||||||
|
serial,
|
||||||
|
primary_device_clone.clone(),
|
||||||
|
primary_offer_clone.clone(),
|
||||||
|
gtk_primary_device_clone.clone(),
|
||||||
|
gtk_primary_offer_clone.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if let Some(pointer) = pointer.take() {
|
||||||
|
// Release old pointer
|
||||||
|
if pointer.as_ref().version() >= 3 {
|
||||||
|
pointer.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if capabilities.contains(Capability::Keyboard) {
|
||||||
|
if keyboard.is_none() {
|
||||||
|
let device_clone = device_clone.clone();
|
||||||
|
|
||||||
|
let primary_device_clone = primary_device_clone.clone();
|
||||||
|
let primary_offer_clone = primary_offer_clone.clone();
|
||||||
|
|
||||||
|
let gtk_primary_device_clone = gtk_primary_device_clone.clone();
|
||||||
|
let gtk_primary_offer_clone = gtk_primary_offer_clone.clone();
|
||||||
|
|
||||||
|
let last_seat_name_clone = last_seat_name.clone();
|
||||||
|
let seat_map_clone = seat_map_clone.clone();
|
||||||
|
let seat_name_clone = seat_name_clone.clone();
|
||||||
|
keyboard = Some(
|
||||||
|
map_keyboard_auto(&seat, move |event, _| {
|
||||||
|
// Set this seat as the last to send an event
|
||||||
|
*last_seat_name_clone.lock().unwrap() =
|
||||||
|
seat_name_clone.lock().unwrap().clone();
|
||||||
|
|
||||||
|
// Get serials from recieved events from the seat keyboard
|
||||||
|
match event {
|
||||||
|
KbEvent::Enter { serial, .. } => {
|
||||||
|
seat_map_clone.lock().unwrap().insert(
|
||||||
|
seat_name_clone.lock().unwrap().clone(),
|
||||||
|
(
|
||||||
|
device_clone.clone(),
|
||||||
|
serial,
|
||||||
|
primary_device_clone.clone(),
|
||||||
|
primary_offer_clone.clone(),
|
||||||
|
gtk_primary_device_clone.clone(),
|
||||||
|
gtk_primary_offer_clone.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
KbEvent::Key { serial, .. } => {
|
||||||
|
seat_map_clone.lock().unwrap().insert(
|
||||||
|
seat_name_clone.lock().unwrap().clone(),
|
||||||
|
(
|
||||||
|
device_clone.clone(),
|
||||||
|
serial,
|
||||||
|
primary_device_clone.clone(),
|
||||||
|
primary_offer_clone.clone(),
|
||||||
|
gtk_primary_device_clone.clone(),
|
||||||
|
gtk_primary_offer_clone.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
KbEvent::Leave { .. } => {
|
||||||
|
seat_map_clone
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.remove(&*seat_name_clone.lock().unwrap());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if let Some(keyboard) = keyboard.take() {
|
||||||
|
// Release old keyboard
|
||||||
|
if keyboard.as_ref().version() >= 3 {
|
||||||
|
keyboard.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
|
|
@ -557,215 +746,77 @@ fn implement_seat(
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Create a device for the seat
|
// Create a device for the seat
|
||||||
let device = Arc::new(Mutex::new(DataDevice::init_for_seat(
|
*device.lock().unwrap() = Some(DataDevice::init_for_seat(
|
||||||
data_device_manager,
|
data_device_manager,
|
||||||
&seat,
|
&seat,
|
||||||
|_| {},
|
|_| {},
|
||||||
)));
|
));
|
||||||
|
|
||||||
let primary_offer = Arc::new(Mutex::new(None));
|
if let Some(manager) = &*primary_device_manager.lock().unwrap() {
|
||||||
let primary_offer_clone = primary_offer.clone();
|
*primary_device.lock().unwrap() = manager
|
||||||
let gtk_primary_offer = Arc::new(Mutex::new(None));
|
.get_device(&seat, |proxy| {
|
||||||
let gtk_primary_offer_clone = gtk_primary_offer.clone();
|
proxy.implement_closure(
|
||||||
let seat_map_clone = seat_map.clone();
|
move |event, _| {
|
||||||
let seat_name_clone = seat_name.clone();
|
if let ZwpPrimarySelectionDeviceEvent::DataOffer { offer } = event {
|
||||||
let (primary_device, gtk_primary_device) = if let Some(manager) =
|
*primary_offer.lock().unwrap() = Some(offer.implement_dummy());
|
||||||
&*primary_device_manager.lock().unwrap()
|
|
||||||
{
|
|
||||||
(
|
|
||||||
Arc::new(Mutex::new(
|
|
||||||
manager
|
|
||||||
.get_device(&seat, |proxy| {
|
|
||||||
let primary_offer_clone = primary_offer_clone.clone();
|
|
||||||
proxy.implement_closure(
|
|
||||||
move |event, _| {
|
|
||||||
if let ZwpPrimarySelectionDeviceEvent::DataOffer { offer } = event {
|
|
||||||
*primary_offer_clone.lock().unwrap() =
|
|
||||||
Some(offer.implement_dummy());
|
|
||||||
|
|
||||||
let map_contents = seat_map_clone
|
let map_contents = seat_map
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get(&seat_name_clone.lock().unwrap().clone())
|
.get(&seat_name.lock().unwrap().clone())
|
||||||
.cloned();
|
.cloned();
|
||||||
if let Some(map_contents) = map_contents {
|
if let Some(map_contents) = map_contents {
|
||||||
seat_map_clone.lock().unwrap().insert(
|
seat_map.lock().unwrap().insert(
|
||||||
seat_name_clone.lock().unwrap().clone(),
|
seat_name.lock().unwrap().clone(),
|
||||||
(
|
(
|
||||||
map_contents.0.clone(),
|
map_contents.0.clone(),
|
||||||
map_contents.1,
|
map_contents.1,
|
||||||
map_contents.2.clone(),
|
map_contents.2,
|
||||||
primary_offer_clone.clone(),
|
primary_offer.clone(),
|
||||||
Arc::new(Mutex::new(None)),
|
Arc::new(Mutex::new(None)),
|
||||||
Arc::new(Mutex::new(None)),
|
Arc::new(Mutex::new(None)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok(),
|
.ok();
|
||||||
)),
|
|
||||||
Arc::new(Mutex::new(None)),
|
|
||||||
)
|
|
||||||
} else if let Some(manager) = &*gtk_primary_device_manager.lock().unwrap() {
|
} else if let Some(manager) = &*gtk_primary_device_manager.lock().unwrap() {
|
||||||
(
|
*gtk_primary_device.lock().unwrap() = manager
|
||||||
Arc::new(Mutex::new(None)),
|
.get_device(&seat, |proxy| {
|
||||||
Arc::new(Mutex::new(
|
proxy.implement_closure(
|
||||||
manager
|
move |event, _| {
|
||||||
.get_device(&seat, |proxy| {
|
if let GtkPrimarySelectionDeviceEvent::DataOffer { offer } = event {
|
||||||
let gtk_primary_offer_clone = gtk_primary_offer_clone.clone();
|
*gtk_primary_offer.lock().unwrap() = Some(offer.implement_dummy());
|
||||||
proxy.implement_closure(
|
|
||||||
move |event, _| {
|
|
||||||
if let GtkPrimarySelectionDeviceEvent::DataOffer { offer } = event {
|
|
||||||
*gtk_primary_offer_clone.lock().unwrap() =
|
|
||||||
Some(offer.implement_dummy());
|
|
||||||
|
|
||||||
let map_contents = seat_map_clone
|
let map_contents = seat_map
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.get(&seat_name_clone.lock().unwrap().clone())
|
.get(&seat_name.lock().unwrap().clone())
|
||||||
.cloned();
|
.cloned();
|
||||||
if let Some(map_contents) = map_contents {
|
if let Some(map_contents) = map_contents {
|
||||||
seat_map_clone.lock().unwrap().insert(
|
seat_map.lock().unwrap().insert(
|
||||||
seat_name_clone.lock().unwrap().clone(),
|
seat_name.lock().unwrap().clone(),
|
||||||
(
|
(
|
||||||
map_contents.0.clone(),
|
map_contents.0.clone(),
|
||||||
map_contents.1,
|
map_contents.1,
|
||||||
Arc::new(Mutex::new(None)),
|
Arc::new(Mutex::new(None)),
|
||||||
Arc::new(Mutex::new(None)),
|
Arc::new(Mutex::new(None)),
|
||||||
map_contents.4.clone(),
|
map_contents.4,
|
||||||
gtk_primary_offer_clone.clone(),
|
gtk_primary_offer.clone(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok(),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(Arc::new(Mutex::new(None)), Arc::new(Mutex::new(None)))
|
|
||||||
};
|
|
||||||
|
|
||||||
let seat_map_clone = seat_map.clone();
|
|
||||||
let device_clone = device.clone();
|
|
||||||
let primary_device_clone = primary_device.clone();
|
|
||||||
let primary_offer_clone = primary_offer_clone.clone();
|
|
||||||
let gtk_primary_device_clone = gtk_primary_device.clone();
|
|
||||||
let gtk_primary_offer_clone = gtk_primary_offer_clone.clone();
|
|
||||||
let seat_name_clone = seat_name.clone();
|
|
||||||
let last_seat_name_clone = last_seat_name.clone();
|
|
||||||
map_keyboard_auto(&seat, move |event, _| {
|
|
||||||
// Set this seat as the last to send an event
|
|
||||||
*last_seat_name_clone.lock().unwrap() = seat_name_clone.lock().unwrap().clone();
|
|
||||||
|
|
||||||
// Get serials from recieved events from the seat keyboard
|
|
||||||
match event {
|
|
||||||
KbEvent::Enter { serial, .. } => {
|
|
||||||
seat_map_clone.lock().unwrap().insert(
|
|
||||||
seat_name_clone.lock().unwrap().clone(),
|
|
||||||
(
|
|
||||||
device_clone.clone(),
|
|
||||||
serial,
|
|
||||||
primary_device_clone.clone(),
|
|
||||||
primary_offer_clone.clone(),
|
|
||||||
gtk_primary_device_clone.clone(),
|
|
||||||
gtk_primary_offer_clone.clone(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
KbEvent::Key { serial, .. } => {
|
|
||||||
seat_map_clone.lock().unwrap().insert(
|
|
||||||
seat_name_clone.lock().unwrap().clone(),
|
|
||||||
(
|
|
||||||
device_clone.clone(),
|
|
||||||
serial,
|
|
||||||
primary_device_clone.clone(),
|
|
||||||
primary_offer_clone.clone(),
|
|
||||||
gtk_primary_device_clone.clone(),
|
|
||||||
gtk_primary_offer_clone.clone(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
KbEvent::Leave { .. } => {
|
|
||||||
seat_map_clone
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.remove(&*seat_name_clone.lock().unwrap());
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
seat.get_pointer(|pointer| {
|
|
||||||
pointer.implement_closure(
|
|
||||||
move |evt, _| {
|
|
||||||
// Set this seat as the last to send an event
|
|
||||||
*last_seat_name.lock().unwrap() = seat_name.lock().unwrap().clone();
|
|
||||||
|
|
||||||
// Get serials from recieved events from the seat pointer
|
|
||||||
match evt {
|
|
||||||
PtrEvent::Enter { serial, .. } => {
|
|
||||||
if let Some(seat) = seat_map
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_mut(&seat_name.lock().unwrap().clone())
|
|
||||||
{
|
|
||||||
// Update serial if "seat" is already presented
|
|
||||||
seat.1 = serial;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
seat_map.lock().unwrap().insert(
|
(),
|
||||||
seat_name.lock().unwrap().clone(),
|
)
|
||||||
(
|
})
|
||||||
device.clone(),
|
.ok();
|
||||||
serial,
|
}
|
||||||
primary_device.clone(),
|
|
||||||
primary_offer.clone(),
|
|
||||||
gtk_primary_device.clone(),
|
|
||||||
gtk_primary_offer.clone(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
PtrEvent::Button { serial, .. } => {
|
|
||||||
if let Some(seat) = seat_map
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.get_mut(&seat_name.lock().unwrap().clone())
|
|
||||||
{
|
|
||||||
// Update serial if seat is already presented
|
|
||||||
seat.1 = serial;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is for consistency with `PtrEvent::Enter`
|
|
||||||
seat_map.lock().unwrap().insert(
|
|
||||||
seat_name.lock().unwrap().clone(),
|
|
||||||
(
|
|
||||||
device.clone(),
|
|
||||||
serial,
|
|
||||||
primary_device.clone(),
|
|
||||||
primary_offer.clone(),
|
|
||||||
gtk_primary_device.clone(),
|
|
||||||
gtk_primary_offer.clone(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize \r and \r\n into \n.
|
// Normalize \r and \r\n into \n.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue