mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
workspace: Add Toggle actions to all the side panels (#49395)
Release Notes: - Add `toggle` actions to all panels to toggle visibility --------- Co-authored-by: Anthony Eid <hello@anthonyeid.me> Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
This commit is contained in:
parent
d2aa2e0c5a
commit
ee9191ecd2
14 changed files with 198 additions and 3 deletions
|
|
@ -145,6 +145,10 @@
|
|||
"restore_on_file_reopen": true,
|
||||
// Whether to automatically close files that have been deleted on disk.
|
||||
"close_on_file_delete": false,
|
||||
// Whether toggling a panel (e.g. with its keyboard shortcut) also closes
|
||||
// the panel when it is already focused, instead of just moving focus back
|
||||
// to the editor.
|
||||
"close_panel_on_toggle": false,
|
||||
// Relative size of the drop target in the editor that will open dropped file as a split pane (0-0.5)
|
||||
// E.g. 0.25 == If you drop onto the top/bottom quarter of the pane a new vertical split will be used
|
||||
// If you drop onto the left/right quarter of the pane a new horizontal split will be used
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ use zed_actions::{
|
|||
agent::{
|
||||
OpenAcpOnboardingModal, OpenOnboardingModal, OpenSettings, ResetAgentZoom, ResetOnboarding,
|
||||
},
|
||||
assistant::{OpenRulesLibrary, ToggleFocus},
|
||||
assistant::{OpenRulesLibrary, Toggle, ToggleFocus},
|
||||
};
|
||||
|
||||
const AGENT_PANEL_KEY: &str = "agent_panel";
|
||||
|
|
@ -789,6 +789,22 @@ impl AgentPanel {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn toggle(
|
||||
workspace: &mut Workspace,
|
||||
_: &Toggle,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) {
|
||||
if workspace
|
||||
.panel::<Self>(cx)
|
||||
.is_some_and(|panel| panel.read(cx).enabled(cx))
|
||||
{
|
||||
if !workspace.toggle_panel_focus::<Self>(window, cx) {
|
||||
workspace.close_panel::<Self>(window, cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn prompt_store(&self) -> &Option<Entity<PromptStore>> {
|
||||
&self.prompt_store
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ use workspace::{
|
|||
actions!(
|
||||
collab_panel,
|
||||
[
|
||||
/// Toggles the collab panel.
|
||||
Toggle,
|
||||
/// Toggles focus on the collaboration panel.
|
||||
ToggleFocus,
|
||||
/// Removes the selected channel or contact.
|
||||
|
|
@ -93,6 +95,11 @@ pub fn init(cx: &mut App) {
|
|||
})
|
||||
}
|
||||
});
|
||||
workspace.register_action(|workspace, _: &Toggle, window, cx| {
|
||||
if !workspace.toggle_panel_focus::<CollabPanel>(window, cx) {
|
||||
workspace.close_panel::<CollabPanel>(window, cx);
|
||||
}
|
||||
});
|
||||
workspace.register_action(|_, _: &OpenChannelNotes, window, cx| {
|
||||
let channel_id = ActiveCall::global(cx)
|
||||
.read(cx)
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ pub struct NotificationPresenter {
|
|||
actions!(
|
||||
notification_panel,
|
||||
[
|
||||
/// Toggles the notification panel.
|
||||
Toggle,
|
||||
/// Toggles focus on the notification panel.
|
||||
ToggleFocus
|
||||
]
|
||||
|
|
@ -86,6 +88,11 @@ pub fn init(cx: &mut App) {
|
|||
workspace.register_action(|workspace, _: &ToggleFocus, window, cx| {
|
||||
workspace.toggle_panel_focus::<NotificationPanel>(window, cx);
|
||||
});
|
||||
workspace.register_action(|workspace, _: &Toggle, window, cx| {
|
||||
if !workspace.toggle_panel_focus::<NotificationPanel>(window, cx) {
|
||||
workspace.close_panel::<NotificationPanel>(window, cx);
|
||||
}
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use tasks_ui::{Spawn, TaskOverrides};
|
|||
use ui::{FluentBuilder, InteractiveElement};
|
||||
use util::maybe;
|
||||
use workspace::{ItemHandle, ShutdownDebugAdapters, Workspace};
|
||||
use zed_actions::ToggleFocus;
|
||||
use zed_actions::debugger::OpenOnboardingModal;
|
||||
use zed_actions::{Toggle, ToggleFocus};
|
||||
|
||||
pub mod attach_modal;
|
||||
pub mod debugger_panel;
|
||||
|
|
@ -121,6 +121,11 @@ pub fn init(cx: &mut App) {
|
|||
.register_action(|workspace, _: &ToggleFocus, window, cx| {
|
||||
workspace.toggle_panel_focus::<DebugPanel>(window, cx);
|
||||
})
|
||||
.register_action(|workspace, _: &Toggle, window, cx| {
|
||||
if !workspace.toggle_panel_focus::<DebugPanel>(window, cx) {
|
||||
workspace.close_panel::<DebugPanel>(window, cx);
|
||||
}
|
||||
})
|
||||
.register_action(|workspace: &mut Workspace, _: &Start, window, cx| {
|
||||
NewProcessModal::show(workspace, window, NewProcessMode::Debug, None, cx);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ actions!(
|
|||
[
|
||||
/// Closes the git panel.
|
||||
Close,
|
||||
/// Toggles the git panel.
|
||||
Toggle,
|
||||
/// Toggles focus on the git panel.
|
||||
ToggleFocus,
|
||||
/// Opens the git panel menu.
|
||||
|
|
@ -225,6 +227,11 @@ pub fn register(workspace: &mut Workspace) {
|
|||
workspace.register_action(|workspace, _: &ToggleFocus, window, cx| {
|
||||
workspace.toggle_panel_focus::<GitPanel>(window, cx);
|
||||
});
|
||||
workspace.register_action(|workspace, _: &Toggle, window, cx| {
|
||||
if !workspace.toggle_panel_focus::<GitPanel>(window, cx) {
|
||||
workspace.close_panel::<GitPanel>(window, cx);
|
||||
}
|
||||
});
|
||||
workspace.register_action(|workspace, _: &ExpandCommitEditor, window, cx| {
|
||||
CommitModal::toggle(workspace, None, window, cx)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ actions!(
|
|||
ToggleActiveEditorPin,
|
||||
/// Unfolds the selected directory.
|
||||
UnfoldDirectory,
|
||||
/// Toggles the outline panel.
|
||||
Toggle,
|
||||
/// Toggles focus on the outline panel.
|
||||
ToggleFocus,
|
||||
]
|
||||
|
|
@ -670,6 +672,11 @@ pub fn init(cx: &mut App) {
|
|||
workspace.register_action(|workspace, _: &ToggleFocus, window, cx| {
|
||||
workspace.toggle_panel_focus::<OutlinePanel>(window, cx);
|
||||
});
|
||||
workspace.register_action(|workspace, _: &Toggle, window, cx| {
|
||||
if !workspace.toggle_panel_focus::<OutlinePanel>(window, cx) {
|
||||
workspace.close_panel::<OutlinePanel>(window, cx);
|
||||
}
|
||||
});
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,10 @@ use workspace::{
|
|||
notifications::{DetachAndPromptErr, NotifyResultExt, NotifyTaskExt},
|
||||
};
|
||||
use worktree::CreatedEntry;
|
||||
use zed_actions::{project_panel::ToggleFocus, workspace::OpenWithSystem};
|
||||
use zed_actions::{
|
||||
project_panel::{Toggle, ToggleFocus},
|
||||
workspace::OpenWithSystem,
|
||||
};
|
||||
|
||||
const PROJECT_PANEL_KEY: &str = "ProjectPanel";
|
||||
const NEW_ENTRY_ID: ProjectEntryId = ProjectEntryId::MAX;
|
||||
|
|
@ -418,6 +421,11 @@ pub fn init(cx: &mut App) {
|
|||
workspace.register_action(|workspace, _: &ToggleFocus, window, cx| {
|
||||
workspace.toggle_panel_focus::<ProjectPanel>(window, cx);
|
||||
});
|
||||
workspace.register_action(|workspace, _: &Toggle, window, cx| {
|
||||
if !workspace.toggle_panel_focus::<ProjectPanel>(window, cx) {
|
||||
workspace.close_panel::<ProjectPanel>(window, cx);
|
||||
}
|
||||
});
|
||||
|
||||
workspace.register_action(|workspace, _: &ToggleHideGitIgnore, _, cx| {
|
||||
let fs = workspace.app_state().fs.clone();
|
||||
|
|
|
|||
|
|
@ -952,6 +952,7 @@ impl VsCodeSettings {
|
|||
bottom_dock_layout: None,
|
||||
centered_layout: None,
|
||||
close_on_file_delete: None,
|
||||
close_panel_on_toggle: None,
|
||||
command_aliases: Default::default(),
|
||||
confirm_quit: self.read_enum("window.confirmBeforeClose", |s| match s {
|
||||
"always" | "keyboardOnly" => Some(true),
|
||||
|
|
|
|||
|
|
@ -113,6 +113,12 @@ pub struct WorkspaceSettingsContent {
|
|||
///
|
||||
/// Default: true
|
||||
pub zoomed_padding: Option<bool>,
|
||||
/// Whether toggling a panel (e.g. with its keyboard shortcut) also closes
|
||||
/// the panel when it is already focused, instead of just moving focus back
|
||||
/// to the editor.
|
||||
///
|
||||
/// Default: false
|
||||
pub close_panel_on_toggle: Option<bool>,
|
||||
/// What draws window decorations/titlebar, the client application (Zed) or display server
|
||||
/// Default: client
|
||||
pub window_decorations: Option<WindowDecorations>,
|
||||
|
|
|
|||
|
|
@ -3630,6 +3630,8 @@ impl Workspace {
|
|||
|
||||
/// Focus the panel of the given type if it isn't already focused. If it is
|
||||
/// already focused, then transfer focus back to the workspace center.
|
||||
/// When the `close_panel_on_toggle` setting is enabled, also closes the
|
||||
/// panel when transferring focus back to the center.
|
||||
pub fn toggle_panel_focus<T: Panel>(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
|
|
@ -3641,6 +3643,10 @@ impl Workspace {
|
|||
did_focus_panel
|
||||
});
|
||||
|
||||
if !did_focus_panel && WorkspaceSettings::get_global(cx).close_panel_on_toggle {
|
||||
self.close_panel::<T>(window, cx);
|
||||
}
|
||||
|
||||
telemetry::event!(
|
||||
"Panel Button Clicked",
|
||||
name = T::persistent_name(),
|
||||
|
|
@ -10546,6 +10552,118 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_close_panel_on_toggle(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
|
||||
let project = Project::test(fs, [], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
let panel = workspace.update_in(cx, |workspace, window, cx| {
|
||||
let panel = cx.new(|cx| TestPanel::new(DockPosition::Right, 100, cx));
|
||||
workspace.add_panel(panel.clone(), window, cx);
|
||||
panel
|
||||
});
|
||||
|
||||
let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
|
||||
pane.update_in(cx, |pane, window, cx| {
|
||||
let item = cx.new(TestItem::new);
|
||||
pane.add_item(Box::new(item), true, true, None, window, cx);
|
||||
});
|
||||
|
||||
// Enable close_panel_on_toggle
|
||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
||||
store.update_user_settings(cx, |settings| {
|
||||
settings.workspace.close_panel_on_toggle = Some(true);
|
||||
});
|
||||
});
|
||||
|
||||
// Panel starts closed. Toggling should open and focus it.
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
assert!(!workspace.right_dock().read(cx).is_open());
|
||||
workspace.toggle_panel_focus::<TestPanel>(window, cx);
|
||||
});
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
assert!(
|
||||
workspace.right_dock().read(cx).is_open(),
|
||||
"Dock should be open after toggling from center"
|
||||
);
|
||||
assert!(
|
||||
panel.read(cx).focus_handle(cx).contains_focused(window, cx),
|
||||
"Panel should be focused after toggling from center"
|
||||
);
|
||||
});
|
||||
|
||||
// Panel is open and focused. Toggling should close the panel and
|
||||
// return focus to the center.
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(window, cx);
|
||||
});
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
assert!(
|
||||
!workspace.right_dock().read(cx).is_open(),
|
||||
"Dock should be closed after toggling from focused panel"
|
||||
);
|
||||
assert!(
|
||||
!panel.read(cx).focus_handle(cx).contains_focused(window, cx),
|
||||
"Panel should not be focused after toggling from focused panel"
|
||||
);
|
||||
});
|
||||
|
||||
// Open the dock and focus something else so the panel is open but not
|
||||
// focused. Toggling should focus the panel (not close it).
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace
|
||||
.right_dock()
|
||||
.update(cx, |dock, cx| dock.set_open(true, window, cx));
|
||||
window.focus(&pane.read(cx).focus_handle(cx), cx);
|
||||
});
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
assert!(workspace.right_dock().read(cx).is_open());
|
||||
assert!(!panel.read(cx).focus_handle(cx).contains_focused(window, cx));
|
||||
workspace.toggle_panel_focus::<TestPanel>(window, cx);
|
||||
});
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
assert!(
|
||||
workspace.right_dock().read(cx).is_open(),
|
||||
"Dock should remain open when toggling focuses an open-but-unfocused panel"
|
||||
);
|
||||
assert!(
|
||||
panel.read(cx).focus_handle(cx).contains_focused(window, cx),
|
||||
"Panel should be focused after toggling an open-but-unfocused panel"
|
||||
);
|
||||
});
|
||||
|
||||
// Now disable the setting and verify the original behavior: toggling
|
||||
// from a focused panel moves focus to center but leaves the dock open.
|
||||
cx.update_global(|store: &mut SettingsStore, cx| {
|
||||
store.update_user_settings(cx, |settings| {
|
||||
settings.workspace.close_panel_on_toggle = Some(false);
|
||||
});
|
||||
});
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace.toggle_panel_focus::<TestPanel>(window, cx);
|
||||
});
|
||||
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
assert!(
|
||||
workspace.right_dock().read(cx).is_open(),
|
||||
"Dock should remain open when setting is disabled"
|
||||
);
|
||||
assert!(
|
||||
!panel.read(cx).focus_handle(cx).contains_focused(window, cx),
|
||||
"Panel should not be focused after toggling with setting disabled"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_pane_zoom_in_out(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ pub struct WorkspaceSettings {
|
|||
pub text_rendering_mode: settings::TextRenderingMode,
|
||||
pub resize_all_panels_in_dock: Vec<DockPosition>,
|
||||
pub close_on_file_delete: bool,
|
||||
pub close_panel_on_toggle: bool,
|
||||
pub use_system_window_tabs: bool,
|
||||
pub zoomed_padding: bool,
|
||||
pub window_decorations: settings::WindowDecorations,
|
||||
|
|
@ -108,6 +109,7 @@ impl Settings for WorkspaceSettings {
|
|||
.map(Into::into)
|
||||
.collect(),
|
||||
close_on_file_delete: workspace.close_on_file_delete.unwrap(),
|
||||
close_panel_on_toggle: workspace.close_panel_on_toggle.unwrap(),
|
||||
use_system_window_tabs: workspace.use_system_window_tabs.unwrap(),
|
||||
zoomed_padding: workspace.zoomed_padding.unwrap(),
|
||||
window_decorations: workspace.window_decorations.unwrap(),
|
||||
|
|
|
|||
|
|
@ -740,6 +740,7 @@ async fn initialize_agent_panel(
|
|||
|
||||
workspace
|
||||
.register_action(agent_ui::AgentPanel::toggle_focus)
|
||||
.register_action(agent_ui::AgentPanel::toggle)
|
||||
.register_action(agent_ui::InlineAssistant::inline_assist);
|
||||
}
|
||||
})?;
|
||||
|
|
|
|||
|
|
@ -302,6 +302,8 @@ pub mod project_panel {
|
|||
actions!(
|
||||
project_panel,
|
||||
[
|
||||
/// Toggles the project panel.
|
||||
Toggle,
|
||||
/// Toggles focus on the project panel.
|
||||
ToggleFocus
|
||||
]
|
||||
|
|
@ -465,6 +467,8 @@ pub mod assistant {
|
|||
actions!(
|
||||
agent,
|
||||
[
|
||||
/// Toggles the agent panel.
|
||||
Toggle,
|
||||
#[action(deprecated_aliases = ["assistant::ToggleFocus"])]
|
||||
ToggleFocus
|
||||
]
|
||||
|
|
@ -639,6 +643,8 @@ actions!(
|
|||
actions!(
|
||||
debug_panel,
|
||||
[
|
||||
/// Toggles the debug panel.
|
||||
Toggle,
|
||||
/// Toggles focus on the debug panel.
|
||||
ToggleFocus
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in a new issue