Fix artifacts on macOS with transparent windows

Due to the way macOS draws shadows for transparent windows, resizing
them will lead to text artifacts remaining present after a window has
been resized.

The `invalidateShadow` call is used whenever the opacity isn't `1.0` to
make sure these shadows are cleared before redrawing, so no artifacts
remain when resizing transparent windows.

Fixes #889.
This commit is contained in:
Christian Duerr 2020-12-21 06:40:22 +00:00 committed by GitHub
parent 6e1b9d8b25
commit 5725f5812c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 0 deletions

View File

@ -42,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- High CPU usage on BSD with live config reload enabled
- Alacritty not discarding invalid escape sequences starting with ESC
- Crash due to clipboard not being properly released on Wayland
- Shadow artifacts when resizing transparent windows on macOS
### Removed

2
Cargo.lock generated
View File

@ -29,6 +29,7 @@ dependencies = [
"alacritty_terminal",
"bitflags",
"clap",
"cocoa 0.24.0",
"copypasta",
"crossfont",
"dirs",
@ -42,6 +43,7 @@ dependencies = [
"objc",
"parking_lot",
"png",
"raw-window-handle",
"serde",
"serde_json",
"serde_yaml",

View File

@ -46,6 +46,8 @@ xdg = "2"
png = { version = "0.16.8", default-features = false, optional = true }
[target.'cfg(target_os = "macos")'.dependencies]
raw-window-handle = "0.3.3"
cocoa = "0.24.0"
objc = "0.2.2"
[target.'cfg(not(any(target_os="windows", target_os="macos")))'.dependencies]

View File

@ -610,6 +610,12 @@ 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

@ -31,6 +31,8 @@ use {
use std::fmt::{self, Display, Formatter};
#[cfg(target_os = "macos")]
use cocoa::base::id;
use glutin::dpi::{PhysicalPosition, PhysicalSize};
use glutin::event_loop::EventLoop;
#[cfg(target_os = "macos")]
@ -41,6 +43,10 @@ use glutin::window::{
CursorIcon, Fullscreen, UserAttentionType, Window as GlutinWindow, WindowBuilder, WindowId,
};
use glutin::{self, ContextBuilder, PossiblyCurrent, WindowedContext};
#[cfg(target_os = "macos")]
use objc::{msg_send, sel, sel_impl};
#[cfg(target_os = "macos")]
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
#[cfg(windows)]
use winapi::shared::minwindef::WORD;
@ -435,6 +441,19 @@ impl Window {
self.windowed_context.resize(size);
}
/// Force macOS to clear shadow of transparent windows.
#[cfg(target_os = "macos")]
pub fn invalidate_shadow(&self) {
let raw_window = match self.window().raw_window_handle() {
RawWindowHandle::MacOS(handle) => handle.ns_window as id,
_ => return,
};
unsafe {
let _: () = msg_send![raw_window, invalidateShadow];
}
}
fn window(&self) -> &GlutinWindow {
self.windowed_context.window()
}