mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +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.
|
- **Breaking:** Remove the unstable `xlib_xconnection()` function from the private interface.
|
||||||
- Added Orbital support for Redox OS
|
- Added Orbital support for Redox OS
|
||||||
- On X11, added `drag_resize_window` method.
|
- 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
|
# 0.27.5
|
||||||
|
|
||||||
|
|
|
@ -947,6 +947,8 @@ impl Window {
|
||||||
|
|
||||||
pub fn set_title(&self, _title: &str) {}
|
pub fn set_title(&self, _title: &str) {}
|
||||||
|
|
||||||
|
pub fn set_transparent(&self, _transparent: bool) {}
|
||||||
|
|
||||||
pub fn set_visible(&self, _visibility: bool) {}
|
pub fn set_visible(&self, _visibility: bool) {}
|
||||||
|
|
||||||
pub fn is_visible(&self) -> Option<bool> {
|
pub fn is_visible(&self) -> Option<bool> {
|
||||||
|
|
|
@ -43,6 +43,10 @@ impl Inner {
|
||||||
debug!("`Window::set_title` is ignored on iOS")
|
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) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
self.window.setHidden(!visible)
|
self.window.setHidden(!visible)
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,6 +324,11 @@ impl Window {
|
||||||
x11_or_wayland!(match self; Window(w) => w.set_title(title));
|
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]
|
#[inline]
|
||||||
pub fn set_visible(&self, visible: bool) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
x11_or_wayland!(match self; Window(w) => w.set_visible(visible))
|
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.resize(size.width, size.height);
|
||||||
window_handle.window.refresh();
|
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.
|
// Mark that refresh isn't required, since we've done it right now.
|
||||||
state
|
state
|
||||||
.window_user_requests
|
.window_user_requests
|
||||||
|
|
|
@ -261,6 +261,9 @@ impl Window {
|
||||||
window_requests.clone(),
|
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`.
|
// Set resizable state, so we can determine how to handle `Window::set_inner_size`.
|
||||||
window_handle.is_resizable.set(attributes.resizable);
|
window_handle.is_resizable.set(attributes.resizable);
|
||||||
|
|
||||||
|
@ -332,6 +335,11 @@ impl Window {
|
||||||
self.send_request(WindowRequest::Title(title.to_owned()));
|
self.send_request(WindowRequest::Title(title.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_transparent(&self, transparent: bool) {
|
||||||
|
self.send_request(WindowRequest::Transparent(transparent));
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_visible(&self, _visible: bool) {
|
pub fn set_visible(&self, _visible: bool) {
|
||||||
// Not possible on Wayland.
|
// Not possible on Wayland.
|
||||||
|
|
|
@ -80,6 +80,9 @@ pub enum WindowRequest {
|
||||||
/// Enable IME on the given window.
|
/// Enable IME on the given window.
|
||||||
AllowIme(bool),
|
AllowIme(bool),
|
||||||
|
|
||||||
|
/// Mark the window as opaque.
|
||||||
|
Transparent(bool),
|
||||||
|
|
||||||
/// Request Attention.
|
/// Request Attention.
|
||||||
///
|
///
|
||||||
/// `None` unsets the attention request.
|
/// `None` unsets the attention request.
|
||||||
|
@ -154,6 +157,9 @@ pub struct WindowHandle {
|
||||||
/// Allow IME events for that window.
|
/// Allow IME events for that window.
|
||||||
pub ime_allowed: Cell<bool>,
|
pub ime_allowed: Cell<bool>,
|
||||||
|
|
||||||
|
/// Wether the window is transparent.
|
||||||
|
pub transparent: Cell<bool>,
|
||||||
|
|
||||||
/// Visible cursor or not.
|
/// Visible cursor or not.
|
||||||
cursor_visible: Cell<bool>,
|
cursor_visible: Cell<bool>,
|
||||||
|
|
||||||
|
@ -194,6 +200,7 @@ impl WindowHandle {
|
||||||
pending_window_requests,
|
pending_window_requests,
|
||||||
cursor_icon: Cell::new(CursorIcon::Default),
|
cursor_icon: Cell::new(CursorIcon::Default),
|
||||||
is_resizable: Cell::new(true),
|
is_resizable: Cell::new(true),
|
||||||
|
transparent: Cell::new(false),
|
||||||
cursor_grab_mode: Cell::new(CursorGrabMode::None),
|
cursor_grab_mode: Cell::new(CursorGrabMode::None),
|
||||||
cursor_visible: Cell::new(true),
|
cursor_visible: Cell::new(true),
|
||||||
pointers: Vec::new(),
|
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) {
|
pub fn set_ime_allowed(&self, allowed: bool, event_sink: &mut EventSink) {
|
||||||
if self.ime_allowed.get() == allowed {
|
if self.ime_allowed.get() == allowed {
|
||||||
return;
|
return;
|
||||||
|
@ -452,6 +472,13 @@ pub fn handle_window_requests(winit_state: &mut WinitState) {
|
||||||
WindowRequest::Minimize => {
|
WindowRequest::Minimize => {
|
||||||
window_handle.window.set_minimized();
|
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) => {
|
WindowRequest::Decorate(decorate) => {
|
||||||
let decorations = match decorate {
|
let decorations = match decorate {
|
||||||
true => Decorations::FollowServer,
|
true => Decorations::FollowServer,
|
||||||
|
|
|
@ -903,6 +903,9 @@ impl UnownedWindow {
|
||||||
.expect("Failed to set window title");
|
.expect("Failed to set window title");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_transparent(&self, _transparent: bool) {}
|
||||||
|
|
||||||
fn set_decorations_inner(&self, decorations: bool) -> util::Flusher<'_> {
|
fn set_decorations_inner(&self, decorations: bool) -> util::Flusher<'_> {
|
||||||
self.shared_state_lock().is_decorated = decorations;
|
self.shared_state_lock().is_decorated = decorations;
|
||||||
let mut hints = self.xconn.get_motif_hints(self.xwindow);
|
let mut hints = self.xconn.get_motif_hints(self.xwindow);
|
||||||
|
|
|
@ -506,6 +506,10 @@ impl WinitWindow {
|
||||||
util::set_title_sync(self, title);
|
util::set_title_sync(self, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_transparent(&self, transparent: bool) {
|
||||||
|
self.setOpaque(!transparent)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_visible(&self, visible: bool) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
match visible {
|
match visible {
|
||||||
true => util::make_key_and_order_front_sync(self),
|
true => util::make_key_and_order_front_sync(self),
|
||||||
|
|
|
@ -240,6 +240,9 @@ impl Window {
|
||||||
.expect("failed to set title");
|
.expect("failed to set title");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_transparent(&self, _transparent: bool) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_visible(&self, _visibility: bool) {}
|
pub fn set_visible(&self, _visibility: bool) {}
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,8 @@ impl Window {
|
||||||
self.canvas.borrow().set_attribute("alt", title);
|
self.canvas.borrow().set_attribute("alt", title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_transparent(&self, _transparent: bool) {}
|
||||||
|
|
||||||
pub fn set_visible(&self, _visible: bool) {
|
pub fn set_visible(&self, _visible: bool) {
|
||||||
// Intentionally a no-op
|
// Intentionally a no-op
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_transparent(&self, _transparent: bool) {}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_visible(&self, visible: bool) {
|
pub fn set_visible(&self, visible: bool) {
|
||||||
let window = self.window.clone();
|
let window = self.window.clone();
|
||||||
|
|
|
@ -306,7 +306,9 @@ impl WindowBuilder {
|
||||||
/// Sets whether the background of the window should be transparent.
|
/// Sets whether the background of the window should be transparent.
|
||||||
///
|
///
|
||||||
/// If this is `true`, writing colors with alpha values different than
|
/// 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`.
|
/// The default is `false`.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -735,6 +737,23 @@ impl Window {
|
||||||
self.window.set_title(title)
|
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.
|
/// Modifies the window's visibility.
|
||||||
///
|
///
|
||||||
/// If `false`, this will hide the window. If `true`, this will show the window.
|
/// If `false`, this will hide the window. If `true`, this will show the window.
|
||||||
|
|
Loading…
Reference in a new issue