Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cursor hittest window functionality #2232

Merged
merged 4 commits into from
Apr 12, 2022

Conversation

msiglreith
Copy link
Member

@msiglreith msiglreith commented Mar 28, 2022

  • Tested on all platforms changed
  • Added an entry to CHANGELOG.md if knowledge of this change could be valuable to users
  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior
  • Created or updated an example program if it would help users understand this functionality
  • Updated feature matrix, if new features were added or implemented

Supersedes #1884
Addresses: #1884 (comment) (CS_OWNDC has been removed in a separate PR)

Adds set_cursor_hittest which allows to configure if a window should passthrough any cursor events. Currently only implemented for macOS and Windows.

@kchibisov
Copy link
Member

I think it makes sense to add something like that. Do I understand correctly that you're basically able to click through the entire window with that? Wayland has such thing as well, but you can enable it for regions, though, I can send you a patch for the entire window toggling, I think it makes more sense that way...

@msiglreith
Copy link
Member Author

Right, it's for the whole window as there seems no way for the two platforms to provide more fine granular control out of the box. The feature was mostly requested in order to support overlay so disabling it for the whole window should be good enough

@kchibisov
Copy link
Member

@msiglreith Wayland impl.

From 4870a28463481b9321d1c7a37aa1be8e9c7f0c5e Mon Sep 17 00:00:00 2001
From: Kirill Chibisov <contact@kchibisov.com>
Date: Thu, 7 Apr 2022 00:23:52 +0300
Subject: [PATCH] on Waylnad add `Window::set_cursor_hittest`

This commit provides Wayland implementation for
`Window::set_cursor_hittest` API.
---
 CHANGELOG.md                                  |  2 +-
 FEATURES.md                                   |  2 +-
 src/platform_impl/linux/wayland/window/mod.rs |  6 ++--
 .../linux/wayland/window/shim.rs              | 31 +++++++++++++++++++
 4 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 047df7eb..7f2886fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre

 # Unreleased

-- On macOS and Windows, add `set_cursor_hittest` to let the window ignore mouse events.
+- On macOS, Windows, and Wayland, add `set_cursor_hittest` to let the window ignore mouse events.
 - On Windows, remove internally unique DC per window.
 - On macOS, remove the need to call `set_ime_position` after moving the window.
 - Added `Window::is_visible`.
diff --git a/FEATURES.md b/FEATURES.md
index 6edb9395..15aacb6b 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -200,7 +200,7 @@ Legend:
 |Mouse set location      |✔️       |✔️      |✔️       |❓           |**N/A**|**N/A**|**N/A**|
 |Cursor grab             |✔️       |▢[#165] |▢[#242]  |✔️         |**N/A**|**N/A**|✔️        |
 |Cursor icon             |✔️       |✔️      |✔️       |✔️           |**N/A**|**N/A**|✔️        |
-|Cursor hittest          |✔️       |✔️      |❌       |❌           |**N/A**|**N/A**|❌        |
+|Cursor hittest          |✔️       |✔️      |❌       |✔️           |**N/A**|**N/A**|❌        |
 |Touch events            |✔️       |❌      |✔️       |✔️          |✔️    |✔️     |❌        |
 |Touch pressure          |✔️       |❌      |❌       |❌          |❌    |✔️     |❌        |
 |Multitouch              |✔️       |❌      |✔️       |✔️          |✔️    |✔️     |❌        |
diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs
index c38459f0..b7c0773e 100644
--- a/src/platform_impl/linux/wayland/window/mod.rs
+++ b/src/platform_impl/linux/wayland/window/mod.rs
@@ -469,8 +469,10 @@ impl Window {
     }

     #[inline]
-    pub fn set_cursor_hittest(&self, _hittest: bool) -> Result<(), ExternalError> {
-        Err(ExternalError::NotSupported(NotSupportedError::new()))
+    pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
+        self.send_request(WindowRequest::PassthroughMouseInput(!hittest));
+
+        Ok(())
     }

     #[inline]
diff --git a/src/platform_impl/linux/wayland/window/shim.rs b/src/platform_impl/linux/wayland/window/shim.rs
index 7c76a2fa..60247b31 100644
--- a/src/platform_impl/linux/wayland/window/shim.rs
+++ b/src/platform_impl/linux/wayland/window/shim.rs
@@ -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);
                 }
--
2.35.1

src/window.rs Outdated Show resolved Hide resolved
msiglreith and others added 2 commits April 9, 2022 12:31
This commit provides Wayland implementation for
Window::set_cursor_hittest API.
@kchibisov kchibisov added this to the Version 0.27 milestone Apr 11, 2022
@msiglreith msiglreith merged commit bf366cb into rust-windowing:master Apr 12, 2022
Copy link
Member

@madsmtm madsmtm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm that this works on macOS (and have updated the PR description to match)

@msiglreith msiglreith deleted the cursor-hittest branch April 17, 2022 14:01
@coderedart
Copy link

does this work with linux (X11) yet?

@maroider
Copy link
Member

maroider commented May 24, 2022

I don't think this works on X11 yet, no

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

6 participants