mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Merge pull request #188 from vberger/master
wayland: Initially paint the window white so that they always exist
This commit is contained in:
commit
7298df74bc
|
@ -40,4 +40,5 @@ dwmapi-sys = "0.1"
|
||||||
wayland-client = { version = "0.8.6", features = ["dlopen"] }
|
wayland-client = { version = "0.8.6", features = ["dlopen"] }
|
||||||
wayland-kbd = "0.8.0"
|
wayland-kbd = "0.8.0"
|
||||||
wayland-window = "0.5.0"
|
wayland-window = "0.5.0"
|
||||||
|
tempfile = "2.1"
|
||||||
x11-dl = "2.8"
|
x11-dl = "2.8"
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use wayland_client::{EnvHandler, default_connect, EventQueue, EventQueueHandle, Init, Proxy};
|
use wayland_client::{EnvHandler, default_connect, EventQueue, EventQueueHandle, Init, Proxy};
|
||||||
use wayland_client::protocol::{wl_compositor, wl_seat, wl_shell, wl_shm, wl_subcompositor,
|
use wayland_client::protocol::{wl_compositor, wl_seat, wl_shell, wl_shm, wl_subcompositor,
|
||||||
wl_display, wl_registry, wl_output, wl_surface};
|
wl_display, wl_registry, wl_output, wl_surface, wl_buffer};
|
||||||
|
|
||||||
use super::wayland_window;
|
use super::{wayland_window, tempfile};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Registry and globals handling
|
* Registry and globals handling
|
||||||
|
@ -213,13 +216,12 @@ impl WaylandContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_window<H: wayland_window::Handler>(&self)
|
pub fn create_window<H: wayland_window::Handler>(&self, width: u32, height: u32)
|
||||||
-> (Arc<wl_surface::WlSurface>, wayland_window::DecoratedSurface<H>)
|
-> (Arc<wl_surface::WlSurface>, wayland_window::DecoratedSurface<H>, wl_buffer::WlBuffer, File)
|
||||||
{
|
{
|
||||||
let mut guard = self.evq.lock().unwrap();
|
let mut guard = self.evq.lock().unwrap();
|
||||||
let mut state = guard.state();
|
let mut state = guard.state();
|
||||||
let env = state.get_mut_handler::<WaylandEnv>(self.env_id);
|
let env = state.get_mut_handler::<WaylandEnv>(self.env_id);
|
||||||
// this "expect" cannot trigger (see https://github.com/vberger/wayland-client-rs/issues/69)
|
|
||||||
let surface = Arc::new(env.inner.compositor.create_surface());
|
let surface = Arc::new(env.inner.compositor.create_surface());
|
||||||
let decorated = wayland_window::DecoratedSurface::new(
|
let decorated = wayland_window::DecoratedSurface::new(
|
||||||
&*surface, 800, 600,
|
&*surface, 800, 600,
|
||||||
|
@ -230,7 +232,19 @@ impl WaylandContext {
|
||||||
env.get_seat(),
|
env.get_seat(),
|
||||||
false
|
false
|
||||||
).expect("Failed to create a tmpfile buffer.");
|
).expect("Failed to create a tmpfile buffer.");
|
||||||
(surface, decorated)
|
// prepare a white content for the window, so that it exists
|
||||||
|
let mut tmp = tempfile::tempfile().expect("Failed to create a tmpfile buffer.");
|
||||||
|
for _ in 0..(width*height) {
|
||||||
|
tmp.write_all(&[0xff,0xff,0xff,0xff]).unwrap();
|
||||||
|
}
|
||||||
|
tmp.flush().unwrap();
|
||||||
|
let pool = env.inner.shm.create_pool(tmp.as_raw_fd(), (width*height*4) as i32);
|
||||||
|
let buffer = pool.create_buffer(0, width as i32, height as i32, width as i32, wl_shm::Format::Argb8888).expect("Pool cannot be already dead");
|
||||||
|
surface.attach(Some(&buffer), 0, 0);
|
||||||
|
surface.commit();
|
||||||
|
// the buffer wiil keep the contents alive as needed
|
||||||
|
pool.destroy();
|
||||||
|
(surface, decorated, buffer, tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ use self::event_loop::EventsLoopSink;
|
||||||
|
|
||||||
extern crate wayland_kbd;
|
extern crate wayland_kbd;
|
||||||
extern crate wayland_window;
|
extern crate wayland_window;
|
||||||
|
extern crate tempfile;
|
||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
mod event_loop;
|
mod event_loop;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
use std::fs::File;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
use wayland_client::{EventQueue, EventQueueHandle, Proxy};
|
use wayland_client::{EventQueue, EventQueueHandle, Proxy};
|
||||||
use wayland_client::protocol::{wl_display,wl_surface,wl_shell_surface};
|
use wayland_client::protocol::{wl_display,wl_surface,wl_shell_surface,wl_buffer};
|
||||||
|
|
||||||
use {CreationError, MouseCursor, CursorState, WindowAttributes};
|
use {CreationError, MouseCursor, CursorState, WindowAttributes};
|
||||||
use platform::MonitorId as PlatformMonitorId;
|
use platform::MonitorId as PlatformMonitorId;
|
||||||
|
@ -39,16 +40,27 @@ impl Window {
|
||||||
{
|
{
|
||||||
let (width, height) = attributes.dimensions.unwrap_or((800,600));
|
let (width, height) = attributes.dimensions.unwrap_or((800,600));
|
||||||
|
|
||||||
let (surface, decorated) = ctxt.create_window::<DecoratedHandler>();
|
let (surface, decorated, buffer, tmpfile) = ctxt.create_window::<DecoratedHandler>(width, height);
|
||||||
|
|
||||||
// init DecoratedSurface
|
// init DecoratedSurface
|
||||||
let (evq, cleanup_signal) = evlp.get_window_init();
|
let (evq, cleanup_signal) = evlp.get_window_init();
|
||||||
let decorated_id = {
|
let decorated_id = {
|
||||||
let mut evq_guard = evq.lock().unwrap();
|
let mut evq_guard = evq.lock().unwrap();
|
||||||
|
// create a handler to clean up initial buffer
|
||||||
|
let initial_buffer_handler_id = evq_guard.add_handler(InitialBufferHandler::new());
|
||||||
|
// register the buffer to it
|
||||||
|
evq_guard.register::<_, InitialBufferHandler>(&buffer, initial_buffer_handler_id);
|
||||||
|
// store the DecoratedSurface handler
|
||||||
let decorated_id = evq_guard.add_handler_with_init(decorated);
|
let decorated_id = evq_guard.add_handler_with_init(decorated);
|
||||||
{
|
{
|
||||||
// initialize the DecoratedHandler
|
|
||||||
let mut state = evq_guard.state();
|
let mut state = evq_guard.state();
|
||||||
|
{
|
||||||
|
// store the buffer and tempfile in the handler, to be cleanded up at the right
|
||||||
|
// time
|
||||||
|
let initial_buffer_h = state.get_mut_handler::<InitialBufferHandler>(initial_buffer_handler_id);
|
||||||
|
initial_buffer_h.initial_buffer = Some((buffer, tmpfile));
|
||||||
|
}
|
||||||
|
// initialize the DecoratedHandler
|
||||||
let decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(decorated_id);
|
let decorated = state.get_mut_handler::<DecoratedSurface<DecoratedHandler>>(decorated_id);
|
||||||
*(decorated.handler()) = Some(DecoratedHandler::new());
|
*(decorated.handler()) = Some(DecoratedHandler::new());
|
||||||
|
|
||||||
|
@ -203,3 +215,29 @@ impl wayland_window::Handler for DecoratedHandler {
|
||||||
self.newsize = Some((max(width,1) as u32, max(height,1) as u32));
|
self.newsize = Some((max(width,1) as u32, max(height,1) as u32));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a handler to release the ressources acquired to draw the initial white screen as soon as
|
||||||
|
// the compositor does not use them any more
|
||||||
|
|
||||||
|
pub struct InitialBufferHandler {
|
||||||
|
initial_buffer: Option<(wl_buffer::WlBuffer, File)>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitialBufferHandler {
|
||||||
|
fn new() -> InitialBufferHandler {
|
||||||
|
InitialBufferHandler {
|
||||||
|
initial_buffer: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl wl_buffer::Handler for InitialBufferHandler {
|
||||||
|
fn release(&mut self, _: &mut EventQueueHandle, buffer: &wl_buffer::WlBuffer) {
|
||||||
|
// release the ressources we've acquired for initial white window
|
||||||
|
buffer.destroy();
|
||||||
|
self.initial_buffer = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_handler!(InitialBufferHandler, wl_buffer::Handler, wl_buffer::WlBuffer);
|
||||||
|
|
Loading…
Reference in a new issue