Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion crates/markdown-editor/src/components/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ pub(crate) struct ShortcutDefinition {
}

const BLOCK_CONTEXT: Option<&str> = Some("BlockEditor");
/// 编辑器根节点的 key context:无 context 的绑定在 gpui 里优先级最高,
/// Esc 若绑成全局会压过对话框/列表自己的 Cancel,所以只在编辑器内生效。
pub(crate) const EDITOR_CONTEXT: &str = "MarkdownEditor";
const SELECT_ALL_ID: &str = "select_all";
const LEGACY_SELECT_ALL_IDS: &[&str] = &[
"select_all_source_text",
Expand Down Expand Up @@ -485,7 +488,7 @@ const SHORTCUT_DEFINITIONS: &[ShortcutDefinition] = &[
command: ShortcutCommand::DismissTransientUi,
id: "dismiss_transient_ui",
default_keys: &["escape"],
context: None,
context: Some(EDITOR_CONTEXT),
},
ShortcutDefinition {
command: ShortcutCommand::ToggleViewMode,
Expand Down
1 change: 1 addition & 0 deletions crates/markdown-editor/src/editor/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ impl Render for Editor {
let bounds_editor = cx.entity().downgrade();

let base = div()
.key_context(crate::components::EDITOR_CONTEXT)
.w_full()
.min_w(px(0.0))
.h_full()
Expand Down
2 changes: 1 addition & 1 deletion crates/notes/src/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ macro_rules! command_list {
"view.dismiss_transient_ui",
"Dismiss Transient UI",
&["escape"],
GLOBAL_CONTEXT,
Some("MarkdownEditor"),
DismissTransientUi
),
(
Expand Down
90 changes: 90 additions & 0 deletions main/src/home/home_connection_quick_open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,96 @@ mod tests {
DatabaseType, DbConnectionConfig, RemoteDesktopParams, RemoteDesktopProtocol,
};

struct EscDelegate;

impl ListDelegate for EscDelegate {
type Item = ListItem;

fn items_count(&self, _section: usize, _cx: &App) -> usize {
0
}

fn render_item(
&mut self,
_ix: IndexPath,
_window: &mut Window,
_cx: &mut Context<ListState<Self>>,
) -> Option<Self::Item> {
None
}

fn set_selected_index(
&mut self,
_ix: Option<IndexPath>,
_window: &mut Window,
_cx: &mut Context<ListState<Self>>,
) {
}

fn cancel(&mut self, window: &mut Window, cx: &mut Context<ListState<Self>>) {
window.close_dialog(cx);
}
}

struct FocusHost {
focus: gpui::FocusHandle,
}

impl gpui::Render for FocusHost {
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl gpui::IntoElement {
use gpui::InteractiveElement as _;
div().size_full().track_focus(&self.focus)
}
}

#[gpui::test]
fn escape_closes_quick_open_dialog(cx: &mut gpui::TestAppContext) {
use gpui::{AppContext as _, InteractiveElement as _};
use gpui_component::{Root, Theme, list::List};

cx.update(|cx| {
cx.set_global(Theme::default());
gpui_component::init(cx);
notes::init(cx);
});
let (_host, cx) = cx.add_window_view(|window, cx| {
let view = cx.new(|cx| FocusHost {
focus: cx.focus_handle(),
});
let focus = view.read(cx).focus.clone();
focus.focus(window, cx);
Root::new(view, window, cx)
});
cx.update(|window, cx| window.draw(cx).clear(cx));

cx.update(|window, cx| {
let list = cx.new(|cx| ListState::new(EscDelegate, window, cx).searchable(true));
let list_for_dialog = list.clone();
window.open_dialog(cx, move |dialog, _window, _cx| {
let list = list_for_dialog.clone();
dialog
.title("open")
.w(px(640.0))
.close_button(false)
.content(move |content, _window, _cx| {
content.p_0().child(div().id("quick-open").child(List::new(&list)))
})
});
list.update(cx, |state, cx| state.focus(window, cx));
});
cx.run_until_parked();
cx.update(|window, cx| window.draw(cx).clear(cx));
cx.update(|window, cx| {
assert!(window.has_active_dialog(cx));
});

cx.simulate_keystrokes("escape");
cx.run_until_parked();
cx.update(|window, cx| {
assert!(!window.has_active_dialog(cx), "Esc must close the quick open dialog");
});
}

#[test]
fn quick_open_matches_database_connection_by_ip() {
let connection = StoredConnection::new_database(
Expand Down
Loading