Add macOS-specific `has_shadow` and `with_has_shadow` to ViewportBuilder (#6850)
* [X] I have followed the instructions in the PR template This PR fixes a ghosting issue I encountered while making a native macOS transparent overlay app using egui and eframe by exposing the [existing macOS window attribute `has_shadow`](https://docs.rs/winit/latest/winit/platform/macos/trait.WindowExtMacOS.html#tymethod.has_shadow) to the `ViewportBuilder` via a new `with_has_shadow` option. ## Example of Ghosting Issue ### Before `ViewportBuilder::with_has_shadow` By default, the underlying `winit` window's `.has_shadow()` defaults to `true`. https://github.com/user-attachments/assets/c3dcc2bd-535a-4960-918e-3ae5df503b12 ### After `ViewportBuilder::with_has_shadow` https://github.com/user-attachments/assets/484462a1-ea88-43e6-85b4-0bb9724e5f14 Source code for the above example can be found here: https://github.com/gaelanmcmillan/egui-overlay-app-with-shadow-artifacts-example/blob/main/src/main.rs ### Further background By default on macOS, `winit` windows have a drop-shadow effect. When creating a fully transparent overlay GUI, this drop-shadow can create a ghosting effect, as the window content has a drop shadow which is not cleared by the app itself. This issue has been experienced by users of `bevy`, another Rust project that has an upstream dependency on `winit`: https://github.com/bevyengine/bevy/issues/18673
This commit is contained in:
parent
7d185acb41
commit
3a02963c33
|
|
@ -1620,6 +1620,7 @@ pub fn create_winit_window_attributes(
|
|||
title_shown: _title_shown,
|
||||
titlebar_buttons_shown: _titlebar_buttons_shown,
|
||||
titlebar_shown: _titlebar_shown,
|
||||
has_shadow: _has_shadow,
|
||||
|
||||
// Windows:
|
||||
drag_and_drop: _drag_and_drop,
|
||||
|
|
@ -1764,7 +1765,8 @@ pub fn create_winit_window_attributes(
|
|||
.with_titlebar_buttons_hidden(!_titlebar_buttons_shown.unwrap_or(true))
|
||||
.with_titlebar_transparent(!_titlebar_shown.unwrap_or(true))
|
||||
.with_fullsize_content_view(_fullsize_content_view.unwrap_or(false))
|
||||
.with_movable_by_window_background(_movable_by_window_background.unwrap_or(false));
|
||||
.with_movable_by_window_background(_movable_by_window_background.unwrap_or(false))
|
||||
.with_has_shadow(_has_shadow.unwrap_or(true));
|
||||
}
|
||||
|
||||
window_attributes
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ pub struct ViewportBuilder {
|
|||
pub title_shown: Option<bool>,
|
||||
pub titlebar_buttons_shown: Option<bool>,
|
||||
pub titlebar_shown: Option<bool>,
|
||||
pub has_shadow: Option<bool>,
|
||||
|
||||
// windows:
|
||||
pub drag_and_drop: Option<bool>,
|
||||
|
|
@ -380,6 +381,10 @@ impl ViewportBuilder {
|
|||
/// The default is `false`.
|
||||
/// If this is not working, it's because the graphic context doesn't support transparency,
|
||||
/// you will need to set the transparency in the eframe!
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// **macOS:** When using this feature to create an overlay-like UI, you likely want to combine this with [`Self::with_has_shadow`] set to `false` in order to avoid ghosting artifacts.
|
||||
#[inline]
|
||||
pub fn with_transparent(mut self, transparent: bool) -> Self {
|
||||
self.transparent = Some(transparent);
|
||||
|
|
@ -433,7 +438,6 @@ impl ViewportBuilder {
|
|||
}
|
||||
|
||||
/// macOS: Set to `true` to allow the window to be moved by dragging the background.
|
||||
///
|
||||
/// Enabling this feature can result in unexpected behaviour with draggable UI widgets such as sliders.
|
||||
#[inline]
|
||||
pub fn with_movable_by_background(mut self, value: bool) -> Self {
|
||||
|
|
@ -462,6 +466,19 @@ impl ViewportBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
/// macOS: Set to `false` to make the window render without a drop shadow.
|
||||
///
|
||||
/// The default is `true`.
|
||||
///
|
||||
/// Disabling this feature can solve ghosting issues experienced if using [`Self::with_transparent`].
|
||||
///
|
||||
/// Look at winit for more details
|
||||
#[inline]
|
||||
pub fn with_has_shadow(mut self, has_shadow: bool) -> Self {
|
||||
self.has_shadow = Some(has_shadow);
|
||||
self
|
||||
}
|
||||
|
||||
/// windows: Whether show or hide the window icon in the taskbar.
|
||||
#[inline]
|
||||
pub fn with_taskbar(mut self, show: bool) -> Self {
|
||||
|
|
@ -653,6 +670,7 @@ impl ViewportBuilder {
|
|||
title_shown: new_title_shown,
|
||||
titlebar_buttons_shown: new_titlebar_buttons_shown,
|
||||
titlebar_shown: new_titlebar_shown,
|
||||
has_shadow: new_has_shadow,
|
||||
close_button: new_close_button,
|
||||
minimize_button: new_minimize_button,
|
||||
maximize_button: new_maximize_button,
|
||||
|
|
@ -823,6 +841,11 @@ impl ViewportBuilder {
|
|||
recreate_window = true;
|
||||
}
|
||||
|
||||
if new_has_shadow.is_some() && self.has_shadow != new_has_shadow {
|
||||
self.has_shadow = new_has_shadow;
|
||||
recreate_window = true;
|
||||
}
|
||||
|
||||
if new_taskbar.is_some() && self.taskbar != new_taskbar {
|
||||
self.taskbar = new_taskbar;
|
||||
recreate_window = true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue