mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
Wayland support for set_cursor_icon (#1204)
This commit is contained in:
parent
237e7ee2e6
commit
5ced36e319
|
@ -22,6 +22,7 @@
|
||||||
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, 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
|
||||||
|
- On Wayland, add support for set_cursor_icon.
|
||||||
|
|
||||||
# 0.20.0 Alpha 3 (2019-08-14)
|
# 0.20.0 Alpha 3 (2019-08-14)
|
||||||
|
|
||||||
|
|
|
@ -190,8 +190,8 @@ Legend:
|
||||||
|----------------------- | ----- | ---- | ------- | ----------- | ----- | ----- | -------- |
|
|----------------------- | ----- | ---- | ------- | ----------- | ----- | ----- | -------- |
|
||||||
|Mouse events |✔️ |▢[#63] |✔️ |✔️ |**N/A**|**N/A**|❓ |
|
|Mouse events |✔️ |▢[#63] |✔️ |✔️ |**N/A**|**N/A**|❓ |
|
||||||
|Mouse set location |✔️ |✔️ |✔️ |❓ |**N/A**|**N/A**|❓ |
|
|Mouse set location |✔️ |✔️ |✔️ |❓ |**N/A**|**N/A**|❓ |
|
||||||
|Cursor grab |✔️ |▢[#165] |▢[#242] |❌[#306] |**N/A**|**N/A**|❓ |
|
|Cursor grab |✔️ |▢[#165] |▢[#242] |✔️ |**N/A**|**N/A**|❓ |
|
||||||
|Cursor icon |✔️ |✔️ |✔️ |❌[#306] |**N/A**|**N/A**|❓ |
|
|Cursor icon |✔️ |✔️ |✔️ |✔️ |**N/A**|**N/A**|❓ |
|
||||||
|Touch events |✔️ |❌ |✔️ |✔️ |✔️ |✔️ |❓ |
|
|Touch events |✔️ |❌ |✔️ |✔️ |✔️ |✔️ |❓ |
|
||||||
|Touch pressure |✔️ |❌ |❌ |❌ |❌ |✔️ |❓ |
|
|Touch pressure |✔️ |❌ |❌ |❌ |❌ |✔️ |❓ |
|
||||||
|Multitouch |✔️ |❌ |✔️ |✔️ |❓ |✔️ |❓ |
|
|Multitouch |✔️ |❌ |✔️ |✔️ |❓ |✔️ |❓ |
|
||||||
|
|
|
@ -29,6 +29,7 @@ use crate::{
|
||||||
sticky_exit_callback, MonitorHandle as PlatformMonitorHandle,
|
sticky_exit_callback, MonitorHandle as PlatformMonitorHandle,
|
||||||
VideoMode as PlatformVideoMode,
|
VideoMode as PlatformVideoMode,
|
||||||
},
|
},
|
||||||
|
window::CursorIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{window::WindowStore, DeviceId, WindowId};
|
use super::{window::WindowStore, DeviceId, WindowId};
|
||||||
|
@ -78,21 +79,23 @@ impl<T> WindowEventsSink<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CursorManager {
|
pub struct CursorManager {
|
||||||
pointer_constraints_proxy: Rc<RefCell<Option<ZwpPointerConstraintsV1>>>,
|
pointer_constraints_proxy: Arc<Mutex<Option<ZwpPointerConstraintsV1>>>,
|
||||||
auto_themer: Option<AutoThemer>,
|
auto_themer: Option<AutoThemer>,
|
||||||
pointers: Vec<AutoPointer>,
|
pointers: Vec<AutoPointer>,
|
||||||
locked_pointers: Vec<ZwpLockedPointerV1>,
|
locked_pointers: Vec<ZwpLockedPointerV1>,
|
||||||
cursor_visible: Rc<RefCell<bool>>,
|
cursor_visible: bool,
|
||||||
|
current_cursor: CursorIcon,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CursorManager {
|
impl CursorManager {
|
||||||
fn new(constraints: Rc<RefCell<Option<ZwpPointerConstraintsV1>>>) -> CursorManager {
|
fn new(constraints: Arc<Mutex<Option<ZwpPointerConstraintsV1>>>) -> CursorManager {
|
||||||
CursorManager {
|
CursorManager {
|
||||||
pointer_constraints_proxy: constraints,
|
pointer_constraints_proxy: constraints,
|
||||||
auto_themer: None,
|
auto_themer: None,
|
||||||
pointers: Vec::new(),
|
pointers: Vec::new(),
|
||||||
locked_pointers: Vec::new(),
|
locked_pointers: Vec::new(),
|
||||||
cursor_visible: Rc::new(RefCell::new(true)),
|
cursor_visible: true,
|
||||||
|
current_cursor: CursorIcon::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,29 +111,96 @@ impl CursorManager {
|
||||||
self.auto_themer = Some(auto_themer);
|
self.auto_themer = Some(auto_themer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_visible(&mut self, visible: bool) {
|
pub fn set_cursor_visible(&mut self, visible: bool) {
|
||||||
if !visible {
|
if !visible {
|
||||||
for pointer in self.pointers.iter() {
|
for pointer in self.pointers.iter() {
|
||||||
(**pointer).set_cursor(0, None, 0, 0);
|
(**pointer).set_cursor(0, None, 0, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for pointer in self.pointers.iter() {
|
self.set_cursor_icon_impl(self.current_cursor);
|
||||||
pointer.set_cursor("left_ptr", None).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(*self.cursor_visible.try_borrow_mut().unwrap()) = visible;
|
self.cursor_visible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grab_pointer(&mut self, surface: Option<&WlSurface>) {
|
/// A helper function to restore cursor styles on PtrEvent::Enter.
|
||||||
for lp in self.locked_pointers.drain(..) {
|
pub fn reload_cursor_style(&mut self) {
|
||||||
lp.destroy();
|
if !self.cursor_visible {
|
||||||
|
self.set_cursor_visible(false);
|
||||||
|
} else {
|
||||||
|
self.set_cursor_icon_impl(self.current_cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_cursor_icon(&mut self, cursor: CursorIcon) {
|
||||||
|
if self.cursor_visible && cursor != self.current_cursor {
|
||||||
|
self.current_cursor = cursor;
|
||||||
|
|
||||||
|
self.set_cursor_icon_impl(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_cursor_icon_impl(&mut self, cursor: CursorIcon) {
|
||||||
|
let cursor = match cursor {
|
||||||
|
CursorIcon::Alias => "link",
|
||||||
|
CursorIcon::Arrow => "arrow",
|
||||||
|
CursorIcon::Cell => "plus",
|
||||||
|
CursorIcon::Copy => "copy",
|
||||||
|
CursorIcon::Crosshair => "crosshair",
|
||||||
|
CursorIcon::Default => "left_ptr",
|
||||||
|
CursorIcon::Hand => "hand",
|
||||||
|
CursorIcon::Help => "question_arrow",
|
||||||
|
CursorIcon::Move => "move",
|
||||||
|
CursorIcon::Grab => "grab",
|
||||||
|
CursorIcon::Grabbing => "grabbing",
|
||||||
|
CursorIcon::Progress => "progress",
|
||||||
|
CursorIcon::AllScroll => "all-scroll",
|
||||||
|
CursorIcon::ContextMenu => "context-menu",
|
||||||
|
|
||||||
|
CursorIcon::NoDrop => "no-drop",
|
||||||
|
CursorIcon::NotAllowed => "crossed_circle",
|
||||||
|
|
||||||
|
// Resize cursors
|
||||||
|
CursorIcon::EResize => "right_side",
|
||||||
|
CursorIcon::NResize => "top_side",
|
||||||
|
CursorIcon::NeResize => "top_right_corner",
|
||||||
|
CursorIcon::NwResize => "top_left_corner",
|
||||||
|
CursorIcon::SResize => "bottom_side",
|
||||||
|
CursorIcon::SeResize => "bottom_right_corner",
|
||||||
|
CursorIcon::SwResize => "bottom_left_corner",
|
||||||
|
CursorIcon::WResize => "left_side",
|
||||||
|
CursorIcon::EwResize => "h_double_arrow",
|
||||||
|
CursorIcon::NsResize => "v_double_arrow",
|
||||||
|
CursorIcon::NwseResize => "bd_double_arrow",
|
||||||
|
CursorIcon::NeswResize => "fd_double_arrow",
|
||||||
|
CursorIcon::ColResize => "h_double_arrow",
|
||||||
|
CursorIcon::RowResize => "v_double_arrow",
|
||||||
|
|
||||||
|
CursorIcon::Text => "text",
|
||||||
|
CursorIcon::VerticalText => "vertical-text",
|
||||||
|
|
||||||
|
CursorIcon::Wait => "watch",
|
||||||
|
|
||||||
|
CursorIcon::ZoomIn => "zoom-in",
|
||||||
|
CursorIcon::ZoomOut => "zoom-out",
|
||||||
|
};
|
||||||
|
|
||||||
|
for pointer in self.pointers.iter() {
|
||||||
|
// Ignore erros, since we don't want to fail hard in case we can't find a proper cursor
|
||||||
|
// in a given theme.
|
||||||
|
let _ = pointer.set_cursor(cursor, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn grab_pointer(&mut self, surface: Option<&WlSurface>) {
|
||||||
|
for locked_pointer in self.locked_pointers.drain(..) {
|
||||||
|
locked_pointer.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface) = surface {
|
if let Some(surface) = surface {
|
||||||
for pointer in self.pointers.iter() {
|
for pointer in self.pointers.iter() {
|
||||||
let locked_pointer = self
|
let locked_pointer = self
|
||||||
.pointer_constraints_proxy
|
.pointer_constraints_proxy
|
||||||
.try_borrow()
|
.try_lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|pointer_constraints| {
|
.and_then(|pointer_constraints| {
|
||||||
|
@ -155,13 +225,12 @@ pub struct EventLoop<T: 'static> {
|
||||||
inner_loop: ::calloop::EventLoop<()>,
|
inner_loop: ::calloop::EventLoop<()>,
|
||||||
// The wayland display
|
// The wayland display
|
||||||
pub display: Arc<Display>,
|
pub display: Arc<Display>,
|
||||||
// the output manager
|
// The output manager
|
||||||
pub outputs: OutputMgr,
|
pub outputs: OutputMgr,
|
||||||
// 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
|
// 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<
|
||||||
|
@ -174,17 +243,19 @@ pub struct EventLoop<T: 'static> {
|
||||||
//
|
//
|
||||||
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs.
|
// We should only try and wake up the `EventLoop` if it still exists, so we hold Weak ptrs.
|
||||||
pub struct EventLoopProxy<T: 'static> {
|
pub struct EventLoopProxy<T: 'static> {
|
||||||
user_sender: ::calloop::channel::Sender<T>,
|
user_sender: calloop::channel::Sender<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventLoopWindowTarget<T> {
|
pub struct EventLoopWindowTarget<T> {
|
||||||
// the event queue
|
// The event queue
|
||||||
pub evq: RefCell<::calloop::Source<EventQueue>>,
|
pub evq: RefCell<::calloop::Source<EventQueue>>,
|
||||||
// The window store
|
// The window store
|
||||||
pub store: Arc<Mutex<WindowStore>>,
|
pub store: Arc<Mutex<WindowStore>>,
|
||||||
// the env
|
// The cursor manager
|
||||||
|
pub cursor_manager: Arc<Mutex<CursorManager>>,
|
||||||
|
// The env
|
||||||
pub env: Environment,
|
pub env: Environment,
|
||||||
// a cleanup switch to prune dead windows
|
// A cleanup switch to prune dead windows
|
||||||
pub cleanup_needed: Arc<Mutex<bool>>,
|
pub cleanup_needed: Arc<Mutex<bool>>,
|
||||||
// The wayland display
|
// The wayland display
|
||||||
pub display: Arc<Display>,
|
pub display: Arc<Display>,
|
||||||
|
@ -229,7 +300,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let pointer_constraints_proxy = Rc::new(RefCell::new(None));
|
let pointer_constraints_proxy = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
let mut seat_manager = SeatManager {
|
let mut seat_manager = SeatManager {
|
||||||
sink: sink.clone(),
|
sink: sink.clone(),
|
||||||
|
@ -238,11 +309,11 @@ impl<T: 'static> EventLoop<T> {
|
||||||
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))),
|
cursor_manager: Arc::new(Mutex::new(CursorManager::new(pointer_constraints_proxy))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let cursor_manager = seat_manager.cursor_manager.clone();
|
let cursor_manager = seat_manager.cursor_manager.clone();
|
||||||
let cursor_manager2 = cursor_manager.clone();
|
let cursor_manager_clone = cursor_manager.clone();
|
||||||
|
|
||||||
let shm_cell = Rc::new(RefCell::new(None));
|
let shm_cell = Rc::new(RefCell::new(None));
|
||||||
let compositor_cell = Rc::new(RefCell::new(None));
|
let compositor_cell = Rc::new(RefCell::new(None));
|
||||||
|
@ -275,7 +346,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
*seat_manager.pointer_constraints_proxy.borrow_mut() =
|
*seat_manager.pointer_constraints_proxy.lock().unwrap() =
|
||||||
Some(pointer_constraints_proxy);
|
Some(pointer_constraints_proxy);
|
||||||
}
|
}
|
||||||
if interface == "wl_shm" {
|
if interface == "wl_shm" {
|
||||||
|
@ -298,7 +369,10 @@ impl<T: 'static> EventLoop<T> {
|
||||||
let compositor = compositor_cell.borrow_mut().take().unwrap();
|
let compositor = compositor_cell.borrow_mut().take().unwrap();
|
||||||
let shm = shm_cell.borrow_mut().take().unwrap();
|
let shm = shm_cell.borrow_mut().take().unwrap();
|
||||||
let auto_themer = AutoThemer::init(None, compositor, &shm);
|
let auto_themer = AutoThemer::init(None, compositor, &shm);
|
||||||
cursor_manager2.borrow_mut().set_auto_themer(auto_themer);
|
cursor_manager_clone
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.set_auto_themer(auto_themer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if interface == "wl_seat" {
|
if interface == "wl_seat" {
|
||||||
|
@ -333,13 +407,13 @@ impl<T: 'static> EventLoop<T> {
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let cursor_manager_clone = cursor_manager.clone();
|
||||||
Ok(EventLoop {
|
Ok(EventLoop {
|
||||||
inner_loop,
|
inner_loop,
|
||||||
sink,
|
sink,
|
||||||
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,
|
||||||
|
@ -348,6 +422,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
evq: RefCell::new(source),
|
evq: RefCell::new(source),
|
||||||
store,
|
store,
|
||||||
env,
|
env,
|
||||||
|
cursor_manager: cursor_manager_clone,
|
||||||
cleanup_needed: Arc::new(Mutex::new(false)),
|
cleanup_needed: Arc::new(Mutex::new(false)),
|
||||||
seats,
|
seats,
|
||||||
display,
|
display,
|
||||||
|
@ -369,7 +444,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
F: 'static + FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
F: 'static + FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_return(callback);
|
self.run_return(callback);
|
||||||
::std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_return<F>(&mut self, mut callback: F)
|
pub fn run_return<F>(&mut self, mut callback: F)
|
||||||
|
@ -579,17 +654,7 @@ 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,
|
|newsize, size, new_dpi, refresh, frame_refresh, closed, wid, frame| {
|
||||||
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);
|
||||||
|
@ -619,17 +684,6 @@ 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);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -645,8 +699,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>>>,
|
pointer_constraints_proxy: Arc<Mutex<Option<ZwpPointerConstraintsV1>>>,
|
||||||
cursor_manager: Rc<RefCell<CursorManager>>,
|
cursor_manager: Arc<Mutex<CursorManager>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> SeatManager<T> {
|
impl<T: 'static> SeatManager<T> {
|
||||||
|
@ -695,7 +749,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>>,
|
cursor_manager: Arc<Mutex<CursorManager>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> SeatData<T> {
|
impl<T: 'static> SeatData<T> {
|
||||||
|
@ -710,11 +764,12 @@ 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.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
self.cursor_manager
|
self.cursor_manager
|
||||||
.borrow_mut()
|
.lock()
|
||||||
|
.unwrap()
|
||||||
.register_pointer(self.pointer.as_ref().unwrap().clone());
|
.register_pointer(self.pointer.as_ref().unwrap().clone());
|
||||||
|
|
||||||
self.relative_pointer = self
|
self.relative_pointer = self
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::event::{
|
use crate::event::{
|
||||||
|
@ -7,7 +5,11 @@ use crate::event::{
|
||||||
WindowEvent,
|
WindowEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{event_loop::WindowEventsSink, window::WindowStore, DeviceId};
|
use super::{
|
||||||
|
event_loop::{CursorManager, WindowEventsSink},
|
||||||
|
window::WindowStore,
|
||||||
|
DeviceId,
|
||||||
|
};
|
||||||
|
|
||||||
use smithay_client_toolkit::reexports::client::protocol::{
|
use smithay_client_toolkit::reexports::client::protocol::{
|
||||||
wl_pointer::{self, Event as PtrEvent, WlPointer},
|
wl_pointer::{self, Event as PtrEvent, WlPointer},
|
||||||
|
@ -31,7 +33,7 @@ pub fn implement_pointer<T: 'static>(
|
||||||
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>>,
|
cursor_manager: Arc<Mutex<CursorManager>>,
|
||||||
) -> WlPointer {
|
) -> WlPointer {
|
||||||
seat.get_pointer(|pointer| {
|
seat.get_pointer(|pointer| {
|
||||||
let mut mouse_focus = None;
|
let mut mouse_focus = None;
|
||||||
|
@ -43,6 +45,7 @@ pub fn implement_pointer<T: 'static>(
|
||||||
move |evt, pointer| {
|
move |evt, pointer| {
|
||||||
let mut sink = sink.lock().unwrap();
|
let mut sink = sink.lock().unwrap();
|
||||||
let store = store.lock().unwrap();
|
let store = store.lock().unwrap();
|
||||||
|
let mut cursor_manager = cursor_manager.lock().unwrap();
|
||||||
match evt {
|
match evt {
|
||||||
PtrEvent::Enter {
|
PtrEvent::Enter {
|
||||||
surface,
|
surface,
|
||||||
|
@ -73,9 +76,7 @@ pub fn implement_pointer<T: 'static>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if *cursor_visible.borrow() == false {
|
cursor_manager.reload_cursor_style();
|
||||||
pointer.set_cursor(0, None, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PtrEvent::Leave { surface, .. } => {
|
PtrEvent::Leave { surface, .. } => {
|
||||||
mouse_focus = None;
|
mouse_focus = None;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use raw_window_handle::unix::WaylandHandle;
|
use raw_window_handle::unix::WaylandHandle;
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
|
mem::replace,
|
||||||
sync::{Arc, Mutex, Weak},
|
sync::{Arc, Mutex, Weak},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,11 +27,12 @@ use smithay_client_toolkit::{
|
||||||
window::{ConceptFrame, Event as WEvent, State as WState, Theme, Window as SWindow},
|
window::{ConceptFrame, Event as WEvent, State as WState, Theme, Window as SWindow},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
use super::{event_loop::CursorManager, make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
surface: wl_surface::WlSurface,
|
surface: wl_surface::WlSurface,
|
||||||
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
|
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
|
||||||
|
cursor_manager: Arc<Mutex<CursorManager>>,
|
||||||
outputs: OutputMgr, // Access to info for all monitors
|
outputs: OutputMgr, // Access to info for all monitors
|
||||||
size: Arc<Mutex<(u32, u32)>>,
|
size: Arc<Mutex<(u32, u32)>>,
|
||||||
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
|
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
|
||||||
|
@ -38,8 +40,6 @@ 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 {
|
||||||
|
@ -54,6 +54,7 @@ impl Window {
|
||||||
let fullscreen = Arc::new(Mutex::new(false));
|
let fullscreen = Arc::new(Mutex::new(false));
|
||||||
|
|
||||||
let window_store = evlp.store.clone();
|
let window_store = evlp.store.clone();
|
||||||
|
let cursor_manager = evlp.cursor_manager.clone();
|
||||||
let surface = evlp.env.create_surface(move |dpi, surface| {
|
let surface = evlp.env.create_surface(move |dpi, surface| {
|
||||||
window_store.lock().unwrap().dpi_change(&surface, dpi);
|
window_store.lock().unwrap().dpi_change(&surface, dpi);
|
||||||
surface.set_buffer_scale(dpi);
|
surface.set_buffer_scale(dpi);
|
||||||
|
@ -142,8 +143,6 @@ 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,
|
||||||
|
@ -152,8 +151,6 @@ 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),
|
||||||
|
@ -171,9 +168,8 @@ impl Window {
|
||||||
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
|
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
|
||||||
need_frame_refresh,
|
need_frame_refresh,
|
||||||
need_refresh,
|
need_refresh,
|
||||||
|
cursor_manager,
|
||||||
fullscreen,
|
fullscreen,
|
||||||
cursor_grab_changed,
|
|
||||||
cursor_visible_changed,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,18 +296,25 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
|
pub fn set_cursor_icon(&self, cursor: CursorIcon) {
|
||||||
// TODO
|
let mut cursor_manager = self.cursor_manager.lock().unwrap();
|
||||||
|
cursor_manager.set_cursor_icon(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_visible(&self, visible: bool) {
|
pub fn set_cursor_visible(&self, visible: bool) {
|
||||||
*self.cursor_visible_changed.lock().unwrap() = Some(visible);
|
let mut cursor_manager = self.cursor_manager.lock().unwrap();
|
||||||
|
cursor_manager.set_cursor_visible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
*self.cursor_grab_changed.lock().unwrap() = Some(grab);
|
let mut cursor_manager = self.cursor_manager.lock().unwrap();
|
||||||
|
if grab {
|
||||||
|
cursor_manager.grab_pointer(Some(&self.surface));
|
||||||
|
} else {
|
||||||
|
cursor_manager.grab_pointer(None);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,8 +374,6 @@ 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>>>,
|
||||||
|
@ -440,9 +441,6 @@ 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>>,
|
||||||
),
|
),
|
||||||
|
@ -454,12 +452,9 @@ impl WindowStore {
|
||||||
window.newsize.take(),
|
window.newsize.take(),
|
||||||
&mut *(window.size.lock().unwrap()),
|
&mut *(window.size.lock().unwrap()),
|
||||||
window.new_dpi,
|
window.new_dpi,
|
||||||
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
|
replace(&mut *window.need_refresh.lock().unwrap(), false),
|
||||||
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
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),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue