Fix winit backend on wayland

We were trying to swap_buffers while the xdg_surface had not been
configured yet, which is a protocol error.
This commit is contained in:
Victor Berger 2017-09-28 19:34:31 +02:00 committed by Victor Berger
parent 502a99c5f9
commit 5a0713feb9
3 changed files with 17 additions and 4 deletions

View File

@ -13,9 +13,9 @@ slog = { version = "2.0.0" }
slog-stdlog = "2.0.0-0.2" slog-stdlog = "2.0.0-0.2"
libloading = "0.4.0" libloading = "0.4.0"
wayland-client = { version = "0.9.9", optional = true } wayland-client = { version = "0.9.9", optional = true }
winit = { version = "0.8.0", optional = true } winit = { version = "0.8.2", optional = true }
drm = { version = "0.2.1", optional = true } drm = { version = "=0.2.1", optional = true }
gbm = { version = "0.2.1", optional = true } gbm = { version = "=0.2.1", optional = true }
glium = { version = "0.17.1", optional = true, default-features = false } glium = { version = "0.17.1", optional = true, default-features = false }
input = { version = "0.2.0", optional = true } input = { version = "0.2.0", optional = true }
clippy = { version = "*", optional = true } clippy = { version = "*", optional = true }

View File

@ -53,7 +53,7 @@ impl InputHandler<winit::WinitInputBackend> for WinitInputHandler {
/* never happens with winit */ /* never happens with winit */
} }
fn on_keyboard_key(&mut self, _: &input::Seat, evt: winit::WinitKeyboardInputEvent) { fn on_keyboard_key(&mut self, _: &input::Seat, evt: winit::WinitKeyboardInputEvent) {
let keycode = evt.key_code() - 8; let keycode = evt.key_code();
let state = evt.state(); let state = evt.state();
debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state)); debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
let serial = self.next_serial(); let serial = self.next_serial();

View File

@ -10,12 +10,14 @@ use backend::input::{Axis, AxisSource, Event as BackendEvent, InputBackend, Inpu
TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent}; TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent};
use nix::c_void; use nix::c_void;
use rental::TryNewError; use rental::TryNewError;
use std::cell::Cell;
use std::cmp; use std::cmp;
use std::error; use std::error;
use std::fmt; use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use winit::{ElementState, Event, EventsLoop, KeyboardInput, MouseButton as WinitMouseButton, MouseCursor, use winit::{ElementState, Event, EventsLoop, KeyboardInput, MouseButton as WinitMouseButton, MouseCursor,
MouseScrollDelta, Touch, TouchPhase, WindowBuilder, WindowEvent}; MouseScrollDelta, Touch, TouchPhase, WindowBuilder, WindowEvent};
use winit::os::unix::WindowExt;
rental! { rental! {
mod rental { mod rental {
@ -61,6 +63,7 @@ impl<H> From<TryNewError<Error, H>> for Error {
/// `EGLGraphicsBackend` graphics backend trait /// `EGLGraphicsBackend` graphics backend trait
pub struct WinitGraphicsBackend { pub struct WinitGraphicsBackend {
window: Rc<Window>, window: Rc<Window>,
ready: Cell<bool>,
logger: ::slog::Logger, logger: ::slog::Logger,
} }
@ -156,6 +159,7 @@ where
Ok(( Ok((
WinitGraphicsBackend { WinitGraphicsBackend {
window: window.clone(), window: window.clone(),
ready: Cell::new(false),
logger: log.new(o!("smithay_winit_component" => "graphics")), logger: log.new(o!("smithay_winit_component" => "graphics")),
}, },
WinitInputBackend { WinitInputBackend {
@ -199,6 +203,15 @@ impl GraphicsBackend for WinitGraphicsBackend {
impl EGLGraphicsBackend for WinitGraphicsBackend { impl EGLGraphicsBackend for WinitGraphicsBackend {
fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> { fn swap_buffers(&self) -> ::std::result::Result<(), SwapBuffersError> {
trace!(self.logger, "Swapping buffers"); trace!(self.logger, "Swapping buffers");
if !self.ready.get() {
if self.window.head().is_ready() {
// avoid locking the mutex every time once the window is ready
self.ready.set(true);
} else {
// Not yet ready, just silently ignore the swap-buffers call
return Ok(());
}
}
self.window self.window
.rent(|egl| egl.rent(|surface| surface.swap_buffers())) .rent(|egl| egl.rent(|surface| surface.swap_buffers()))
} }