Merge pull request #440 from Smithay/fix/x11_device_events
x11: add virtual device events
This commit is contained in:
commit
9bf4dc5f3c
|
@ -166,13 +166,13 @@ pub fn run_x11(log: Logger) {
|
||||||
|
|
||||||
event_loop
|
event_loop
|
||||||
.handle()
|
.handle()
|
||||||
.insert_source(backend, |event, _window, state| match event {
|
.insert_source(backend, |event, _, state| match event {
|
||||||
X11Event::CloseRequested => {
|
X11Event::CloseRequested { .. } => {
|
||||||
state.running.store(false, Ordering::SeqCst);
|
state.running.store(false, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
X11Event::Resized(size) => {
|
X11Event::Resized { new_size, .. } => {
|
||||||
let size = { (size.w as i32, size.h as i32).into() };
|
let size = { (new_size.w as i32, new_size.h as i32).into() };
|
||||||
|
|
||||||
state.backend_data.mode = Mode {
|
state.backend_data.mode = Mode {
|
||||||
size,
|
size,
|
||||||
|
@ -193,7 +193,7 @@ pub fn run_x11(log: Logger) {
|
||||||
state.backend_data.render = true;
|
state.backend_data.render = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
X11Event::PresentCompleted | X11Event::Refresh => {
|
X11Event::PresentCompleted { .. } | X11Event::Refresh { .. } => {
|
||||||
state.backend_data.render = true;
|
state.backend_data.render = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Input backend implementation for the X11 backend.
|
//! Input backend implementation for the X11 backend.
|
||||||
|
|
||||||
|
use super::{window_inner::WindowInner, Window, WindowTemporary};
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::input::{
|
backend::input::{
|
||||||
self, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend, KeyState,
|
self, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend, KeyState,
|
||||||
|
@ -7,6 +8,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
utils::{Logical, Size},
|
utils::{Logical, Size},
|
||||||
};
|
};
|
||||||
|
use std::sync::Weak;
|
||||||
|
|
||||||
/// Marker used to define the `InputBackend` types for the X11 backend.
|
/// Marker used to define the `InputBackend` types for the X11 backend.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -43,12 +45,22 @@ impl Device for X11VirtualDevice {
|
||||||
|
|
||||||
/// X11-Backend internal event wrapping `X11`'s types into a [`KeyboardKeyEvent`].
|
/// X11-Backend internal event wrapping `X11`'s types into a [`KeyboardKeyEvent`].
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct X11KeyboardInputEvent {
|
pub struct X11KeyboardInputEvent {
|
||||||
pub(crate) time: u32,
|
pub(crate) time: u32,
|
||||||
pub(crate) key: u32,
|
pub(crate) key: u32,
|
||||||
pub(crate) count: u32,
|
pub(crate) count: u32,
|
||||||
pub(crate) state: KeyState,
|
pub(crate) state: KeyState,
|
||||||
|
pub(crate) window: Weak<WindowInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl X11KeyboardInputEvent {
|
||||||
|
/// Returns a temporary reference to the window belonging to this event.
|
||||||
|
///
|
||||||
|
/// Returns None if the window is not alive anymore.
|
||||||
|
pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
|
||||||
|
self.window.upgrade().map(Window).map(WindowTemporary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl input::Event<X11Input> for X11KeyboardInputEvent {
|
impl input::Event<X11Input> for X11KeyboardInputEvent {
|
||||||
|
@ -77,11 +89,21 @@ impl KeyboardKeyEvent<X11Input> for X11KeyboardInputEvent {
|
||||||
|
|
||||||
/// X11-Backend internal event wrapping `X11`'s types into a [`PointerAxisEvent`]
|
/// X11-Backend internal event wrapping `X11`'s types into a [`PointerAxisEvent`]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct X11MouseWheelEvent {
|
pub struct X11MouseWheelEvent {
|
||||||
pub(crate) time: u32,
|
pub(crate) time: u32,
|
||||||
pub(crate) axis: Axis,
|
pub(crate) axis: Axis,
|
||||||
pub(crate) amount: f64,
|
pub(crate) amount: f64,
|
||||||
|
pub(crate) window: Weak<WindowInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl X11MouseWheelEvent {
|
||||||
|
/// Returns a temporary reference to the window belonging to this event.
|
||||||
|
///
|
||||||
|
/// Returns None if the window is not alive anymore.
|
||||||
|
pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
|
||||||
|
self.window.upgrade().map(Window).map(WindowTemporary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl input::Event<X11Input> for X11MouseWheelEvent {
|
impl input::Event<X11Input> for X11MouseWheelEvent {
|
||||||
|
@ -115,11 +137,21 @@ impl PointerAxisEvent<X11Input> for X11MouseWheelEvent {
|
||||||
|
|
||||||
/// X11-Backend internal event wrapping `X11`'s types into a [`PointerButtonEvent`]
|
/// X11-Backend internal event wrapping `X11`'s types into a [`PointerButtonEvent`]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct X11MouseInputEvent {
|
pub struct X11MouseInputEvent {
|
||||||
pub(crate) time: u32,
|
pub(crate) time: u32,
|
||||||
pub(crate) raw: u32,
|
pub(crate) raw: u32,
|
||||||
pub(crate) state: ButtonState,
|
pub(crate) state: ButtonState,
|
||||||
|
pub(crate) window: Weak<WindowInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl X11MouseInputEvent {
|
||||||
|
/// Returns a temporary reference to the window belonging to this event.
|
||||||
|
///
|
||||||
|
/// Returns None if the window is not alive anymore.
|
||||||
|
pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
|
||||||
|
self.window.upgrade().map(Window).map(WindowTemporary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl input::Event<X11Input> for X11MouseInputEvent {
|
impl input::Event<X11Input> for X11MouseInputEvent {
|
||||||
|
@ -144,12 +176,22 @@ impl PointerButtonEvent<X11Input> for X11MouseInputEvent {
|
||||||
|
|
||||||
/// X11-Backend internal event wrapping `X11`'s types into a [`PointerMotionAbsoluteEvent`]
|
/// X11-Backend internal event wrapping `X11`'s types into a [`PointerMotionAbsoluteEvent`]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct X11MouseMovedEvent {
|
pub struct X11MouseMovedEvent {
|
||||||
pub(crate) time: u32,
|
pub(crate) time: u32,
|
||||||
pub(crate) x: f64,
|
pub(crate) x: f64,
|
||||||
pub(crate) y: f64,
|
pub(crate) y: f64,
|
||||||
pub(crate) size: Size<u16, Logical>,
|
pub(crate) size: Size<u16, Logical>,
|
||||||
|
pub(crate) window: Weak<WindowInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl X11MouseMovedEvent {
|
||||||
|
/// Returns a temporary reference to the window belonging to this event.
|
||||||
|
///
|
||||||
|
/// Returns None if the window is not alive anymore.
|
||||||
|
pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
|
||||||
|
self.window.upgrade().map(Window).map(WindowTemporary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl input::Event<X11Input> for X11MouseMovedEvent {
|
impl input::Event<X11Input> for X11MouseMovedEvent {
|
||||||
|
|
|
@ -129,21 +129,35 @@ pub use self::surface::*;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum X11Event {
|
pub enum X11Event {
|
||||||
/// The X server has required the compositor to redraw the contents of window.
|
/// The X server has required the compositor to redraw the contents of window.
|
||||||
Refresh,
|
Refresh {
|
||||||
|
/// XID of the window
|
||||||
|
window_id: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// An input event occurred.
|
/// An input event occurred.
|
||||||
Input(InputEvent<X11Input>),
|
Input(InputEvent<X11Input>),
|
||||||
|
|
||||||
/// The window was resized.
|
/// The window was resized.
|
||||||
Resized(Size<u16, Logical>),
|
Resized {
|
||||||
|
/// The new size of the window
|
||||||
|
new_size: Size<u16, Logical>,
|
||||||
|
/// XID of the window
|
||||||
|
window_id: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// The last buffer presented to the window has been displayed.
|
/// The last buffer presented to the window has been displayed.
|
||||||
///
|
///
|
||||||
/// When this event is scheduled, the next frame may be rendered.
|
/// When this event is scheduled, the next frame may be rendered.
|
||||||
PresentCompleted,
|
PresentCompleted {
|
||||||
|
/// XID of the window
|
||||||
|
window_id: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// The window has received a request to be closed.
|
/// The window has received a request to be closed.
|
||||||
CloseRequested,
|
CloseRequested {
|
||||||
|
/// XID of the window
|
||||||
|
window_id: u32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an active connection to the X to manage events on the Window provided by the backend.
|
/// Represents an active connection to the X to manage events on the Window provided by the backend.
|
||||||
|
@ -241,6 +255,7 @@ impl X11Backend {
|
||||||
atoms,
|
atoms,
|
||||||
depth,
|
depth,
|
||||||
visual_id,
|
visual_id,
|
||||||
|
devices: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(X11Backend {
|
Ok(X11Backend {
|
||||||
|
@ -376,6 +391,14 @@ impl X11Handle {
|
||||||
resize: recv,
|
resize: recv,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a temporary reference to a window by its XID
|
||||||
|
pub fn window_ref_from_id(&self, id: u32) -> Option<impl AsRef<Window> + '_> {
|
||||||
|
X11Inner::window_ref_from_id(&self.inner, &id)
|
||||||
|
.and_then(|w| w.upgrade())
|
||||||
|
.map(Window)
|
||||||
|
.map(WindowTemporary)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builder used to construct a window.
|
/// Builder used to construct a window.
|
||||||
|
@ -498,11 +521,19 @@ impl PartialEq for Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WindowTemporary(Window);
|
||||||
|
|
||||||
|
impl AsRef<Window> for WindowTemporary {
|
||||||
|
fn as_ref(&self) -> &Window {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EventSource for X11Backend {
|
impl EventSource for X11Backend {
|
||||||
type Event = X11Event;
|
type Event = X11Event;
|
||||||
|
|
||||||
/// The window the incoming events are applicable to.
|
/// The window the incoming events are applicable to.
|
||||||
type Metadata = Window;
|
type Metadata = ();
|
||||||
|
|
||||||
type Ret = ();
|
type Ret = ();
|
||||||
|
|
||||||
|
@ -565,30 +596,48 @@ pub(crate) struct X11Inner {
|
||||||
atoms: Atoms,
|
atoms: Atoms,
|
||||||
depth: x11::xproto::Depth,
|
depth: x11::xproto::Depth,
|
||||||
visual_id: u32,
|
visual_id: u32,
|
||||||
|
devices: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl X11Inner {
|
impl X11Inner {
|
||||||
|
fn window_ref_from_id(inner: &Arc<Mutex<X11Inner>>, id: &u32) -> Option<Weak<WindowInner>> {
|
||||||
|
let mut inner = inner.lock().unwrap();
|
||||||
|
inner.windows.retain(|_, weak| weak.upgrade().is_some());
|
||||||
|
inner.windows.get(id).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
fn process_event<F>(inner: &Arc<Mutex<X11Inner>>, log: &Logger, event: x11::Event, callback: &mut F)
|
fn process_event<F>(inner: &Arc<Mutex<X11Inner>>, log: &Logger, event: x11::Event, callback: &mut F)
|
||||||
where
|
where
|
||||||
F: FnMut(X11Event, &mut Window),
|
F: FnMut(X11Event, &mut ()),
|
||||||
{
|
{
|
||||||
use self::X11Event::Input;
|
{
|
||||||
|
let mut inner = inner.lock().unwrap();
|
||||||
fn window_from_id(inner: &Arc<Mutex<X11Inner>>, id: &u32) -> Option<Arc<WindowInner>> {
|
if !inner.windows.is_empty() && !inner.devices {
|
||||||
inner
|
callback(
|
||||||
.lock()
|
Input(InputEvent::DeviceAdded {
|
||||||
.unwrap()
|
device: X11VirtualDevice,
|
||||||
.windows
|
}),
|
||||||
.get(id)
|
&mut (),
|
||||||
.cloned()
|
);
|
||||||
.and_then(|weak| weak.upgrade())
|
inner.devices = true;
|
||||||
|
} else if inner.windows.is_empty() && inner.devices {
|
||||||
|
callback(
|
||||||
|
Input(InputEvent::DeviceRemoved {
|
||||||
|
device: X11VirtualDevice,
|
||||||
|
}),
|
||||||
|
&mut (),
|
||||||
|
);
|
||||||
|
inner.devices = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use self::X11Event::Input;
|
||||||
|
|
||||||
// If X11 is deadlocking somewhere here, make sure you drop your mutex guards.
|
// If X11 is deadlocking somewhere here, make sure you drop your mutex guards.
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
x11::Event::ButtonPress(button_press) => {
|
x11::Event::ButtonPress(button_press) => {
|
||||||
if let Some(window) = window_from_id(inner, &button_press.event) {
|
if let Some(window) = X11Inner::window_ref_from_id(inner, &button_press.event) {
|
||||||
// X11 decided to associate scroll wheel with a button, 4, 5, 6 and 7 for
|
// X11 decided to associate scroll wheel with a button, 4, 5, 6 and 7 for
|
||||||
// up, down, right and left. For scrolling, a press event is emitted and a
|
// up, down, right and left. For scrolling, a press event is emitted and a
|
||||||
// release is them immediately followed for scrolling. This means we can
|
// release is them immediately followed for scrolling. This means we can
|
||||||
|
@ -631,9 +680,10 @@ impl X11Inner {
|
||||||
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
|
window,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut Window(window),
|
&mut (),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
callback(
|
callback(
|
||||||
|
@ -642,9 +692,10 @@ impl X11Inner {
|
||||||
time: button_press.time,
|
time: button_press.time,
|
||||||
raw: button_press.detail as u32,
|
raw: button_press.detail as u32,
|
||||||
state: ButtonState::Pressed,
|
state: ButtonState::Pressed,
|
||||||
|
window,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut Window(window),
|
&mut (),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,22 +709,23 @@ impl X11Inner {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window) = window_from_id(inner, &button_release.event) {
|
if let Some(window) = X11Inner::window_ref_from_id(inner, &button_release.event) {
|
||||||
callback(
|
callback(
|
||||||
Input(InputEvent::PointerButton {
|
Input(InputEvent::PointerButton {
|
||||||
event: X11MouseInputEvent {
|
event: X11MouseInputEvent {
|
||||||
time: button_release.time,
|
time: button_release.time,
|
||||||
raw: button_release.detail as u32,
|
raw: button_release.detail as u32,
|
||||||
state: ButtonState::Released,
|
state: ButtonState::Released,
|
||||||
|
window,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut Window(window),
|
&mut (),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::KeyPress(key_press) => {
|
x11::Event::KeyPress(key_press) => {
|
||||||
if let Some(window) = window_from_id(inner, &key_press.event) {
|
if let Some(window) = X11Inner::window_ref_from_id(inner, &key_press.event) {
|
||||||
// Do not hold the lock.
|
// Do not hold the lock.
|
||||||
let count = { inner.lock().unwrap().key_counter.fetch_add(1, Ordering::SeqCst) + 1 };
|
let count = { inner.lock().unwrap().key_counter.fetch_add(1, Ordering::SeqCst) + 1 };
|
||||||
|
|
||||||
|
@ -689,15 +741,16 @@ impl X11Inner {
|
||||||
key: key_press.detail as u32 - 8,
|
key: key_press.detail as u32 - 8,
|
||||||
count,
|
count,
|
||||||
state: KeyState::Pressed,
|
state: KeyState::Pressed,
|
||||||
|
window,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut Window(window),
|
&mut (),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::KeyRelease(key_release) => {
|
x11::Event::KeyRelease(key_release) => {
|
||||||
if let Some(window) = window_from_id(inner, &key_release.event) {
|
if let Some(window) = X11Inner::window_ref_from_id(inner, &key_release.event) {
|
||||||
let count = {
|
let count = {
|
||||||
let key_counter = inner.lock().unwrap().key_counter.clone();
|
let key_counter = inner.lock().unwrap().key_counter.clone();
|
||||||
|
|
||||||
|
@ -721,15 +774,18 @@ impl X11Inner {
|
||||||
key: key_release.detail as u32 - 8,
|
key: key_release.detail as u32 - 8,
|
||||||
count,
|
count,
|
||||||
state: KeyState::Released,
|
state: KeyState::Released,
|
||||||
|
window,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut Window(window),
|
&mut (),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::MotionNotify(motion_notify) => {
|
x11::Event::MotionNotify(motion_notify) => {
|
||||||
if let Some(window) = window_from_id(inner, &motion_notify.event) {
|
if let Some(window) =
|
||||||
|
X11Inner::window_ref_from_id(inner, &motion_notify.event).and_then(|w| w.upgrade())
|
||||||
|
{
|
||||||
// Use event_x/y since those are relative the the window receiving events.
|
// Use event_x/y since those are relative the the window receiving events.
|
||||||
let x = motion_notify.event_x as f64;
|
let x = motion_notify.event_x as f64;
|
||||||
let y = motion_notify.event_y as f64;
|
let y = motion_notify.event_y as f64;
|
||||||
|
@ -743,15 +799,18 @@ impl X11Inner {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
size: window_size,
|
size: window_size,
|
||||||
|
window: Arc::downgrade(&window),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
&mut Window(window),
|
&mut (),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::ConfigureNotify(configure_notify) => {
|
x11::Event::ConfigureNotify(configure_notify) => {
|
||||||
if let Some(window) = window_from_id(inner, &configure_notify.window) {
|
if let Some(window) =
|
||||||
|
X11Inner::window_ref_from_id(inner, &configure_notify.window).and_then(|w| w.upgrade())
|
||||||
|
{
|
||||||
let previous_size = { *window.size.lock().unwrap() };
|
let previous_size = { *window.size.lock().unwrap() };
|
||||||
|
|
||||||
// Did the size of the window change?
|
// Did the size of the window change?
|
||||||
|
@ -768,8 +827,11 @@ impl X11Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
(callback)(
|
(callback)(
|
||||||
X11Event::Resized(configure_notify_size),
|
X11Event::Resized {
|
||||||
&mut Window(window.clone()),
|
new_size: configure_notify_size,
|
||||||
|
window_id: configure_notify.window,
|
||||||
|
},
|
||||||
|
&mut (),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(resize_sender) = window.resize.lock().unwrap().as_ref() {
|
if let Some(resize_sender) = window.resize.lock().unwrap().as_ref() {
|
||||||
|
@ -780,40 +842,61 @@ impl X11Inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::EnterNotify(enter_notify) => {
|
x11::Event::EnterNotify(enter_notify) => {
|
||||||
if let Some(window) = window_from_id(inner, &enter_notify.event) {
|
if let Some(window) =
|
||||||
|
X11Inner::window_ref_from_id(inner, &enter_notify.event).and_then(|w| w.upgrade())
|
||||||
|
{
|
||||||
window.cursor_enter();
|
window.cursor_enter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::LeaveNotify(leave_notify) => {
|
x11::Event::LeaveNotify(leave_notify) => {
|
||||||
if let Some(window) = window_from_id(inner, &leave_notify.event) {
|
if let Some(window) =
|
||||||
|
X11Inner::window_ref_from_id(inner, &leave_notify.event).and_then(|w| w.upgrade())
|
||||||
|
{
|
||||||
window.cursor_leave();
|
window.cursor_leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::ClientMessage(client_message) => {
|
x11::Event::ClientMessage(client_message) => {
|
||||||
if let Some(window) = window_from_id(inner, &client_message.window) {
|
if let Some(window) =
|
||||||
|
X11Inner::window_ref_from_id(inner, &client_message.window).and_then(|w| w.upgrade())
|
||||||
|
{
|
||||||
if client_message.data.as_data32()[0] == window.atoms.WM_DELETE_WINDOW
|
if client_message.data.as_data32()[0] == window.atoms.WM_DELETE_WINDOW
|
||||||
// Destroy the window?
|
// Destroy the window?
|
||||||
{
|
{
|
||||||
(callback)(X11Event::CloseRequested, &mut Window(window));
|
(callback)(
|
||||||
|
X11Event::CloseRequested {
|
||||||
|
window_id: client_message.window,
|
||||||
|
},
|
||||||
|
&mut (),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::Expose(expose) => {
|
x11::Event::Expose(expose) => {
|
||||||
if let Some(window) = window_from_id(inner, &expose.window) {
|
|
||||||
if expose.count == 0 {
|
if expose.count == 0 {
|
||||||
(callback)(X11Event::Refresh, &mut Window(window));
|
(callback)(
|
||||||
}
|
X11Event::Refresh {
|
||||||
|
window_id: expose.window,
|
||||||
|
},
|
||||||
|
&mut (),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x11::Event::PresentCompleteNotify(complete_notify) => {
|
x11::Event::PresentCompleteNotify(complete_notify) => {
|
||||||
if let Some(window) = window_from_id(inner, &complete_notify.window) {
|
if let Some(window) =
|
||||||
|
X11Inner::window_ref_from_id(inner, &complete_notify.window).and_then(|w| w.upgrade())
|
||||||
|
{
|
||||||
window.last_msc.store(complete_notify.msc, Ordering::SeqCst);
|
window.last_msc.store(complete_notify.msc, Ordering::SeqCst);
|
||||||
|
|
||||||
(callback)(X11Event::PresentCompleted, &mut Window(window));
|
(callback)(
|
||||||
|
X11Event::PresentCompleted {
|
||||||
|
window_id: complete_notify.window,
|
||||||
|
},
|
||||||
|
&mut (),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::{
|
||||||
utils::{Logical, Size},
|
utils::{Logical, Size},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::X11Error;
|
use super::{WindowTemporary, X11Error};
|
||||||
|
|
||||||
/// An error that may occur when presenting.
|
/// An error that may occur when presenting.
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
@ -55,17 +55,7 @@ impl X11Surface {
|
||||||
///
|
///
|
||||||
/// This will return [`None`] if the window has been destroyed.
|
/// This will return [`None`] if the window has been destroyed.
|
||||||
pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
|
pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
|
||||||
let window = self.window.upgrade().map(Window).map(WindowTemporary);
|
self.window.upgrade().map(Window).map(WindowTemporary)
|
||||||
|
|
||||||
struct WindowTemporary(Window);
|
|
||||||
|
|
||||||
impl AsRef<Window> for WindowTemporary {
|
|
||||||
fn as_ref(&self) -> &Window {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a handle to the GBM device used to allocate buffers.
|
/// Returns a handle to the GBM device used to allocate buffers.
|
||||||
|
|
Loading…
Reference in New Issue