mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-25 01:34:02 +00:00
Rename MainThreadPlatform to ForegroundPlatform and fix crash on quit
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
6daddf5146
commit
3a932cc9bf
5 changed files with 68 additions and 67 deletions
|
@ -107,7 +107,7 @@ pub struct AsyncAppContext(Rc<RefCell<MutableAppContext>>);
|
|||
#[derive(Clone)]
|
||||
pub struct TestAppContext {
|
||||
cx: Rc<RefCell<MutableAppContext>>,
|
||||
main_thread_platform: Rc<platform::test::MainThreadPlatform>,
|
||||
foreground_platform: Rc<platform::test::ForegroundPlatform>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -115,13 +115,13 @@ impl App {
|
|||
asset_source: A,
|
||||
f: F,
|
||||
) -> T {
|
||||
let main_thread_platform = platform::test::main_thread_platform();
|
||||
let foreground_platform = platform::test::foreground_platform();
|
||||
let platform = platform::test::platform();
|
||||
let foreground = Rc::new(executor::Foreground::test());
|
||||
let cx = Rc::new(RefCell::new(MutableAppContext::new(
|
||||
foreground,
|
||||
Arc::new(platform),
|
||||
Rc::new(main_thread_platform),
|
||||
Rc::new(foreground_platform),
|
||||
asset_source,
|
||||
)));
|
||||
cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx));
|
||||
|
@ -135,16 +135,16 @@ impl App {
|
|||
F: Future<Output = T>,
|
||||
{
|
||||
let platform = Arc::new(platform::test::platform());
|
||||
let main_thread_platform = Rc::new(platform::test::main_thread_platform());
|
||||
let foreground_platform = Rc::new(platform::test::foreground_platform());
|
||||
let foreground = Rc::new(executor::Foreground::test());
|
||||
let cx = TestAppContext {
|
||||
cx: Rc::new(RefCell::new(MutableAppContext::new(
|
||||
foreground.clone(),
|
||||
platform,
|
||||
main_thread_platform.clone(),
|
||||
foreground_platform.clone(),
|
||||
asset_source,
|
||||
))),
|
||||
main_thread_platform,
|
||||
foreground_platform,
|
||||
};
|
||||
cx.cx.borrow_mut().weak_self = Some(Rc::downgrade(&cx.cx));
|
||||
|
||||
|
@ -154,17 +154,17 @@ impl App {
|
|||
|
||||
pub fn new(asset_source: impl AssetSource) -> Result<Self> {
|
||||
let platform = platform::current::platform();
|
||||
let main_thread_platform = platform::current::main_thread_platform();
|
||||
let foreground_platform = platform::current::foreground_platform();
|
||||
let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
|
||||
let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
|
||||
foreground,
|
||||
platform.clone(),
|
||||
main_thread_platform.clone(),
|
||||
foreground_platform.clone(),
|
||||
asset_source,
|
||||
))));
|
||||
|
||||
let cx = app.0.clone();
|
||||
main_thread_platform.on_menu_command(Box::new(move |command, arg| {
|
||||
foreground_platform.on_menu_command(Box::new(move |command, arg| {
|
||||
let mut cx = cx.borrow_mut();
|
||||
if let Some(key_window_id) = cx.platform.key_window_id() {
|
||||
if let Some((presenter, _)) = cx.presenters_and_platform_windows.get(&key_window_id)
|
||||
|
@ -191,7 +191,7 @@ impl App {
|
|||
let cx = self.0.clone();
|
||||
self.0
|
||||
.borrow_mut()
|
||||
.main_thread_platform
|
||||
.foreground_platform
|
||||
.on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
|
||||
self
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ impl App {
|
|||
let cx = self.0.clone();
|
||||
self.0
|
||||
.borrow_mut()
|
||||
.main_thread_platform
|
||||
.foreground_platform
|
||||
.on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
|
||||
self
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ impl App {
|
|||
let cx = self.0.clone();
|
||||
self.0
|
||||
.borrow_mut()
|
||||
.main_thread_platform
|
||||
.foreground_platform
|
||||
.on_event(Box::new(move |event| {
|
||||
callback(event, &mut *cx.borrow_mut())
|
||||
}));
|
||||
|
@ -229,7 +229,7 @@ impl App {
|
|||
let cx = self.0.clone();
|
||||
self.0
|
||||
.borrow_mut()
|
||||
.main_thread_platform
|
||||
.foreground_platform
|
||||
.on_open_files(Box::new(move |paths| {
|
||||
callback(paths, &mut *cx.borrow_mut())
|
||||
}));
|
||||
|
@ -240,7 +240,7 @@ impl App {
|
|||
where
|
||||
F: 'static + FnOnce(&mut MutableAppContext),
|
||||
{
|
||||
let platform = self.0.borrow().main_thread_platform.clone();
|
||||
let platform = self.0.borrow().foreground_platform.clone();
|
||||
platform.run(Box::new(move || {
|
||||
let mut cx = self.0.borrow_mut();
|
||||
on_finish_launching(&mut *cx);
|
||||
|
@ -366,12 +366,11 @@ impl TestAppContext {
|
|||
}
|
||||
|
||||
pub fn simulate_new_path_selection(&self, result: impl FnOnce(PathBuf) -> Option<PathBuf>) {
|
||||
self.main_thread_platform
|
||||
.simulate_new_path_selection(result);
|
||||
self.foreground_platform.simulate_new_path_selection(result);
|
||||
}
|
||||
|
||||
pub fn did_prompt_for_new_path(&self) -> bool {
|
||||
self.main_thread_platform.as_ref().did_prompt_for_new_path()
|
||||
self.foreground_platform.as_ref().did_prompt_for_new_path()
|
||||
}
|
||||
|
||||
pub fn simulate_prompt_answer(&self, window_id: usize, answer: usize) {
|
||||
|
@ -529,7 +528,7 @@ type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
|
|||
|
||||
pub struct MutableAppContext {
|
||||
weak_self: Option<rc::Weak<RefCell<Self>>>,
|
||||
main_thread_platform: Rc<dyn platform::MainThreadPlatform>,
|
||||
foreground_platform: Rc<dyn platform::ForegroundPlatform>,
|
||||
platform: Arc<dyn platform::Platform>,
|
||||
assets: Arc<AssetCache>,
|
||||
cx: AppContext,
|
||||
|
@ -554,13 +553,13 @@ impl MutableAppContext {
|
|||
fn new(
|
||||
foreground: Rc<executor::Foreground>,
|
||||
platform: Arc<dyn platform::Platform>,
|
||||
main_thread_platform: Rc<dyn platform::MainThreadPlatform>,
|
||||
foreground_platform: Rc<dyn platform::ForegroundPlatform>,
|
||||
asset_source: impl AssetSource,
|
||||
) -> Self {
|
||||
let fonts = platform.fonts();
|
||||
Self {
|
||||
weak_self: None,
|
||||
main_thread_platform,
|
||||
foreground_platform,
|
||||
platform,
|
||||
assets: Arc::new(AssetCache::new(asset_source)),
|
||||
cx: AppContext {
|
||||
|
@ -721,7 +720,7 @@ impl MutableAppContext {
|
|||
}
|
||||
|
||||
pub fn set_menus(&mut self, menus: Vec<Menu>) {
|
||||
self.main_thread_platform.set_menus(menus);
|
||||
self.foreground_platform.set_menus(menus);
|
||||
}
|
||||
|
||||
fn prompt<F>(
|
||||
|
@ -755,7 +754,7 @@ impl MutableAppContext {
|
|||
{
|
||||
let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
|
||||
let foreground = self.foreground.clone();
|
||||
self.main_thread_platform.prompt_for_paths(
|
||||
self.foreground_platform.prompt_for_paths(
|
||||
options,
|
||||
Box::new(move |paths| {
|
||||
foreground
|
||||
|
@ -771,7 +770,7 @@ impl MutableAppContext {
|
|||
{
|
||||
let app = self.weak_self.as_ref().unwrap().upgrade().unwrap();
|
||||
let foreground = self.foreground.clone();
|
||||
self.main_thread_platform.prompt_for_new_path(
|
||||
self.foreground_platform.prompt_for_new_path(
|
||||
directory,
|
||||
Box::new(move |path| {
|
||||
foreground
|
||||
|
|
|
@ -27,7 +27,24 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
pub(crate) trait MainThreadPlatform {
|
||||
pub trait Platform: Send + Sync {
|
||||
fn dispatcher(&self) -> Arc<dyn Dispatcher>;
|
||||
fn fonts(&self) -> Arc<dyn FontSystem>;
|
||||
|
||||
fn activate(&self, ignoring_other_apps: bool);
|
||||
fn open_window(
|
||||
&self,
|
||||
id: usize,
|
||||
options: WindowOptions,
|
||||
executor: Rc<executor::Foreground>,
|
||||
) -> Box<dyn Window>;
|
||||
fn key_window_id(&self) -> Option<usize>;
|
||||
fn quit(&self);
|
||||
fn write_to_clipboard(&self, item: ClipboardItem);
|
||||
fn read_from_clipboard(&self) -> Option<ClipboardItem>;
|
||||
}
|
||||
|
||||
pub(crate) trait ForegroundPlatform {
|
||||
fn on_become_active(&self, callback: Box<dyn FnMut()>);
|
||||
fn on_resign_active(&self, callback: Box<dyn FnMut()>);
|
||||
fn on_event(&self, callback: Box<dyn FnMut(Event) -> bool>);
|
||||
|
@ -48,23 +65,6 @@ pub(crate) trait MainThreadPlatform {
|
|||
);
|
||||
}
|
||||
|
||||
pub trait Platform: Send + Sync {
|
||||
fn dispatcher(&self) -> Arc<dyn Dispatcher>;
|
||||
fn fonts(&self) -> Arc<dyn FontSystem>;
|
||||
|
||||
fn activate(&self, ignoring_other_apps: bool);
|
||||
fn open_window(
|
||||
&self,
|
||||
id: usize,
|
||||
options: WindowOptions,
|
||||
executor: Rc<executor::Foreground>,
|
||||
) -> Box<dyn Window>;
|
||||
fn key_window_id(&self) -> Option<usize>;
|
||||
fn quit(&self);
|
||||
fn write_to_clipboard(&self, item: ClipboardItem);
|
||||
fn read_from_clipboard(&self) -> Option<ClipboardItem>;
|
||||
}
|
||||
|
||||
pub trait Dispatcher: Send + Sync {
|
||||
fn is_main_thread(&self) -> bool;
|
||||
fn run_on_main_thread(&self, task: Runnable);
|
||||
|
|
|
@ -11,18 +11,18 @@ mod window;
|
|||
use cocoa::base::{BOOL, NO, YES};
|
||||
pub use dispatcher::Dispatcher;
|
||||
pub use fonts::FontSystem;
|
||||
use platform::{MacMainThreadPlatform, MacPlatform};
|
||||
use platform::{MacForegroundPlatform, MacPlatform};
|
||||
use std::{rc::Rc, sync::Arc};
|
||||
use window::Window;
|
||||
|
||||
pub(crate) fn main_thread_platform() -> Rc<dyn super::MainThreadPlatform> {
|
||||
Rc::new(MacMainThreadPlatform::default())
|
||||
}
|
||||
|
||||
pub(crate) fn platform() -> Arc<dyn super::Platform> {
|
||||
Arc::new(MacPlatform::new())
|
||||
}
|
||||
|
||||
pub(crate) fn foreground_platform() -> Rc<dyn super::ForegroundPlatform> {
|
||||
Rc::new(MacForegroundPlatform::default())
|
||||
}
|
||||
|
||||
trait BoolExt {
|
||||
fn to_objc(self) -> BOOL;
|
||||
}
|
||||
|
|
|
@ -76,10 +76,10 @@ unsafe fn build_classes() {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MacMainThreadPlatform(RefCell<MacMainThreadPlatformState>);
|
||||
pub struct MacForegroundPlatform(RefCell<MacForegroundPlatformState>);
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MacMainThreadPlatformState {
|
||||
pub struct MacForegroundPlatformState {
|
||||
become_active: Option<Box<dyn FnMut()>>,
|
||||
resign_active: Option<Box<dyn FnMut()>>,
|
||||
event: Option<Box<dyn FnMut(crate::Event) -> bool>>,
|
||||
|
@ -89,7 +89,7 @@ pub struct MacMainThreadPlatformState {
|
|||
menu_actions: Vec<(String, Option<Box<dyn Any>>)>,
|
||||
}
|
||||
|
||||
impl MacMainThreadPlatform {
|
||||
impl MacForegroundPlatform {
|
||||
unsafe fn create_menu_bar(&self, menus: Vec<Menu>) -> id {
|
||||
let menu_bar = NSMenu::new(nil).autorelease();
|
||||
let mut state = self.0.borrow_mut();
|
||||
|
@ -170,7 +170,7 @@ impl MacMainThreadPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
impl platform::MainThreadPlatform for MacMainThreadPlatform {
|
||||
impl platform::ForegroundPlatform for MacForegroundPlatform {
|
||||
fn on_become_active(&self, callback: Box<dyn FnMut()>) {
|
||||
self.0.borrow_mut().become_active = Some(callback);
|
||||
}
|
||||
|
@ -451,16 +451,16 @@ impl platform::Platform for MacPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn get_main_thread_platform(object: &mut Object) -> &MacMainThreadPlatform {
|
||||
unsafe fn get_foreground_platform(object: &mut Object) -> &MacForegroundPlatform {
|
||||
let platform_ptr: *mut c_void = *object.get_ivar(MAC_PLATFORM_IVAR);
|
||||
assert!(!platform_ptr.is_null());
|
||||
&*(platform_ptr as *const MacMainThreadPlatform)
|
||||
&*(platform_ptr as *const MacForegroundPlatform)
|
||||
}
|
||||
|
||||
extern "C" fn send_event(this: &mut Object, _sel: Sel, native_event: id) {
|
||||
unsafe {
|
||||
if let Some(event) = Event::from_native(native_event, None) {
|
||||
let platform = get_main_thread_platform(this);
|
||||
let platform = get_foreground_platform(this);
|
||||
if let Some(callback) = platform.0.borrow_mut().event.as_mut() {
|
||||
if callback(event) {
|
||||
return;
|
||||
|
@ -477,7 +477,7 @@ extern "C" fn did_finish_launching(this: &mut Object, _: Sel, _: id) {
|
|||
let app: id = msg_send![APP_CLASS, sharedApplication];
|
||||
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
|
||||
|
||||
let platform = get_main_thread_platform(this);
|
||||
let platform = get_foreground_platform(this);
|
||||
let callback = platform.0.borrow_mut().finish_launching.take();
|
||||
if let Some(callback) = callback {
|
||||
callback();
|
||||
|
@ -486,14 +486,14 @@ extern "C" fn did_finish_launching(this: &mut Object, _: Sel, _: id) {
|
|||
}
|
||||
|
||||
extern "C" fn did_become_active(this: &mut Object, _: Sel, _: id) {
|
||||
let platform = unsafe { get_main_thread_platform(this) };
|
||||
let platform = unsafe { get_foreground_platform(this) };
|
||||
if let Some(callback) = platform.0.borrow_mut().become_active.as_mut() {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn did_resign_active(this: &mut Object, _: Sel, _: id) {
|
||||
let platform = unsafe { get_main_thread_platform(this) };
|
||||
let platform = unsafe { get_foreground_platform(this) };
|
||||
if let Some(callback) = platform.0.borrow_mut().resign_active.as_mut() {
|
||||
callback();
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ extern "C" fn open_files(this: &mut Object, _: Sel, _: id, paths: id) {
|
|||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let platform = unsafe { get_main_thread_platform(this) };
|
||||
let platform = unsafe { get_foreground_platform(this) };
|
||||
if let Some(callback) = platform.0.borrow_mut().open_files.as_mut() {
|
||||
callback(paths);
|
||||
}
|
||||
|
@ -523,13 +523,15 @@ extern "C" fn open_files(this: &mut Object, _: Sel, _: id, paths: id) {
|
|||
|
||||
extern "C" fn handle_menu_item(this: &mut Object, _: Sel, item: id) {
|
||||
unsafe {
|
||||
let platform = get_main_thread_platform(this);
|
||||
if let Some(callback) = platform.0.borrow_mut().menu_command.as_mut() {
|
||||
let platform = get_foreground_platform(this);
|
||||
let mut platform = platform.0.borrow_mut();
|
||||
if let Some(mut callback) = platform.menu_command.take() {
|
||||
let tag: NSInteger = msg_send![item, tag];
|
||||
let index = tag as usize;
|
||||
if let Some((action, arg)) = platform.0.borrow_mut().menu_actions.get(index) {
|
||||
if let Some((action, arg)) = platform.menu_actions.get(index) {
|
||||
callback(action, arg.as_ref().map(Box::as_ref));
|
||||
}
|
||||
platform.menu_command = Some(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ pub(crate) struct Platform {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct MainThreadPlatform {
|
||||
pub(crate) struct ForegroundPlatform {
|
||||
last_prompt_for_new_path_args: RefCell<Option<(PathBuf, Box<dyn FnOnce(Option<PathBuf>)>)>>,
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub struct Window {
|
|||
pub(crate) last_prompt: RefCell<Option<Box<dyn FnOnce(usize)>>>,
|
||||
}
|
||||
|
||||
impl MainThreadPlatform {
|
||||
impl ForegroundPlatform {
|
||||
pub(crate) fn simulate_new_path_selection(
|
||||
&self,
|
||||
result: impl FnOnce(PathBuf) -> Option<PathBuf>,
|
||||
|
@ -49,7 +49,7 @@ impl MainThreadPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
impl super::MainThreadPlatform for MainThreadPlatform {
|
||||
impl super::ForegroundPlatform for ForegroundPlatform {
|
||||
fn on_become_active(&self, _: Box<dyn FnMut()>) {}
|
||||
|
||||
fn on_resign_active(&self, _: Box<dyn FnMut()>) {}
|
||||
|
@ -183,10 +183,10 @@ impl super::Window for Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn main_thread_platform() -> MainThreadPlatform {
|
||||
MainThreadPlatform::default()
|
||||
}
|
||||
|
||||
pub(crate) fn platform() -> Platform {
|
||||
Platform::new()
|
||||
}
|
||||
|
||||
pub(crate) fn foreground_platform() -> ForegroundPlatform {
|
||||
ForegroundPlatform::default()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue