mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-29 04:40:04 -04:00
winit-x11: replace xfixes with x11rb in set_hittest
The xfixes implementation is not that reliable and rather simple to replace, so use x11rb to implement the same functionality. Fixes #4120. Co-authored-by: avitran0 <holyhades64@gmail.com>
This commit is contained in:
@@ -26,10 +26,9 @@ use winit_core::window::{
|
|||||||
};
|
};
|
||||||
use x11rb::connection::{Connection, RequestConnection};
|
use x11rb::connection::{Connection, RequestConnection};
|
||||||
use x11rb::properties::{WmHints, WmSizeHints, WmSizeHintsSpecification};
|
use x11rb::properties::{WmHints, WmSizeHints, WmSizeHintsSpecification};
|
||||||
use x11rb::protocol::shape::SK;
|
use x11rb::protocol::shape::{ConnectionExt as ShapeExt, SK, SO};
|
||||||
use x11rb::protocol::sync::{ConnectionExt as _, Int64};
|
use x11rb::protocol::sync::{ConnectionExt as _, Int64};
|
||||||
use x11rb::protocol::xfixes::{ConnectionExt, RegionWrapper};
|
use x11rb::protocol::xproto::{self, ClipOrdering, ConnectionExt as _, Rectangle};
|
||||||
use x11rb::protocol::xproto::{self, ConnectionExt as _, Rectangle};
|
|
||||||
use x11rb::protocol::{randr, xinput};
|
use x11rb::protocol::{randr, xinput};
|
||||||
|
|
||||||
use crate::atoms::*;
|
use crate::atoms::*;
|
||||||
@@ -1967,6 +1966,15 @@ impl UnownedWindow {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> {
|
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), RequestError> {
|
||||||
|
// Implement cursor hittest for X11 by either setting an empty or full window input shape.
|
||||||
|
|
||||||
|
// In X11, every window has two "shapes":
|
||||||
|
// * Bounding shape: defines the visible outline of the window.
|
||||||
|
// * Input shape: defines the region of the window that receives pointer/keyboard events.
|
||||||
|
// If the input shape is the full window rectangle, the window behaves normally.
|
||||||
|
// If the input shape is empty, the window is completely click‑through.
|
||||||
|
// Here, we implement hit test by mapping `hittest = true` to "restore a full input shape"
|
||||||
|
// and `hittest = false` to "clear the input shape" (empty list of rectangles).
|
||||||
let mut rectangles: Vec<Rectangle> = Vec::new();
|
let mut rectangles: Vec<Rectangle> = Vec::new();
|
||||||
if hittest {
|
if hittest {
|
||||||
let size = self.surface_size();
|
let size = self.surface_size();
|
||||||
@@ -1977,11 +1985,17 @@ impl UnownedWindow {
|
|||||||
height: size.height as u16,
|
height: size.height as u16,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
let region = RegionWrapper::create_region(self.xconn.xcb_connection(), &rectangles)
|
|
||||||
.map_err(|_e| RequestError::Ignored)?;
|
|
||||||
self.xconn
|
self.xconn
|
||||||
.xcb_connection()
|
.xcb_connection()
|
||||||
.xfixes_set_window_shape_region(self.xwindow, SK::INPUT, 0, 0, region.region())
|
.shape_rectangles(
|
||||||
|
SO::SET,
|
||||||
|
SK::INPUT,
|
||||||
|
ClipOrdering::UNSORTED,
|
||||||
|
self.xwindow,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&rectangles,
|
||||||
|
)
|
||||||
.map_err(|_e| RequestError::Ignored)?;
|
.map_err(|_e| RequestError::Ignored)?;
|
||||||
self.shared_state_lock().cursor_hittest = Some(hittest);
|
self.shared_state_lock().cursor_hittest = Some(hittest);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -42,4 +42,8 @@ changelog entry.
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `keyboard` support for OpenHarmony.
|
- Add `keyboard` support for OpenHarmony.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- On X11, fix `set_hittest` not working on some window managers.
|
||||||
|
|||||||
Reference in New Issue
Block a user