Disable shadows for transparent windows on macOS

Commit 5725f58 introduced a performance regression on macOS due to
excessive calls to the `invalidateShadow` function, however calling this
function only on redraw after a resize was performed does not fix the
underlying problem.

As a solution, window shadows are now disabled completely for all
transparent windows. This makes sure there is no performance impact,
while still solving the problem with text artifacts on resize.

Fixes #4604.
This commit is contained in:
Christian Duerr 2020-12-22 04:25:43 +00:00 committed by GitHub
parent 8982000f01
commit f19cbca9b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 10 deletions

View File

@ -254,6 +254,10 @@ impl Display {
#[cfg(target_os = "macos")]
crossfont::set_font_smoothing(config.ui_config.font.use_thin_strokes);
// Disable shadows for transparent windows on macOS.
#[cfg(target_os = "macos")]
window.set_has_shadow(config.ui_config.background_opacity() >= 1.0);
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
let is_x11 = event_loop.is_x11();
#[cfg(not(any(feature = "x11", target_os = "macos", windows)))]
@ -610,12 +614,6 @@ impl Display {
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
self.request_frame(&self.window);
// Clear window shadows to prevent shadow artifacts on macOS.
#[cfg(target_os = "macos")]
if config.ui_config.background_opacity() < 1.0 {
self.window.invalidate_shadow();
}
self.window.swap_buffers();
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]

View File

@ -1279,6 +1279,10 @@ impl<N: Notify + OnResize> Processor<N> {
#[cfg(target_os = "macos")]
crossfont::set_font_smoothing(config.ui_config.font.use_thin_strokes);
// Disable shadows for transparent windows on macOS.
#[cfg(target_os = "macos")]
processor.ctx.window.set_has_shadow(config.ui_config.background_opacity() >= 1.0);
*processor.ctx.config = config;
// Update cursor blinking.

View File

@ -32,7 +32,7 @@ use {
use std::fmt::{self, Display, Formatter};
#[cfg(target_os = "macos")]
use cocoa::base::id;
use cocoa::base::{id, NO, YES};
use glutin::dpi::{PhysicalPosition, PhysicalSize};
use glutin::event_loop::EventLoop;
#[cfg(target_os = "macos")]
@ -441,16 +441,19 @@ impl Window {
self.windowed_context.resize(size);
}
/// Force macOS to clear shadow of transparent windows.
/// Disable macOS window shadows.
///
/// This prevents rendering artifacts from showing up when the window is transparent.
#[cfg(target_os = "macos")]
pub fn invalidate_shadow(&self) {
pub fn set_has_shadow(&self, has_shadows: bool) {
let raw_window = match self.window().raw_window_handle() {
RawWindowHandle::MacOS(handle) => handle.ns_window as id,
_ => return,
};
let value = if has_shadows { YES } else { NO };
unsafe {
let _: () = msg_send![raw_window, invalidateShadow];
let _: () = msg_send![raw_window, setHasShadow: value];
}
}