mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Wayland support for set_cursor_grab and set_cursor_visible (#1180)
* Fixed relative_pointer not being set up when the "zwp_relative_pointer_manager_v1" callback comes after the "wl_seat" callback * Ran cargo fmt * Updated changelog * Added wayland support for set_grab_cursor and set_cursor_visible * Updated changelog * Ran cargo fmt * Fixed set_cursor_visible and set_cursor_grab so they can be called from any thread. * Ran cargo_fmt * Improved CHANGELOG * Added workaround so that when cursor is hidden it takes effect before the cursor enters the surface. Making the cursor visible again still only happens once the cursor re-enters the surface * Switched to using Rc<RefCell> instead of Arc<Mutex> since all accesses to the relative_pointer_manager_proxy will happen on the same thread. * Forgot to run cargo fmt * Switched to using Rc and RefCell instead of Arc and Mutex where applicable. * Improved comments and documentation relating to changing a hidden cursor back to visible on wayland. * Wayland: Fixed cursor not appearing immendiately when setting the cursor to visible. * Forgot to run cargo fmt * Switched to only storing the pointers in CursorManager as AutoPointer. * Fixed typo and removed println * Update CHANGELOG.md Co-Authored-By: Kirill Chibisov <wchibisovkirill@gmail.com>
This commit is contained in:
parent
18a0119b06
commit
237e7ee2e6
|
@ -20,6 +20,7 @@
|
||||||
- On X11, return dummy monitor data to avoid panicking when no monitors exist.
|
- On X11, return dummy monitor data to avoid panicking when no monitors exist.
|
||||||
- On X11, prevent stealing input focus when creating a new window.
|
- On X11, prevent stealing input focus when creating a new window.
|
||||||
Only steal input focus when entering fullscreen mode.
|
Only steal input focus when entering fullscreen mode.
|
||||||
|
- On Wayland, add support for set_cursor_visible and set_cursor_grab.
|
||||||
- On Wayland, fixed DeviceEvents for relative mouse movement is not always produced
|
- On Wayland, fixed DeviceEvents for relative mouse movement is not always produced
|
||||||
|
|
||||||
# 0.20.0 Alpha 3 (2019-08-14)
|
# 0.20.0 Alpha 3 (2019-08-14)
|
||||||
|
|
|
@ -7,11 +7,19 @@ use std::{
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use smithay_client_toolkit::reexports::protocols::unstable::pointer_constraints::v1::client::{
|
||||||
|
zwp_locked_pointer_v1::ZwpLockedPointerV1, zwp_pointer_constraints_v1::ZwpPointerConstraintsV1,
|
||||||
|
};
|
||||||
use smithay_client_toolkit::reexports::protocols::unstable::relative_pointer::v1::client::{
|
use smithay_client_toolkit::reexports::protocols::unstable::relative_pointer::v1::client::{
|
||||||
zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
|
zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
|
||||||
zwp_relative_pointer_v1::ZwpRelativePointerV1,
|
zwp_relative_pointer_v1::ZwpRelativePointerV1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use smithay_client_toolkit::pointer::{AutoPointer, AutoThemer};
|
||||||
|
use smithay_client_toolkit::reexports::client::protocol::{
|
||||||
|
wl_compositor::WlCompositor, wl_shm::WlShm, wl_surface::WlSurface,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{PhysicalPosition, PhysicalSize},
|
dpi::{PhysicalPosition, PhysicalSize},
|
||||||
event::ModifiersState,
|
event::ModifiersState,
|
||||||
|
@ -69,6 +77,79 @@ impl<T> WindowEventsSink<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CursorManager {
|
||||||
|
pointer_constraints_proxy: Rc<RefCell<Option<ZwpPointerConstraintsV1>>>,
|
||||||
|
auto_themer: Option<AutoThemer>,
|
||||||
|
pointers: Vec<AutoPointer>,
|
||||||
|
locked_pointers: Vec<ZwpLockedPointerV1>,
|
||||||
|
cursor_visible: Rc<RefCell<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CursorManager {
|
||||||
|
fn new(constraints: Rc<RefCell<Option<ZwpPointerConstraintsV1>>>) -> CursorManager {
|
||||||
|
CursorManager {
|
||||||
|
pointer_constraints_proxy: constraints,
|
||||||
|
auto_themer: None,
|
||||||
|
pointers: Vec::new(),
|
||||||
|
locked_pointers: Vec::new(),
|
||||||
|
cursor_visible: Rc::new(RefCell::new(true)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_pointer(&mut self, pointer: wl_pointer::WlPointer) {
|
||||||
|
let auto_themer = self
|
||||||
|
.auto_themer
|
||||||
|
.as_ref()
|
||||||
|
.expect("AutoThemer not initialized. Server did not advertise shm or compositor?");
|
||||||
|
self.pointers.push(auto_themer.theme_pointer(pointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_auto_themer(&mut self, auto_themer: AutoThemer) {
|
||||||
|
self.auto_themer = Some(auto_themer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_cursor_visible(&mut self, visible: bool) {
|
||||||
|
if !visible {
|
||||||
|
for pointer in self.pointers.iter() {
|
||||||
|
(**pointer).set_cursor(0, None, 0, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for pointer in self.pointers.iter() {
|
||||||
|
pointer.set_cursor("left_ptr", None).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*self.cursor_visible.try_borrow_mut().unwrap()) = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn grab_pointer(&mut self, surface: Option<&WlSurface>) {
|
||||||
|
for lp in self.locked_pointers.drain(..) {
|
||||||
|
lp.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(surface) = surface {
|
||||||
|
for pointer in self.pointers.iter() {
|
||||||
|
let locked_pointer = self
|
||||||
|
.pointer_constraints_proxy
|
||||||
|
.try_borrow()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|pointer_constraints| {
|
||||||
|
super::pointer::implement_locked_pointer(
|
||||||
|
surface,
|
||||||
|
&**pointer,
|
||||||
|
pointer_constraints,
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(locked_pointer) = locked_pointer {
|
||||||
|
self.locked_pointers.push(locked_pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct EventLoop<T: 'static> {
|
pub struct EventLoop<T: 'static> {
|
||||||
// The loop
|
// The loop
|
||||||
inner_loop: ::calloop::EventLoop<()>,
|
inner_loop: ::calloop::EventLoop<()>,
|
||||||
|
@ -79,6 +160,8 @@ pub struct EventLoop<T: 'static> {
|
||||||
// our sink, shared with some handlers, buffering the events
|
// our sink, shared with some handlers, buffering the events
|
||||||
sink: Arc<Mutex<WindowEventsSink<T>>>,
|
sink: Arc<Mutex<WindowEventsSink<T>>>,
|
||||||
pending_user_events: Rc<RefCell<VecDeque<T>>>,
|
pending_user_events: Rc<RefCell<VecDeque<T>>>,
|
||||||
|
// Utility for grabbing the cursor and changing visibility
|
||||||
|
cursor_manager: Rc<RefCell<CursorManager>>,
|
||||||
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
|
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
|
||||||
user_sender: ::calloop::channel::Sender<T>,
|
user_sender: ::calloop::channel::Sender<T>,
|
||||||
_kbd_source: ::calloop::Source<
|
_kbd_source: ::calloop::Source<
|
||||||
|
@ -146,14 +229,24 @@ impl<T: 'static> EventLoop<T> {
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let pointer_constraints_proxy = Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
let mut seat_manager = SeatManager {
|
let mut seat_manager = SeatManager {
|
||||||
sink: sink.clone(),
|
sink: sink.clone(),
|
||||||
relative_pointer_manager_proxy: Rc::new(RefCell::new(None)),
|
relative_pointer_manager_proxy: Rc::new(RefCell::new(None)),
|
||||||
|
pointer_constraints_proxy: pointer_constraints_proxy.clone(),
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
seats: seats.clone(),
|
seats: seats.clone(),
|
||||||
kbd_sender,
|
kbd_sender,
|
||||||
|
cursor_manager: Rc::new(RefCell::new(CursorManager::new(pointer_constraints_proxy))),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cursor_manager = seat_manager.cursor_manager.clone();
|
||||||
|
let cursor_manager2 = cursor_manager.clone();
|
||||||
|
|
||||||
|
let shm_cell = Rc::new(RefCell::new(None));
|
||||||
|
let compositor_cell = Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
let env = Environment::from_display_with_cb(
|
let env = Environment::from_display_with_cb(
|
||||||
&display,
|
&display,
|
||||||
&mut event_queue,
|
&mut event_queue,
|
||||||
|
@ -175,6 +268,39 @@ impl<T: 'static> EventLoop<T> {
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.unwrap() = Some(relative_pointer_manager_proxy);
|
.unwrap() = Some(relative_pointer_manager_proxy);
|
||||||
}
|
}
|
||||||
|
if interface == "zwp_pointer_constraints_v1" {
|
||||||
|
let pointer_constraints_proxy = registry
|
||||||
|
.bind(version, id, move |pointer_constraints| {
|
||||||
|
pointer_constraints.implement_closure(|_, _| (), ())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
*seat_manager.pointer_constraints_proxy.borrow_mut() =
|
||||||
|
Some(pointer_constraints_proxy);
|
||||||
|
}
|
||||||
|
if interface == "wl_shm" {
|
||||||
|
let shm: WlShm = registry
|
||||||
|
.bind(version, id, move |shm| shm.implement_closure(|_, _| (), ()))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
(*shm_cell.borrow_mut()) = Some(shm);
|
||||||
|
}
|
||||||
|
if interface == "wl_compositor" {
|
||||||
|
let compositor: WlCompositor = registry
|
||||||
|
.bind(version, id, move |compositor| {
|
||||||
|
compositor.implement_closure(|_, _| (), ())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
(*compositor_cell.borrow_mut()) = Some(compositor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if compositor_cell.borrow().is_some() && shm_cell.borrow().is_some() {
|
||||||
|
let compositor = compositor_cell.borrow_mut().take().unwrap();
|
||||||
|
let shm = shm_cell.borrow_mut().take().unwrap();
|
||||||
|
let auto_themer = AutoThemer::init(None, compositor, &shm);
|
||||||
|
cursor_manager2.borrow_mut().set_auto_themer(auto_themer);
|
||||||
|
}
|
||||||
|
|
||||||
if interface == "wl_seat" {
|
if interface == "wl_seat" {
|
||||||
seat_manager.add_seat(id, version, registry)
|
seat_manager.add_seat(id, version, registry)
|
||||||
}
|
}
|
||||||
|
@ -213,6 +339,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
pending_user_events,
|
pending_user_events,
|
||||||
display: display.clone(),
|
display: display.clone(),
|
||||||
outputs: env.outputs.clone(),
|
outputs: env.outputs.clone(),
|
||||||
|
cursor_manager,
|
||||||
_user_source: user_source,
|
_user_source: user_source,
|
||||||
user_sender,
|
user_sender,
|
||||||
_kbd_source: kbd_source,
|
_kbd_source: kbd_source,
|
||||||
|
@ -452,7 +579,17 @@ impl<T> EventLoop<T> {
|
||||||
}
|
}
|
||||||
// process pending resize/refresh
|
// process pending resize/refresh
|
||||||
window_target.store.lock().unwrap().for_each(
|
window_target.store.lock().unwrap().for_each(
|
||||||
|newsize, size, new_dpi, refresh, frame_refresh, closed, wid, frame| {
|
|newsize,
|
||||||
|
size,
|
||||||
|
new_dpi,
|
||||||
|
refresh,
|
||||||
|
frame_refresh,
|
||||||
|
closed,
|
||||||
|
cursor_visible,
|
||||||
|
cursor_grab,
|
||||||
|
surface,
|
||||||
|
wid,
|
||||||
|
frame| {
|
||||||
if let Some(frame) = frame {
|
if let Some(frame) = frame {
|
||||||
if let Some((w, h)) = newsize {
|
if let Some((w, h)) = newsize {
|
||||||
frame.resize(w, h);
|
frame.resize(w, h);
|
||||||
|
@ -482,6 +619,17 @@ impl<T> EventLoop<T> {
|
||||||
if closed {
|
if closed {
|
||||||
sink.send_window_event(crate::event::WindowEvent::CloseRequested, wid);
|
sink.send_window_event(crate::event::WindowEvent::CloseRequested, wid);
|
||||||
}
|
}
|
||||||
|
if let Some(grab) = cursor_grab {
|
||||||
|
self.cursor_manager.borrow_mut().grab_pointer(if grab {
|
||||||
|
Some(surface)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(visible) = cursor_visible {
|
||||||
|
self.cursor_manager.borrow_mut().set_cursor_visible(visible);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -497,6 +645,8 @@ struct SeatManager<T: 'static> {
|
||||||
seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
|
seats: Arc<Mutex<Vec<(u32, wl_seat::WlSeat)>>>,
|
||||||
kbd_sender: ::calloop::channel::Sender<(crate::event::WindowEvent, super::WindowId)>,
|
kbd_sender: ::calloop::channel::Sender<(crate::event::WindowEvent, super::WindowId)>,
|
||||||
relative_pointer_manager_proxy: Rc<RefCell<Option<ZwpRelativePointerManagerV1>>>,
|
relative_pointer_manager_proxy: Rc<RefCell<Option<ZwpRelativePointerManagerV1>>>,
|
||||||
|
pointer_constraints_proxy: Rc<RefCell<Option<ZwpPointerConstraintsV1>>>,
|
||||||
|
cursor_manager: Rc<RefCell<CursorManager>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> SeatManager<T> {
|
impl<T: 'static> SeatManager<T> {
|
||||||
|
@ -513,6 +663,7 @@ impl<T: 'static> SeatManager<T> {
|
||||||
touch: None,
|
touch: None,
|
||||||
kbd_sender: self.kbd_sender.clone(),
|
kbd_sender: self.kbd_sender.clone(),
|
||||||
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
|
modifiers_tracker: Arc::new(Mutex::new(ModifiersState::default())),
|
||||||
|
cursor_manager: self.cursor_manager.clone(),
|
||||||
};
|
};
|
||||||
let seat = registry
|
let seat = registry
|
||||||
.bind(min(version, 5), id, move |seat| {
|
.bind(min(version, 5), id, move |seat| {
|
||||||
|
@ -544,6 +695,7 @@ struct SeatData<T> {
|
||||||
keyboard: Option<wl_keyboard::WlKeyboard>,
|
keyboard: Option<wl_keyboard::WlKeyboard>,
|
||||||
touch: Option<wl_touch::WlTouch>,
|
touch: Option<wl_touch::WlTouch>,
|
||||||
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
||||||
|
cursor_manager: Rc<RefCell<CursorManager>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> SeatData<T> {
|
impl<T: 'static> SeatData<T> {
|
||||||
|
@ -558,8 +710,13 @@ impl<T: 'static> SeatData<T> {
|
||||||
self.sink.clone(),
|
self.sink.clone(),
|
||||||
self.store.clone(),
|
self.store.clone(),
|
||||||
self.modifiers_tracker.clone(),
|
self.modifiers_tracker.clone(),
|
||||||
|
self.cursor_manager.borrow().cursor_visible.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
self.cursor_manager
|
||||||
|
.borrow_mut()
|
||||||
|
.register_pointer(self.pointer.as_ref().unwrap().clone());
|
||||||
|
|
||||||
self.relative_pointer = self
|
self.relative_pointer = self
|
||||||
.relative_pointer_manager_proxy
|
.relative_pointer_manager_proxy
|
||||||
.try_borrow()
|
.try_borrow()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::event::{
|
use crate::event::{
|
||||||
|
@ -17,11 +19,19 @@ use smithay_client_toolkit::reexports::protocols::unstable::relative_pointer::v1
|
||||||
zwp_relative_pointer_v1::ZwpRelativePointerV1,
|
zwp_relative_pointer_v1::ZwpRelativePointerV1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use smithay_client_toolkit::reexports::protocols::unstable::pointer_constraints::v1::client::{
|
||||||
|
zwp_locked_pointer_v1::ZwpLockedPointerV1, zwp_pointer_constraints_v1::Lifetime,
|
||||||
|
zwp_pointer_constraints_v1::ZwpPointerConstraintsV1,
|
||||||
|
};
|
||||||
|
|
||||||
|
use smithay_client_toolkit::reexports::client::protocol::wl_surface::WlSurface;
|
||||||
|
|
||||||
pub fn implement_pointer<T: 'static>(
|
pub fn implement_pointer<T: 'static>(
|
||||||
seat: &wl_seat::WlSeat,
|
seat: &wl_seat::WlSeat,
|
||||||
sink: Arc<Mutex<WindowEventsSink<T>>>,
|
sink: Arc<Mutex<WindowEventsSink<T>>>,
|
||||||
store: Arc<Mutex<WindowStore>>,
|
store: Arc<Mutex<WindowStore>>,
|
||||||
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
modifiers_tracker: Arc<Mutex<ModifiersState>>,
|
||||||
|
cursor_visible: Rc<RefCell<bool>>,
|
||||||
) -> WlPointer {
|
) -> WlPointer {
|
||||||
seat.get_pointer(|pointer| {
|
seat.get_pointer(|pointer| {
|
||||||
let mut mouse_focus = None;
|
let mut mouse_focus = None;
|
||||||
|
@ -62,6 +72,10 @@ pub fn implement_pointer<T: 'static>(
|
||||||
wid,
|
wid,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *cursor_visible.borrow() == false {
|
||||||
|
pointer.set_cursor(0, None, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PtrEvent::Leave { surface, .. } => {
|
PtrEvent::Leave { surface, .. } => {
|
||||||
mouse_focus = None;
|
mouse_focus = None;
|
||||||
|
@ -241,3 +255,13 @@ pub fn implement_relative_pointer<T: 'static>(
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn implement_locked_pointer(
|
||||||
|
surface: &WlSurface,
|
||||||
|
pointer: &WlPointer,
|
||||||
|
constraints: &ZwpPointerConstraintsV1,
|
||||||
|
) -> Result<ZwpLockedPointerV1, ()> {
|
||||||
|
constraints.lock_pointer(surface, pointer, None, Lifetime::Persistent.to_raw(), |c| {
|
||||||
|
c.implement_closure(|_, _| (), ())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ pub struct Window {
|
||||||
need_frame_refresh: Arc<Mutex<bool>>,
|
need_frame_refresh: Arc<Mutex<bool>>,
|
||||||
need_refresh: Arc<Mutex<bool>>,
|
need_refresh: Arc<Mutex<bool>>,
|
||||||
fullscreen: Arc<Mutex<bool>>,
|
fullscreen: Arc<Mutex<bool>>,
|
||||||
|
cursor_grab_changed: Arc<Mutex<Option<bool>>>,
|
||||||
|
cursor_visible_changed: Arc<Mutex<Option<bool>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -140,6 +142,8 @@ impl Window {
|
||||||
let need_frame_refresh = Arc::new(Mutex::new(true));
|
let need_frame_refresh = Arc::new(Mutex::new(true));
|
||||||
let frame = Arc::new(Mutex::new(frame));
|
let frame = Arc::new(Mutex::new(frame));
|
||||||
let need_refresh = Arc::new(Mutex::new(true));
|
let need_refresh = Arc::new(Mutex::new(true));
|
||||||
|
let cursor_grab_changed = Arc::new(Mutex::new(None));
|
||||||
|
let cursor_visible_changed = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
evlp.store.lock().unwrap().windows.push(InternalWindow {
|
evlp.store.lock().unwrap().windows.push(InternalWindow {
|
||||||
closed: false,
|
closed: false,
|
||||||
|
@ -148,6 +152,8 @@ impl Window {
|
||||||
need_refresh: need_refresh.clone(),
|
need_refresh: need_refresh.clone(),
|
||||||
fullscreen: fullscreen.clone(),
|
fullscreen: fullscreen.clone(),
|
||||||
need_frame_refresh: need_frame_refresh.clone(),
|
need_frame_refresh: need_frame_refresh.clone(),
|
||||||
|
cursor_grab_changed: cursor_grab_changed.clone(),
|
||||||
|
cursor_visible_changed: cursor_visible_changed.clone(),
|
||||||
surface: surface.clone(),
|
surface: surface.clone(),
|
||||||
kill_switch: kill_switch.clone(),
|
kill_switch: kill_switch.clone(),
|
||||||
frame: Arc::downgrade(&frame),
|
frame: Arc::downgrade(&frame),
|
||||||
|
@ -166,6 +172,8 @@ impl Window {
|
||||||
need_frame_refresh,
|
need_frame_refresh,
|
||||||
need_refresh,
|
need_refresh,
|
||||||
fullscreen,
|
fullscreen,
|
||||||
|
cursor_grab_changed,
|
||||||
|
cursor_visible_changed,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,13 +305,14 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_visible(&self, _visible: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
// TODO: This isn't possible on Wayland yet
|
*self.cursor_visible_changed.lock().unwrap() = Some(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
*self.cursor_grab_changed.lock().unwrap() = Some(grab);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -362,6 +371,8 @@ struct InternalWindow {
|
||||||
need_refresh: Arc<Mutex<bool>>,
|
need_refresh: Arc<Mutex<bool>>,
|
||||||
fullscreen: Arc<Mutex<bool>>,
|
fullscreen: Arc<Mutex<bool>>,
|
||||||
need_frame_refresh: Arc<Mutex<bool>>,
|
need_frame_refresh: Arc<Mutex<bool>>,
|
||||||
|
cursor_grab_changed: Arc<Mutex<Option<bool>>>,
|
||||||
|
cursor_visible_changed: Arc<Mutex<Option<bool>>>,
|
||||||
closed: bool,
|
closed: bool,
|
||||||
kill_switch: Arc<Mutex<bool>>,
|
kill_switch: Arc<Mutex<bool>>,
|
||||||
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
||||||
|
@ -429,6 +440,9 @@ impl WindowStore {
|
||||||
bool,
|
bool,
|
||||||
bool,
|
bool,
|
||||||
bool,
|
bool,
|
||||||
|
Option<bool>,
|
||||||
|
Option<bool>,
|
||||||
|
&wl_surface::WlSurface,
|
||||||
WindowId,
|
WindowId,
|
||||||
Option<&mut SWindow<ConceptFrame>>,
|
Option<&mut SWindow<ConceptFrame>>,
|
||||||
),
|
),
|
||||||
|
@ -443,6 +457,9 @@ impl WindowStore {
|
||||||
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
|
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
|
||||||
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
||||||
window.closed,
|
window.closed,
|
||||||
|
window.cursor_visible_changed.lock().unwrap().take(),
|
||||||
|
window.cursor_grab_changed.lock().unwrap().take(),
|
||||||
|
&window.surface,
|
||||||
make_wid(&window.surface),
|
make_wid(&window.surface),
|
||||||
opt_mutex_lock.as_mut().map(|m| &mut **m),
|
opt_mutex_lock.as_mut().map(|m| &mut **m),
|
||||||
);
|
);
|
||||||
|
|
|
@ -655,6 +655,8 @@ impl Window {
|
||||||
///
|
///
|
||||||
/// - **macOS:** This presently merely locks the cursor in a fixed location, which looks visually
|
/// - **macOS:** This presently merely locks the cursor in a fixed location, which looks visually
|
||||||
/// awkward.
|
/// awkward.
|
||||||
|
/// - **Wayland:** This presently merely locks the cursor in a fixed location, which looks visually
|
||||||
|
/// awkward.
|
||||||
/// - **Android:** Has no effect.
|
/// - **Android:** Has no effect.
|
||||||
/// - **iOS:** Always returns an Err.
|
/// - **iOS:** Always returns an Err.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -670,6 +672,7 @@ impl Window {
|
||||||
///
|
///
|
||||||
/// - **Windows:** The cursor is only hidden within the confines of the window.
|
/// - **Windows:** The cursor is only hidden within the confines of the window.
|
||||||
/// - **X11:** The cursor is only hidden within the confines of the window.
|
/// - **X11:** The cursor is only hidden within the confines of the window.
|
||||||
|
/// - **Wayland:** The cursor is only hidden within the confines of the window.
|
||||||
/// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
|
/// - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is
|
||||||
/// outside of the window.
|
/// outside of the window.
|
||||||
/// - **iOS:** Has no effect.
|
/// - **iOS:** Has no effect.
|
||||||
|
|
Loading…
Reference in a new issue