Detailed changes
@@ -219,7 +219,7 @@
"context": "BufferSearchBar && in_replace",
"bindings": {
"enter": "search::ReplaceNext",
- "cmd-enter": "search::ReplaceAll"
+ "ctrl-enter": "search::ReplaceAll"
}
},
{
@@ -258,7 +258,7 @@
"bindings": {
"escape": "project_search::ToggleFocus",
"alt-tab": "search::CycleMode",
- "cmd-shift-h": "search::ToggleReplace",
+ "ctrl-shift-h": "search::ToggleReplace",
"alt-ctrl-g": "search::ActivateRegexMode",
"alt-ctrl-x": "search::ActivateTextMode"
}
@@ -304,8 +304,10 @@
}
],
"ctrl-alt-shift-down": "editor::DuplicateLine",
- "ctrl-shift-right": "editor::SelectLargerSyntaxNode",
- "ctrl-shift-left": "editor::SelectSmallerSyntaxNode",
+ "ctrl-shift-left": "editor::SelectToPreviousWordStart",
+ "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": [
"editor::SelectNext",
{
@@ -354,14 +356,14 @@
"ctrl-shift-]": "editor::UnfoldLines",
"ctrl-space": "editor::ShowCompletions",
"ctrl-.": "editor::ToggleCodeActions",
- "alt-cmd-r": "editor::RevealInFinder",
+ "alt-ctrl-r": "editor::RevealInFinder",
"ctrl-alt-shift-c": "editor::DisplayCursorNames"
}
},
{
"context": "Editor && mode == full",
"bindings": {
- "cmd-shift-o": "outline::Toggle",
+ "ctrl-shift-o": "outline::Toggle",
"ctrl-g": "go_to_line::Toggle"
}
},
@@ -419,7 +421,7 @@
"ctrl-shift-f": "pane::DeploySearch",
"ctrl-k ctrl-s": "zed::OpenKeymap",
"ctrl-k ctrl-t": "theme_selector::Toggle",
- "ctrl-t": "project_symbols::Toggle",
+ "ctrl-shift-t": "project_symbols::Toggle",
"ctrl-p": "file_finder::Toggle",
"ctrl-tab": "tab_switcher::Toggle",
"ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
@@ -549,7 +551,7 @@
"delete": "project_panel::Delete",
"ctrl-backspace": ["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"
}
},
@@ -610,7 +612,12 @@
"pagedown": ["terminal::SendKeystroke", "pagedown"],
"escape": ["terminal::SendKeystroke", "escape"],
"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.
"active_pane_magnification": 1.0,
// 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",
// Whether to enable vim modes and key bindings
"vim_mode": false,
@@ -92,7 +92,8 @@ pub enum ShowScrollbar {
#[serde(rename_all = "snake_case")]
pub enum MultiCursorModifier {
Alt,
- Cmd,
+ #[serde(alias = "cmd", alias = "ctrl")]
+ CmdOrCtrl,
}
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
@@ -449,7 +449,8 @@ impl EditorElement {
},
cx,
);
- } else if modifiers.shift && !modifiers.control && !modifiers.alt && !modifiers.command {
+ } else if modifiers.shift && !modifiers.control && !modifiers.alt && !modifiers.secondary()
+ {
editor.select(
SelectPhase::Extend {
position,
@@ -461,7 +462,7 @@ impl EditorElement {
let multi_cursor_setting = EditorSettings::get_global(cx).multi_cursor_modifier;
let multi_cursor_modifier = match multi_cursor_setting {
MultiCursorModifier::Alt => modifiers.alt,
- MultiCursorModifier::Cmd => modifiers.command,
+ MultiCursorModifier::CmdOrCtrl => modifiers.secondary(),
};
editor.select(
SelectPhase::Begin {
@@ -513,8 +514,8 @@ impl EditorElement {
let multi_cursor_setting = EditorSettings::get_global(cx).multi_cursor_modifier;
let multi_cursor_modifier = match multi_cursor_setting {
- MultiCursorModifier::Alt => event.modifiers.command,
- MultiCursorModifier::Cmd => event.modifiers.alt,
+ MultiCursorModifier::Alt => event.modifiers.secondary(),
+ MultiCursorModifier::CmdOrCtrl => event.modifiers.alt,
};
if !pending_nonempty_selections && multi_cursor_modifier && text_hitbox.is_hovered(cx) {
@@ -93,7 +93,7 @@ impl Editor {
modifiers: Modifiers,
cx: &mut ViewContext<Self>,
) {
- if !modifiers.command || self.has_pending_selection() {
+ if !modifiers.secondary() || self.has_pending_selection() {
self.hide_hovered_link(cx);
return;
}
@@ -113,7 +113,7 @@ impl Editor {
&snapshot,
point_for_position,
self,
- modifiers.command,
+ modifiers.secondary(),
modifiers.shift,
cx,
);
@@ -256,7 +256,7 @@ pub fn update_inlay_link_and_hover_points(
snapshot: &EditorSnapshot,
point_for_position: PointForPosition,
editor: &mut Editor,
- cmd_held: bool,
+ secondary_held: bool,
shift_held: bool,
cx: &mut ViewContext<'_, Editor>,
) {
@@ -394,7 +394,9 @@ pub fn update_inlay_link_and_hover_points(
if let Some((language_server_id, 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;
show_link_definition(
shift_held,
@@ -762,7 +764,7 @@ mod tests {
let «variable» = A;
"});
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
cx.run_until_parked();
// Assert no link highlights
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;
cx.background_executor.run_until_parked();
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;
cx.background_executor.run_until_parked();
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
@@ -868,7 +870,7 @@ mod tests {
// No definitions returned
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;
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;
cx.background_executor.run_until_parked();
@@ -928,7 +930,7 @@ mod tests {
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.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
fn test() { do_work(); }
@@ -940,7 +942,7 @@ mod tests {
fn test() { do_work(); }
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.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
fn test() { do_work(); }
@@ -948,7 +950,7 @@ mod tests {
"});
// 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
.handle_request::<GotoDefinition, _, _>(move |_, _| async move {
// 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;
cx.background_executor.run_until_parked();
cx.assert_editor_state(indoc! {"
@@ -1030,7 +1032,7 @@ mod tests {
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();
assert!(requests.try_next().is_err());
cx.assert_editor_text_highlights::<HoveredLinkState>(indoc! {"
@@ -1144,7 +1146,7 @@ mod tests {
});
// Press cmd to trigger highlight
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.update_editor(|editor, 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:?}");
});
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
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.assert_editor_state(indoc! {"
struct «TestStructˇ»;
@@ -1207,12 +1209,12 @@ mod tests {
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! {"
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!(
cx.opened_url(),
Some("https://zed.dev/channel/had-(oops)".into())
@@ -1235,12 +1237,12 @@ mod tests {
let screen_coord =
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>(
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()));
}
@@ -1260,12 +1262,12 @@ mod tests {
let screen_coord =
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>(
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()));
}
@@ -1386,7 +1388,7 @@ mod tests {
});
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.assert_editor_state(indoc! {"
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.assert_editor_state(indoc! {"
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;
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
open_file_picker(&workspace, cx);
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("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);
picker.update(cx, |finder, _| {
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 with a shortcut
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
let picker = open_file_picker(&workspace, cx);
picker.update(cx, |finder, _| {
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
// Open file on modifiers release
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
cx.dispatch_action(Toggle);
cx.simulate_modifiers_change(Modifiers::none());
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 with a shortcut
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
let picker = open_file_picker(&workspace, cx);
picker.update(cx, |finder, _| {
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
// 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.simulate_modifiers_change(Modifiers::none());
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;
- cx.simulate_modifiers_change(Modifiers::command());
+ cx.simulate_modifiers_change(Modifiers::secondary_key());
open_file_picker(&workspace, cx);
cx.simulate_modifiers_change(Modifiers::command_shift());
@@ -1510,12 +1510,12 @@ impl Interactivity {
};
if self.location.is_some()
&& 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({
move |e: &crate::ModifiersChangedEvent, _phase, cx| {
- if e.modifiers.command != command_held
+ if e.modifiers.secondary() != secondary_held
&& text_bounds.contains(&cx.mouse_position())
{
cx.refresh();
@@ -37,7 +37,7 @@ impl Keystroke {
control: self.modifiers.control,
alt: false,
shift: false,
- command: false,
+ platform: false,
function: false,
},
key: ime_key.to_string(),
@@ -62,7 +62,7 @@ impl Keystroke {
let mut control = false;
let mut alt = false;
let mut shift = false;
- let mut command = false;
+ let mut platform = false;
let mut function = false;
let mut key = None;
let mut ime_key = None;
@@ -73,8 +73,13 @@ impl Keystroke {
"ctrl" => control = true,
"alt" => alt = true,
"shift" => shift = true,
- "cmd" => command = 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 next.is_empty() && source.ends_with('-') {
@@ -101,7 +106,7 @@ impl Keystroke {
control,
alt,
shift,
- command,
+ platform,
function,
},
key,
@@ -114,7 +119,7 @@ impl Keystroke {
/// be able to simulate typing "space", etc.
pub fn with_simulated_ime(mut self) -> Self {
if self.ime_key.is_none()
- && !self.modifiers.command
+ && !self.modifiers.platform
&& !self.modifiers.control
&& !self.modifiers.function
&& !self.modifiers.alt
@@ -147,8 +152,15 @@ impl std::fmt::Display for Keystroke {
if self.modifiers.alt {
f.write_char('⌥')?;
}
- if self.modifiers.command {
+ if self.modifiers.platform {
+ #[cfg(target_os = "macos")]
f.write_char('⌘')?;
+
+ #[cfg(target_os = "linux")]
+ f.write_char('❖')?;
+
+ #[cfg(target_os = "windows")]
+ f.write_char('⊞')?;
}
if self.modifiers.shift {
f.write_char('⇧')?;
@@ -188,7 +200,8 @@ pub struct Modifiers {
/// The command key, on macos
/// the windows key, on windows
- pub command: bool,
+ /// the super key, on linux
+ pub platform: bool,
/// The function key
pub function: bool,
@@ -197,7 +210,22 @@ pub struct Modifiers {
impl Modifiers {
/// Returns true if any modifier key is pressed
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
@@ -205,10 +233,45 @@ impl Modifiers {
Default::default()
}
- /// helper method for Modifiers with just command
+ /// helper method for Modifiers with just the command key
pub fn command() -> 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()
}
}
@@ -233,7 +296,7 @@ impl Modifiers {
pub fn command_shift() -> Modifiers {
Modifiers {
shift: true,
- command: true,
+ platform: true,
..Default::default()
}
}
@@ -243,7 +306,7 @@ impl Modifiers {
(other.control || !self.control)
&& (other.alt || !self.alt)
&& (other.shift || !self.shift)
- && (other.command || !self.command)
+ && (other.platform || !self.platform)
&& (other.function || !self.function)
}
}
@@ -190,7 +190,7 @@ impl WaylandClient {
control: false,
alt: false,
function: false,
- command: false,
+ platform: false,
},
scroll_direction: -1.0,
axis_source: AxisSource::Wheel,
@@ -692,6 +692,11 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
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();
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.alt = alt;
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 {
key,
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 {
return;
};
@@ -725,80 +738,56 @@ impl Dispatch<wl_keyboard::WlKeyboard, ()> for WaylandClientState {
let keysym = keymap_state.key_get_one_sym(keycode);
match key_state {
- wl_keyboard::KeyState::Pressed => {
- let input = if keysym.is_modifier_key() {
- PlatformInput::ModifiersChanged(ModifiersChangedEvent {
- modifiers: state.modifiers,
+ wl_keyboard::KeyState::Pressed if !keysym.is_modifier_key() => {
+ let input = PlatformInput::KeyDown(KeyDownEvent {
+ keystroke: Keystroke::from_xkb(keymap_state, state.modifiers, keycode),
+ 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 {
- 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();
- }
+ .unwrap();
drop(state);
focused_window.handle_input(input);
}
- wl_keyboard::KeyState::Released => {
- let input = if keysym.is_modifier_key() {
- PlatformInput::ModifiersChanged(ModifiersChangedEvent {
- modifiers: state.modifiers,
- })
- } else {
- PlatformInput::KeyUp(KeyUpEvent {
- keystroke: Keystroke::from_xkb(
- keymap_state,
- state.modifiers,
- keycode,
- ),
- })
- };
+ wl_keyboard::KeyState::Released if !keysym.is_modifier_key() => {
+ let input = 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);
@@ -18,7 +18,7 @@ pub(crate) fn modifiers_from_state(state: xproto::KeyButMask) -> Modifiers {
control: state.contains(xproto::KeyButMask::CONTROL),
alt: state.contains(xproto::KeyButMask::MOD1),
shift: state.contains(xproto::KeyButMask::SHIFT),
- command: state.contains(xproto::KeyButMask::MOD4),
+ platform: state.contains(xproto::KeyButMask::MOD4),
function: false,
}
}
@@ -77,7 +77,7 @@ unsafe fn read_modifiers(native_event: id) -> Modifiers {
control,
alt,
shift,
- command,
+ platform: command,
function,
}
}
@@ -323,7 +323,7 @@ unsafe fn parse_keystroke(native_event: id) -> Keystroke {
control,
alt,
shift,
- command,
+ platform: command,
function,
},
key,
@@ -279,7 +279,7 @@ impl MacPlatform {
let mut mask = NSEventModifierFlags::empty();
for (modifier, flag) in &[
(
- keystroke.modifiers.command,
+ keystroke.modifiers.platform,
NSEventModifierFlags::NSCommandKeyMask,
),
(
@@ -853,7 +853,7 @@ impl PlatformWindow for MacWindow {
control,
alt,
shift,
- command,
+ platform: command,
function,
}
}
@@ -239,7 +239,7 @@ impl WindowsWindowInner {
control: self.is_virtual_key_pressed(VK_CONTROL),
alt: self.is_virtual_key_pressed(VK_MENU),
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,
}
}
@@ -418,7 +418,7 @@ impl<D: PickerDelegate> Picker<D> {
.id(("item", ix))
.cursor_pointer()
.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
// and produces right mouse button events. This matches platforms norms
@@ -427,7 +427,9 @@ impl<D: PickerDelegate> Picker<D> {
.on_mouse_up(
MouseButton::Right,
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(
@@ -1456,7 +1456,7 @@ impl ProjectPanel {
if kind.is_dir() {
this.toggle_expanded(entry_id, cx);
} else {
- if event.down.modifiers.command {
+ if event.down.modifiers.secondary() {
this.split_entry(entry_id, cx);
} else {
this.open_entry(entry_id, event.up.click_count > 1, cx);
@@ -18,7 +18,7 @@ impl AlacModifiers {
ks.modifiers.alt,
ks.modifiers.control,
ks.modifiers.shift,
- ks.modifiers.command,
+ ks.modifiers.platform,
) {
(false, false, false, false) => AlacModifiers::None,
(true, false, false, false) => AlacModifiers::Alt,
@@ -336,7 +336,7 @@ mod test {
control: false,
alt: false,
shift: false,
- command: false,
+ platform: false,
function: false,
},
key: "🖖🏻".to_string(), //2 char string
@@ -432,7 +432,7 @@ impl TerminalBuilder {
last_mouse_position: None,
next_link_id: 0,
selection_phase: SelectionPhase::Ended,
- cmd_pressed: false,
+ secondary_pressed: false,
hovered_word: false,
url_regex,
word_regex,
@@ -585,7 +585,7 @@ pub struct Terminal {
scroll_px: Pixels,
next_link_id: usize,
selection_phase: SelectionPhase,
- cmd_pressed: bool,
+ secondary_pressed: bool,
hovered_word: bool,
url_regex: RegexSearch,
word_regex: RegexSearch,
@@ -1029,11 +1029,11 @@ impl Terminal {
}
pub fn try_modifiers_change(&mut self, modifiers: &Modifiers) -> bool {
- let changed = self.cmd_pressed != modifiers.command;
- if !self.cmd_pressed && modifiers.command {
+ let changed = self.secondary_pressed != modifiers.secondary();
+ if !self.secondary_pressed && modifiers.secondary() {
self.refresh_hovered_word();
}
- self.cmd_pressed = modifiers.command;
+ self.secondary_pressed = modifiers.secondary();
changed
}
@@ -1136,7 +1136,7 @@ impl Terminal {
self.pty_tx.notify(bytes);
}
}
- } else if self.cmd_pressed {
+ } else if self.secondary_pressed {
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);
if let Some(link) = self.last_content.cells[mouse_cell_index].hyperlink() {
cx.open_url(link.uri());
- } else if self.cmd_pressed {
+ } else if self.secondary_pressed {
self.events
.push_back(InternalEvent::FindHyperlink(position, true));
}
@@ -1402,7 +1402,7 @@ impl Terminal {
}
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> {
@@ -113,7 +113,7 @@ impl RenderOnce for KeyBinding {
el.child(Key::new("Alt")).child(Key::new("+"))
}
})
- .when(keystroke.modifiers.command, |el| {
+ .when(keystroke.modifiers.platform, |el| {
match self.platform_style {
PlatformStyle::Mac => el.child(KeyIcon::new(IconName::Command)),
PlatformStyle::Linux => {
@@ -120,7 +120,7 @@ impl NeovimConnection {
let special = keystroke.modifiers.shift
|| keystroke.modifiers.control
|| keystroke.modifiers.alt
- || keystroke.modifiers.command
+ || keystroke.modifiers.platform
|| keystroke.key.len() > 1;
let start = if special { "<" } else { "" };
let shift = if keystroke.modifiers.shift { "S-" } else { "" };
@@ -130,7 +130,7 @@ impl NeovimConnection {
""
};
let alt = if keystroke.modifiers.alt { "M-" } else { "" };
- let cmd = if keystroke.modifiers.command {
+ let cmd = if keystroke.modifiers.platform {
"D-"
} else {
""