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:
committed by
Kirill Chibisov
parent
7035dd554f
commit
3eb731f8b5
@@ -43,3 +43,4 @@ changelog entry.
|
|||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- On macOS, fixed crash when dragging non-file content onto window.
|
- On macOS, fixed crash when dragging non-file content onto window.
|
||||||
|
- On X11, fix `set_hittest` not working on some window managers.
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ use std::{cmp, env};
|
|||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, info, warn};
|
||||||
use x11rb::connection::Connection;
|
use x11rb::connection::Connection;
|
||||||
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::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::cursor::{Cursor, CustomCursor as RootCustomCursor};
|
use crate::cursor::{Cursor, CustomCursor as RootCustomCursor};
|
||||||
@@ -1622,6 +1621,15 @@ impl UnownedWindow {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
|
pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
|
||||||
|
// 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.inner_size();
|
let size = self.inner_size();
|
||||||
@@ -1632,11 +1640,18 @@ 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| ExternalError::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| ExternalError::Ignored)?;
|
.map_err(|_e| ExternalError::Ignored)?;
|
||||||
self.shared_state_lock().cursor_hittest = Some(hittest);
|
self.shared_state_lock().cursor_hittest = Some(hittest);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user