summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-12-21 06:40:22 +0000
committerGitHub <noreply@github.com>2020-12-21 06:40:22 +0000
commit5725f5812ca5e8d7d992da4ac66aa454a8a9a9ad (patch)
tree9f15030007cb7a7f66c95640623f74e735754152
parent6e1b9d8b2502f5b47dc28eb5e0853e46ad8b4e84 (diff)
downloadalacritty-5725f5812ca5e8d7d992da4ac66aa454a8a9a9ad.tar.gz
alacritty-5725f5812ca5e8d7d992da4ac66aa454a8a9a9ad.zip
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.
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.lock2
-rw-r--r--alacritty/Cargo.toml2
-rw-r--r--alacritty/src/display.rs6
-rw-r--r--alacritty/src/window.rs19
5 files changed, 30 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae6deaea..d9701053 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/Cargo.lock b/Cargo.lock
index f3aa5acd..f9b53890 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml
index 6e833f34..4810ced4 100644
--- a/alacritty/Cargo.toml
+++ b/alacritty/Cargo.toml
@@ -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]
diff --git a/alacritty/src/display.rs b/alacritty/src/display.rs
index 1fe1d2de..fb82b9f8 100644
--- a/alacritty/src/display.rs
+++ b/alacritty/src/display.rs
@@ -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))))]
diff --git a/alacritty/src/window.rs b/alacritty/src/window.rs
index f4a38183..1b874d15 100644
--- a/alacritty/src/window.rs
+++ b/alacritty/src/window.rs
@@ -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()
}