gpui: Add support for window transparency & blur on macOS (#9610)

This PR adds support for transparent and blurred window backgrounds on
macOS.

Release Notes:

- Added support for transparent and blurred window backgrounds on macOS
([#5040](https://github.com/zed-industries/zed/issues/5040)).
- This requires themes to specify a new `background.appearance` key
("opaque", "transparent" or "blurred") and to include an alpha value in
colors that should be transparent.

<img width="913" alt="image"
src="https://github.com/zed-industries/zed/assets/2588851/7547ee2a-e376-4d55-9114-e6fc2f5110bc">
<img width="994" alt="image"
src="https://github.com/zed-industries/zed/assets/2588851/b36fbc14-6e4d-4140-9448-69cad803c45a">
<img width="1020" alt="image"
src="https://github.com/zed-industries/zed/assets/2588851/d70e2005-54fd-4991-a211-ed484ccf26ef">

---------

Co-authored-by: Luiz Marcondes <luizgustavodevergennes@gmail.com>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
jansol 2024-03-29 17:10:47 +02:00 committed by GitHub
parent 1360dffead
commit 49144d94bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 173 additions and 17 deletions

View file

@ -1,5 +1,7 @@
use std::sync::Arc;
use gpui::WindowBackgroundAppearance;
use crate::prelude::*;
use crate::{
@ -15,6 +17,7 @@ fn zed_pro_daylight() -> Theme {
name: "Zed Pro Daylight".into(),
appearance: Appearance::Light,
styles: ThemeStyles {
window_background_appearance: WindowBackgroundAppearance::Opaque,
system: SystemColors::default(),
colors: ThemeColors::light(),
status: StatusColors::light(),
@ -45,6 +48,7 @@ pub(crate) fn zed_pro_moonlight() -> Theme {
name: "Zed Pro Moonlight".into(),
appearance: Appearance::Dark,
styles: ThemeStyles {
window_background_appearance: WindowBackgroundAppearance::Opaque,
system: SystemColors::default(),
colors: ThemeColors::dark(),
status: StatusColors::dark(),

View file

@ -1,6 +1,6 @@
use std::sync::Arc;
use gpui::{hsla, FontStyle, FontWeight, HighlightStyle};
use gpui::{hsla, FontStyle, FontWeight, HighlightStyle, WindowBackgroundAppearance};
use crate::{
default_color_scales, Appearance, PlayerColors, StatusColors, SyntaxTheme, SystemColors, Theme,
@ -39,8 +39,8 @@ pub(crate) fn one_dark() -> Theme {
id: "one_dark".to_string(),
name: "One Dark".into(),
appearance: Appearance::Dark,
styles: ThemeStyles {
window_background_appearance: WindowBackgroundAppearance::Opaque,
system: SystemColors::default(),
colors: ThemeColors {
border: hsla(225. / 360., 13. / 100., 12. / 100., 1.),

View file

@ -122,6 +122,13 @@ impl ThemeRegistry {
AppearanceContent::Light => SyntaxTheme::light(),
AppearanceContent::Dark => SyntaxTheme::dark(),
};
let window_background_appearance = user_theme
.style
.window_background_appearance
.map(Into::into)
.unwrap_or_default();
if !user_theme.style.syntax.is_empty() {
syntax_colors.highlights = user_theme
.style
@ -153,6 +160,7 @@ impl ThemeRegistry {
},
styles: ThemeStyles {
system: SystemColors::default(),
window_background_appearance,
colors: theme_colors,
status: status_colors,
player: player_colors,

View file

@ -1,5 +1,5 @@
use anyhow::Result;
use gpui::{FontStyle, FontWeight, HighlightStyle, Hsla};
use gpui::{FontStyle, FontWeight, HighlightStyle, Hsla, WindowBackgroundAppearance};
use indexmap::IndexMap;
use palette::FromColor;
use schemars::gen::SchemaGenerator;
@ -33,6 +33,25 @@ pub enum AppearanceContent {
Dark,
}
/// The background appearance of the window.
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum WindowBackgroundContent {
Opaque,
Transparent,
Blurred,
}
impl From<WindowBackgroundContent> for WindowBackgroundAppearance {
fn from(value: WindowBackgroundContent) -> Self {
match value {
WindowBackgroundContent::Opaque => WindowBackgroundAppearance::Opaque,
WindowBackgroundContent::Transparent => WindowBackgroundAppearance::Transparent,
WindowBackgroundContent::Blurred => WindowBackgroundAppearance::Blurred,
}
}
}
/// The content of a serialized theme family.
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ThemeFamilyContent {
@ -53,6 +72,9 @@ pub struct ThemeContent {
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
pub struct ThemeStyleContent {
#[serde(default, rename = "background.appearance")]
pub window_background_appearance: Option<WindowBackgroundContent>,
#[serde(flatten, default)]
pub colors: ThemeColorsContent,

View file

@ -244,6 +244,12 @@ impl ThemeSettings {
if let Some(theme_overrides) = &self.theme_overrides {
let mut base_theme = (*self.active_theme).clone();
if let Some(window_background_appearance) = theme_overrides.window_background_appearance
{
base_theme.styles.window_background_appearance =
window_background_appearance.into();
}
base_theme
.styles
.colors

View file

@ -1,4 +1,4 @@
use gpui::Hsla;
use gpui::{Hsla, WindowBackgroundAppearance};
use refineable::Refineable;
use std::sync::Arc;
@ -235,6 +235,8 @@ pub struct ThemeColors {
#[derive(Refineable, Clone)]
pub struct ThemeStyles {
/// The background appearance of the window.
pub window_background_appearance: WindowBackgroundAppearance,
pub system: SystemColors,
/// An array of colors used for theme elements that iterate through a series of colors.
///

View file

@ -27,7 +27,9 @@ pub use schema::*;
pub use settings::*;
pub use styles::*;
use gpui::{AppContext, AssetSource, Hsla, SharedString, WindowAppearance};
use gpui::{
AppContext, AssetSource, Hsla, SharedString, WindowAppearance, WindowBackgroundAppearance,
};
use serde::Deserialize;
#[derive(Debug, PartialEq, Clone, Copy, Deserialize)]
@ -158,6 +160,12 @@ impl Theme {
pub fn appearance(&self) -> Appearance {
self.appearance
}
/// Returns the [`WindowBackgroundAppearance`] for the theme.
#[inline(always)]
pub fn window_background_appearance(&self) -> WindowBackgroundAppearance {
self.styles.window_background_appearance
}
}
pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla {