mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 13:51:30 +11:00
Add Window::set_transparent
Provide a hint to system compositor whether the window is transparent or not. Only implemented on macOS and Wayland for now.
This commit is contained in:
parent
6f60c7a6cc
commit
62ce14a013
|
@ -53,6 +53,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
- **Breaking:** Remove the unstable `xlib_xconnection()` function from the private interface.
|
||||
- Added Orbital support for Redox OS
|
||||
- On X11, added `drag_resize_window` method.
|
||||
- Added `Window::set_transparent` to provide a hint about transparency of the window on Wayland and macOS.
|
||||
|
||||
# 0.27.5
|
||||
|
||||
|
|
|
@ -947,6 +947,8 @@ impl Window {
|
|||
|
||||
pub fn set_title(&self, _title: &str) {}
|
||||
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
pub fn set_visible(&self, _visibility: bool) {}
|
||||
|
||||
pub fn is_visible(&self) -> Option<bool> {
|
||||
|
|
|
@ -43,6 +43,10 @@ impl Inner {
|
|||
debug!("`Window::set_title` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, _transparent: bool) {
|
||||
debug!("`Window::set_transparent` is ignored on iOS")
|
||||
}
|
||||
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
self.window.setHidden(!visible)
|
||||
}
|
||||
|
|
|
@ -324,6 +324,11 @@ impl Window {
|
|||
x11_or_wayland!(match self; Window(w) => w.set_title(title));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_transparent(transparent));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
x11_or_wayland!(match self; Window(w) => w.set_visible(visible))
|
||||
|
|
|
@ -431,6 +431,9 @@ impl<T: 'static> EventLoop<T> {
|
|||
window_handle.window.resize(size.width, size.height);
|
||||
window_handle.window.refresh();
|
||||
|
||||
// Update the opaque region.
|
||||
window_handle.set_transparent(window_handle.transparent.get());
|
||||
|
||||
// Mark that refresh isn't required, since we've done it right now.
|
||||
state
|
||||
.window_user_requests
|
||||
|
|
|
@ -261,6 +261,9 @@ impl Window {
|
|||
window_requests.clone(),
|
||||
);
|
||||
|
||||
// Set opaque region.
|
||||
window_handle.set_transparent(attributes.transparent);
|
||||
|
||||
// Set resizable state, so we can determine how to handle `Window::set_inner_size`.
|
||||
window_handle.is_resizable.set(attributes.resizable);
|
||||
|
||||
|
@ -332,6 +335,11 @@ impl Window {
|
|||
self.send_request(WindowRequest::Title(title.to_owned()));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
self.send_request(WindowRequest::Transparent(transparent));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, _visible: bool) {
|
||||
// Not possible on Wayland.
|
||||
|
|
|
@ -80,6 +80,9 @@ pub enum WindowRequest {
|
|||
/// Enable IME on the given window.
|
||||
AllowIme(bool),
|
||||
|
||||
/// Mark the window as opaque.
|
||||
Transparent(bool),
|
||||
|
||||
/// Request Attention.
|
||||
///
|
||||
/// `None` unsets the attention request.
|
||||
|
@ -154,6 +157,9 @@ pub struct WindowHandle {
|
|||
/// Allow IME events for that window.
|
||||
pub ime_allowed: Cell<bool>,
|
||||
|
||||
/// Wether the window is transparent.
|
||||
pub transparent: Cell<bool>,
|
||||
|
||||
/// Visible cursor or not.
|
||||
cursor_visible: Cell<bool>,
|
||||
|
||||
|
@ -194,6 +200,7 @@ impl WindowHandle {
|
|||
pending_window_requests,
|
||||
cursor_icon: Cell::new(CursorIcon::Default),
|
||||
is_resizable: Cell::new(true),
|
||||
transparent: Cell::new(false),
|
||||
cursor_grab_mode: Cell::new(CursorGrabMode::None),
|
||||
cursor_visible: Cell::new(true),
|
||||
pointers: Vec::new(),
|
||||
|
@ -349,6 +356,19 @@ impl WindowHandle {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
self.transparent.set(transparent);
|
||||
let surface = self.window.surface();
|
||||
if transparent {
|
||||
surface.set_opaque_region(None);
|
||||
} else {
|
||||
let region = self.compositor.create_region();
|
||||
region.add(0, 0, i32::MAX, i32::MAX);
|
||||
surface.set_opaque_region(Some(®ion.detach()));
|
||||
region.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_ime_allowed(&self, allowed: bool, event_sink: &mut EventSink) {
|
||||
if self.ime_allowed.get() == allowed {
|
||||
return;
|
||||
|
@ -452,6 +472,13 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
|||
WindowRequest::Minimize => {
|
||||
window_handle.window.set_minimized();
|
||||
}
|
||||
WindowRequest::Transparent(transparent) => {
|
||||
window_handle.set_transparent(transparent);
|
||||
|
||||
// This requires surface commit.
|
||||
let window_request = window_user_requests.get_mut(window_id).unwrap();
|
||||
window_request.redraw_requested = true;
|
||||
}
|
||||
WindowRequest::Decorate(decorate) => {
|
||||
let decorations = match decorate {
|
||||
true => Decorations::FollowServer,
|
||||
|
|
|
@ -903,6 +903,9 @@ impl UnownedWindow {
|
|||
.expect("Failed to set window title");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
fn set_decorations_inner(&self, decorations: bool) -> util::Flusher<'_> {
|
||||
self.shared_state_lock().is_decorated = decorations;
|
||||
let mut hints = self.xconn.get_motif_hints(self.xwindow);
|
||||
|
|
|
@ -506,6 +506,10 @@ impl WinitWindow {
|
|||
util::set_title_sync(self, title);
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
self.setOpaque(!transparent)
|
||||
}
|
||||
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
match visible {
|
||||
true => util::make_key_and_order_front_sync(self),
|
||||
|
|
|
@ -240,6 +240,9 @@ impl Window {
|
|||
.expect("failed to set title");
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, _visibility: bool) {}
|
||||
|
||||
|
|
|
@ -87,6 +87,8 @@ impl Window {
|
|||
self.canvas.borrow().set_attribute("alt", title);
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
pub fn set_visible(&self, _visible: bool) {
|
||||
// Intentionally a no-op
|
||||
}
|
||||
|
|
|
@ -113,6 +113,8 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_transparent(&self, _transparent: bool) {}
|
||||
|
||||
#[inline]
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
let window = self.window.clone();
|
||||
|
|
|
@ -306,7 +306,9 @@ impl WindowBuilder {
|
|||
/// Sets whether the background of the window should be transparent.
|
||||
///
|
||||
/// If this is `true`, writing colors with alpha values different than
|
||||
/// `1.0` will produce a transparent window.
|
||||
/// `1.0` will produce a transparent window. On some platforms this
|
||||
/// is more of a hint for the system and you'd still have the alpha
|
||||
/// buffer. To control it see [`Window::set_transparent`].
|
||||
///
|
||||
/// The default is `false`.
|
||||
#[inline]
|
||||
|
@ -735,6 +737,23 @@ impl Window {
|
|||
self.window.set_title(title)
|
||||
}
|
||||
|
||||
/// Change the window transparency state.
|
||||
///
|
||||
/// This is just a hint that may not change anything about
|
||||
/// the window transparency, however doing a missmatch between
|
||||
/// the content of your window and this hint may result in
|
||||
/// visual artifacts.
|
||||
///
|
||||
/// The default value follows the [`WindowBuilder::with_transparent`].
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - **Windows / X11 / Web / iOS / Android / Orbital:** Unsupported.
|
||||
#[inline]
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
self.window.set_transparent(transparent)
|
||||
}
|
||||
|
||||
/// Modifies the window's visibility.
|
||||
///
|
||||
/// If `false`, this will hide the window. If `true`, this will show the window.
|
||||
|
|
Loading…
Reference in a new issue