Skip to content

Commit

Permalink
Fix transparency on X11 (#2006)
Browse files Browse the repository at this point in the history
* find transparent in x11

* remove debug hooks

* update changelog

* polish and failed to find visual warning
  • Loading branch information
sandmor authored Aug 22, 2021
1 parent b5d0d6f commit b54d477
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

- On X11, select an appropriate visual for transparency if is requested
- On Wayland and X11, fix diagonal window resize cursor orientation.
- On macOS, drop the event callback before exiting.
- On Android, implement `Window::request_redraw`
Expand Down
46 changes: 30 additions & 16 deletions src/platform_impl/linux/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{
ptr, slice,
sync::Arc,
};
use x11_dl::xlib::TrueColor;

use libc;
use mio_misc::channel::Sender;
Expand Down Expand Up @@ -180,13 +181,40 @@ impl UnownedWindow {
};

// creating
let (visual, depth) = match pl_attribs.visual_infos {
Some(vi) => (vi.visual, vi.depth),
None if window_attrs.transparent == true => {
// Find a suitable visual
let mut vinfo = MaybeUninit::uninit();
let vinfo_initialized = unsafe {
(xconn.xlib.XMatchVisualInfo)(
xconn.display,
screen_id,
32,
TrueColor,
vinfo.as_mut_ptr(),
) != 0
};
if vinfo_initialized {
let vinfo = unsafe { vinfo.assume_init() };
(vinfo.visual, vinfo.depth)
} else {
debug!("Could not set transparency, because XMatchVisualInfo returned zero for the required parameters");
(ffi::CopyFromParent as *mut ffi::Visual, ffi::CopyFromParent)
}
}
_ => (ffi::CopyFromParent as *mut ffi::Visual, ffi::CopyFromParent),
};

let mut set_win_attr = {
let mut swa: ffi::XSetWindowAttributes = unsafe { mem::zeroed() };
swa.colormap = if let Some(vi) = pl_attribs.visual_infos {
unsafe {
let visual = vi.visual;
(xconn.xlib.XCreateColormap)(xconn.display, root, visual, ffi::AllocNone)
}
} else if window_attrs.transparent {
unsafe { (xconn.xlib.XCreateColormap)(xconn.display, root, visual, ffi::AllocNone) }
} else {
0
};
Expand Down Expand Up @@ -220,23 +248,9 @@ impl UnownedWindow {
dimensions.0 as c_uint,
dimensions.1 as c_uint,
0,
match pl_attribs.visual_infos {
Some(vi) => vi.depth,
None => ffi::CopyFromParent,
},
depth,
ffi::InputOutput as c_uint,
// TODO: If window wants transparency and `visual_infos` is None,
// we need to find our own visual which has an `alphaMask` which
// is > 0, like we do in glutin.
//
// It is non obvious which masks, if any, we should pass to
// `XGetVisualInfo`. winit doesn't receive any info about what
// properties the user wants. Users should consider choosing the
// visual themselves as glutin does.
match pl_attribs.visual_infos {
Some(vi) => vi.visual,
None => ffi::CopyFromParent as *mut ffi::Visual,
},
visual,
window_attributes,
&mut set_win_attr,
)
Expand Down

0 comments on commit b54d477

Please sign in to comment.