Skip to content

Commit

Permalink
Add "new window" option to the dock menu
Browse files Browse the repository at this point in the history
Fixes: #11651
Co-Authored-By: versecafe <147033096+versecafe@users.noreply.github.com>
  • Loading branch information
ConradIrwin and versecafe committed May 20, 2024
1 parent 3a79aa8 commit fb30e91
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 4 deletions.
9 changes: 7 additions & 2 deletions crates/gpui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ use crate::{
current_platform, init_app_menus, Action, ActionRegistry, Any, AnyView, AnyWindowHandle,
AppMetadata, AssetCache, AssetSource, BackgroundExecutor, ClipboardItem, Context,
DispatchPhase, DisplayId, Entity, EventEmitter, ForegroundExecutor, Global, KeyBinding, Keymap,
Keystroke, LayoutId, Menu, PathPromptOptions, Pixels, Platform, PlatformDisplay, Point,
PromptBuilder, PromptHandle, PromptLevel, Render, RenderablePromptHandle, Reservation,
Keystroke, LayoutId, Menu, MenuItem, PathPromptOptions, Pixels, Platform, PlatformDisplay,
Point, PromptBuilder, PromptHandle, PromptLevel, Render, RenderablePromptHandle, Reservation,
SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextSystem, View, ViewContext,
Window, WindowAppearance, WindowContext, WindowHandle, WindowId,
};
Expand Down Expand Up @@ -1167,6 +1167,11 @@ impl AppContext {
self.platform.set_menus(menus, &self.keymap.borrow());
}

/// Sets the right click menu for the app icon in the dock
pub fn set_dock_menu(&mut self, menus: Vec<MenuItem>) {
self.platform.set_dock_menu(menus, &self.keymap.borrow());
}

/// Adds given path to the bottom of the list of recent paths for the application.
/// The list is usually shown on the application icon's context menu in the dock,
/// and allows to open the recent files via that context menu.
Expand Down
1 change: 1 addition & 0 deletions crates/gpui/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ pub(crate) trait Platform: 'static {
fn on_reopen(&self, callback: Box<dyn FnMut()>);

fn set_menus(&self, menus: Vec<Menu>, keymap: &Keymap);
fn set_dock_menu(&self, menu: Vec<MenuItem>, keymap: &Keymap);
fn add_recent_document(&self, _path: &Path) {}
fn on_app_menu_action(&self, callback: Box<dyn FnMut(&dyn Action)>);
fn on_will_open_app_menu(&self, callback: Box<dyn FnMut()>);
Expand Down
1 change: 1 addition & 0 deletions crates/gpui/src/platform/linux/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ impl<P: LinuxClient + 'static> Platform for P {

// todo(linux)
fn set_menus(&self, menus: Vec<Menu>, keymap: &Keymap) {}
fn set_dock_menu(&self, menu: Vec<MenuItem>, keymap: &Keymap) {}

fn local_timezone(&self) -> UtcOffset {
UtcOffset::UTC
Expand Down
53 changes: 52 additions & 1 deletion crates/gpui/src/platform/mac/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use cocoa::{
},
};
use core_foundation::{
base::{CFType, CFTypeRef, OSStatus, TCFType as _},
base::{CFRelease, CFType, CFTypeRef, OSStatus, TCFType as _},
boolean::CFBoolean,
data::CFData,
dictionary::{CFDictionary, CFDictionaryRef, CFMutableDictionary},
Expand Down Expand Up @@ -120,6 +120,10 @@ unsafe fn build_classes() {
sel!(menuWillOpen:),
menu_will_open as extern "C" fn(&mut Object, Sel, id),
);
decl.add_method(
sel!(applicationDockMenu:),
handle_dock_menu as extern "C" fn(&mut Object, Sel, id) -> id,
);
decl.add_method(
sel!(application:openURLs:),
open_urls as extern "C" fn(&mut Object, Sel, id, id),
Expand Down Expand Up @@ -147,6 +151,7 @@ pub(crate) struct MacPlatformState {
menu_actions: Vec<Box<dyn Action>>,
open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
finish_launching: Option<Box<dyn FnOnce()>>,
dock_menu: Option<id>,
}

impl Default for MacPlatform {
Expand Down Expand Up @@ -174,6 +179,7 @@ impl MacPlatform {
menu_actions: Default::default(),
open_urls: None,
finish_launching: None,
dock_menu: None,
}))
}

Expand Down Expand Up @@ -226,6 +232,27 @@ impl MacPlatform {
application_menu
}

unsafe fn create_dock_menu(
&self,
menu_items: Vec<MenuItem>,
delegate: id,
actions: &mut Vec<Box<dyn Action>>,
keymap: &Keymap,
) -> id {
let dock_menu = NSMenu::new(nil);
dock_menu.setDelegate_(delegate);
for item_config in menu_items {
dock_menu.addItem_(Self::create_menu_item(
item_config,
delegate,
actions,
keymap,
));
}

dock_menu
}

unsafe fn create_menu_item(
item: MenuItem,
delegate: id,
Expand Down Expand Up @@ -731,6 +758,18 @@ impl Platform for MacPlatform {
}
}

fn set_dock_menu<'a>(&self, menu: Vec<MenuItem<'a>>, keymap: &Keymap) {
unsafe {
let app: id = msg_send![APP_CLASS, sharedApplication];
let mut state = self.0.lock();
let actions = &mut state.menu_actions;
let new = self.create_dock_menu(menu, app.delegate(), actions, keymap);
if let Some(old) = state.dock_menu.replace(new) {
CFRelease(old as _)
}
}
}

fn add_recent_document(&self, path: &Path) {
if let Some(path_str) = path.to_str() {
unsafe {
Expand Down Expand Up @@ -1128,6 +1167,18 @@ extern "C" fn menu_will_open(this: &mut Object, _: Sel, _: id) {
}
}

extern "C" fn handle_dock_menu(this: &mut Object, _: Sel, _: id) -> id {
unsafe {
let platform = get_mac_platform(this);
let mut state = platform.0.lock();
if let Some(id) = state.dock_menu {
id
} else {
nil
}
}
}

unsafe fn ns_string(string: &str) -> id {
NSString::alloc(nil).init_str(string).autorelease()
}
Expand Down
1 change: 1 addition & 0 deletions crates/gpui/src/platform/test/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ impl Platform for TestPlatform {
}

fn set_menus(&self, _menus: Vec<crate::Menu>, _keymap: &Keymap) {}
fn set_dock_menu(&self, _menu: Vec<crate::MenuItem>, _keymap: &Keymap) {}

fn add_recent_document(&self, _paths: &Path) {}

Expand Down
1 change: 1 addition & 0 deletions crates/gpui/src/platform/windows/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ impl Platform for WindowsPlatform {

// todo(windows)
fn set_menus(&self, menus: Vec<Menu>, keymap: &Keymap) {}
fn set_dock_menu(&self, menus: Vec<MenuItem>, keymap: &Keymap) {}

fn on_app_menu_action(&self, callback: Box<dyn FnMut(&dyn Action)>) {
self.state.borrow_mut().callbacks.app_menu_action = Some(callback);
Expand Down
3 changes: 2 additions & 1 deletion crates/zed/src/zed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use client::ZED_URL_SCHEME;
use collections::VecDeque;
use editor::{scroll::Autoscroll, Editor, MultiBuffer};
use gpui::{
actions, point, px, AppContext, AsyncAppContext, Context, FocusableView, PromptLevel,
actions, point, px, AppContext, AsyncAppContext, Context, FocusableView, MenuItem, PromptLevel,
TitlebarOptions, View, ViewContext, VisualContext, WindowKind, WindowOptions,
};
pub use open_listener::*;
Expand Down Expand Up @@ -670,6 +670,7 @@ fn reload_keymaps(cx: &mut AppContext, keymap_content: &KeymapFile) {
load_default_keymap(cx);
keymap_content.clone().add_to_cx(cx).log_err();
cx.set_menus(app_menus());
cx.set_dock_menu(vec![MenuItem::action("New Window", workspace::NewWindow)])
}

pub fn load_default_keymap(cx: &mut AppContext) {
Expand Down

0 comments on commit fb30e91

Please sign in to comment.