linux: Indicate when the window is focused (#14266)

Mikayla Maki created

fixes #14202

Release Notes:

- Added a representation of the current focus state to Zed's window
style ([#14202](https://github.com/zed-industries/zed/issues/14202))

Change summary

assets/themes/andromeda/andromeda.json   |  1 +
assets/themes/atelier/atelier.json       | 20 ++++++++++++++++++++
assets/themes/ayu/ayu.json               |  3 +++
assets/themes/gruvbox/gruvbox.json       |  6 ++++++
assets/themes/one/one.json               |  2 ++
assets/themes/rose_pine/rose_pine.json   |  3 +++
assets/themes/sandcastle/sandcastle.json |  1 +
assets/themes/solarized/solarized.json   |  2 ++
assets/themes/summercamp/summercamp.json |  1 +
crates/gpui/src/platform/mac/platform.rs |  2 +-
crates/theme/src/default_colors.rs       |  2 ++
crates/theme/src/one_themes.rs           |  1 +
crates/theme/src/schema.rs               |  7 +++++++
crates/theme/src/styles/colors.rs        |  1 +
crates/title_bar/src/title_bar.rs        | 13 +++++++++++--
15 files changed, 62 insertions(+), 3 deletions(-)

Detailed changes

assets/themes/andromeda/andromeda.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#10a793ff",
         "status_bar.background": "#262933ff",
         "title_bar.background": "#262933ff",
+        "title_bar.inactive_background": "#21242bff",
         "toolbar.background": "#1e2025ff",
         "tab_bar.background": "#21242bff",
         "tab.inactive_background": "#21242bff",

assets/themes/atelier/atelier.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#566ddaff",
         "status_bar.background": "#3a353fff",
         "title_bar.background": "#3a353fff",
+        "title_bar.inactive_background": "#221f26ff",
         "toolbar.background": "#19171cff",
         "tab_bar.background": "#221f26ff",
         "tab.inactive_background": "#221f26ff",
@@ -422,6 +423,7 @@
         "icon.accent": "#586cdaff",
         "status_bar.background": "#bfbcc5ff",
         "title_bar.background": "#bfbcc5ff",
+        "title_bar.inactive_background": "#e6e3ebff",
         "toolbar.background": "#efecf4ff",
         "tab_bar.background": "#e6e3ebff",
         "tab.inactive_background": "#e6e3ebff",
@@ -806,6 +808,7 @@
         "icon.accent": "#6684e0ff",
         "status_bar.background": "#45433bff",
         "title_bar.background": "#45433bff",
+        "title_bar.inactive_background": "#262622ff",
         "toolbar.background": "#20201dff",
         "tab_bar.background": "#262622ff",
         "tab.inactive_background": "#262622ff",
@@ -1190,6 +1193,7 @@
         "icon.accent": "#6684dfff",
         "status_bar.background": "#cecab4ff",
         "title_bar.background": "#cecab4ff",
+        "title_bar.inactive_background": "#eeebd7ff",
         "toolbar.background": "#fefbecff",
         "tab_bar.background": "#eeebd7ff",
         "tab.inactive_background": "#eeebd7ff",
@@ -1574,6 +1578,7 @@
         "icon.accent": "#36a165ff",
         "status_bar.background": "#424136ff",
         "title_bar.background": "#424136ff",
+        "title_bar.inactive_background": "#2c2b23ff",
         "toolbar.background": "#22221bff",
         "tab_bar.background": "#2c2b23ff",
         "tab.inactive_background": "#2c2b23ff",
@@ -1958,6 +1963,7 @@
         "icon.accent": "#37a165ff",
         "status_bar.background": "#c5c4b9ff",
         "title_bar.background": "#c5c4b9ff",
+        "title_bar.inactive_background": "#ebeae3ff",
         "toolbar.background": "#f4f3ecff",
         "tab_bar.background": "#ebeae3ff",
         "tab.inactive_background": "#ebeae3ff",
@@ -2342,6 +2348,7 @@
         "icon.accent": "#407ee6ff",
         "status_bar.background": "#443c39ff",
         "title_bar.background": "#443c39ff",
+        "title_bar.inactive_background": "#27211eff",
         "toolbar.background": "#1b1918ff",
         "tab_bar.background": "#27211eff",
         "tab.inactive_background": "#27211eff",
@@ -2726,6 +2733,7 @@
         "icon.accent": "#407ee6ff",
         "status_bar.background": "#ccc7c5ff",
         "title_bar.background": "#ccc7c5ff",
+        "title_bar.inactive_background": "#e9e6e4ff",
         "toolbar.background": "#f0eeedff",
         "tab_bar.background": "#e9e6e4ff",
         "tab.inactive_background": "#e9e6e4ff",
@@ -3110,6 +3118,7 @@
         "icon.accent": "#5169ebff",
         "status_bar.background": "#433a43ff",
         "title_bar.background": "#433a43ff",
+        "title_bar.inactive_background": "#252025ff",
         "toolbar.background": "#1b181bff",
         "tab_bar.background": "#252025ff",
         "tab.inactive_background": "#252025ff",
@@ -3494,6 +3503,7 @@
         "icon.accent": "#5169ebff",
         "status_bar.background": "#c6b8c6ff",
         "title_bar.background": "#c6b8c6ff",
+        "title_bar.inactive_background": "#e0d5e0ff",
         "toolbar.background": "#f7f3f7ff",
         "tab_bar.background": "#e0d5e0ff",
         "tab.inactive_background": "#e0d5e0ff",
@@ -3878,6 +3888,7 @@
         "icon.accent": "#267eadff",
         "status_bar.background": "#33444dff",
         "title_bar.background": "#33444dff",
+        "title_bar.inactive_background": "#1c2529ff",
         "toolbar.background": "#161b1dff",
         "tab_bar.background": "#1c2529ff",
         "tab.inactive_background": "#1c2529ff",
@@ -4262,6 +4273,7 @@
         "icon.accent": "#267eadff",
         "status_bar.background": "#a6cadcff",
         "title_bar.background": "#a6cadcff",
+        "title_bar.inactive_background": "#cdeaf9ff",
         "toolbar.background": "#ebf8ffff",
         "tab_bar.background": "#cdeaf9ff",
         "tab.inactive_background": "#cdeaf9ff",
@@ -4646,6 +4658,7 @@
         "icon.accent": "#7272caff",
         "status_bar.background": "#3b3535ff",
         "title_bar.background": "#3b3535ff",
+        "title_bar.inactive_background": "#252020ff",
         "toolbar.background": "#1b1818ff",
         "tab_bar.background": "#252020ff",
         "tab.inactive_background": "#252020ff",
@@ -5030,6 +5043,7 @@
         "icon.accent": "#7272caff",
         "status_bar.background": "#c1bbbbff",
         "title_bar.background": "#c1bbbbff",
+        "title_bar.inactive_background": "#ebe3e3ff",
         "toolbar.background": "#f4ececff",
         "tab_bar.background": "#ebe3e3ff",
         "tab.inactive_background": "#ebe3e3ff",
@@ -5414,6 +5428,7 @@
         "icon.accent": "#468b8fff",
         "status_bar.background": "#353f39ff",
         "title_bar.background": "#353f39ff",
+        "title_bar.inactive_background": "#1f2621ff",
         "toolbar.background": "#171c19ff",
         "tab_bar.background": "#1f2621ff",
         "tab.inactive_background": "#1f2621ff",
@@ -5798,6 +5813,7 @@
         "icon.accent": "#488b90ff",
         "status_bar.background": "#bcc5bfff",
         "title_bar.background": "#bcc5bfff",
+        "title_bar.inactive_background": "#e3ebe6ff",
         "toolbar.background": "#ecf4eeff",
         "tab_bar.background": "#e3ebe6ff",
         "tab.inactive_background": "#e3ebe6ff",
@@ -6182,6 +6198,7 @@
         "icon.accent": "#3e62f4ff",
         "status_bar.background": "#3b453bff",
         "title_bar.background": "#3b453bff",
+        "title_bar.inactive_background": "#1f231fff",
         "toolbar.background": "#131513ff",
         "tab_bar.background": "#1f231fff",
         "tab.inactive_background": "#1f231fff",
@@ -6566,6 +6583,7 @@
         "icon.accent": "#3e61f4ff",
         "status_bar.background": "#b4ceb4ff",
         "title_bar.background": "#b4ceb4ff",
+        "title_bar.inactive_background": "#daeedaff",
         "toolbar.background": "#f3faf3ff",
         "tab_bar.background": "#daeedaff",
         "tab.inactive_background": "#daeedaff",
@@ -6950,6 +6968,7 @@
         "icon.accent": "#3e8ed0ff",
         "status_bar.background": "#3e4769ff",
         "title_bar.background": "#3e4769ff",
+        "title_bar.inactive_background": "#262f51ff",
         "toolbar.background": "#202646ff",
         "tab_bar.background": "#262f51ff",
         "tab.inactive_background": "#262f51ff",
@@ -7334,6 +7353,7 @@
         "icon.accent": "#3e8fd0ff",
         "status_bar.background": "#c1c5d8ff",
         "title_bar.background": "#c1c5d8ff",
+        "title_bar.inactive_background": "#e5e8f5ff",
         "toolbar.background": "#f5f7ffff",
         "tab_bar.background": "#e5e8f5ff",
         "tab.inactive_background": "#e5e8f5ff",

assets/themes/ayu/ayu.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#5ac1feff",
         "status_bar.background": "#313337ff",
         "title_bar.background": "#313337ff",
+        "title_bar.inactive_background": "#1f2127ff",
         "toolbar.background": "#0d1016ff",
         "tab_bar.background": "#1f2127ff",
         "tab.inactive_background": "#1f2127ff",
@@ -407,6 +408,7 @@
         "icon.accent": "#3b9ee5ff",
         "status_bar.background": "#dcdddeff",
         "title_bar.background": "#dcdddeff",
+        "title_bar.inactive_background": "#ececedff",
         "toolbar.background": "#fcfcfcff",
         "tab_bar.background": "#ececedff",
         "tab.inactive_background": "#ececedff",
@@ -776,6 +778,7 @@
         "icon.accent": "#72cffeff",
         "status_bar.background": "#464a52ff",
         "title_bar.background": "#464a52ff",
+        "title_bar.inactive_background": "#353944ff",
         "toolbar.background": "#242835ff",
         "tab_bar.background": "#353944ff",
         "tab.inactive_background": "#353944ff",

assets/themes/gruvbox/gruvbox.json 🔗

@@ -47,6 +47,7 @@
         "icon.accent": "#83a598ff",
         "status_bar.background": "#4c4642ff",
         "title_bar.background": "#4c4642ff",
+        "title_bar.inactive_background": "#3a3735ff",
         "toolbar.background": "#282828ff",
         "tab_bar.background": "#3a3735ff",
         "tab.inactive_background": "#3a3735ff",
@@ -430,6 +431,7 @@
         "icon.accent": "#83a598ff",
         "status_bar.background": "#4c4642ff",
         "title_bar.background": "#4c4642ff",
+        "title_bar.inactive_background": "#393634ff",
         "toolbar.background": "#1d2021ff",
         "tab_bar.background": "#393634ff",
         "tab.inactive_background": "#393634ff",
@@ -813,6 +815,7 @@
         "icon.accent": "#83a598ff",
         "status_bar.background": "#4c4642ff",
         "title_bar.background": "#4c4642ff",
+        "title_bar.inactive_background": "#3b3735ff",
         "toolbar.background": "#32302fff",
         "tab_bar.background": "#3b3735ff",
         "tab.inactive_background": "#3b3735ff",
@@ -1196,6 +1199,7 @@
         "icon.accent": "#0b6678ff",
         "status_bar.background": "#d9c8a4ff",
         "title_bar.background": "#d9c8a4ff",
+        "title_bar.inactive_background": "#ecddb4ff",
         "toolbar.background": "#fbf1c7ff",
         "tab_bar.background": "#ecddb4ff",
         "tab.inactive_background": "#ecddb4ff",
@@ -1579,6 +1583,7 @@
         "icon.accent": "#0b6678ff",
         "status_bar.background": "#d9c8a4ff",
         "title_bar.background": "#d9c8a4ff",
+        "title_bar.inactive_background": "#ecddb5ff",
         "toolbar.background": "#f9f5d7ff",
         "tab_bar.background": "#ecddb5ff",
         "tab.inactive_background": "#ecddb5ff",
@@ -1962,6 +1967,7 @@
         "icon.accent": "#0b6678ff",
         "status_bar.background": "#d9c8a4ff",
         "title_bar.background": "#d9c8a4ff",
+        "title_bar.inactive_background": "#ecdcb3ff",
         "toolbar.background": "#f2e5bcff",
         "tab_bar.background": "#ecdcb3ff",
         "tab.inactive_background": "#ecdcb3ff",

assets/themes/one/one.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#74ade8ff",
         "status_bar.background": "#3b414dff",
         "title_bar.background": "#3b414dff",
+        "title_bar.inactive_background": "#2e343eff",
         "toolbar.background": "#282c33ff",
         "tab_bar.background": "#2f343eff",
         "tab.inactive_background": "#2f343eff",
@@ -412,6 +413,7 @@
         "icon.accent": "#5c78e2ff",
         "status_bar.background": "#dcdcddff",
         "title_bar.background": "#dcdcddff",
+        "title_bar.inactive_background": "#ebebecff",
         "toolbar.background": "#fafafaff",
         "tab_bar.background": "#ebebecff",
         "tab.inactive_background": "#ebebecff",

assets/themes/rose_pine/rose_pine.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#9bced6ff",
         "status_bar.background": "#292738ff",
         "title_bar.background": "#292738ff",
+        "title_bar.inactive_background": "#1c1b2aff",
         "toolbar.background": "#191724ff",
         "tab_bar.background": "#1c1b2aff",
         "tab.inactive_background": "#1c1b2aff",
@@ -417,6 +418,7 @@
         "icon.accent": "#57949fff",
         "status_bar.background": "#dcd8d8ff",
         "title_bar.background": "#dcd8d8ff",
+        "title_bar.inactive_background": "#fef9f2ff",
         "toolbar.background": "#faf4edff",
         "tab_bar.background": "#fef9f2ff",
         "tab.inactive_background": "#fef9f2ff",
@@ -796,6 +798,7 @@
         "icon.accent": "#9bced6ff",
         "status_bar.background": "#38354eff",
         "title_bar.background": "#38354eff",
+        "title_bar.inactive_background": "#28253cff",
         "toolbar.background": "#232136ff",
         "tab_bar.background": "#28253cff",
         "tab.inactive_background": "#28253cff",

assets/themes/sandcastle/sandcastle.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#518b8bff",
         "status_bar.background": "#333944ff",
         "title_bar.background": "#333944ff",
+        "title_bar.inactive_background": "#2b3038ff",
         "toolbar.background": "#282c33ff",
         "tab_bar.background": "#2b3038ff",
         "tab.inactive_background": "#2b3038ff",

assets/themes/solarized/solarized.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#278ad1ff",
         "status_bar.background": "#073743ff",
         "title_bar.background": "#073743ff",
+        "title_bar.inactive_background": "#04313bff",
         "toolbar.background": "#002a35ff",
         "tab_bar.background": "#04313bff",
         "tab.inactive_background": "#04313bff",
@@ -407,6 +408,7 @@
         "icon.accent": "#288bd1ff",
         "status_bar.background": "#cfd0c4ff",
         "title_bar.background": "#cfd0c4ff",
+        "title_bar.inactive_background": "#f3eddaff",
         "toolbar.background": "#fdf6e3ff",
         "tab_bar.background": "#f3eddaff",
         "tab.inactive_background": "#f3eddaff",

assets/themes/summercamp/summercamp.json 🔗

@@ -38,6 +38,7 @@
         "icon.accent": "#499befff",
         "status_bar.background": "#2a261cff",
         "title_bar.background": "#2a261cff",
+        "title_bar.inactive_background": "#231f16ff",
         "toolbar.background": "#1b1810ff",
         "tab_bar.background": "#231f16ff",
         "tab.inactive_background": "#231f16ff",

crates/gpui/src/platform/mac/platform.rs 🔗

@@ -797,7 +797,7 @@ impl Platform for MacPlatform {
                 CursorStyle::OpenHand => msg_send![class!(NSCursor), openHandCursor],
                 CursorStyle::PointingHand => msg_send![class!(NSCursor), pointingHandCursor],
                 CursorStyle::ResizeLeftRight => msg_send![class!(NSCursor), resizeLeftRightCursor],
-                CursorStyle::ResizeUpDown => msg_send![class!(NSCursor), verticalResizeCursor],
+                CursorStyle::ResizeUpDown => msg_send![class!(NSCursor), resizeUpDownCursor],
                 CursorStyle::ResizeLeft => msg_send![class!(NSCursor), resizeLeftCursor],
                 CursorStyle::ResizeRight => msg_send![class!(NSCursor), resizeRightCursor],
                 CursorStyle::ResizeColumn => msg_send![class!(NSCursor), resizeLeftRightCursor],

crates/theme/src/default_colors.rs 🔗

@@ -50,6 +50,7 @@ impl ThemeColors {
             icon_accent: blue().light().step_11(),
             status_bar_background: neutral().light().step_2(),
             title_bar_background: neutral().light().step_2(),
+            title_bar_inactive_background: neutral().light_alpha().step_3(),
             toolbar_background: neutral().light().step_1(),
             tab_bar_background: neutral().light().step_2(),
             tab_inactive_background: neutral().light().step_2(),
@@ -147,6 +148,7 @@ impl ThemeColors {
             icon_accent: blue().dark().step_11(),
             status_bar_background: neutral().dark().step_2(),
             title_bar_background: neutral().dark().step_2(),
+            title_bar_inactive_background: neutral().dark_alpha().step_3(),
             toolbar_background: neutral().dark().step_1(),
             tab_bar_background: neutral().dark().step_2(),
             tab_inactive_background: neutral().dark().step_2(),

crates/theme/src/one_themes.rs 🔗

@@ -76,6 +76,7 @@ pub(crate) fn one_dark() -> Theme {
                 icon_accent: blue,
                 status_bar_background: bg,
                 title_bar_background: bg,
+                title_bar_inactive_background: SystemColors::default().transparent,
                 toolbar_background: editor,
                 tab_bar_background: bg,
                 tab_inactive_background: bg,

crates/theme/src/schema.rs 🔗

@@ -300,6 +300,9 @@ pub struct ThemeColorsContent {
     #[serde(rename = "title_bar.background")]
     pub title_bar_background: Option<String>,
 
+    #[serde(rename = "title_bar.inactive_background")]
+    pub title_bar_inactive_background: Option<String>,
+
     #[serde(rename = "toolbar.background")]
     pub toolbar_background: Option<String>,
 
@@ -663,6 +666,10 @@ impl ThemeColorsContent {
                 .title_bar_background
                 .as_ref()
                 .and_then(|color| try_parse_color(color).ok()),
+            title_bar_inactive_background: self
+                .title_bar_inactive_background
+                .as_ref()
+                .and_then(|color| try_parse_color(color).ok()),
             toolbar_background: self
                 .toolbar_background
                 .as_ref()

crates/theme/src/styles/colors.rs 🔗

@@ -113,6 +113,7 @@ pub struct ThemeColors {
     // ===
     pub status_bar_background: Hsla,
     pub title_bar_background: Hsla,
+    pub title_bar_inactive_background: Hsla,
     pub toolbar_background: Hsla,
     pub tab_bar_background: Hsla,
     pub tab_inactive_background: Hsla,

crates/title_bar/src/title_bar.rs 🔗

@@ -73,6 +73,15 @@ impl Render for TitleBar {
         let height = Self::height(cx);
         let supported_controls = cx.window_controls();
         let decorations = cx.window_decorations();
+        let titlebar_color = if cfg!(target_os = "linux") {
+            if cx.is_window_active() {
+                cx.theme().colors().title_bar_background
+            } else {
+                cx.theme().colors().title_bar_inactive_background
+            }
+        } else {
+            cx.theme().colors().title_bar_background
+        };
 
         h_flex()
             .id("titlebar")
@@ -99,9 +108,9 @@ impl Render for TitleBar {
                     // this border is to avoid a transparent gap in the rounded corners
                     .mt(px(-1.))
                     .border(px(1.))
-                    .border_color(cx.theme().colors().title_bar_background),
+                    .border_color(titlebar_color),
             })
-            .bg(cx.theme().colors().title_bar_background)
+            .bg(titlebar_color)
             .content_stretch()
             .child(
                 div()