Add an action listener to workspace for ActivatePreviousItem and ActivateNextItem (#42588)
Release Notes: - pane::ActivatePreviousItem and pane::ActivateNextItem now toggle the most recent pane when called from a dock panel a couple months ago i posted a work around that used `SendKeystrokes` to cycle through pane items when focused on a dock. #35253 this pr would add this functionality to the these actions by default. i implemented this by adding an action listener to the workspace level. ------ if the current context is a dock that does not hold a pane it retrieves the most recent pane from `activation_history` and activates the next item on that pane instead. - `"Pane > Editor"` cycles through the current pane like normal - `"Dock > Pane > Terminal"` also cycles through the pane items like normal - `"Dock > (Any Child that is not a child of Pane)"` cycles through the items of the most recent pane. this is the standard behavior in VS Code i believe. in the video below you can see the actions cycling through the editor like normal when focus is on the editor. then you can see the editor continue to cycle when the focus is on the project panel. and that the focus stays on the project panel. and you can see the action cycle the terminal items when the focus is moved to the terminal https://github.com/user-attachments/assets/999ab740-d2fa-4d00-9e53-f7605217e6ac the only thing i noticed is that for this to work the keybindings must be set above `Pane` so they have to be set globally or on workspace. otherwise they do not match in the context
This commit is contained in:
@@ -5967,6 +5967,88 @@ impl Workspace {
|
||||
},
|
||||
))
|
||||
.on_action(cx.listener(Workspace::toggle_centered_layout))
|
||||
.on_action(cx.listener(
|
||||
|workspace: &mut Workspace, _action: &pane::ActivateNextItem, window, cx| {
|
||||
if let Some(active_dock) = workspace.active_dock(window, cx) {
|
||||
let dock = active_dock.read(cx);
|
||||
if let Some(active_panel) = dock.active_panel() {
|
||||
if active_panel.pane(cx).is_none() {
|
||||
let mut recent_pane: Option<Entity<Pane>> = None;
|
||||
let mut recent_timestamp = 0;
|
||||
for pane_handle in workspace.panes() {
|
||||
let pane = pane_handle.read(cx);
|
||||
for entry in pane.activation_history() {
|
||||
if entry.timestamp > recent_timestamp {
|
||||
recent_timestamp = entry.timestamp;
|
||||
recent_pane = Some(pane_handle.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pane) = recent_pane {
|
||||
pane.update(cx, |pane, cx| {
|
||||
let current_index = pane.active_item_index();
|
||||
let items_len = pane.items_len();
|
||||
if items_len > 0 {
|
||||
let next_index = if current_index + 1 < items_len {
|
||||
current_index + 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
pane.activate_item(
|
||||
next_index, false, false, window, cx,
|
||||
);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cx.propagate();
|
||||
},
|
||||
))
|
||||
.on_action(cx.listener(
|
||||
|workspace: &mut Workspace, _action: &pane::ActivatePreviousItem, window, cx| {
|
||||
if let Some(active_dock) = workspace.active_dock(window, cx) {
|
||||
let dock = active_dock.read(cx);
|
||||
if let Some(active_panel) = dock.active_panel() {
|
||||
if active_panel.pane(cx).is_none() {
|
||||
let mut recent_pane: Option<Entity<Pane>> = None;
|
||||
let mut recent_timestamp = 0;
|
||||
for pane_handle in workspace.panes() {
|
||||
let pane = pane_handle.read(cx);
|
||||
for entry in pane.activation_history() {
|
||||
if entry.timestamp > recent_timestamp {
|
||||
recent_timestamp = entry.timestamp;
|
||||
recent_pane = Some(pane_handle.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pane) = recent_pane {
|
||||
pane.update(cx, |pane, cx| {
|
||||
let current_index = pane.active_item_index();
|
||||
let items_len = pane.items_len();
|
||||
if items_len > 0 {
|
||||
let prev_index = if current_index > 0 {
|
||||
current_index - 1
|
||||
} else {
|
||||
items_len.saturating_sub(1)
|
||||
};
|
||||
pane.activate_item(
|
||||
prev_index, false, false, window, cx,
|
||||
);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cx.propagate();
|
||||
},
|
||||
))
|
||||
.on_action(cx.listener(Workspace::cancel))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user