anvil: restore correct dispatching of wayland clients

This commit is contained in:
Victor Berger 2020-04-17 18:27:26 +02:00 committed by Victor Berger
parent 548a929d1c
commit cd6e148143
3 changed files with 71 additions and 58 deletions

View File

@ -7,6 +7,15 @@ extern crate slog;
#[macro_use(define_roles)] #[macro_use(define_roles)]
extern crate smithay; extern crate smithay;
use std::{
cell::RefCell,
rc::Rc,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
use slog::Drain; use slog::Drain;
use smithay::reexports::{ use smithay::reexports::{
calloop::{generic::Generic, mio::Interest, EventLoop}, calloop::{generic::Generic, mio::Interest, EventLoop},
@ -34,15 +43,13 @@ static POSSIBLE_BACKENDS: &[&str] = &[
]; ];
pub struct AnvilState { pub struct AnvilState {
pub need_wayland_dispatch: bool, pub running: Arc<AtomicBool>,
pub running: bool,
} }
impl Default for AnvilState { impl Default for AnvilState {
fn default() -> AnvilState { fn default() -> AnvilState {
AnvilState { AnvilState {
need_wayland_dispatch: false, running: Arc::new(AtomicBool::new(true)),
running: true,
} }
} }
} }
@ -54,17 +61,25 @@ fn main() {
o!(), o!(),
); );
let mut event_loop = EventLoop::<AnvilState>::new().unwrap(); let event_loop = EventLoop::<AnvilState>::new().unwrap();
let mut display = Display::new(); let display = Rc::new(RefCell::new(Display::new()));
// Glue for event dispatching // Glue for event dispatching
let mut wayland_event_source = Generic::from_raw_fd(display.get_poll_fd()); let mut wayland_event_source = Generic::from_raw_fd(display.borrow().get_poll_fd());
wayland_event_source.set_interest(Interest::READABLE); wayland_event_source.set_interest(Interest::READABLE);
let _wayland_source = let _wayland_source = event_loop.handle().insert_source(wayland_event_source, {
event_loop let display = display.clone();
.handle() let log = log.clone();
.insert_source(wayland_event_source, |_, state: &mut AnvilState| { move |_, state: &mut AnvilState| {
state.need_wayland_dispatch = true; let mut display = display.borrow_mut();
match display.dispatch(std::time::Duration::from_millis(0), state) {
Ok(_) => {}
Err(e) => {
error!(log, "I/O error on the Wayland display: {}", e);
state.running.store(false, Ordering::SeqCst);
}
}
}
}); });
let arg = ::std::env::args().nth(1); let arg = ::std::env::args().nth(1);
@ -72,7 +87,7 @@ fn main() {
#[cfg(feature = "winit")] #[cfg(feature = "winit")]
Some("--winit") => { Some("--winit") => {
info!(log, "Starting anvil with winit backend"); info!(log, "Starting anvil with winit backend");
if let Err(()) = winit::run_winit(&mut display, &mut event_loop, log.clone()) { if let Err(()) = winit::run_winit(display, event_loop, log.clone()) {
crit!(log, "Failed to initialize winit backend."); crit!(log, "Failed to initialize winit backend.");
} }
} }

View File

@ -5,10 +5,7 @@ use std::{
os::unix::io::{AsRawFd, RawFd}, os::unix::io::{AsRawFd, RawFd},
path::PathBuf, path::PathBuf,
rc::Rc, rc::Rc,
sync::{ sync::{atomic::Ordering, Arc, Mutex},
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
}; };
use glium::Surface as GliumSurface; use glium::Surface as GliumSurface;
@ -85,8 +82,17 @@ type RenderDevice = EglDevice<
type RenderSurface = type RenderSurface =
EglSurface<GbmSurface<FallbackDevice<AtomicDrmDevice<SessionFd>, LegacyDrmDevice<SessionFd>>>>; EglSurface<GbmSurface<FallbackDevice<AtomicDrmDevice<SessionFd>, LegacyDrmDevice<SessionFd>>>>;
pub fn run_udev(mut display: Display, mut event_loop: EventLoop<AnvilState>, log: Logger) -> Result<(), ()> { pub fn run_udev(
let name = display.add_socket_auto().unwrap().into_string().unwrap(); display: Rc<RefCell<Display>>,
mut event_loop: EventLoop<AnvilState>,
log: Logger,
) -> Result<(), ()> {
let name = display
.borrow_mut()
.add_socket_auto()
.unwrap()
.into_string()
.unwrap();
info!(log, "Listening on wayland socket"; "name" => name.clone()); info!(log, "Listening on wayland socket"; "name" => name.clone());
::std::env::set_var("WAYLAND_DISPLAY", name); ::std::env::set_var("WAYLAND_DISPLAY", name);
@ -98,8 +104,6 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<AnvilState>, log
#[cfg(not(feature = "egl"))] #[cfg(not(feature = "egl"))]
let buffer_utils = BufferUtils::new(log.clone()); let buffer_utils = BufferUtils::new(log.clone());
let display = Rc::new(RefCell::new(display));
/* /*
* Initialize the compositor * Initialize the compositor
*/ */
@ -115,7 +119,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<AnvilState>, log
let (udev_observer, udev_notifier) = notify_multiplexer(); let (udev_observer, udev_notifier) = notify_multiplexer();
let udev_session_id = notifier.register(udev_observer); let udev_session_id = notifier.register(udev_observer);
let running = Arc::new(AtomicBool::new(true)); let mut state = AnvilState::default();
let pointer_location = Rc::new(RefCell::new((0.0, 0.0))); let pointer_location = Rc::new(RefCell::new((0.0, 0.0)));
let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default));
@ -237,7 +241,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<AnvilState>, log
keyboard, keyboard,
window_map.clone(), window_map.clone(),
(w, h), (w, h),
running.clone(), state.running.clone(),
pointer_location, pointer_location,
session, session,
)); ));
@ -258,21 +262,14 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<AnvilState>, log
/* /*
* And run our loop * And run our loop
*/ */
let mut state = AnvilState::default();
while running.load(Ordering::SeqCst) { while state.running.load(Ordering::SeqCst) {
if event_loop if event_loop
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut state) .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
.is_err() .is_err()
{ {
running.store(false, Ordering::SeqCst); state.running.store(false, Ordering::SeqCst);
} else { } else {
if state.need_wayland_dispatch {
display
.borrow_mut()
.dispatch(std::time::Duration::from_millis(0), &mut state)
.unwrap();
}
display.borrow_mut().flush_clients(&mut state); display.borrow_mut().flush_clients(&mut state);
window_map.borrow_mut().refresh(); window_map.borrow_mut().refresh();
} }

View File

@ -1,10 +1,7 @@
use std::{ use std::{
cell::RefCell, cell::RefCell,
rc::Rc, rc::Rc,
sync::{ sync::{atomic::Ordering, Arc, Mutex},
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
}; };
use smithay::{ use smithay::{
@ -30,15 +27,15 @@ use crate::shell::init_shell;
use crate::AnvilState; use crate::AnvilState;
pub fn run_winit( pub fn run_winit(
display: &mut Display, display: Rc<RefCell<Display>>,
event_loop: &mut EventLoop<AnvilState>, mut event_loop: EventLoop<AnvilState>,
log: Logger, log: Logger,
) -> Result<(), ()> { ) -> Result<(), ()> {
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?; let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
let egl_buffer_reader = Rc::new(RefCell::new( let egl_buffer_reader = Rc::new(RefCell::new(
if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display) { if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) {
info!(log, "EGL hardware-acceleration enabled"); info!(log, "EGL hardware-acceleration enabled");
Some(egl_buffer_reader) Some(egl_buffer_reader)
} else { } else {
@ -57,25 +54,31 @@ pub fn run_winit(
#[cfg(not(feature = "egl"))] #[cfg(not(feature = "egl"))]
let buffer_utils = BufferUtils::new(log.clone()); let buffer_utils = BufferUtils::new(log.clone());
let name = display.add_socket_auto().unwrap().into_string().unwrap(); let name = display
.borrow_mut()
.add_socket_auto()
.unwrap()
.into_string()
.unwrap();
info!(log, "Listening on wayland socket"; "name" => name.clone()); info!(log, "Listening on wayland socket"; "name" => name.clone());
::std::env::set_var("WAYLAND_DISPLAY", name); ::std::env::set_var("WAYLAND_DISPLAY", name);
let running = Arc::new(AtomicBool::new(true)); let mut state = AnvilState::default();
/* /*
* Initialize the globals * Initialize the globals
*/ */
init_shm_global(display, vec![], log.clone()); init_shm_global(&mut display.borrow_mut(), vec![], log.clone());
let (compositor_token, _, _, window_map) = init_shell(display, buffer_utils, log.clone()); let (compositor_token, _, _, window_map) =
init_shell(&mut display.borrow_mut(), buffer_utils, log.clone());
let dnd_icon = Arc::new(Mutex::new(None)); let dnd_icon = Arc::new(Mutex::new(None));
let dnd_icon2 = dnd_icon.clone(); let dnd_icon2 = dnd_icon.clone();
init_data_device( init_data_device(
display, &mut display.borrow_mut(),
move |event| match event { move |event| match event {
DataDeviceEvent::DnDStarted { icon, .. } => { DataDeviceEvent::DnDStarted { icon, .. } => {
*dnd_icon2.lock().unwrap() = icon; *dnd_icon2.lock().unwrap() = icon;
@ -90,7 +93,12 @@ pub fn run_winit(
log.clone(), log.clone(),
); );
let (mut seat, _) = Seat::new(display, "winit".into(), compositor_token, log.clone()); let (mut seat, _) = Seat::new(
&mut display.borrow_mut(),
"winit".into(),
compositor_token,
log.clone(),
);
let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default));
@ -107,7 +115,7 @@ pub fn run_winit(
.expect("Failed to initialize the keyboard"); .expect("Failed to initialize the keyboard");
let (output, _) = Output::new( let (output, _) = Output::new(
display, &mut display.borrow_mut(),
"Winit".into(), "Winit".into(),
PhysicalProperties { PhysicalProperties {
width: 0, width: 0,
@ -142,13 +150,13 @@ pub fn run_winit(
keyboard, keyboard,
window_map.clone(), window_map.clone(),
(0, 0), (0, 0),
running.clone(), state.running.clone(),
pointer_location.clone(), pointer_location.clone(),
)); ));
info!(log, "Initialization completed, starting the main loop."); info!(log, "Initialization completed, starting the main loop.");
while running.load(Ordering::SeqCst) { while state.running.load(Ordering::SeqCst) {
input.dispatch_new_events().unwrap(); input.dispatch_new_events().unwrap();
// drawing logic // drawing logic
@ -192,20 +200,13 @@ pub fn run_winit(
} }
} }
let mut state = AnvilState::default();
if event_loop if event_loop
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut state) .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
.is_err() .is_err()
{ {
running.store(false, Ordering::SeqCst); state.running.store(false, Ordering::SeqCst);
} else { } else {
if state.need_wayland_dispatch { display.borrow_mut().flush_clients(&mut state);
display
.dispatch(std::time::Duration::from_millis(0), &mut state)
.unwrap();
}
display.flush_clients(&mut state);
window_map.borrow_mut().refresh(); window_map.borrow_mut().refresh();
} }
} }