winit-sonoma-fix/src/platform/linux/wayland/window.rs

218 lines
6.3 KiB
Rust
Raw Normal View History

2016-10-08 23:51:29 +11:00
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicBool;
use wayland_client::{EventQueue, EventQueueHandle, Proxy};
use wayland_client::protocol::{wl_display,wl_surface};
2017-03-05 00:04:01 +11:00
use {CreationError, MouseCursor, CursorState, WindowAttributes};
2016-10-08 23:51:29 +11:00
use platform::MonitorId as PlatformMonitorId;
2017-03-05 00:04:01 +11:00
use super::{WaylandContext, EventsLoop};
2016-10-08 23:51:29 +11:00
use super::wayland_window;
use super::wayland_window::DecoratedSurface;
pub struct Window {
2017-03-11 09:56:31 +11:00
// the global wayland context
2016-10-08 23:51:29 +11:00
ctxt: Arc<WaylandContext>,
2017-03-11 09:56:31 +11:00
// the EventQueue of our EventsLoop
2017-03-05 00:04:01 +11:00
evq: Arc<Mutex<EventQueue>>,
2017-03-11 09:56:31 +11:00
// signal to advertize the EventsLoop when we are destroyed
cleanup_signal: Arc<AtomicBool>,
2017-03-11 09:56:31 +11:00
// our wayland surface
2016-10-08 23:51:29 +11:00
surface: Arc<wl_surface::WlSurface>,
2017-03-11 09:56:31 +11:00
// our current inner dimensions
2016-10-08 23:51:29 +11:00
size: Mutex<(u32, u32)>,
2017-03-11 09:56:31 +11:00
// the id of our DecoratedHandler in the EventQueue
2016-10-08 23:51:29 +11:00
decorated_id: usize
}
2017-03-05 00:04:01 +11:00
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WindowId(usize);
2017-03-05 00:04:01 +11:00
#[inline]
pub fn make_wid(s: &wl_surface::WlSurface) -> WindowId {
WindowId(s.ptr() as usize)
}
impl Window {
2017-03-05 00:04:01 +11:00
pub fn new(evlp: &EventsLoop, ctxt: Arc<WaylandContext>, attributes: &WindowAttributes) -> Result<Window, CreationError>
{
2016-10-08 23:51:29 +11:00
let (width, height) = attributes.dimensions.unwrap_or((800,600));
let (surface, decorated) = ctxt.create_window::<DecoratedHandler>(width, height);
2016-10-08 23:51:29 +11:00
// init DecoratedSurface
let (evq, cleanup_signal) = evlp.get_window_init();
2017-03-05 00:04:01 +11:00
let decorated_id = {
let mut evq_guard = evq.lock().unwrap();
// store the DecoratedSurface handler
2017-03-05 00:04:01 +11:00
let decorated_id = evq_guard.add_handler_with_init(decorated);
{
let mut state = evq_guard.state();
// initialize the DecoratedHandler
2017-03-05 00:04:01 +11:00
let decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(decorated_id);
*(decorated.handler()) = Some(DecoratedHandler::new());
2017-03-11 09:56:31 +11:00
// set fullscreen if necessary
if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = attributes.fullscreen.get_monitor() {
2017-03-05 00:04:01 +11:00
ctxt.with_output(monitor_id.clone(), |output| {
decorated.set_fullscreen(Some(output))
2017-03-05 00:04:01 +11:00
});
} else if attributes.decorations {
decorated.set_decorate(true);
}
// Finally, set the decorations size
decorated.resize(width as i32, height as i32);
2016-10-08 23:51:29 +11:00
}
2017-03-05 00:04:01 +11:00
decorated_id
};
let me = Window {
2016-10-08 23:51:29 +11:00
ctxt: ctxt,
2017-03-05 00:04:01 +11:00
evq: evq,
cleanup_signal: cleanup_signal,
2016-10-08 23:51:29 +11:00
surface: surface,
size: Mutex::new((width, height)),
decorated_id: decorated_id
};
2017-03-11 09:56:31 +11:00
// register ourselves to the EventsLoop
evlp.register_window(me.decorated_id, me.surface.clone());
2016-10-08 23:51:29 +11:00
2017-03-05 00:04:01 +11:00
Ok(me)
}
2016-10-08 23:51:29 +11:00
2017-03-05 00:04:01 +11:00
#[inline]
pub fn id(&self) -> WindowId {
make_wid(&self.surface)
}
pub fn set_title(&self, title: &str) {
2016-10-10 01:19:06 +11:00
let mut guard = self.evq.lock().unwrap();
let mut state = guard.state();
let decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(self.decorated_id);
2016-10-10 01:19:06 +11:00
decorated.set_title(title.into())
}
#[inline]
pub fn show(&self) {
// TODO
}
#[inline]
pub fn hide(&self) {
// TODO
}
#[inline]
pub fn get_position(&self) -> Option<(i32, i32)> {
// Not possible with wayland
None
}
#[inline]
pub fn set_position(&self, _x: i32, _y: i32) {
// Not possible with wayland
}
pub fn get_inner_size(&self) -> Option<(u32, u32)> {
2016-10-10 01:19:06 +11:00
Some(self.size.lock().unwrap().clone())
}
#[inline]
pub fn get_outer_size(&self) -> Option<(u32, u32)> {
2016-10-10 01:19:06 +11:00
let (w, h) = self.size.lock().unwrap().clone();
let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
Some((w as u32, h as u32))
}
#[inline]
2016-10-10 01:19:06 +11:00
// NOTE: This will only resize the borders, the contents must be updated by the user
pub fn set_inner_size(&self, x: u32, y: u32) {
2016-10-10 01:19:06 +11:00
let mut guard = self.evq.lock().unwrap();
let mut state = guard.state();
let mut decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(self.decorated_id);
decorated.resize(x as i32, y as i32);
*(self.size.lock().unwrap()) = (x, y);
}
#[inline]
2015-12-13 23:13:20 +11:00
pub fn set_cursor(&self, _cursor: MouseCursor) {
// TODO
}
#[inline]
2015-12-23 00:35:55 +11:00
pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> {
use CursorState::{Grab, Normal, Hide};
// TODO : not yet possible on wayland to grab cursor
match state {
Grab => Err("Cursor cannot be grabbed on wayland yet.".to_string()),
Hide => Err("Cursor cannot be hidden on wayland yet.".to_string()),
Normal => Ok(())
}
}
#[inline]
pub fn hidpi_factor(&self) -> f32 {
// TODO
1.0
}
#[inline]
pub fn set_cursor_position(&self, _x: i32, _y: i32) -> Result<(), ()> {
// TODO: not yet possible on wayland
2015-12-23 00:35:55 +11:00
Err(())
}
pub fn get_display(&self) -> &wl_display::WlDisplay {
2016-10-08 23:51:29 +11:00
&self.ctxt.display
}
pub fn get_surface(&self) -> &wl_surface::WlSurface {
2016-10-08 23:51:29 +11:00
&self.surface
}
}
impl Drop for Window {
fn drop(&mut self) {
2016-10-08 23:51:29 +11:00
self.surface.destroy();
self.cleanup_signal.store(true, ::std::sync::atomic::Ordering::Relaxed);
2016-10-08 23:51:29 +11:00
}
}
2017-03-05 00:04:01 +11:00
pub struct DecoratedHandler {
newsize: Option<(u32, u32)>,
closed: bool,
2016-10-08 23:51:29 +11:00
}
impl DecoratedHandler {
fn new() -> DecoratedHandler {
DecoratedHandler {
newsize: None,
closed: false,
}
}
2017-03-05 00:04:01 +11:00
pub fn take_newsize(&mut self) -> Option<(u32, u32)> {
2016-10-08 23:51:29 +11:00
self.newsize.take()
}
pub fn is_closed(&self) -> bool { self.closed }
2016-10-08 23:51:29 +11:00
}
impl wayland_window::Handler for DecoratedHandler {
fn configure(&mut self,
_: &mut EventQueueHandle,
_: wayland_window::Configure,
2016-10-08 23:51:29 +11:00
width: i32, height: i32)
{
use std::cmp::max;
self.newsize = Some((max(width,1) as u32, max(height,1) as u32));
}
fn close(&mut self, _: &mut EventQueueHandle) {
self.closed = true;
}
}