2019-06-22 01:33:15 +10:00
|
|
|
use std::{
|
|
|
|
collections::VecDeque,
|
|
|
|
io::{Seek, SeekFrom, Write},
|
|
|
|
sync::{Arc, Mutex, Weak},
|
|
|
|
};
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
dpi::{LogicalPosition, LogicalSize},
|
|
|
|
error::{ExternalError, NotSupportedError, OsError as RootOsError},
|
|
|
|
monitor::MonitorHandle as RootMonitorHandle,
|
|
|
|
platform_impl::{
|
|
|
|
MonitorHandle as PlatformMonitorHandle,
|
|
|
|
PlatformSpecificWindowBuilderAttributes as PlAttributes,
|
|
|
|
},
|
|
|
|
window::{CursorIcon, WindowAttributes},
|
|
|
|
};
|
|
|
|
|
|
|
|
use smithay_client_toolkit::{
|
|
|
|
output::OutputMgr,
|
|
|
|
reexports::client::{
|
|
|
|
protocol::{wl_seat, wl_shm, wl_subsurface, wl_surface},
|
|
|
|
Display, NewProxy,
|
|
|
|
},
|
|
|
|
surface::{get_dpi_factor, get_outputs},
|
|
|
|
window::{ConceptFrame, Event as WEvent, State as WState, Theme, Window as SWindow},
|
|
|
|
};
|
2018-05-06 03:36:34 +10:00
|
|
|
|
2019-02-21 20:51:43 +11:00
|
|
|
use super::{make_wid, EventLoopWindowTarget, MonitorHandle, WindowId};
|
2019-06-18 04:27:00 +10:00
|
|
|
use crate::platform_impl::platform::wayland::event_loop::{available_monitors, primary_monitor};
|
2015-12-09 08:54:06 +11:00
|
|
|
|
|
|
|
pub struct Window {
|
2019-06-14 02:50:02 +10:00
|
|
|
_bg_surface: wl_surface::WlSurface,
|
|
|
|
user_surface: wl_surface::WlSurface,
|
|
|
|
_user_subsurface: wl_subsurface::WlSubsurface,
|
2018-10-15 10:15:43 +11:00
|
|
|
frame: Arc<Mutex<SWindow<ConceptFrame>>>,
|
2018-06-17 00:14:12 +10:00
|
|
|
outputs: OutputMgr, // Access to info for all monitors
|
2017-10-20 18:46:42 +11:00
|
|
|
size: Arc<Mutex<(u32, u32)>>,
|
|
|
|
kill_switch: (Arc<Mutex<bool>>, Arc<Mutex<bool>>),
|
2018-05-06 03:36:34 +10:00
|
|
|
display: Arc<Display>,
|
|
|
|
need_frame_refresh: Arc<Mutex<bool>>,
|
2019-04-26 03:09:32 +10:00
|
|
|
need_refresh: Arc<Mutex<bool>>,
|
|
|
|
fullscreen: Arc<Mutex<bool>>,
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Window {
|
2019-06-22 01:33:15 +10:00
|
|
|
pub fn new<T>(
|
|
|
|
evlp: &EventLoopWindowTarget<T>,
|
|
|
|
attributes: WindowAttributes,
|
|
|
|
pl_attribs: PlAttributes,
|
|
|
|
) -> Result<Window, RootOsError> {
|
2019-05-30 11:29:54 +10:00
|
|
|
let (width, height) = attributes.inner_size.map(Into::into).unwrap_or((800, 600));
|
2018-05-06 03:36:34 +10:00
|
|
|
// Create the window
|
2017-10-20 18:46:42 +11:00
|
|
|
let size = Arc::new(Mutex::new((width, height)));
|
2019-04-26 03:09:32 +10:00
|
|
|
let fullscreen = Arc::new(Mutex::new(false));
|
2018-05-06 03:36:34 +10:00
|
|
|
|
2018-12-11 06:55:40 +11:00
|
|
|
let window_store = evlp.store.clone();
|
2019-06-14 02:50:02 +10:00
|
|
|
let bg_surface = evlp
|
|
|
|
.env
|
|
|
|
.compositor
|
|
|
|
.create_surface(NewProxy::implement_dummy)
|
|
|
|
.unwrap();
|
|
|
|
let user_surface = evlp.env.create_surface(move |dpi, surface| {
|
2018-12-11 06:55:40 +11:00
|
|
|
window_store.lock().unwrap().dpi_change(&surface, dpi);
|
|
|
|
surface.set_buffer_scale(dpi);
|
|
|
|
});
|
2019-06-14 02:50:02 +10:00
|
|
|
let user_subsurface = evlp
|
|
|
|
.env
|
|
|
|
.subcompositor
|
|
|
|
.get_subsurface(&user_surface, &bg_surface, NewProxy::implement_dummy)
|
|
|
|
.unwrap();
|
|
|
|
user_subsurface.set_desync();
|
2018-05-06 03:36:34 +10:00
|
|
|
|
|
|
|
let window_store = evlp.store.clone();
|
2019-06-14 02:50:02 +10:00
|
|
|
let my_surface = user_surface.clone();
|
|
|
|
let my_bg_surface = bg_surface.clone();
|
|
|
|
|
|
|
|
// prepare a 1px buffer to display on the root window
|
2019-06-18 04:27:00 +10:00
|
|
|
let mut pool = smithay_client_toolkit::utils::MemPool::new(&evlp.env.shm, || {}).unwrap();
|
2019-06-14 02:50:02 +10:00
|
|
|
pool.resize(4).unwrap();
|
|
|
|
pool.seek(SeekFrom::Start(0)).unwrap();
|
|
|
|
pool.write(&[0, 0, 0, 0]).unwrap();
|
|
|
|
pool.flush().unwrap();
|
|
|
|
let buffer = pool.buffer(0, 1, 1, 4, wl_shm::Format::Argb8888);
|
|
|
|
|
2018-10-15 10:15:43 +11:00
|
|
|
let mut frame = SWindow::<ConceptFrame>::init_from_env(
|
2018-09-21 03:48:36 +10:00
|
|
|
&evlp.env,
|
2019-06-14 02:50:02 +10:00
|
|
|
bg_surface.clone(),
|
2018-05-06 03:36:34 +10:00
|
|
|
(width, height),
|
2019-06-22 01:33:15 +10:00
|
|
|
move |event| {
|
|
|
|
match event {
|
|
|
|
WEvent::Configure { new_size, states } => {
|
|
|
|
let mut store = window_store.lock().unwrap();
|
|
|
|
let is_fullscreen = states.contains(&WState::Fullscreen);
|
|
|
|
|
|
|
|
for window in &mut store.windows {
|
|
|
|
if window.surface.as_ref().equals(&my_surface.as_ref()) {
|
|
|
|
window.newsize = new_size;
|
|
|
|
*(window.need_refresh.lock().unwrap()) = true;
|
|
|
|
*(window.fullscreen.lock().unwrap()) = is_fullscreen;
|
|
|
|
*(window.need_frame_refresh.lock().unwrap()) = true;
|
|
|
|
if !window.configured {
|
|
|
|
// this is our first configure event, display ourselves !
|
|
|
|
window.configured = true;
|
|
|
|
my_bg_surface.attach(Some(&buffer), 0, 0);
|
|
|
|
my_bg_surface.commit();
|
|
|
|
}
|
|
|
|
return;
|
2019-06-14 02:50:02 +10:00
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
}
|
2019-06-22 01:33:15 +10:00
|
|
|
},
|
|
|
|
WEvent::Refresh => {
|
|
|
|
let store = window_store.lock().unwrap();
|
|
|
|
for window in &store.windows {
|
|
|
|
if window.surface.as_ref().equals(&my_surface.as_ref()) {
|
|
|
|
*(window.need_frame_refresh.lock().unwrap()) = true;
|
|
|
|
return;
|
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
}
|
2019-06-22 01:33:15 +10:00
|
|
|
},
|
|
|
|
WEvent::Close => {
|
|
|
|
let mut store = window_store.lock().unwrap();
|
|
|
|
for window in &mut store.windows {
|
|
|
|
if window.surface.as_ref().equals(&my_surface.as_ref()) {
|
|
|
|
window.closed = true;
|
|
|
|
return;
|
|
|
|
}
|
2018-05-06 03:36:34 +10:00
|
|
|
}
|
2019-06-22 01:33:15 +10:00
|
|
|
},
|
2018-05-06 03:36:34 +10:00
|
|
|
}
|
|
|
|
},
|
2019-06-22 01:33:15 +10:00
|
|
|
)
|
|
|
|
.unwrap();
|
2018-05-06 03:36:34 +10:00
|
|
|
|
2018-11-16 08:59:56 +11:00
|
|
|
if let Some(app_id) = pl_attribs.app_id {
|
|
|
|
frame.set_app_id(app_id);
|
|
|
|
}
|
|
|
|
|
2018-05-06 03:36:34 +10:00
|
|
|
for &(_, ref seat) in evlp.seats.lock().unwrap().iter() {
|
|
|
|
frame.new_seat(seat);
|
|
|
|
}
|
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
// Check for fullscreen requirements
|
2019-02-06 02:30:33 +11:00
|
|
|
if let Some(RootMonitorHandle {
|
|
|
|
inner: PlatformMonitorHandle::Wayland(ref monitor_id),
|
2018-05-06 03:36:34 +10:00
|
|
|
}) = attributes.fullscreen
|
|
|
|
{
|
|
|
|
frame.set_fullscreen(Some(&monitor_id.proxy));
|
2017-11-04 03:35:29 +11:00
|
|
|
} else if attributes.maximized {
|
2018-05-06 03:36:34 +10:00
|
|
|
frame.set_maximized();
|
2017-09-28 00:31:46 +10:00
|
|
|
}
|
2017-11-04 03:35:29 +11:00
|
|
|
|
2018-06-14 01:18:44 +10:00
|
|
|
frame.set_resizable(attributes.resizable);
|
|
|
|
|
2017-11-04 03:35:29 +11:00
|
|
|
// set decorations
|
|
|
|
frame.set_decorate(attributes.decorations);
|
|
|
|
|
2019-02-21 20:51:43 +11:00
|
|
|
// set title
|
|
|
|
frame.set_title(attributes.title);
|
|
|
|
|
2017-11-04 03:35:29 +11:00
|
|
|
// min-max dimensions
|
2019-05-30 11:29:54 +10:00
|
|
|
frame.set_min_size(attributes.min_inner_size.map(Into::into));
|
|
|
|
frame.set_max_size(attributes.max_inner_size.map(Into::into));
|
2016-10-08 23:51:29 +11:00
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
let kill_switch = Arc::new(Mutex::new(false));
|
2018-01-13 16:38:12 +11:00
|
|
|
let need_frame_refresh = Arc::new(Mutex::new(true));
|
2017-11-04 03:35:29 +11:00
|
|
|
let frame = Arc::new(Mutex::new(frame));
|
2019-02-21 20:51:43 +11:00
|
|
|
let need_refresh = Arc::new(Mutex::new(true));
|
2017-10-20 18:46:42 +11:00
|
|
|
|
2018-05-06 03:36:34 +10:00
|
|
|
evlp.store.lock().unwrap().windows.push(InternalWindow {
|
|
|
|
closed: false,
|
|
|
|
newsize: None,
|
2018-06-15 09:42:18 +10:00
|
|
|
size: size.clone(),
|
2019-02-21 20:51:43 +11:00
|
|
|
need_refresh: need_refresh.clone(),
|
2019-04-26 03:09:32 +10:00
|
|
|
fullscreen: fullscreen.clone(),
|
2018-05-06 03:36:34 +10:00
|
|
|
need_frame_refresh: need_frame_refresh.clone(),
|
2019-06-14 02:50:02 +10:00
|
|
|
surface: user_surface.clone(),
|
2018-05-06 03:36:34 +10:00
|
|
|
kill_switch: kill_switch.clone(),
|
|
|
|
frame: Arc::downgrade(&frame),
|
2018-06-15 09:42:18 +10:00
|
|
|
current_dpi: 1,
|
|
|
|
new_dpi: None,
|
2019-06-14 02:50:02 +10:00
|
|
|
configured: false,
|
2018-05-06 03:36:34 +10:00
|
|
|
});
|
2016-10-08 23:51:29 +11:00
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
Ok(Window {
|
|
|
|
display: evlp.display.clone(),
|
2019-06-14 02:50:02 +10:00
|
|
|
_bg_surface: bg_surface,
|
2019-06-22 01:33:15 +10:00
|
|
|
user_surface,
|
2019-06-14 02:50:02 +10:00
|
|
|
_user_subsurface: user_subsurface,
|
2019-06-22 01:33:15 +10:00
|
|
|
frame,
|
2018-06-17 00:14:12 +10:00
|
|
|
outputs: evlp.env.outputs.clone(),
|
2019-06-22 01:33:15 +10:00
|
|
|
size,
|
2018-01-13 16:38:12 +11:00
|
|
|
kill_switch: (kill_switch, evlp.cleanup_needed.clone()),
|
2019-02-21 20:51:43 +11:00
|
|
|
need_frame_refresh,
|
|
|
|
need_refresh,
|
2019-04-26 03:09:32 +10:00
|
|
|
fullscreen,
|
2017-10-20 18:46:42 +11:00
|
|
|
})
|
2017-03-05 00:04:01 +11:00
|
|
|
}
|
2016-10-08 23:51:29 +11:00
|
|
|
|
2017-03-05 00:04:01 +11:00
|
|
|
#[inline]
|
|
|
|
pub fn id(&self) -> WindowId {
|
2019-06-14 02:50:02 +10:00
|
|
|
make_wid(&self.user_surface)
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_title(&self, title: &str) {
|
2017-11-04 03:35:29 +11:00
|
|
|
self.frame.lock().unwrap().set_title(title.into());
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_visible(&self, _visible: bool) {
|
2015-12-13 21:43:39 +11:00
|
|
|
// TODO
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn outer_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
|
|
|
Err(NotSupportedError::new())
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn inner_position(&self) -> Result<LogicalPosition, NotSupportedError> {
|
|
|
|
Err(NotSupportedError::new())
|
2018-04-17 11:40:30 +10:00
|
|
|
}
|
|
|
|
|
2015-12-09 08:54:06 +11:00
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_outer_position(&self, _pos: LogicalPosition) {
|
2015-12-13 21:43:39 +11:00
|
|
|
// Not possible with wayland
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn inner_size(&self) -> LogicalSize {
|
|
|
|
self.size.lock().unwrap().clone().into()
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
2019-02-21 20:51:43 +11:00
|
|
|
pub fn request_redraw(&self) {
|
|
|
|
*self.need_refresh.lock().unwrap() = true;
|
|
|
|
}
|
|
|
|
|
2015-12-09 08:54:06 +11:00
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn outer_size(&self) -> LogicalSize {
|
2016-10-10 01:19:06 +11:00
|
|
|
let (w, h) = self.size.lock().unwrap().clone();
|
2018-05-06 03:36:34 +10:00
|
|
|
// let (w, h) = super::wayland_window::add_borders(w as i32, h as i32);
|
2019-05-30 11:29:54 +10:00
|
|
|
(w, h).into()
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2016-10-10 01:19:06 +11:00
|
|
|
// NOTE: This will only resize the borders, the contents must be updated by the user
|
2018-06-15 09:42:18 +10:00
|
|
|
pub fn set_inner_size(&self, size: LogicalSize) {
|
|
|
|
let (w, h) = size.into();
|
|
|
|
self.frame.lock().unwrap().resize(w, h);
|
|
|
|
*(self.size.lock().unwrap()) = (w, h);
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
2018-03-23 20:35:35 +11:00
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_min_inner_size(&self, dimensions: Option<LogicalSize>) {
|
2019-06-22 01:33:15 +10:00
|
|
|
self.frame
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.set_min_size(dimensions.map(Into::into));
|
2018-03-23 20:35:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_max_inner_size(&self, dimensions: Option<LogicalSize>) {
|
2019-06-22 01:33:15 +10:00
|
|
|
self.frame
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.set_max_size(dimensions.map(Into::into));
|
2018-03-23 20:35:35 +11:00
|
|
|
}
|
|
|
|
|
2018-06-14 01:18:44 +10:00
|
|
|
#[inline]
|
|
|
|
pub fn set_resizable(&self, resizable: bool) {
|
|
|
|
self.frame.lock().unwrap().set_resizable(resizable);
|
|
|
|
}
|
|
|
|
|
2015-12-09 08:54:06 +11:00
|
|
|
#[inline]
|
2018-06-15 09:42:18 +10:00
|
|
|
pub fn hidpi_factor(&self) -> i32 {
|
2019-06-14 02:50:02 +10:00
|
|
|
get_dpi_factor(&self.user_surface)
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
2018-01-13 16:38:12 +11:00
|
|
|
pub fn set_decorations(&self, decorate: bool) {
|
|
|
|
self.frame.lock().unwrap().set_decorate(decorate);
|
|
|
|
*(self.need_frame_refresh.lock().unwrap()) = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_maximized(&self, maximized: bool) {
|
|
|
|
if maximized {
|
2018-05-06 03:36:34 +10:00
|
|
|
self.frame.lock().unwrap().set_maximized();
|
2018-01-13 16:38:12 +11:00
|
|
|
} else {
|
2018-05-06 03:36:34 +10:00
|
|
|
self.frame.lock().unwrap().unset_maximized();
|
2018-01-13 16:38:12 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn fullscreen(&self) -> Option<MonitorHandle> {
|
2019-04-26 03:09:32 +10:00
|
|
|
if *(self.fullscreen.lock().unwrap()) {
|
2019-05-30 11:29:54 +10:00
|
|
|
Some(self.current_monitor())
|
2019-04-26 03:09:32 +10:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-06 02:30:33 +11:00
|
|
|
pub fn set_fullscreen(&self, monitor: Option<RootMonitorHandle>) {
|
|
|
|
if let Some(RootMonitorHandle {
|
|
|
|
inner: PlatformMonitorHandle::Wayland(ref monitor_id),
|
2018-05-06 03:36:34 +10:00
|
|
|
}) = monitor
|
|
|
|
{
|
|
|
|
self.frame
|
|
|
|
.lock()
|
|
|
|
.unwrap()
|
|
|
|
.set_fullscreen(Some(&monitor_id.proxy));
|
2018-01-13 16:38:12 +11:00
|
|
|
} else {
|
2018-05-06 03:36:34 +10:00
|
|
|
self.frame.lock().unwrap().unset_fullscreen();
|
2018-01-13 16:38:12 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-29 21:04:15 +11:00
|
|
|
pub fn set_theme<T: Theme>(&self, theme: T) {
|
|
|
|
self.frame.lock().unwrap().set_theme(theme)
|
|
|
|
}
|
|
|
|
|
2015-12-09 08:54:06 +11:00
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_cursor_icon(&self, _cursor: CursorIcon) {
|
2018-06-20 00:30:15 +10:00
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_cursor_visible(&self, _visible: bool) {
|
2018-06-20 00:30:15 +10:00
|
|
|
// TODO: This isn't possible on Wayland yet
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_cursor_grab(&self, _grab: bool) -> Result<(), ExternalError> {
|
|
|
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
2018-06-20 00:30:15 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn set_cursor_position(&self, _pos: LogicalPosition) -> Result<(), ExternalError> {
|
|
|
|
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
2018-03-23 20:35:35 +11:00
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn display(&self) -> &Display {
|
2017-10-20 18:46:42 +11:00
|
|
|
&*self.display
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
2018-03-23 20:35:35 +11:00
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn surface(&self) -> &wl_surface::WlSurface {
|
2019-06-14 02:50:02 +10:00
|
|
|
&self.user_surface
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
2017-09-07 18:33:46 +10:00
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn current_monitor(&self) -> MonitorHandle {
|
2019-06-14 02:50:02 +10:00
|
|
|
let output = get_outputs(&self.user_surface).last().unwrap().clone();
|
2019-02-21 20:51:43 +11:00
|
|
|
MonitorHandle {
|
2018-12-11 06:55:40 +11:00
|
|
|
proxy: output,
|
|
|
|
mgr: self.outputs.clone(),
|
|
|
|
}
|
2017-09-07 18:33:46 +10:00
|
|
|
}
|
2018-06-17 00:14:12 +10:00
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
|
|
|
available_monitors(&self.outputs)
|
2018-06-17 00:14:12 +10:00
|
|
|
}
|
|
|
|
|
2019-05-30 11:29:54 +10:00
|
|
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
|
|
|
primary_monitor(&self.outputs)
|
2018-06-17 00:14:12 +10:00
|
|
|
}
|
2015-12-09 08:54:06 +11:00
|
|
|
}
|
|
|
|
|
2015-12-13 21:43:39 +11:00
|
|
|
impl Drop for Window {
|
|
|
|
fn drop(&mut self) {
|
2017-10-20 18:46:42 +11:00
|
|
|
*(self.kill_switch.0.lock().unwrap()) = true;
|
|
|
|
*(self.kill_switch.1.lock().unwrap()) = true;
|
2016-10-08 23:51:29 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
/*
|
|
|
|
* Internal store for windows
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct InternalWindow {
|
2019-02-21 20:51:43 +11:00
|
|
|
surface: wl_surface::WlSurface,
|
2018-06-15 09:42:18 +10:00
|
|
|
newsize: Option<(u32, u32)>,
|
|
|
|
size: Arc<Mutex<(u32, u32)>>,
|
2019-02-21 20:51:43 +11:00
|
|
|
need_refresh: Arc<Mutex<bool>>,
|
2019-04-26 03:09:32 +10:00
|
|
|
fullscreen: Arc<Mutex<bool>>,
|
2018-01-13 16:38:12 +11:00
|
|
|
need_frame_refresh: Arc<Mutex<bool>>,
|
2017-07-06 00:23:10 +10:00
|
|
|
closed: bool,
|
2017-10-20 18:46:42 +11:00
|
|
|
kill_switch: Arc<Mutex<bool>>,
|
2018-10-15 10:15:43 +11:00
|
|
|
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
2018-06-15 09:42:18 +10:00
|
|
|
current_dpi: i32,
|
2018-11-21 07:21:58 +11:00
|
|
|
new_dpi: Option<i32>,
|
2019-06-14 02:50:02 +10:00
|
|
|
configured: bool,
|
2016-10-08 23:51:29 +11:00
|
|
|
}
|
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
pub struct WindowStore {
|
2018-05-06 03:36:34 +10:00
|
|
|
windows: Vec<InternalWindow>,
|
2017-10-20 18:46:42 +11:00
|
|
|
}
|
2017-03-05 00:04:01 +11:00
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
impl WindowStore {
|
|
|
|
pub fn new() -> WindowStore {
|
2018-05-06 03:36:34 +10:00
|
|
|
WindowStore {
|
|
|
|
windows: Vec::new(),
|
|
|
|
}
|
2016-10-08 23:51:29 +11:00
|
|
|
}
|
2017-07-06 00:23:10 +10:00
|
|
|
|
2019-02-21 20:51:43 +11:00
|
|
|
pub fn find_wid(&self, surface: &wl_surface::WlSurface) -> Option<WindowId> {
|
2017-10-20 18:46:42 +11:00
|
|
|
for window in &self.windows {
|
2019-02-21 20:51:43 +11:00
|
|
|
if surface.as_ref().equals(&window.surface.as_ref()) {
|
2017-10-20 18:46:42 +11:00
|
|
|
return Some(make_wid(surface));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
2017-09-28 00:31:46 +10:00
|
|
|
}
|
|
|
|
|
2018-04-25 06:20:40 +10:00
|
|
|
pub fn cleanup(&mut self) -> Vec<WindowId> {
|
|
|
|
let mut pruned = Vec::new();
|
2017-10-20 18:46:42 +11:00
|
|
|
self.windows.retain(|w| {
|
|
|
|
if *w.kill_switch.lock().unwrap() {
|
|
|
|
// window is dead, cleanup
|
2018-04-25 06:20:40 +10:00
|
|
|
pruned.push(make_wid(&w.surface));
|
2017-10-20 18:46:42 +11:00
|
|
|
w.surface.destroy();
|
|
|
|
false
|
|
|
|
} else {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
});
|
2018-04-25 06:20:40 +10:00
|
|
|
pruned
|
2017-10-20 18:46:42 +11:00
|
|
|
}
|
2016-10-08 23:51:29 +11:00
|
|
|
|
2019-02-21 20:51:43 +11:00
|
|
|
pub fn new_seat(&self, seat: &wl_seat::WlSeat) {
|
2018-05-06 03:36:34 +10:00
|
|
|
for window in &self.windows {
|
|
|
|
if let Some(w) = window.frame.upgrade() {
|
|
|
|
w.lock().unwrap().new_seat(seat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-21 20:51:43 +11:00
|
|
|
fn dpi_change(&mut self, surface: &wl_surface::WlSurface, new: i32) {
|
2018-06-15 09:42:18 +10:00
|
|
|
for window in &mut self.windows {
|
2019-02-21 20:51:43 +11:00
|
|
|
if surface.as_ref().equals(&window.surface.as_ref()) {
|
2018-06-15 09:42:18 +10:00
|
|
|
window.new_dpi = Some(new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-20 18:46:42 +11:00
|
|
|
pub fn for_each<F>(&mut self, mut f: F)
|
2018-05-06 03:36:34 +10:00
|
|
|
where
|
2019-06-22 01:33:15 +10:00
|
|
|
F: FnMut(
|
|
|
|
Option<(u32, u32)>,
|
|
|
|
&mut (u32, u32),
|
|
|
|
Option<i32>,
|
|
|
|
bool,
|
|
|
|
bool,
|
|
|
|
bool,
|
|
|
|
WindowId,
|
|
|
|
Option<&mut SWindow<ConceptFrame>>,
|
|
|
|
),
|
2016-10-08 23:51:29 +11:00
|
|
|
{
|
2017-10-20 18:46:42 +11:00
|
|
|
for window in &mut self.windows {
|
2017-11-04 03:35:29 +11:00
|
|
|
let opt_arc = window.frame.upgrade();
|
2017-10-20 18:46:42 +11:00
|
|
|
let mut opt_mutex_lock = opt_arc.as_ref().map(|m| m.lock().unwrap());
|
|
|
|
f(
|
|
|
|
window.newsize.take(),
|
2018-06-15 09:42:18 +10:00
|
|
|
&mut *(window.size.lock().unwrap()),
|
|
|
|
window.new_dpi,
|
2019-02-21 20:51:43 +11:00
|
|
|
::std::mem::replace(&mut *window.need_refresh.lock().unwrap(), false),
|
2018-01-13 16:38:12 +11:00
|
|
|
::std::mem::replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
2017-10-20 18:46:42 +11:00
|
|
|
window.closed,
|
|
|
|
make_wid(&window.surface),
|
2018-05-06 03:36:34 +10:00
|
|
|
opt_mutex_lock.as_mut().map(|m| &mut **m),
|
2017-10-20 18:46:42 +11:00
|
|
|
);
|
2018-06-15 09:42:18 +10:00
|
|
|
if let Some(dpi) = window.new_dpi.take() {
|
|
|
|
window.current_dpi = dpi;
|
|
|
|
}
|
2017-10-20 18:46:42 +11:00
|
|
|
// avoid re-spamming the event
|
|
|
|
window.closed = false;
|
|
|
|
}
|
2016-10-08 23:51:29 +11:00
|
|
|
}
|
2017-10-20 18:46:42 +11:00
|
|
|
}
|