Detailed changes
@@ -362,7 +362,9 @@
// Whether to show user picture in the titlebar.
"show_user_picture": true,
// Whether to show the sign in button in the titlebar.
- "show_sign_in": true
+ "show_sign_in": true,
+ // Whether to show the menus in the titlebar.
+ "show_menus": false
},
// Scrollbar related settings
"scrollbar": {
@@ -7,7 +7,7 @@ use super::{
use crate::{
Action, AnyWindowHandle, BackgroundExecutor, ClipboardEntry, ClipboardItem, ClipboardString,
CursorStyle, ForegroundExecutor, Image, ImageFormat, KeyContext, Keymap, MacDispatcher,
- MacDisplay, MacWindow, Menu, MenuItem, PathPromptOptions, Platform, PlatformDisplay,
+ MacDisplay, MacWindow, Menu, MenuItem, OwnedMenu, PathPromptOptions, Platform, PlatformDisplay,
PlatformKeyboardLayout, PlatformTextSystem, PlatformWindow, Result, SemanticVersion, Task,
WindowAppearance, WindowParams, hash,
};
@@ -170,6 +170,7 @@ pub(crate) struct MacPlatformState {
open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
finish_launching: Option<Box<dyn FnOnce()>>,
dock_menu: Option<id>,
+ menus: Option<Vec<OwnedMenu>>,
}
impl Default for MacPlatform {
@@ -207,6 +208,7 @@ impl MacPlatform {
finish_launching: None,
dock_menu: None,
on_keyboard_layout_change: None,
+ menus: None,
}))
}
@@ -226,7 +228,7 @@ impl MacPlatform {
unsafe fn create_menu_bar(
&self,
- menus: Vec<Menu>,
+ menus: &Vec<Menu>,
delegate: id,
actions: &mut Vec<Box<dyn Action>>,
keymap: &Keymap,
@@ -241,7 +243,7 @@ impl MacPlatform {
menu.setTitle_(menu_title);
menu.setDelegate_(delegate);
- for item_config in menu_config.items {
+ for item_config in &menu_config.items {
menu.addItem_(Self::create_menu_item(
item_config,
delegate,
@@ -277,7 +279,7 @@ impl MacPlatform {
dock_menu.setDelegate_(delegate);
for item_config in menu_items {
dock_menu.addItem_(Self::create_menu_item(
- item_config,
+ &item_config,
delegate,
actions,
keymap,
@@ -289,7 +291,7 @@ impl MacPlatform {
}
unsafe fn create_menu_item(
- item: MenuItem,
+ item: &MenuItem,
delegate: id,
actions: &mut Vec<Box<dyn Action>>,
keymap: &Keymap,
@@ -399,7 +401,7 @@ impl MacPlatform {
let tag = actions.len() as NSInteger;
let _: () = msg_send![item, setTag: tag];
- actions.push(action);
+ actions.push(action.boxed_clone());
item
}
MenuItem::Submenu(Menu { name, items }) => {
@@ -865,10 +867,15 @@ impl Platform for MacPlatform {
let app: id = msg_send![APP_CLASS, sharedApplication];
let mut state = self.0.lock();
let actions = &mut state.menu_actions;
- let menu = self.create_menu_bar(menus, NSWindow::delegate(app), actions, keymap);
+ let menu = self.create_menu_bar(&menus, NSWindow::delegate(app), actions, keymap);
drop(state);
app.setMainMenu_(menu);
}
+ self.0.lock().menus = Some(menus.into_iter().map(|menu| menu.owned()).collect());
+ }
+
+ fn get_menus(&self) -> Option<Vec<OwnedMenu>> {
+ self.0.lock().menus.clone()
}
fn set_dock_menu(&self, menu: Vec<MenuItem>, keymap: &Keymap) {
@@ -1,4 +1,5 @@
use gpui::{Entity, OwnedMenu, OwnedMenuItem};
+use settings::Settings;
#[cfg(not(target_os = "macos"))]
use gpui::{Action, actions};
@@ -11,6 +12,8 @@ use serde::Deserialize;
use smallvec::SmallVec;
use ui::{ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
+use crate::title_bar_settings::TitleBarSettings;
+
#[cfg(not(target_os = "macos"))]
actions!(
app_menu,
@@ -242,15 +245,21 @@ impl ApplicationMenu {
cx.defer_in(window, move |_, window, cx| next_handle.show(window, cx));
}
- pub fn all_menus_shown(&self) -> bool {
- self.entries.iter().any(|entry| entry.handle.is_deployed())
+ pub fn all_menus_shown(&self, cx: &mut Context<Self>) -> bool {
+ show_menus(cx)
+ || self.entries.iter().any(|entry| entry.handle.is_deployed())
|| self.pending_menu_open.is_some()
}
}
+pub(crate) fn show_menus(cx: &mut App) -> bool {
+ TitleBarSettings::get_global(cx).show_menus
+ && (cfg!(not(target_os = "macos")) || option_env!("ZED_USE_CROSS_PLATFORM_MENU").is_some())
+}
+
impl Render for ApplicationMenu {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let all_menus_shown = self.all_menus_shown();
+ let all_menus_shown = self.all_menus_shown(cx);
if let Some(pending_menu_open) = self.pending_menu_open.take() {
if let Some(entry) = self
@@ -1,6 +1,6 @@
use gpui::{
- AnyElement, Context, Decorations, InteractiveElement, IntoElement, MouseButton, ParentElement,
- Pixels, StatefulInteractiveElement, Styled, Window, WindowControlArea, div, px,
+ AnyElement, Context, Decorations, Hsla, InteractiveElement, IntoElement, MouseButton,
+ ParentElement, Pixels, StatefulInteractiveElement, Styled, Window, WindowControlArea, div, px,
};
use smallvec::SmallVec;
use std::mem;
@@ -37,6 +37,18 @@ impl PlatformTitleBar {
px(32.)
}
+ pub fn title_bar_color(&self, window: &mut Window, cx: &mut Context<Self>) -> Hsla {
+ if cfg!(any(target_os = "linux", target_os = "freebsd")) {
+ if window.is_window_active() && !self.should_move {
+ cx.theme().colors().title_bar_background
+ } else {
+ cx.theme().colors().title_bar_inactive_background
+ }
+ } else {
+ cx.theme().colors().title_bar_background
+ }
+ }
+
pub fn set_children<T>(&mut self, children: T)
where
T: IntoIterator<Item = AnyElement>,
@@ -50,15 +62,7 @@ impl Render for PlatformTitleBar {
let supported_controls = window.window_controls();
let decorations = window.window_decorations();
let height = Self::height(window);
- let titlebar_color = if cfg!(any(target_os = "linux", target_os = "freebsd")) {
- if window.is_window_active() && !self.should_move {
- cx.theme().colors().title_bar_background
- } else {
- cx.theme().colors().title_bar_inactive_background
- }
- } else {
- cx.theme().colors().title_bar_background
- };
+ let titlebar_color = self.title_bar_color(window, cx);
let close_action = Box::new(workspace::CloseWindow);
let children = mem::take(&mut self.children);
@@ -8,7 +8,10 @@ mod title_bar_settings;
#[cfg(feature = "stories")]
mod stories;
-use crate::{application_menu::ApplicationMenu, platform_title_bar::PlatformTitleBar};
+use crate::{
+ application_menu::{ApplicationMenu, show_menus},
+ platform_title_bar::PlatformTitleBar,
+};
#[cfg(not(target_os = "macos"))]
use crate::application_menu::{
@@ -133,6 +136,8 @@ impl Render for TitleBar {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let title_bar_settings = *TitleBarSettings::get_global(cx);
+ let show_menus = show_menus(cx);
+
let mut children = Vec::new();
children.push(
@@ -142,10 +147,14 @@ impl Render for TitleBar {
let mut render_project_items = title_bar_settings.show_branch_name
|| title_bar_settings.show_project_items;
title_bar
- .when_some(self.application_menu.clone(), |title_bar, menu| {
- render_project_items &= !menu.read(cx).all_menus_shown();
- title_bar.child(menu)
- })
+ .when_some(
+ self.application_menu.clone().filter(|_| !show_menus),
+ |title_bar, menu| {
+ render_project_items &=
+ !menu.update(cx, |menu, cx| menu.all_menus_shown(cx));
+ title_bar.child(menu)
+ },
+ )
.when(render_project_items, |title_bar| {
title_bar
.when(title_bar_settings.show_project_items, |title_bar| {
@@ -190,11 +199,39 @@ impl Render for TitleBar {
.into_any_element(),
);
- self.platform_titlebar.update(cx, |this, _| {
- this.set_children(children);
- });
+ if show_menus {
+ self.platform_titlebar.update(cx, |this, _| {
+ this.set_children(
+ self.application_menu
+ .clone()
+ .map(|menu| menu.into_any_element()),
+ );
+ });
- self.platform_titlebar.clone().into_any_element()
+ let height = PlatformTitleBar::height(window);
+ let title_bar_color = self.platform_titlebar.update(cx, |platform_titlebar, cx| {
+ platform_titlebar.title_bar_color(window, cx)
+ });
+
+ v_flex()
+ .w_full()
+ .child(self.platform_titlebar.clone().into_any_element())
+ .child(
+ h_flex()
+ .bg(title_bar_color)
+ .h(height)
+ .pl_2()
+ .justify_between()
+ .w_full()
+ .children(children),
+ )
+ .into_any_element()
+ } else {
+ self.platform_titlebar.update(cx, |this, _| {
+ this.set_children(children);
+ });
+ self.platform_titlebar.clone().into_any_element()
+ }
}
}
@@ -11,6 +11,7 @@ pub struct TitleBarSettings {
pub show_branch_name: bool,
pub show_project_items: bool,
pub show_sign_in: bool,
+ pub show_menus: bool,
}
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
@@ -39,6 +40,10 @@ pub struct TitleBarSettingsContent {
///
/// Default: true
pub show_sign_in: Option<bool>,
+ /// Whether to show the menus in the title bar.
+ ///
+ /// Default: false
+ pub show_menus: Option<bool>,
}
impl Settings for TitleBarSettings {
@@ -112,7 +112,8 @@ To disable this behavior use:
"show_project_items": true, // Show/hide project host and name
"show_onboarding_banner": true, // Show/hide onboarding banners
"show_user_picture": true, // Show/hide user avatar
- "show_sign_in": true // Show/hide sign-in button
+ "show_sign_in": true, // Show/hide sign-in button
+ "show_menus": false // Show/hide menus
},
```