History

Introduce more GPUI2 APIs needed for transitioning the workspace (#3208)

Release Notes: - N/A

Antonio Scandurra committed 3 years ago

Commit 6d2e1a82 parents 8793300 76c675a7 files · +81 −101Browse files

Unified · Split

7 files
  1. crates/gpui2/src/app.rs +34 −43
  2. crates/gpui2/src/app/async_context.rs +10 −6
  3. crates/gpui2/src/app/test_context.rs +0 −9
  4. crates/gpui2/src/platform.rs +1 −14
  5. crates/gpui2/src/platform/mac/window.rs +6 −11
  6. crates/gpui2/src/view.rs +4 −0
  7. crates/gpui2/src/window.rs +26 −18
crates/gpui2/src/app.rs+34−43
@@ -16,13 +16,13 @@ use crate::{ · 15 unmodified lines
1616 current_platform, image_cache::ImageCache, Action, AnyBox, AnyView, AnyWindowHandle,
1717 AppMetadata, AssetSource, BackgroundExecutor, ClipboardItem, Context, DispatchPhase, DisplayId,
1818 Entity, FocusEvent, FocusHandle, FocusId, ForegroundExecutor, KeyBinding, Keymap, LayoutId,
19− Pixels, Platform, Point, Render, SharedString, SubscriberSet, Subscription, SvgRenderer, Task,
20− TextStyle, TextStyleRefinement, TextSystem, View, Window, WindowContext, WindowHandle,
21− WindowId,
19+ PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, Render, SharedString,
20+ SubscriberSet, Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement, TextSystem,
21+ View, Window, WindowContext, WindowHandle, WindowId,
2222 };
2323 use anyhow::{anyhow, Result};
2424 use collections::{HashMap, HashSet, VecDeque};
25−use futures::{future::LocalBoxFuture, Future};
25+use futures::{channel::oneshot, future::LocalBoxFuture, Future};
2626 use parking_lot::Mutex;
2727 use slotmap::SlotMap;
2828 use std::{
@@ -31,7 +31,7 @@ use std::{ · 2 unmodified lines
3131 marker::PhantomData,
3232 mem,
3333 ops::{Deref, DerefMut},
34− path::PathBuf,
34+ path::{Path, PathBuf},
3535 rc::{Rc, Weak},
3636 sync::{atomic::Ordering::SeqCst, Arc},
3737 time::Duration,
@@ -262,38 +262,13 @@ impl AppContext { · 224 unmodified lines
262262 .collect()
263263 }
264264
265− pub(crate) fn update_window<R>(
266− &mut self,
267− handle: AnyWindowHandle,
268− update: impl FnOnce(AnyView, &mut WindowContext) -> R,
269− ) -> Result<R> {
270− self.update(|cx| {
271− let mut window = cx
272− .windows
273− .get_mut(handle.id)
274− .ok_or_else(|| anyhow!("window not found"))?
275− .take()
276− .unwrap();
277−
278− let root_view = window.root_view.clone().unwrap();
279− let result = update(root_view, &mut WindowContext::new(cx, &mut window));
280−
281− cx.windows
282− .get_mut(handle.id)
283− .ok_or_else(|| anyhow!("window not found"))?
284− .replace(window);
285−
286− Ok(result)
287− })
288− }
289−
290265 /// Opens a new window with the given option and the root view returned by the given function.
291266 /// The function is invoked with a `WindowContext`, which can be used to interact with window-specific
292267 /// functionality.
293268 pub fn open_window<V: Render>(
294269 &mut self,
295270 options: crate::WindowOptions,
296− build_root_view: impl FnOnce(&mut WindowContext) -> View<V> + 'static,
271+ build_root_view: impl FnOnce(&mut WindowContext) -> View<V>,
297272 ) -> WindowHandle<V> {
298273 self.update(|cx| {
299274 let id = cx.windows.insert(None);
@@ -306,47 +281,63 @@ impl AppContext { · 6 unmodified lines
306281 })
307282 }
308283
309− pub(crate) fn platform(&self) -> &Rc<dyn Platform> {
310− &self.platform
311− }
312−
313284 /// Instructs the platform to activate the application by bringing it to the foreground.
314285 pub fn activate(&self, ignoring_other_apps: bool) {
315− self.platform().activate(ignoring_other_apps);
286+ self.platform.activate(ignoring_other_apps);
287+ }
288+
289+ /// Returns the list of currently active displays.
290+ pub fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
291+ self.platform.displays()
316292 }
317293
318294 /// Writes data to the platform clipboard.
319295 pub fn write_to_clipboard(&self, item: ClipboardItem) {
320− self.platform().write_to_clipboard(item)
296+ self.platform.write_to_clipboard(item)
321297 }
322298
323299 /// Reads data from the platform clipboard.
324300 pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
325− self.platform().read_from_clipboard()
301+ self.platform.read_from_clipboard()
326302 }
327303
328304 /// Writes credentials to the platform keychain.
329305 pub fn write_credentials(&self, url: &str, username: &str, password: &[u8]) -> Result<()> {
330− self.platform().write_credentials(url, username, password)
306+ self.platform.write_credentials(url, username, password)
331307 }
332308
333309 /// Reads credentials from the platform keychain.
334310 pub fn read_credentials(&self, url: &str) -> Result<Option<(String, Vec<u8>)>> {
335− self.platform().read_credentials(url)
311+ self.platform.read_credentials(url)
336312 }
337313
338314 /// Deletes credentials from the platform keychain.
339315 pub fn delete_credentials(&self, url: &str) -> Result<()> {
340− self.platform().delete_credentials(url)
316+ self.platform.delete_credentials(url)
341317 }
342318
343319 /// Directs the platform's default browser to open the given URL.
344320 pub fn open_url(&self, url: &str) {
345− self.platform().open_url(url);
321+ self.platform.open_url(url);
346322 }
347323
348324 pub fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
349− self.platform().path_for_auxiliary_executable(name)
325+ self.platform.path_for_auxiliary_executable(name)
326+ }
327+
328+ pub fn prompt_for_paths(
329+ &self,
330+ options: PathPromptOptions,
331+ ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
332+ self.platform.prompt_for_paths(options)
333+ }
334+
335+ pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
336+ self.platform.prompt_for_new_path(directory)
337+ }
338+
339+ pub fn reveal_path(&self, path: &Path) {
340+ self.platform.reveal_path(path)
350341 }
351342
352343 pub(crate) fn push_effect(&mut self, effect: Effect) {
crates/gpui2/src/app/async_context.rs+10−6
@@ -1,6 +1,7 @@
11 use crate::{
22 AnyView, AnyWindowHandle, AppContext, BackgroundExecutor, Context, ForegroundExecutor, Model,
33 ModelContext, Render, Result, Task, View, ViewContext, VisualContext, WindowContext,
4+ WindowHandle,
45 };
56 use anyhow::{anyhow, Context as _};
67 use derive_more::{Deref, DerefMut};
@@ -82,17 +83,20 @@ impl AsyncAppContext { · 75 unmodified lines
8283 Ok(f(&mut *lock))
8384 }
8485
85− pub fn update_window<R>(
86+ pub fn open_window<V>(
8687 &self,
87− handle: AnyWindowHandle,
88− update: impl FnOnce(AnyView, &mut WindowContext) -> R,
89− ) -> Result<R> {
88+ options: crate::WindowOptions,
89+ build_root_view: impl FnOnce(&mut WindowContext) -> View<V>,
90+ ) -> Result<WindowHandle<V>>
91+ where
92+ V: Render,
93+ {
9094 let app = self
9195 .app
9296 .upgrade()
9397 .ok_or_else(|| anyhow!("app was released"))?;
94− let mut app_context = app.borrow_mut();
95− app_context.update_window(handle, update)
98+ let mut lock = app.borrow_mut();
99+ Ok(lock.open_window(options, build_root_view))
96100 }
97101
98102 pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
crates/gpui2/src/app/test_context.rs+0−9
@@ -87,15 +87,6 @@ impl TestAppContext { · 86 unmodified lines
8787 cx.update(f)
8888 }
8989
90− pub fn update_window<R>(
91− &self,
92− handle: AnyWindowHandle,
93− update: impl FnOnce(AnyView, &mut WindowContext) -> R,
94− ) -> R {
95− let mut app = self.app.borrow_mut();
96− app.update_window(handle, update).unwrap()
97− }
98−
9990 pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
10091 where
10192 Fut: Future<Output = R> + 'static,
crates/gpui2/src/platform.rs+1−14
@@ -138,12 +138,7 @@ pub(crate) trait PlatformWindow { · 137 unmodified lines
138138 fn mouse_position(&self) -> Point<Pixels>;
139139 fn as_any_mut(&mut self) -> &mut dyn Any;
140140 fn set_input_handler(&mut self, input_handler: Box<dyn PlatformInputHandler>);
141− fn prompt(
142− &self,
143− level: WindowPromptLevel,
144− msg: &str,
145− answers: &[&str],
146− ) -> oneshot::Receiver<usize>;
141+ fn prompt(&self, level: PromptLevel, msg: &str, answers: &[&str]) -> oneshot::Receiver<usize>;
147142 fn activate(&self);
148143 fn set_title(&mut self, title: &str);
149144 fn set_edited(&mut self, edited: bool);
@@ -454,14 +449,6 @@ impl Default for WindowAppearance { · 304 unmodified lines
454449 }
455450 }
456451
457−#[derive(Copy, Clone, Debug, PartialEq, Default)]
458−pub enum WindowPromptLevel {
459− #[default]
460− Info,
461− Warning,
462− Critical,
463−}
464−
465452 #[derive(Copy, Clone, Debug)]
466453 pub struct PathPromptOptions {
467454 pub files: bool,
crates/gpui2/src/platform/mac/window.rs+6−11
@@ -3,8 +3,8 @@ use crate::{ · 2 unmodified lines
33 display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, ExternalPaths,
44 FileDropEvent, ForegroundExecutor, GlobalPixels, InputEvent, KeyDownEvent, Keystroke,
55 Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent,
6− Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, Scene,
7− Size, Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
6+ Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
7+ PromptLevel, Scene, Size, Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions,
88 };
99 use block::ConcreteBlock;
1010 use cocoa::{
@@ -742,12 +742,7 @@ impl PlatformWindow for MacWindow { · 731 unmodified lines
742742 self.0.as_ref().lock().input_handler = Some(input_handler);
743743 }
744744
745− fn prompt(
746− &self,
747− level: WindowPromptLevel,
748− msg: &str,
749− answers: &[&str],
750− ) -> oneshot::Receiver<usize> {
745+ fn prompt(&self, level: PromptLevel, msg: &str, answers: &[&str]) -> oneshot::Receiver<usize> {
751746 // macOs applies overrides to modal window buttons after they are added.
752747 // Two most important for this logic are:
753748 // * Buttons with "Cancel" title will be displayed as the last buttons in the modal
@@ -777,9 +772,9 @@ impl PlatformWindow for MacWindow { · 23 unmodified lines
777772 let alert: id = msg_send![class!(NSAlert), alloc];
778773 let alert: id = msg_send![alert, init];
779774 let alert_style = match level {
780− WindowPromptLevel::Info => 1,
781− WindowPromptLevel::Warning => 0,
782− WindowPromptLevel::Critical => 2,
775+ PromptLevel::Info => 1,
776+ PromptLevel::Warning => 0,
777+ PromptLevel::Critical => 2,
783778 };
784779 let _: () = msg_send![alert, setAlertStyle: alert_style];
785780 let _: () = msg_send![alert, setMessageText: ns_string(msg)];
crates/gpui2/src/view.rs+4−0
@@ -98,6 +98,10 @@ pub struct WeakView<V> { · 97 unmodified lines
9898 }
9999
100100 impl<V: 'static> WeakView<V> {
101+ pub fn entity_id(&self) -> EntityId {
102+ self.model.entity_id
103+ }
104+
101105 pub fn upgrade(&self) -> Option<View<V>> {
102106 Entity::upgrade_from(self)
103107 }
crates/gpui2/src/window.rs+26−18
@@ -4,14 +4,15 @@ use crate::{ · 3 unmodified lines
44 Entity, EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId,
55 Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
66 Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent,
7− MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad,
8− Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder,
9− Shadow, SharedString, Size, Style, Subscription, TaffyLayoutEngine, Task, Underline,
10− UnderlineStyle, View, VisualContext, WeakView, WindowOptions, SUBPIXEL_VARIANTS,
7+ MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite,
8+ PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels,
9+ SceneBuilder, Shadow, SharedString, Size, Style, Subscription, TaffyLayoutEngine, Task,
10+ Underline, UnderlineStyle, View, VisualContext, WeakView, WindowOptions, SUBPIXEL_VARIANTS,
1111 };
1212 use anyhow::{anyhow, Result};
1313 use collections::HashMap;
1414 use derive_more::{Deref, DerefMut};
15+use futures::channel::oneshot;
1516 use parking_lot::RwLock;
1617 use slotmap::SlotMap;
1718 use smallvec::SmallVec;
@@ -195,7 +196,7 @@ impl Window { · 177 unmodified lines
195196 options: WindowOptions,
196197 cx: &mut AppContext,
197198 ) -> Self {
198− let platform_window = cx.platform().open_window(handle, options);
199+ let platform_window = cx.platform.open_window(handle, options);
199200 let display_id = platform_window.display().id();
200201 let sprite_atlas = platform_window.sprite_atlas();
201202 let mouse_position = platform_window.mouse_position();
@@ -419,7 +420,7 @@ impl<'a> WindowContext<'a> { · 217 unmodified lines
419420 } else {
420421 let mut async_cx = self.to_async();
421422 self.next_frame_callbacks.insert(display_id, vec![f]);
422− self.platform().set_display_link_output_callback(
423+ self.platform.set_display_link_output_callback(
423424 display_id,
424425 Box::new(move |_current_time, _output_time| {
425426 let _ = async_cx.update(|_, cx| {
@@ -434,32 +435,26 @@ impl<'a> WindowContext<'a> { · 8 unmodified lines
434435 }
435436
436437 if cx.next_frame_callbacks.get(&display_id).unwrap().is_empty() {
437− cx.platform().stop_display_link(display_id);
438+ cx.platform.stop_display_link(display_id);
438439 }
439440 });
440441 }),
441442 );
442443 }
443444
444− self.platform().start_display_link(display_id);
445+ self.platform.start_display_link(display_id);
445446 }
446447
447448 /// Spawn the future returned by the given closure on the application thread pool.
448449 /// The closure is provided a handle to the current window and an `AsyncWindowContext` for
449450 /// use within your future.
450− pub fn spawn<Fut, R>(
451− &mut self,
452− f: impl FnOnce(AnyWindowHandle, AsyncWindowContext) -> Fut,
453− ) -> Task<R>
451+ pub fn spawn<Fut, R>(&mut self, f: impl FnOnce(AsyncWindowContext) -> Fut) -> Task<R>
454452 where
455453 R: 'static,
456454 Fut: Future<Output = R> + 'static,
457455 {
458− let window = self.window.handle;
459− self.app.spawn(move |app| {
460− let cx = AsyncWindowContext::new(app, window);
461− f(window, cx)
462− })
456+ self.app
457+ .spawn(|app| f(AsyncWindowContext::new(app, self.window.handle)))
463458 }
464459
465460 /// Update the global of the given type. The given closure is given simultaneous mutable
@@ -1153,6 +1148,19 @@ impl<'a> WindowContext<'a> { · 687 unmodified lines
11531148 )
11541149 }
11551150
1151+ pub fn activate_window(&self) {
1152+ self.window.platform_window.activate();
1153+ }
1154+
1155+ pub fn prompt(
1156+ &self,
1157+ level: PromptLevel,
1158+ msg: &str,
1159+ answers: &[&str],
1160+ ) -> oneshot::Receiver<usize> {
1161+ self.window.platform_window.prompt(level, msg, answers)
1162+ }
1163+
11561164 fn dispatch_action(
11571165 &mut self,
11581166 action: Box<dyn Action>,
@@ -1809,7 +1817,7 @@ impl<'a, V: 'static> ViewContext<'a, V> { · 650 unmodified lines
18091817 Fut: Future<Output = R> + 'static,
18101818 {
18111819 let view = self.view().downgrade();
1812− self.window_cx.spawn(move |_, cx| f(view, cx))
1820+ self.window_cx.spawn(|cx| f(view, cx))
18131821 }
18141822
18151823 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t