Add cursor hittest window functionality (#2232)

Co-authored-by: z4122 <412213484@qq.com>
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
This commit is contained in:
Markus Siglreithmaier 2022-04-12 19:10:46 +02:00 committed by GitHub
parent 142d55ff24
commit bf366cb99d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 120 additions and 6 deletions

View file

@ -396,6 +396,11 @@ impl Window {
x11_or_wayland!(match self; Window(window) => window.drag_window())
}
#[inline]
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
x11_or_wayland!(match self; Window(w) => w.set_cursor_hittest(hittest))
}
#[inline]
pub fn scale_factor(&self) -> f64 {
x11_or_wayland!(match self; Window(w) => w.scale_factor() as f64)

View file

@ -482,6 +482,13 @@ impl Window {
Ok(())
}
#[inline]
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
self.send_request(WindowRequest::PassthroughMouseInput(!hittest));
Ok(())
}
#[inline]
pub fn set_ime_position(&self, position: Position) {
let scale_factor = self.scale_factor() as f64;

View file

@ -1,6 +1,7 @@
use std::cell::Cell;
use std::sync::{Arc, Mutex};
use sctk::reexports::client::protocol::wl_compositor::WlCompositor;
use sctk::reexports::client::protocol::wl_output::WlOutput;
use sctk::reexports::client::Attached;
use sctk::reexports::protocols::staging::xdg_activation::v1::client::xdg_activation_token_v1;
@ -75,6 +76,9 @@ pub enum WindowRequest {
/// `None` unsets the attention request.
Attention(Option<UserAttentionType>),
/// Passthrough mouse input to underlying windows.
PassthroughMouseInput(bool),
/// Redraw was requested.
Redraw,
@ -167,6 +171,9 @@ pub struct WindowHandle {
/// Indicator whether user attention is requested.
attention_requested: Cell<bool>,
/// Compositor
compositor: Attached<WlCompositor>,
}
impl WindowHandle {
@ -177,6 +184,9 @@ impl WindowHandle {
pending_window_requests: Arc<Mutex<Vec<WindowRequest>>>,
) -> Self {
let xdg_activation = env.get_global::<XdgActivationV1>();
// Unwrap is safe, since we can't create window without compositor anyway and won't be
// here.
let compositor = env.get_global::<WlCompositor>().unwrap();
Self {
window,
@ -189,6 +199,7 @@ impl WindowHandle {
text_inputs: Vec::new(),
xdg_activation,
attention_requested: Cell::new(false),
compositor,
}
}
@ -304,6 +315,20 @@ impl WindowHandle {
}
}
pub fn passthrough_mouse_input(&self, passthrough_mouse_input: bool) {
if passthrough_mouse_input {
let region = self.compositor.create_region();
region.add(0, 0, 0, 0);
self.window
.surface()
.set_input_region(Some(&region.detach()));
region.destroy();
} else {
// Using `None` results in the entire window being clickable.
self.window.surface().set_input_region(None);
}
}
pub fn set_cursor_visible(&self, visible: bool) {
self.cursor_visible.replace(visible);
let cursor_icon = match visible {
@ -425,6 +450,12 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
let window_update = window_updates.get_mut(window_id).unwrap();
window_update.refresh_frame = true;
}
WindowRequest::PassthroughMouseInput(passthrough) => {
window_handle.passthrough_mouse_input(passthrough);
let window_update = window_updates.get_mut(window_id).unwrap();
window_update.refresh_frame = true;
}
WindowRequest::Attention(request_type) => {
window_handle.set_user_attention(request_type);
}

View file

@ -1358,6 +1358,11 @@ impl UnownedWindow {
self.set_cursor_position_physical(x, y)
}
#[inline]
pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), ExternalError> {
Err(ExternalError::NotSupported(NotSupportedError::new()))
}
pub fn drag_window(&self) -> Result<(), ExternalError> {
let pointer = self
.xconn