1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-23 15:04:36 +03:00

wayland: speculative handling of pointer when seat changes

It compiles and launches under weston, so that's promising.
I can't test the suspend/resume case on the hardware I have available.

refs: #1497
This commit is contained in:
Wez Furlong 2022-03-19 05:44:39 -07:00
parent 0c7e735a86
commit bd9088372a
5 changed files with 50 additions and 19 deletions

View File

@ -77,6 +77,7 @@ As features stabilize some brief notes about them will accumulate here.
* Fixed lingering hover state in titlebar when the mouse pointer left the window. Thanks to [@davidrios](https://github.com/davidrios)! [#1434](https://github.com/wez/wezterm/issues/1434)
* We now respect the difference between `Italic` and `Oblique` font styles when matching fonts. You may explicitly specify `style="Oblique"` rather than using `italic=true` for fonts that offer both italic and oblique variants. [#1646](https://github.com/wez/wezterm/issues/1646)
* Hang when clicking a URL would launch the browser for the first time on unix systems [#1721](https://github.com/wez/wezterm/issues/1721)
* Wayland input handling gets broken after suspend/resume. Thanks to [@LawnGnome](https://github.com/LawnGnome)! [#1497](https://github.com/wez/wezterm/issues/1497)
### 20220101-133340-7edc5b5a

View File

@ -37,7 +37,7 @@ pub struct WaylandConnection {
// bottom of this list, and opengl, which depends on everything
// must be ahead of the rest.
pub(crate) gl_connection: RefCell<Option<Rc<crate::egl::GlConnection>>>,
pub(crate) pointer: PointerDispatcher,
pub(crate) pointer: RefCell<PointerDispatcher>,
pub(crate) keyboard_mapper: RefCell<Option<Keyboard>>,
pub(crate) keyboard_window_id: RefCell<Option<usize>>,
pub(crate) surface_to_window_id: RefCell<HashMap<u32, usize>>,
@ -132,16 +132,9 @@ impl WaylandConnection {
// fires for this seat with has_keyboard = true.
seat_keyboards.remove(&seat_data.name);
}
if seat_data.has_pointer {
// TODO: ideally do something similar to the keyboard state,
// but the pointer state has a lot of other stuff floating
// around it so it's not so clear cut right now.
log::error!(
"seat {} changed; it has a pointer that is
defunct={} and we don't know what to do about it",
seat_data.name,
seat_data.defunct
);
if seat_data.has_pointer && !seat_data.defunct {
let conn = Connection::get().unwrap().wayland();
conn.pointer.borrow_mut().seat_changed(&seat);
}
});
}
@ -153,7 +146,7 @@ impl WaylandConnection {
next_window_id: AtomicUsize::new(1),
windows: RefCell::new(HashMap::new()),
event_q: RefCell::new(event_q),
pointer: pointer.unwrap(),
pointer: RefCell::new(pointer.unwrap()),
seat_listener,
gl_connection: RefCell::new(None),
keyboard_mapper: RefCell::new(None),

View File

@ -43,8 +43,9 @@ impl CopyAndPaste {
pub fn get_clipboard_data(&mut self, clipboard: Clipboard) -> anyhow::Result<FileDescriptor> {
let conn = crate::Connection::get().unwrap().wayland();
let pointer = conn.pointer.borrow();
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
conn.pointer.primary_selection_device.as_ref()
pointer.primary_selection_device.as_ref()
} else {
None
};
@ -74,11 +75,12 @@ impl CopyAndPaste {
pub fn set_clipboard_data(&mut self, clipboard: Clipboard, data: String) {
let conn = crate::Connection::get().unwrap().wayland();
let pointer = conn.pointer.borrow();
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
conn.environment
.borrow()
.get_primary_selection_manager()
.zip(conn.pointer.primary_selection_device.as_ref())
.zip(pointer.primary_selection_device.as_ref())
} else {
None
};
@ -94,6 +96,7 @@ impl CopyAndPaste {
.unwrap()
.wayland()
.pointer
.borrow()
.data_device
.set_selection(None, 0);
}
@ -119,6 +122,7 @@ impl CopyAndPaste {
});
source.offer(TEXT_MIME_TYPE.to_string());
conn.pointer
.borrow()
.data_device
.set_selection(Some(&source), self.last_serial);
}

View File

@ -91,7 +91,9 @@ impl Inner {
pub struct PointerDispatcher {
inner: Arc<Mutex<Inner>>,
dev_mgr: Attached<WlDataDeviceManager>,
pub(crate) data_device: Main<WlDataDevice>,
selection_manager: Option<PrimarySelectionDeviceManager>,
pub(crate) primary_selection_device: Option<PrimarySelectionDevice>,
auto_pointer: ThemedPointer,
#[allow(dead_code)]
@ -249,12 +251,15 @@ impl PointerDispatcher {
}
});
let primary_selection_device =
selection_manager.map(|m| PrimarySelectionDevice::init_for_seat(&m, seat));
let primary_selection_device = selection_manager
.as_ref()
.map(|m| PrimarySelectionDevice::init_for_seat(&m, seat));
Ok(Self {
inner,
dev_mgr,
data_device,
selection_manager,
primary_selection_device,
themer,
auto_pointer,
@ -262,6 +267,34 @@ impl PointerDispatcher {
})
}
pub fn seat_changed(&mut self, seat: &WlSeat) {
let inner = Arc::clone(&self.inner);
let pointer = seat.get_pointer();
pointer.quick_assign({
let inner = Arc::clone(&inner);
move |_, evt, _| {
inner.lock().unwrap().handle_event(evt);
}
});
let data_device = self.dev_mgr.get_data_device(seat);
data_device.quick_assign({
let inner = Arc::clone(&inner);
move |_device, event, _| {
inner.lock().unwrap().handle_data_event(event, &inner);
}
});
let primary_selection_device = self
.selection_manager
.as_ref()
.map(|m| PrimarySelectionDevice::init_for_seat(&m, seat));
self.data_device = data_device;
self.primary_selection_device = primary_selection_device;
self.seat = seat.clone();
}
pub fn add_window(&self, surface: &WlSurface, pending: &Arc<Mutex<PendingMouse>>) {
let mut inner = self.inner.lock().unwrap();
inner

View File

@ -334,7 +334,7 @@ impl WaylandWindow {
let copy_and_paste = CopyAndPaste::create();
let pending_mouse = PendingMouse::create(window_id, &copy_and_paste);
conn.pointer.add_window(&surface, &pending_mouse);
conn.pointer.borrow().add_window(&surface, &pending_mouse);
let inner = Rc::new(RefCell::new(WaylandWindowInner {
window_id,
@ -985,7 +985,7 @@ impl WaylandWindowInner {
None => return,
};
let conn = Connection::get().unwrap().wayland();
conn.pointer.set_cursor(cursor, None);
conn.pointer.borrow().set_cursor(cursor, None);
}
fn invalidate(&mut self) {
@ -1035,7 +1035,7 @@ impl WaylandWindowInner {
if let Some(window) = self.window.as_ref() {
let serial = self.copy_and_paste.lock().unwrap().last_serial;
let conn = Connection::get().unwrap().wayland();
window.start_interactive_move(&conn.pointer.seat, serial);
window.start_interactive_move(&conn.pointer.borrow().seat, serial);
}
}