mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 02:17:35 +03:00
Fix assorted linux issues (#10061)
- Fix a bug where modifiers would be dispatched before they changed - Add a secondary modifier - Improve keybindings Release Notes: - N/A
This commit is contained in:
parent
e0cd96db7b
commit
1da2441e7b
@ -219,7 +219,7 @@
|
|||||||
"context": "BufferSearchBar && in_replace",
|
"context": "BufferSearchBar && in_replace",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"enter": "search::ReplaceNext",
|
"enter": "search::ReplaceNext",
|
||||||
"cmd-enter": "search::ReplaceAll"
|
"ctrl-enter": "search::ReplaceAll"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -258,7 +258,7 @@
|
|||||||
"bindings": {
|
"bindings": {
|
||||||
"escape": "project_search::ToggleFocus",
|
"escape": "project_search::ToggleFocus",
|
||||||
"alt-tab": "search::CycleMode",
|
"alt-tab": "search::CycleMode",
|
||||||
"cmd-shift-h": "search::ToggleReplace",
|
"ctrl-shift-h": "search::ToggleReplace",
|
||||||
"alt-ctrl-g": "search::ActivateRegexMode",
|
"alt-ctrl-g": "search::ActivateRegexMode",
|
||||||
"alt-ctrl-x": "search::ActivateTextMode"
|
"alt-ctrl-x": "search::ActivateTextMode"
|
||||||
}
|
}
|
||||||
@ -304,8 +304,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ctrl-alt-shift-down": "editor::DuplicateLine",
|
"ctrl-alt-shift-down": "editor::DuplicateLine",
|
||||||
"ctrl-shift-right": "editor::SelectLargerSyntaxNode",
|
"ctrl-shift-left": "editor::SelectToPreviousWordStart",
|
||||||
"ctrl-shift-left": "editor::SelectSmallerSyntaxNode",
|
"ctrl-shift-right": "editor::SelectToNextWordEnd",
|
||||||
|
"ctrl-shift-up": "editor::SelectLargerSyntaxNode", //todo(linux) tmp keybinding
|
||||||
|
"ctrl-shift-down": "editor::SelectSmallerSyntaxNode", //todo(linux) tmp keybinding
|
||||||
"ctrl-d": [
|
"ctrl-d": [
|
||||||
"editor::SelectNext",
|
"editor::SelectNext",
|
||||||
{
|
{
|
||||||
@ -354,14 +356,14 @@
|
|||||||
"ctrl-shift-]": "editor::UnfoldLines",
|
"ctrl-shift-]": "editor::UnfoldLines",
|
||||||
"ctrl-space": "editor::ShowCompletions",
|
"ctrl-space": "editor::ShowCompletions",
|
||||||
"ctrl-.": "editor::ToggleCodeActions",
|
"ctrl-.": "editor::ToggleCodeActions",
|
||||||
"alt-cmd-r": "editor::RevealInFinder",
|
"alt-ctrl-r": "editor::RevealInFinder",
|
||||||
"ctrl-alt-shift-c": "editor::DisplayCursorNames"
|
"ctrl-alt-shift-c": "editor::DisplayCursorNames"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"context": "Editor && mode == full",
|
"context": "Editor && mode == full",
|
||||||
"bindings": {
|
"bindings": {
|
||||||
"cmd-shift-o": "outline::Toggle",
|
"ctrl-shift-o": "outline::Toggle",
|
||||||
"ctrl-g": "go_to_line::Toggle"
|
"ctrl-g": "go_to_line::Toggle"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -419,7 +421,7 @@
|
|||||||
"ctrl-shift-f": "pane::DeploySearch",
|
"ctrl-shift-f": "pane::DeploySearch",
|
||||||
"ctrl-k ctrl-s": "zed::OpenKeymap",
|
"ctrl-k ctrl-s": "zed::OpenKeymap",
|
||||||
"ctrl-k ctrl-t": "theme_selector::Toggle",
|
"ctrl-k ctrl-t": "theme_selector::Toggle",
|
||||||
"ctrl-t": "project_symbols::Toggle",
|
"ctrl-shift-t": "project_symbols::Toggle",
|
||||||
"ctrl-p": "file_finder::Toggle",
|
"ctrl-p": "file_finder::Toggle",
|
||||||
"ctrl-tab": "tab_switcher::Toggle",
|
"ctrl-tab": "tab_switcher::Toggle",
|
||||||
"ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
|
"ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
|
||||||
@ -549,7 +551,7 @@
|
|||||||
"delete": "project_panel::Delete",
|
"delete": "project_panel::Delete",
|
||||||
"ctrl-backspace": ["project_panel::Delete", { "skip_prompt": true }],
|
"ctrl-backspace": ["project_panel::Delete", { "skip_prompt": true }],
|
||||||
"ctrl-delete": ["project_panel::Delete", { "skip_prompt": true }],
|
"ctrl-delete": ["project_panel::Delete", { "skip_prompt": true }],
|
||||||
"alt-cmd-r": "project_panel::RevealInFinder",
|
"alt-ctrl-r": "project_panel::RevealInFinder",
|
||||||
"alt-shift-f": "project_panel::NewSearchInDirectory"
|
"alt-shift-f": "project_panel::NewSearchInDirectory"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -610,7 +612,12 @@
|
|||||||
"pagedown": ["terminal::SendKeystroke", "pagedown"],
|
"pagedown": ["terminal::SendKeystroke", "pagedown"],
|
||||||
"escape": ["terminal::SendKeystroke", "escape"],
|
"escape": ["terminal::SendKeystroke", "escape"],
|
||||||
"enter": ["terminal::SendKeystroke", "enter"],
|
"enter": ["terminal::SendKeystroke", "enter"],
|
||||||
"ctrl-c": ["terminal::SendKeystroke", "ctrl-c"]
|
"ctrl-c": ["terminal::SendKeystroke", "ctrl-c"],
|
||||||
|
|
||||||
|
// Some nice conveniences
|
||||||
|
"ctrl-backspace": ["terminal::SendText", "\u0015"],
|
||||||
|
"ctrl-right": ["terminal::SendText", "\u0005"],
|
||||||
|
"ctrl-left": ["terminal::SendText", "\u0001"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
// which gives the same size as all other panes.
|
// which gives the same size as all other panes.
|
||||||
"active_pane_magnification": 1.0,
|
"active_pane_magnification": 1.0,
|
||||||
// The key to use for adding multiple cursors
|
// The key to use for adding multiple cursors
|
||||||
// Currently "alt" or "cmd" are supported.
|
// Currently "alt" or "cmd_or_ctrl" (also aliased as
|
||||||
|
// "cmd" and "ctrl") are supported.
|
||||||
"multi_cursor_modifier": "alt",
|
"multi_cursor_modifier": "alt",
|
||||||
// Whether to enable vim modes and key bindings
|
// Whether to enable vim modes and key bindings
|
||||||
"vim_mode": false,
|
"vim_mode": false,
|
||||||
|
@ -92,7 +92,8 @@ pub enum ShowScrollbar {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum MultiCursorModifier {
|
pub enum MultiCursorModifier {
|
||||||
Alt,
|
Alt,
|
||||||
Cmd,
|
#[serde(alias = "cmd", alias = "ctrl")]
|
||||||
|
CmdOrCtrl,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
|
@ -449,7 +449,8 @@ impl EditorElement {
|
|||||||
},
|
},
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
} else if modifiers.shift && !modifiers.control && !modifiers.alt && !modifiers.command {
|
} else if modifiers.shift && !modifiers.control && !modifiers.alt && !modifiers.secondary()
|
||||||
|
{
|
||||||
editor.select(
|
editor.select(
|
||||||
SelectPhase::Extend {
|
SelectPhase::Extend {
|
||||||
position,
|
position,
|
||||||
@ -461,7 +462,7 @@ impl EditorElement {
|
|||||||
let multi_cursor_setting = EditorSettings::get_global(cx).multi_cursor_modifier;
|
let multi_cursor_setting = EditorSettings::get_global(cx).multi_cursor_modifier;
|
||||||
let multi_cursor_modifier = match multi_cursor_setting {
|
let multi_cursor_modifier = match multi_cursor_setting {
|
||||||
MultiCursorModifier::Alt => modifiers.alt,
|
MultiCursorModifier::Alt => modifiers.alt,
|
||||||
MultiCursorModifier::Cmd => modifiers.command,
|
MultiCursorModifier::CmdOrCtrl => modifiers.secondary(),
|
||||||
};
|
};
|
||||||
editor.select(
|
editor.select(
|
||||||
SelectPhase::Begin {
|
SelectPhase::Begin {
|
||||||
@ -513,8 +514,8 @@ impl EditorElement {
|
|||||||
|
|
||||||
let multi_cursor_setting = EditorSettings::get_global(cx).multi_cursor_modifier;
|
let multi_cursor_setting = EditorSettings::get_global(cx).multi_cursor_modifier;
|
||||||
let multi_cursor_modifier = match multi_cursor_setting {
|
let multi_cursor_modifier = match multi_cursor_setting {
|
||||||
MultiCursorModifier::Alt => event.modifiers.command,
|
MultiCursorModifier::Alt => event.modifiers.secondary(),
|
||||||
MultiCursorModifier::Cmd => event.modifiers.alt,
|
MultiCursorModifier::CmdOrCtrl => event.modifiers.alt,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !pending_nonempty_selections && multi_cursor_modifier && text_hitbox.is_hovered(cx) {
|
if !pending_nonempty_selections && multi_cursor_modifier && text_hitbox.is_hovered(cx) {
|
||||||
|
@ -93,7 +93,7 @@ impl Editor {
|
|||||||
modifiers: Modifiers,
|
modifiers: Modifiers,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
if !modifiers.command || self.has_pending_selection() {
|
if !modifiers.secondary() || self.has_pending_selection() {
|
||||||
self.hide_hovered_link(cx);
|
self.hide_hovered_link(cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ impl Editor {
|
|||||||
&snapshot,
|
&snapshot,
|
||||||
point_for_position,
|
point_for_position,
|
||||||
self,
|
self,
|
||||||
modifiers.command,
|
modifiers.secondary(),
|
||||||
modifiers.shift,
|
modifiers.shift,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
@ -256,7 +256,7 @@ pub fn update_inlay_link_and_hover_points(
|
|||||||
snapshot: &EditorSnapshot,
|
snapshot: &EditorSnapshot,
|
||||||
point_for_position: PointForPosition,
|
point_for_position: PointForPosition,
|
||||||
editor: &mut Editor,
|
editor: &mut Editor,
|
||||||
cmd_held: bool,
|
secondary_held: bool,
|
||||||
shift_held: bool,
|
shift_held: bool,
|
||||||
cx: &mut ViewContext<'_, Editor>,
|
cx: &mut ViewContext<'_, Editor>,
|
||||||
) {
|
) {
|
||||||
@ -394,7 +394,9 @@ pub fn update_inlay_link_and_hover_points(
|
|||||||
if let Some((language_server_id, location)) =
|
if let Some((language_server_id, location)) =
|
||||||
hovered_hint_part.location
|
hovered_hint_part.location
|
||||||
{
|
{
|
||||||
if cmd_held && !editor.has_pending_nonempty_selection() {
|
if secondary_held
|
||||||
|
&& !editor.has_pending_nonempty_selection()
|
||||||
|
{
|
||||||
go_to_definition_updated = true;
|
go_to_definition_updated = true;
|
||||||
show_link_definition(
|
show_link_definition(
|
||||||
shift_held,
|
shift_held,
|
||||||
@ -762,7 +764,7 @@ mod tests {
|
|||||||
let «variable» = A;
|
let «variable» = A;
|
||||||
"});
|
"});
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
// Assert no link highlights
|
// Assert no link highlights
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
@ -823,7 +825,7 @@ mod tests {
|
|||||||
])))
|
])))
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
@ -849,7 +851,7 @@ mod tests {
|
|||||||
])))
|
])))
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
@ -868,7 +870,7 @@ mod tests {
|
|||||||
// No definitions returned
|
// No definitions returned
|
||||||
Ok(Some(lsp::GotoDefinitionResponse::Link(vec![])))
|
Ok(Some(lsp::GotoDefinitionResponse::Link(vec![])))
|
||||||
});
|
});
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
|
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
@ -912,7 +914,7 @@ mod tests {
|
|||||||
])))
|
])))
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
|
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
@ -928,7 +930,7 @@ mod tests {
|
|||||||
fn do_work() { test(); }
|
fn do_work() { test(); }
|
||||||
"});
|
"});
|
||||||
|
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
fn test() { do_work(); }
|
fn test() { do_work(); }
|
||||||
@ -940,7 +942,7 @@ mod tests {
|
|||||||
fn test() { do_work(); }
|
fn test() { do_work(); }
|
||||||
fn do_work() { tesˇt(); }
|
fn do_work() { tesˇt(); }
|
||||||
"});
|
"});
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
fn test() { do_work(); }
|
fn test() { do_work(); }
|
||||||
@ -948,7 +950,7 @@ mod tests {
|
|||||||
"});
|
"});
|
||||||
|
|
||||||
// Cmd click with existing definition doesn't re-request and dismisses highlight
|
// Cmd click with existing definition doesn't re-request and dismisses highlight
|
||||||
cx.simulate_click(hover_point, Modifiers::command());
|
cx.simulate_click(hover_point, Modifiers::secondary_key());
|
||||||
cx.lsp
|
cx.lsp
|
||||||
.handle_request::<GotoDefinition, _, _>(move |_, _| async move {
|
.handle_request::<GotoDefinition, _, _>(move |_, _| async move {
|
||||||
// Empty definition response to make sure we aren't hitting the lsp and using
|
// Empty definition response to make sure we aren't hitting the lsp and using
|
||||||
@ -987,7 +989,7 @@ mod tests {
|
|||||||
},
|
},
|
||||||
])))
|
])))
|
||||||
});
|
});
|
||||||
cx.simulate_click(hover_point, Modifiers::command());
|
cx.simulate_click(hover_point, Modifiers::secondary_key());
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
@ -1030,7 +1032,7 @@ mod tests {
|
|||||||
s.set_pending_anchor_range(anchor_range, crate::SelectMode::Character)
|
s.set_pending_anchor_range(anchor_range, crate::SelectMode::Character)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
assert!(requests.try_next().is_err());
|
assert!(requests.try_next().is_err());
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
@ -1144,7 +1146,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
// Press cmd to trigger highlight
|
// Press cmd to trigger highlight
|
||||||
let hover_point = cx.pixel_position_for(midpoint);
|
let hover_point = cx.pixel_position_for(midpoint);
|
||||||
cx.simulate_mouse_move(hover_point, Modifiers::command());
|
cx.simulate_mouse_move(hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.update_editor(|editor, cx| {
|
cx.update_editor(|editor, cx| {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
@ -1175,9 +1177,9 @@ mod tests {
|
|||||||
assert!(actual_ranges.is_empty(), "When no cmd is pressed, should have no hint label selected, but got: {actual_ranges:?}");
|
assert!(actual_ranges.is_empty(), "When no cmd is pressed, should have no hint label selected, but got: {actual_ranges:?}");
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.simulate_click(hover_point, Modifiers::command());
|
cx.simulate_click(hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
struct «TestStructˇ»;
|
struct «TestStructˇ»;
|
||||||
@ -1207,12 +1209,12 @@ mod tests {
|
|||||||
Let's test a [complex](https://zed.dev/channel/had-(ˇoops)) case.
|
Let's test a [complex](https://zed.dev/channel/had-(ˇoops)) case.
|
||||||
"});
|
"});
|
||||||
|
|
||||||
cx.simulate_mouse_move(screen_coord, Modifiers::command());
|
cx.simulate_mouse_move(screen_coord, Modifiers::secondary_key());
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
|
||||||
Let's test a [complex](«https://zed.dev/channel/had-(oops)ˇ») case.
|
Let's test a [complex](«https://zed.dev/channel/had-(oops)ˇ») case.
|
||||||
"});
|
"});
|
||||||
|
|
||||||
cx.simulate_click(screen_coord, Modifiers::command());
|
cx.simulate_click(screen_coord, Modifiers::secondary_key());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cx.opened_url(),
|
cx.opened_url(),
|
||||||
Some("https://zed.dev/channel/had-(oops)".into())
|
Some("https://zed.dev/channel/had-(oops)".into())
|
||||||
@ -1235,12 +1237,12 @@ mod tests {
|
|||||||
let screen_coord =
|
let screen_coord =
|
||||||
cx.pixel_position(indoc! {"https://zed.dev/relˇeases is a cool webpage."});
|
cx.pixel_position(indoc! {"https://zed.dev/relˇeases is a cool webpage."});
|
||||||
|
|
||||||
cx.simulate_mouse_move(screen_coord, Modifiers::command());
|
cx.simulate_mouse_move(screen_coord, Modifiers::secondary_key());
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(
|
cx.assert_editor_text_highlights::<HoveredLinkState>(
|
||||||
indoc! {"«https://zed.dev/releasesˇ» is a cool webpage."},
|
indoc! {"«https://zed.dev/releasesˇ» is a cool webpage."},
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.simulate_click(screen_coord, Modifiers::command());
|
cx.simulate_click(screen_coord, Modifiers::secondary_key());
|
||||||
assert_eq!(cx.opened_url(), Some("https://zed.dev/releases".into()));
|
assert_eq!(cx.opened_url(), Some("https://zed.dev/releases".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,12 +1262,12 @@ mod tests {
|
|||||||
let screen_coord =
|
let screen_coord =
|
||||||
cx.pixel_position(indoc! {"A cool webpage is https://zed.dev/releˇases"});
|
cx.pixel_position(indoc! {"A cool webpage is https://zed.dev/releˇases"});
|
||||||
|
|
||||||
cx.simulate_mouse_move(screen_coord, Modifiers::command());
|
cx.simulate_mouse_move(screen_coord, Modifiers::secondary_key());
|
||||||
cx.assert_editor_text_highlights::<HoveredLinkState>(
|
cx.assert_editor_text_highlights::<HoveredLinkState>(
|
||||||
indoc! {"A cool webpage is «https://zed.dev/releasesˇ»"},
|
indoc! {"A cool webpage is «https://zed.dev/releasesˇ»"},
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.simulate_click(screen_coord, Modifiers::command());
|
cx.simulate_click(screen_coord, Modifiers::secondary_key());
|
||||||
assert_eq!(cx.opened_url(), Some("https://zed.dev/releases".into()));
|
assert_eq!(cx.opened_url(), Some("https://zed.dev/releases".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1386,7 +1388,7 @@ mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
cx.simulate_click(definition_hover_point, Modifiers::command());
|
cx.simulate_click(definition_hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
fn test() {
|
fn test() {
|
||||||
@ -1398,7 +1400,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
"});
|
"});
|
||||||
|
|
||||||
cx.simulate_click(reference_hover_point, Modifiers::command());
|
cx.simulate_click(reference_hover_point, Modifiers::secondary_key());
|
||||||
cx.background_executor.run_until_parked();
|
cx.background_executor.run_until_parked();
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
fn «testˇ»() {
|
fn «testˇ»() {
|
||||||
|
@ -1490,7 +1490,7 @@ async fn test_keeps_file_finder_open_after_modifier_keys_release(cx: &mut gpui::
|
|||||||
|
|
||||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
open_file_picker(&workspace, cx);
|
open_file_picker(&workspace, cx);
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::none());
|
cx.simulate_modifiers_change(Modifiers::none());
|
||||||
@ -1519,7 +1519,7 @@ async fn test_opens_file_on_modifier_keys_release(cx: &mut gpui::TestAppContext)
|
|||||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||||
open_queried_buffer("2", 1, "2.txt", &workspace, cx).await;
|
open_queried_buffer("2", 1, "2.txt", &workspace, cx).await;
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
let picker = open_file_picker(&workspace, cx);
|
let picker = open_file_picker(&workspace, cx);
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 2);
|
||||||
@ -1560,7 +1560,7 @@ async fn test_switches_between_release_norelease_modes_on_forward_nav(
|
|||||||
open_queried_buffer("2", 1, "2.txt", &workspace, cx).await;
|
open_queried_buffer("2", 1, "2.txt", &workspace, cx).await;
|
||||||
|
|
||||||
// Open with a shortcut
|
// Open with a shortcut
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
let picker = open_file_picker(&workspace, cx);
|
let picker = open_file_picker(&workspace, cx);
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 2);
|
assert_eq!(finder.delegate.matches.len(), 2);
|
||||||
@ -1581,7 +1581,7 @@ async fn test_switches_between_release_norelease_modes_on_forward_nav(
|
|||||||
|
|
||||||
// Back to navigation with initial shortcut
|
// Back to navigation with initial shortcut
|
||||||
// Open file on modifiers release
|
// Open file on modifiers release
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
cx.dispatch_action(Toggle);
|
cx.dispatch_action(Toggle);
|
||||||
cx.simulate_modifiers_change(Modifiers::none());
|
cx.simulate_modifiers_change(Modifiers::none());
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
@ -1617,7 +1617,7 @@ async fn test_switches_between_release_norelease_modes_on_backward_nav(
|
|||||||
open_queried_buffer("3", 1, "3.txt", &workspace, cx).await;
|
open_queried_buffer("3", 1, "3.txt", &workspace, cx).await;
|
||||||
|
|
||||||
// Open with a shortcut
|
// Open with a shortcut
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
let picker = open_file_picker(&workspace, cx);
|
let picker = open_file_picker(&workspace, cx);
|
||||||
picker.update(cx, |finder, _| {
|
picker.update(cx, |finder, _| {
|
||||||
assert_eq!(finder.delegate.matches.len(), 3);
|
assert_eq!(finder.delegate.matches.len(), 3);
|
||||||
@ -1640,7 +1640,7 @@ async fn test_switches_between_release_norelease_modes_on_backward_nav(
|
|||||||
|
|
||||||
// Back to navigation with initial shortcut
|
// Back to navigation with initial shortcut
|
||||||
// Open file on modifiers release
|
// Open file on modifiers release
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
cx.dispatch_action(SelectPrev); // <-- File Finder's SelectPrev, not menu's
|
cx.dispatch_action(SelectPrev); // <-- File Finder's SelectPrev, not menu's
|
||||||
cx.simulate_modifiers_change(Modifiers::none());
|
cx.simulate_modifiers_change(Modifiers::none());
|
||||||
cx.read(|cx| {
|
cx.read(|cx| {
|
||||||
@ -1669,7 +1669,7 @@ async fn test_extending_modifiers_does_not_confirm_selection(cx: &mut gpui::Test
|
|||||||
|
|
||||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command());
|
cx.simulate_modifiers_change(Modifiers::secondary_key());
|
||||||
open_file_picker(&workspace, cx);
|
open_file_picker(&workspace, cx);
|
||||||
|
|
||||||
cx.simulate_modifiers_change(Modifiers::command_shift());
|
cx.simulate_modifiers_change(Modifiers::command_shift());
|
||||||
|
@ -1510,12 +1510,12 @@ impl Interactivity {
|
|||||||
};
|
};
|
||||||
if self.location.is_some()
|
if self.location.is_some()
|
||||||
&& text_bounds.contains(&cx.mouse_position())
|
&& text_bounds.contains(&cx.mouse_position())
|
||||||
&& cx.modifiers().command
|
&& cx.modifiers().secondary()
|
||||||
{
|
{
|
||||||
let command_held = cx.modifiers().command;
|
let secondary_held = cx.modifiers().secondary();
|
||||||
cx.on_key_event({
|
cx.on_key_event({
|
||||||
move |e: &crate::ModifiersChangedEvent, _phase, cx| {
|
move |e: &crate::ModifiersChangedEvent, _phase, cx| {
|
||||||
if e.modifiers.command != command_held
|
if e.modifiers.secondary() != secondary_held
|
||||||
&& text_bounds.contains(&cx.mouse_position())
|
&& text_bounds.contains(&cx.mouse_position())
|
||||||
{
|
{
|
||||||
cx.refresh();
|
cx.refresh();
|
||||||
|
@ -37,7 +37,7 @@ impl Keystroke {
|
|||||||
control: self.modifiers.control,
|
control: self.modifiers.control,
|
||||||
alt: false,
|
alt: false,
|
||||||
shift: false,
|
shift: false,
|
||||||
command: false,
|
platform: false,
|
||||||
function: false,
|
function: false,
|
||||||
},
|
},
|
||||||
key: ime_key.to_string(),
|
key: ime_key.to_string(),
|
||||||
@ -62,7 +62,7 @@ impl Keystroke {
|
|||||||
let mut control = false;
|
let mut control = false;
|
||||||
let mut alt = false;
|
let mut alt = false;
|
||||||
let mut shift = false;
|
let mut shift = false;
|
||||||
let mut command = false;
|
let mut platform = false;
|
||||||
let mut function = false;
|
let mut function = false;
|
||||||
let mut key = None;
|
let mut key = None;
|
||||||
let mut ime_key = None;
|
let mut ime_key = None;
|
||||||
@ -73,8 +73,13 @@ impl Keystroke {
|
|||||||
"ctrl" => control = true,
|
"ctrl" => control = true,
|
||||||
"alt" => alt = true,
|
"alt" => alt = true,
|
||||||
"shift" => shift = true,
|
"shift" => shift = true,
|
||||||
"cmd" => command = true,
|
|
||||||
"fn" => function = true,
|
"fn" => function = true,
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
"cmd" => platform = true,
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
"super" => platform = true,
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
"win" => platform = true,
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(next) = components.peek() {
|
if let Some(next) = components.peek() {
|
||||||
if next.is_empty() && source.ends_with('-') {
|
if next.is_empty() && source.ends_with('-') {
|
||||||
@ -101,7 +106,7 @@ impl Keystroke {
|
|||||||
control,
|
control,
|
||||||
alt,
|
alt,
|
||||||
shift,
|
shift,
|
||||||
command,
|
platform,
|
||||||
function,
|
function,
|
||||||
},
|
},
|
||||||
key,
|
key,
|
||||||
@ -114,7 +119,7 @@ impl Keystroke {
|
|||||||
/// be able to simulate typing "space", etc.
|
/// be able to simulate typing "space", etc.
|
||||||
pub fn with_simulated_ime(mut self) -> Self {
|
pub fn with_simulated_ime(mut self) -> Self {
|
||||||
if self.ime_key.is_none()
|
if self.ime_key.is_none()
|
||||||
&& !self.modifiers.command
|
&& !self.modifiers.platform
|
||||||
&& !self.modifiers.control
|
&& !self.modifiers.control
|
||||||
&& !self.modifiers.function
|
&& !self.modifiers.function
|
||||||
&& !self.modifiers.alt
|
&& !self.modifiers.alt
|
||||||
@ -147,8 +152,15 @@ impl std::fmt::Display for Keystroke {
|
|||||||
if self.modifiers.alt {
|
if self.modifiers.alt {
|
||||||
f.write_char('⌥')?;
|
f.write_char('⌥')?;
|
||||||
}
|
}
|
||||||
if self.modifiers.command {
|
if self.modifiers.platform {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
f.write_char('⌘')?;
|
f.write_char('⌘')?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
f.write_char('❖')?;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
f.write_char('⊞')?;
|
||||||
}
|
}
|
||||||
if self.modifiers.shift {
|
if self.modifiers.shift {
|
||||||
f.write_char('⇧')?;
|
f.write_char('⇧')?;
|
||||||
@ -188,7 +200,8 @@ pub struct Modifiers {
|
|||||||
|
|
||||||
/// The command key, on macos
|
/// The command key, on macos
|
||||||
/// the windows key, on windows
|
/// the windows key, on windows
|
||||||
pub command: bool,
|
/// the super key, on linux
|
||||||
|
pub platform: bool,
|
||||||
|
|
||||||
/// The function key
|
/// The function key
|
||||||
pub function: bool,
|
pub function: bool,
|
||||||
@ -197,7 +210,22 @@ pub struct Modifiers {
|
|||||||
impl Modifiers {
|
impl Modifiers {
|
||||||
/// Returns true if any modifier key is pressed
|
/// Returns true if any modifier key is pressed
|
||||||
pub fn modified(&self) -> bool {
|
pub fn modified(&self) -> bool {
|
||||||
self.control || self.alt || self.shift || self.command || self.function
|
self.control || self.alt || self.shift || self.platform || self.function
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether the semantically 'secondary' modifier key is pressed
|
||||||
|
/// On macos, this is the command key
|
||||||
|
/// On windows and linux, this is the control key
|
||||||
|
pub fn secondary(&self) -> bool {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
return self.platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
{
|
||||||
|
return self.control;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// helper method for Modifiers with no modifiers
|
/// helper method for Modifiers with no modifiers
|
||||||
@ -205,10 +233,45 @@ impl Modifiers {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// helper method for Modifiers with just command
|
/// helper method for Modifiers with just the command key
|
||||||
pub fn command() -> Modifiers {
|
pub fn command() -> Modifiers {
|
||||||
Modifiers {
|
Modifiers {
|
||||||
command: true,
|
platform: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A helper method for Modifiers with just the secondary key pressed
|
||||||
|
pub fn secondary_key() -> Modifiers {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
Modifiers {
|
||||||
|
platform: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
{
|
||||||
|
Modifiers {
|
||||||
|
control: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// helper method for Modifiers with just the windows key
|
||||||
|
pub fn windows() -> Modifiers {
|
||||||
|
Modifiers {
|
||||||
|
platform: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// helper method for Modifiers with just the super key
|
||||||
|
pub fn super_key() -> Modifiers {
|
||||||
|
Modifiers {
|
||||||
|
platform: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,7 +296,7 @@ impl Modifiers {
|
|||||||
pub fn command_shift() -> Modifiers {
|
pub fn command_shift() -> Modifiers {
|
||||||
Modifiers {
|
Modifiers {
|
||||||
shift: true,
|
shift: true,
|
||||||
command: true,
|
platform: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,7 +306,7 @@ impl Modifiers {
|
|||||||
(other.control || !self.control)
|
(other.control || !self.control)
|
||||||
&& (other.alt || !self.alt)
|
&& (other.alt || !self.alt)
|
||||||
&& (other.shift || !self.shift)
|
&& (other.shift || !self.shift)
|
||||||
&& (other.command || !self.command)
|
&& (other.platform || !self.platform)
|
||||||
&& (other.function || !self.function)
|
&& (other.function || !self.function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ impl WaylandClient {
|
|||||||
control: false,
|
control: false,
|
||||||
alt: false,
|
alt: false,
|
||||||
function: false,
|
function: false,
|
||||||
command: false,
|
platform: false,
|
||||||
},
|
},
|
||||||
scroll_direction: -1.0,
|
scroll_direction: -1.0,
|
||||||
axis_source: AxisSource::Wheel,
|
axis_source: AxisSource::Wheel,
|
||||||
@ -692,6 +692,11 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
|||||||
group,
|
group,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let focused_window = state.keyboard_focused_window.clone();
|
||||||
|
let Some(focused_window) = focused_window else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let keymap_state = state.keymap_state.as_mut().unwrap();
|
let keymap_state = state.keymap_state.as_mut().unwrap();
|
||||||
keymap_state.update_mask(mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
keymap_state.update_mask(mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
||||||
|
|
||||||
@ -707,14 +712,22 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
|||||||
state.modifiers.shift = shift;
|
state.modifiers.shift = shift;
|
||||||
state.modifiers.alt = alt;
|
state.modifiers.alt = alt;
|
||||||
state.modifiers.control = control;
|
state.modifiers.control = control;
|
||||||
state.modifiers.command = command;
|
state.modifiers.platform = command;
|
||||||
|
|
||||||
|
let input = PlatformInput::ModifiersChanged(ModifiersChangedEvent {
|
||||||
|
modifiers: state.modifiers,
|
||||||
|
});
|
||||||
|
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
focused_window.handle_input(input);
|
||||||
}
|
}
|
||||||
wl_keyboard::Event::Key {
|
wl_keyboard::Event::Key {
|
||||||
key,
|
key,
|
||||||
state: WEnum::Value(key_state),
|
state: WEnum::Value(key_state),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let focused_window = &state.keyboard_focused_window;
|
let focused_window = state.keyboard_focused_window.clone();
|
||||||
let Some(focused_window) = focused_window else {
|
let Some(focused_window) = focused_window else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -725,80 +738,56 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
|
|||||||
let keysym = keymap_state.key_get_one_sym(keycode);
|
let keysym = keymap_state.key_get_one_sym(keycode);
|
||||||
|
|
||||||
match key_state {
|
match key_state {
|
||||||
wl_keyboard::KeyState::Pressed => {
|
wl_keyboard::KeyState::Pressed if !keysym.is_modifier_key() => {
|
||||||
let input = if keysym.is_modifier_key() {
|
let input = PlatformInput::KeyDown(KeyDownEvent {
|
||||||
PlatformInput::ModifiersChanged(ModifiersChangedEvent {
|
keystroke: Keystroke::from_xkb(keymap_state, state.modifiers, keycode),
|
||||||
modifiers: state.modifiers,
|
is_held: false, // todo(linux)
|
||||||
|
});
|
||||||
|
|
||||||
|
state.repeat.current_id += 1;
|
||||||
|
state.repeat.current_keysym = Some(keysym);
|
||||||
|
|
||||||
|
let rate = state.repeat.characters_per_second;
|
||||||
|
let delay = state.repeat.delay;
|
||||||
|
let id = state.repeat.current_id;
|
||||||
|
let this = this.clone();
|
||||||
|
|
||||||
|
let timer = Timer::from_duration(delay);
|
||||||
|
let state_ = Rc::clone(&this.client_state_inner);
|
||||||
|
let input_ = input.clone();
|
||||||
|
state
|
||||||
|
.loop_handle
|
||||||
|
.insert_source(timer, move |event, _metadata, shared_data| {
|
||||||
|
let state_ = state_.borrow_mut();
|
||||||
|
let is_repeating = id == state_.repeat.current_id
|
||||||
|
&& state_.repeat.current_keysym.is_some()
|
||||||
|
&& state_.keyboard_focused_window.is_some();
|
||||||
|
|
||||||
|
if !is_repeating {
|
||||||
|
return TimeoutAction::Drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
let focused_window =
|
||||||
|
state_.keyboard_focused_window.as_ref().unwrap().clone();
|
||||||
|
|
||||||
|
drop(state_);
|
||||||
|
|
||||||
|
focused_window.handle_input(input_.clone());
|
||||||
|
|
||||||
|
TimeoutAction::ToDuration(Duration::from_secs(1) / rate)
|
||||||
})
|
})
|
||||||
} else {
|
.unwrap();
|
||||||
PlatformInput::KeyDown(KeyDownEvent {
|
|
||||||
keystroke: Keystroke::from_xkb(
|
|
||||||
keymap_state,
|
|
||||||
state.modifiers,
|
|
||||||
keycode,
|
|
||||||
),
|
|
||||||
is_held: false, // todo(linux)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
if !keysym.is_modifier_key() {
|
|
||||||
state.repeat.current_id += 1;
|
|
||||||
state.repeat.current_keysym = Some(keysym);
|
|
||||||
|
|
||||||
let rate = state.repeat.characters_per_second;
|
|
||||||
let delay = state.repeat.delay;
|
|
||||||
let id = state.repeat.current_id;
|
|
||||||
let this = this.clone();
|
|
||||||
|
|
||||||
let timer = Timer::from_duration(delay);
|
|
||||||
let state_ = Rc::clone(&this.client_state_inner);
|
|
||||||
let input_ = input.clone();
|
|
||||||
state
|
|
||||||
.loop_handle
|
|
||||||
.insert_source(timer, move |event, _metadata, shared_data| {
|
|
||||||
let state_ = state_.borrow_mut();
|
|
||||||
let is_repeating = id == state_.repeat.current_id
|
|
||||||
&& state_.repeat.current_keysym.is_some()
|
|
||||||
&& state_.keyboard_focused_window.is_some();
|
|
||||||
|
|
||||||
if !is_repeating {
|
|
||||||
return TimeoutAction::Drop;
|
|
||||||
}
|
|
||||||
|
|
||||||
let focused_window =
|
|
||||||
state_.keyboard_focused_window.as_ref().unwrap().clone();
|
|
||||||
|
|
||||||
drop(state_);
|
|
||||||
|
|
||||||
focused_window.handle_input(input_.clone());
|
|
||||||
|
|
||||||
TimeoutAction::ToDuration(Duration::from_secs(1) / rate)
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
focused_window.handle_input(input);
|
focused_window.handle_input(input);
|
||||||
}
|
}
|
||||||
wl_keyboard::KeyState::Released => {
|
wl_keyboard::KeyState::Released if !keysym.is_modifier_key() => {
|
||||||
let input = if keysym.is_modifier_key() {
|
let input = PlatformInput::KeyUp(KeyUpEvent {
|
||||||
PlatformInput::ModifiersChanged(ModifiersChangedEvent {
|
keystroke: Keystroke::from_xkb(keymap_state, state.modifiers, keycode),
|
||||||
modifiers: state.modifiers,
|
});
|
||||||
})
|
|
||||||
} else {
|
|
||||||
PlatformInput::KeyUp(KeyUpEvent {
|
|
||||||
keystroke: Keystroke::from_xkb(
|
|
||||||
keymap_state,
|
|
||||||
state.modifiers,
|
|
||||||
keycode,
|
|
||||||
),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
if !keysym.is_modifier_key() {
|
state.repeat.current_keysym = None;
|
||||||
state.repeat.current_keysym = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ pub(crate) fn modifiers_from_state(state: xproto::KeyButMask) -> Modifiers {
|
|||||||
control: state.contains(xproto::KeyButMask::CONTROL),
|
control: state.contains(xproto::KeyButMask::CONTROL),
|
||||||
alt: state.contains(xproto::KeyButMask::MOD1),
|
alt: state.contains(xproto::KeyButMask::MOD1),
|
||||||
shift: state.contains(xproto::KeyButMask::SHIFT),
|
shift: state.contains(xproto::KeyButMask::SHIFT),
|
||||||
command: state.contains(xproto::KeyButMask::MOD4),
|
platform: state.contains(xproto::KeyButMask::MOD4),
|
||||||
function: false,
|
function: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ unsafe fn read_modifiers(native_event: id) -> Modifiers {
|
|||||||
control,
|
control,
|
||||||
alt,
|
alt,
|
||||||
shift,
|
shift,
|
||||||
command,
|
platform: command,
|
||||||
function,
|
function,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,7 +323,7 @@ unsafe fn parse_keystroke(native_event: id) -> Keystroke {
|
|||||||
control,
|
control,
|
||||||
alt,
|
alt,
|
||||||
shift,
|
shift,
|
||||||
command,
|
platform: command,
|
||||||
function,
|
function,
|
||||||
},
|
},
|
||||||
key,
|
key,
|
||||||
|
@ -279,7 +279,7 @@ impl MacPlatform {
|
|||||||
let mut mask = NSEventModifierFlags::empty();
|
let mut mask = NSEventModifierFlags::empty();
|
||||||
for (modifier, flag) in &[
|
for (modifier, flag) in &[
|
||||||
(
|
(
|
||||||
keystroke.modifiers.command,
|
keystroke.modifiers.platform,
|
||||||
NSEventModifierFlags::NSCommandKeyMask,
|
NSEventModifierFlags::NSCommandKeyMask,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -853,7 +853,7 @@ impl PlatformWindow for MacWindow {
|
|||||||
control,
|
control,
|
||||||
alt,
|
alt,
|
||||||
shift,
|
shift,
|
||||||
command,
|
platform: command,
|
||||||
function,
|
function,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ impl WindowsWindowInner {
|
|||||||
control: self.is_virtual_key_pressed(VK_CONTROL),
|
control: self.is_virtual_key_pressed(VK_CONTROL),
|
||||||
alt: self.is_virtual_key_pressed(VK_MENU),
|
alt: self.is_virtual_key_pressed(VK_MENU),
|
||||||
shift: self.is_virtual_key_pressed(VK_SHIFT),
|
shift: self.is_virtual_key_pressed(VK_SHIFT),
|
||||||
command: self.is_virtual_key_pressed(VK_LWIN) || self.is_virtual_key_pressed(VK_RWIN),
|
platform: self.is_virtual_key_pressed(VK_LWIN) || self.is_virtual_key_pressed(VK_RWIN),
|
||||||
function: false,
|
function: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ impl<D: PickerDelegate> Picker<D> {
|
|||||||
.id(("item", ix))
|
.id(("item", ix))
|
||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
.on_click(cx.listener(move |this, event: &ClickEvent, cx| {
|
.on_click(cx.listener(move |this, event: &ClickEvent, cx| {
|
||||||
this.handle_click(ix, event.down.modifiers.command, cx)
|
this.handle_click(ix, event.down.modifiers.secondary(), cx)
|
||||||
}))
|
}))
|
||||||
// As of this writing, GPUI intercepts `ctrl-[mouse-event]`s on macOS
|
// As of this writing, GPUI intercepts `ctrl-[mouse-event]`s on macOS
|
||||||
// and produces right mouse button events. This matches platforms norms
|
// and produces right mouse button events. This matches platforms norms
|
||||||
@ -427,7 +427,9 @@ impl<D: PickerDelegate> Picker<D> {
|
|||||||
.on_mouse_up(
|
.on_mouse_up(
|
||||||
MouseButton::Right,
|
MouseButton::Right,
|
||||||
cx.listener(move |this, event: &MouseUpEvent, cx| {
|
cx.listener(move |this, event: &MouseUpEvent, cx| {
|
||||||
this.handle_click(ix, event.modifiers.command, cx)
|
// We specficially want to use the platform key here, as
|
||||||
|
// ctrl will already be held down for the tab switcher.
|
||||||
|
this.handle_click(ix, event.modifiers.platform, cx)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.children(
|
.children(
|
||||||
|
@ -1456,7 +1456,7 @@ impl ProjectPanel {
|
|||||||
if kind.is_dir() {
|
if kind.is_dir() {
|
||||||
this.toggle_expanded(entry_id, cx);
|
this.toggle_expanded(entry_id, cx);
|
||||||
} else {
|
} else {
|
||||||
if event.down.modifiers.command {
|
if event.down.modifiers.secondary() {
|
||||||
this.split_entry(entry_id, cx);
|
this.split_entry(entry_id, cx);
|
||||||
} else {
|
} else {
|
||||||
this.open_entry(entry_id, event.up.click_count > 1, cx);
|
this.open_entry(entry_id, event.up.click_count > 1, cx);
|
||||||
|
@ -18,7 +18,7 @@ impl AlacModifiers {
|
|||||||
ks.modifiers.alt,
|
ks.modifiers.alt,
|
||||||
ks.modifiers.control,
|
ks.modifiers.control,
|
||||||
ks.modifiers.shift,
|
ks.modifiers.shift,
|
||||||
ks.modifiers.command,
|
ks.modifiers.platform,
|
||||||
) {
|
) {
|
||||||
(false, false, false, false) => AlacModifiers::None,
|
(false, false, false, false) => AlacModifiers::None,
|
||||||
(true, false, false, false) => AlacModifiers::Alt,
|
(true, false, false, false) => AlacModifiers::Alt,
|
||||||
@ -336,7 +336,7 @@ mod test {
|
|||||||
control: false,
|
control: false,
|
||||||
alt: false,
|
alt: false,
|
||||||
shift: false,
|
shift: false,
|
||||||
command: false,
|
platform: false,
|
||||||
function: false,
|
function: false,
|
||||||
},
|
},
|
||||||
key: "🖖🏻".to_string(), //2 char string
|
key: "🖖🏻".to_string(), //2 char string
|
||||||
|
@ -432,7 +432,7 @@ impl TerminalBuilder {
|
|||||||
last_mouse_position: None,
|
last_mouse_position: None,
|
||||||
next_link_id: 0,
|
next_link_id: 0,
|
||||||
selection_phase: SelectionPhase::Ended,
|
selection_phase: SelectionPhase::Ended,
|
||||||
cmd_pressed: false,
|
secondary_pressed: false,
|
||||||
hovered_word: false,
|
hovered_word: false,
|
||||||
url_regex,
|
url_regex,
|
||||||
word_regex,
|
word_regex,
|
||||||
@ -585,7 +585,7 @@ pub struct Terminal {
|
|||||||
scroll_px: Pixels,
|
scroll_px: Pixels,
|
||||||
next_link_id: usize,
|
next_link_id: usize,
|
||||||
selection_phase: SelectionPhase,
|
selection_phase: SelectionPhase,
|
||||||
cmd_pressed: bool,
|
secondary_pressed: bool,
|
||||||
hovered_word: bool,
|
hovered_word: bool,
|
||||||
url_regex: RegexSearch,
|
url_regex: RegexSearch,
|
||||||
word_regex: RegexSearch,
|
word_regex: RegexSearch,
|
||||||
@ -1029,11 +1029,11 @@ impl Terminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_modifiers_change(&mut self, modifiers: &Modifiers) -> bool {
|
pub fn try_modifiers_change(&mut self, modifiers: &Modifiers) -> bool {
|
||||||
let changed = self.cmd_pressed != modifiers.command;
|
let changed = self.secondary_pressed != modifiers.secondary();
|
||||||
if !self.cmd_pressed && modifiers.command {
|
if !self.secondary_pressed && modifiers.secondary() {
|
||||||
self.refresh_hovered_word();
|
self.refresh_hovered_word();
|
||||||
}
|
}
|
||||||
self.cmd_pressed = modifiers.command;
|
self.secondary_pressed = modifiers.secondary();
|
||||||
changed
|
changed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1136,7 +1136,7 @@ impl Terminal {
|
|||||||
self.pty_tx.notify(bytes);
|
self.pty_tx.notify(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if self.cmd_pressed {
|
} else if self.secondary_pressed {
|
||||||
self.word_from_position(Some(position));
|
self.word_from_position(Some(position));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1266,7 +1266,7 @@ impl Terminal {
|
|||||||
let mouse_cell_index = content_index_for_mouse(position, &self.last_content.size);
|
let mouse_cell_index = content_index_for_mouse(position, &self.last_content.size);
|
||||||
if let Some(link) = self.last_content.cells[mouse_cell_index].hyperlink() {
|
if let Some(link) = self.last_content.cells[mouse_cell_index].hyperlink() {
|
||||||
cx.open_url(link.uri());
|
cx.open_url(link.uri());
|
||||||
} else if self.cmd_pressed {
|
} else if self.secondary_pressed {
|
||||||
self.events
|
self.events
|
||||||
.push_back(InternalEvent::FindHyperlink(position, true));
|
.push_back(InternalEvent::FindHyperlink(position, true));
|
||||||
}
|
}
|
||||||
@ -1402,7 +1402,7 @@ impl Terminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_navigate_to_selected_word(&self) -> bool {
|
pub fn can_navigate_to_selected_word(&self) -> bool {
|
||||||
self.cmd_pressed && self.hovered_word
|
self.secondary_pressed && self.hovered_word
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn task(&self) -> Option<&TaskState> {
|
pub fn task(&self) -> Option<&TaskState> {
|
||||||
|
@ -113,7 +113,7 @@ impl RenderOnce for KeyBinding {
|
|||||||
el.child(Key::new("Alt")).child(Key::new("+"))
|
el.child(Key::new("Alt")).child(Key::new("+"))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.when(keystroke.modifiers.command, |el| {
|
.when(keystroke.modifiers.platform, |el| {
|
||||||
match self.platform_style {
|
match self.platform_style {
|
||||||
PlatformStyle::Mac => el.child(KeyIcon::new(IconName::Command)),
|
PlatformStyle::Mac => el.child(KeyIcon::new(IconName::Command)),
|
||||||
PlatformStyle::Linux => {
|
PlatformStyle::Linux => {
|
||||||
|
@ -120,7 +120,7 @@ impl NeovimConnection {
|
|||||||
let special = keystroke.modifiers.shift
|
let special = keystroke.modifiers.shift
|
||||||
|| keystroke.modifiers.control
|
|| keystroke.modifiers.control
|
||||||
|| keystroke.modifiers.alt
|
|| keystroke.modifiers.alt
|
||||||
|| keystroke.modifiers.command
|
|| keystroke.modifiers.platform
|
||||||
|| keystroke.key.len() > 1;
|
|| keystroke.key.len() > 1;
|
||||||
let start = if special { "<" } else { "" };
|
let start = if special { "<" } else { "" };
|
||||||
let shift = if keystroke.modifiers.shift { "S-" } else { "" };
|
let shift = if keystroke.modifiers.shift { "S-" } else { "" };
|
||||||
@ -130,7 +130,7 @@ impl NeovimConnection {
|
|||||||
""
|
""
|
||||||
};
|
};
|
||||||
let alt = if keystroke.modifiers.alt { "M-" } else { "" };
|
let alt = if keystroke.modifiers.alt { "M-" } else { "" };
|
||||||
let cmd = if keystroke.modifiers.command {
|
let cmd = if keystroke.modifiers.platform {
|
||||||
"D-"
|
"D-"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
Loading…
Reference in New Issue
Block a user