fix(floating-panes): handle uncaught errors (#3944)
* fix(floating-panes): handle uncaught errors * style(fmt): rustfmt
This commit is contained in:
parent
9d3b4c5391
commit
ce6a08f86b
4 changed files with 119 additions and 59 deletions
|
|
@ -761,16 +761,12 @@ impl<'a> FloatingPaneGrid<'a> {
|
|||
a_pane.y().cmp(&b_pane.y())
|
||||
}
|
||||
});
|
||||
let active_pane_position = panes
|
||||
.iter()
|
||||
.position(|(id, _)| id == current_pane_id)
|
||||
.unwrap();
|
||||
let active_pane_position = panes.iter().position(|(id, _)| id == current_pane_id)?;
|
||||
|
||||
let next_active_pane_id = panes
|
||||
.get(active_pane_position + 1)
|
||||
.or_else(|| panes.get(0))
|
||||
.map(|p| p.0)
|
||||
.unwrap();
|
||||
.map(|p| p.0)?;
|
||||
Some(next_active_pane_id)
|
||||
}
|
||||
pub fn previous_selectable_pane_id(&self, current_pane_id: &PaneId) -> Option<PaneId> {
|
||||
|
|
|
|||
|
|
@ -88,12 +88,16 @@ impl FloatingPanes {
|
|||
}
|
||||
pub fn stack(&self) -> Option<FloatingPanesStack> {
|
||||
if self.panes_are_visible() {
|
||||
let layers = self
|
||||
let layers: Vec<PaneGeom> = self
|
||||
.z_indices
|
||||
.iter()
|
||||
.map(|pane_id| self.panes.get(pane_id).unwrap().position_and_size())
|
||||
.filter_map(|pane_id| self.panes.get(pane_id).map(|p| p.position_and_size()))
|
||||
.collect();
|
||||
Some(FloatingPanesStack { layers })
|
||||
if layers.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(FloatingPanesStack { layers })
|
||||
}
|
||||
} else if self.has_pinned_panes() {
|
||||
let layers = self
|
||||
.z_indices
|
||||
|
|
@ -257,7 +261,8 @@ impl FloatingPanes {
|
|||
pub fn position_floating_pane_layout(
|
||||
&mut self,
|
||||
floating_pane_layout: &FloatingPaneLayout,
|
||||
) -> PaneGeom {
|
||||
) -> Result<PaneGeom> {
|
||||
let err_context = || format!("failed to find position for floating pane");
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
let floating_pane_grid = FloatingPaneGrid::new(
|
||||
|
|
@ -266,7 +271,9 @@ impl FloatingPanes {
|
|||
display_area,
|
||||
viewport,
|
||||
);
|
||||
let mut position = floating_pane_grid.find_room_for_new_pane().unwrap(); // TODO: no unwrap
|
||||
let mut position = floating_pane_grid
|
||||
.find_room_for_new_pane()
|
||||
.with_context(err_context)?;
|
||||
if let Some(x) = &floating_pane_layout.x {
|
||||
position.x = x.to_position(viewport.cols);
|
||||
}
|
||||
|
|
@ -301,7 +308,7 @@ impl FloatingPanes {
|
|||
.y
|
||||
.saturating_sub((position.y + position.rows.as_usize()) - viewport.rows);
|
||||
}
|
||||
position
|
||||
Ok(position)
|
||||
}
|
||||
pub fn first_floating_pane_id(&self) -> Option<PaneId> {
|
||||
self.panes.keys().next().copied()
|
||||
|
|
@ -432,7 +439,7 @@ impl FloatingPanes {
|
|||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.resize(new_screen_size).unwrap();
|
||||
floating_pane_grid.resize(new_screen_size).non_fatal();
|
||||
self.set_force_render();
|
||||
}
|
||||
|
||||
|
|
@ -530,17 +537,20 @@ impl FloatingPanes {
|
|||
Some(p) => {
|
||||
// render previously active pane so that its frame does not remain actively
|
||||
// colored
|
||||
let previously_active_pane = self
|
||||
.panes
|
||||
.get_mut(self.active_panes.get(&client_id).unwrap())
|
||||
.unwrap();
|
||||
let Some(previously_active_pane) = self.get_active_pane_mut(client_id) else {
|
||||
log::error!("Failed to get active pane");
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
previously_active_pane.set_should_render(true);
|
||||
// we render the full viewport to remove any ui elements that might have been
|
||||
// there before (eg. another user's cursor)
|
||||
previously_active_pane.render_full_viewport();
|
||||
|
||||
let next_active_pane = self.panes.get_mut(&p).unwrap();
|
||||
let Some(next_active_pane) = self.get_pane_mut(p) else {
|
||||
log::error!("Failed to get next active pane");
|
||||
return Ok(false);
|
||||
};
|
||||
next_active_pane.set_should_render(true);
|
||||
// we render the full viewport to remove any ui elements that might have been
|
||||
// there before (eg. another user's cursor)
|
||||
|
|
@ -588,9 +598,10 @@ impl FloatingPanes {
|
|||
display_area,
|
||||
viewport,
|
||||
);
|
||||
let pane_id = floating_pane_grid.pane_id_on_edge(direction).unwrap();
|
||||
self.focus_pane(pane_id, client_id);
|
||||
self.set_force_render();
|
||||
if let Some(pane_id) = floating_pane_grid.pane_id_on_edge(direction) {
|
||||
self.focus_pane(pane_id, client_id);
|
||||
self.set_force_render();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_active_pane_down(&mut self, client_id: ClientId) {
|
||||
|
|
@ -641,7 +652,7 @@ impl FloatingPanes {
|
|||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_left(&pane_id).unwrap();
|
||||
floating_pane_grid.move_pane_left(&pane_id).non_fatal();
|
||||
self.set_force_render();
|
||||
}
|
||||
pub fn move_active_pane_right(&mut self, client_id: ClientId) {
|
||||
|
|
@ -658,7 +669,7 @@ impl FloatingPanes {
|
|||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_right(&pane_id).unwrap();
|
||||
floating_pane_grid.move_pane_right(&pane_id).non_fatal();
|
||||
self.set_force_render();
|
||||
}
|
||||
pub fn move_active_pane(
|
||||
|
|
@ -667,8 +678,9 @@ impl FloatingPanes {
|
|||
_os_api: &mut Box<dyn ServerOsApi>,
|
||||
client_id: ClientId,
|
||||
) {
|
||||
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
|
||||
self.move_pane(search_backwards, active_pane_id)
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
self.move_pane(search_backwards, active_pane_id)
|
||||
}
|
||||
}
|
||||
pub fn move_pane(&mut self, search_backwards: bool, pane_id: PaneId) {
|
||||
let new_position_id = {
|
||||
|
|
@ -685,11 +697,17 @@ impl FloatingPanes {
|
|||
}
|
||||
};
|
||||
if let Some(new_position_id) = new_position_id {
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let Some(current_position) = self.panes.get(&pane_id) else {
|
||||
log::error!("Failed to find current position");
|
||||
return;
|
||||
};
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
let new_position = self.panes.get_mut(&new_position_id).unwrap();
|
||||
let Some(new_position) = self.panes.get_mut(&new_position_id) else {
|
||||
log::error!("Failed to find new position");
|
||||
return;
|
||||
};
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
|
|
@ -698,7 +716,10 @@ impl FloatingPanes {
|
|||
}
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
let Some(current_position) = self.panes.get_mut(&pane_id) else {
|
||||
log::error!("Failed to find current position");
|
||||
return;
|
||||
};
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
|
|
@ -801,8 +822,16 @@ impl FloatingPanes {
|
|||
panes.sort_by(|(a_id, _a_pane), (b_id, _b_pane)| {
|
||||
// TODO: continue
|
||||
Ord::cmp(
|
||||
&self.z_indices.iter().position(|id| id == *b_id).unwrap(),
|
||||
&self.z_indices.iter().position(|id| id == *a_id).unwrap(),
|
||||
&self
|
||||
.z_indices
|
||||
.iter()
|
||||
.position(|id| id == *b_id)
|
||||
.unwrap_or(0),
|
||||
&self
|
||||
.z_indices
|
||||
.iter()
|
||||
.position(|id| id == *a_id)
|
||||
.unwrap_or(0),
|
||||
)
|
||||
});
|
||||
Ok(panes
|
||||
|
|
@ -832,8 +861,16 @@ impl FloatingPanes {
|
|||
panes.sort_by(|(a_id, _a_pane), (b_id, _b_pane)| {
|
||||
// TODO: continue
|
||||
Ord::cmp(
|
||||
&self.z_indices.iter().position(|id| id == *b_id).unwrap(),
|
||||
&self.z_indices.iter().position(|id| id == *a_id).unwrap(),
|
||||
&self
|
||||
.z_indices
|
||||
.iter()
|
||||
.position(|id| id == *b_id)
|
||||
.unwrap_or(0),
|
||||
&self
|
||||
.z_indices
|
||||
.iter()
|
||||
.position(|id| id == *a_id)
|
||||
.unwrap_or(0),
|
||||
)
|
||||
});
|
||||
Ok(panes
|
||||
|
|
@ -850,8 +887,16 @@ impl FloatingPanes {
|
|||
|
||||
panes.sort_by(|(a_id, _a_pane), (b_id, _b_pane)| {
|
||||
Ord::cmp(
|
||||
&self.z_indices.iter().position(|id| id == *b_id).unwrap(),
|
||||
&self.z_indices.iter().position(|id| id == *a_id).unwrap(),
|
||||
&self
|
||||
.z_indices
|
||||
.iter()
|
||||
.position(|id| id == *b_id)
|
||||
.unwrap_or(0),
|
||||
&self
|
||||
.z_indices
|
||||
.iter()
|
||||
.position(|id| id == *a_id)
|
||||
.unwrap_or(0),
|
||||
)
|
||||
});
|
||||
panes.iter().find(|(_, p)| p.contains(point)).is_some()
|
||||
|
|
@ -862,7 +907,7 @@ impl FloatingPanes {
|
|||
search_selectable: bool,
|
||||
) -> Option<&mut Box<dyn Pane>> {
|
||||
self.get_pane_id_at(position, search_selectable)
|
||||
.unwrap()
|
||||
.ok()?
|
||||
.and_then(|pane_id| self.panes.get_mut(&pane_id))
|
||||
}
|
||||
pub fn set_pane_being_moved_with_mouse(&mut self, pane_id: PaneId, position: Position) {
|
||||
|
|
@ -875,7 +920,10 @@ impl FloatingPanes {
|
|||
// true => changed position
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
let (pane_id, previous_position) = self.pane_being_moved_with_mouse.unwrap();
|
||||
let Some((pane_id, previous_position)) = self.pane_being_moved_with_mouse else {
|
||||
log::error!("Pane is not being moved with mousd");
|
||||
return false;
|
||||
};
|
||||
if click_position == &previous_position {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -889,7 +937,7 @@ impl FloatingPanes {
|
|||
);
|
||||
floating_pane_grid
|
||||
.move_pane_by(pane_id, move_x_by, move_y_by)
|
||||
.unwrap();
|
||||
.non_fatal();
|
||||
self.set_pane_being_moved_with_mouse(pane_id, *click_position);
|
||||
self.set_force_render();
|
||||
true
|
||||
|
|
@ -962,21 +1010,30 @@ impl FloatingPanes {
|
|||
}
|
||||
pub fn switch_active_pane_with(&mut self, _os_api: &mut Box<dyn ServerOsApi>, pane_id: PaneId) {
|
||||
if let Some(active_pane_id) = self.first_active_floating_pane_id() {
|
||||
let current_position = self.panes.get(&active_pane_id).unwrap();
|
||||
let Some(current_position) = self.panes.get(&active_pane_id) else {
|
||||
log::error!("Can't find current position");
|
||||
return;
|
||||
};
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
let new_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
let Some(new_position) = self.panes.get_mut(&pane_id) else {
|
||||
log::error!("Can't find position");
|
||||
return;
|
||||
};
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(new_position, os_api, self.senders, self.character_cell_size).unwrap();
|
||||
resize_pty!(new_position, os_api, self.senders, self.character_cell_size).non_fatal();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
||||
let Some(current_position) = self.panes.get_mut(&active_pane_id) else {
|
||||
log::error!("Can't find current position");
|
||||
return;
|
||||
};
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
|
|
@ -987,7 +1044,7 @@ impl FloatingPanes {
|
|||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
.non_fatal();
|
||||
current_position.set_should_render(true);
|
||||
self.focus_pane_for_all_clients(active_pane_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ impl<'a> LayoutApplier<'a> {
|
|||
for floating_pane_layout in floating_panes_layout {
|
||||
let position_and_size = self
|
||||
.floating_panes
|
||||
.position_floating_pane_layout(&floating_pane_layout);
|
||||
.position_floating_pane_layout(&floating_pane_layout)?;
|
||||
let pid_to_focus = if floating_pane_layout.already_running {
|
||||
self.floating_panes.set_geom_for_pane_with_run(
|
||||
floating_pane_layout.run.clone(),
|
||||
|
|
@ -682,7 +682,8 @@ impl<'a> LayoutApplier<'a> {
|
|||
// contain partial positioning information (eg. just x coords with no y or size) or no
|
||||
// positioning information at all
|
||||
for (pane, floating_pane_layout) in panes_to_apply.drain(..) {
|
||||
pane_applier.apply_floating_panes_layout_to_floating_pane(pane, floating_pane_layout);
|
||||
pane_applier
|
||||
.apply_floating_panes_layout_to_floating_pane(pane, floating_pane_layout)?;
|
||||
}
|
||||
|
||||
// here we apply positioning on a best-effort basis to any remaining panes we've got (these
|
||||
|
|
@ -969,17 +970,18 @@ impl<'a> PaneApplier<'a> {
|
|||
&mut self,
|
||||
mut pane: Box<dyn Pane>,
|
||||
floating_panes_layout: FloatingPaneLayout,
|
||||
) {
|
||||
) -> Result<()> {
|
||||
let position_and_size = self
|
||||
.floating_panes
|
||||
.position_floating_pane_layout(&floating_panes_layout);
|
||||
.position_floating_pane_layout(&floating_panes_layout)?;
|
||||
if let Some(pane_title) = floating_panes_layout.name.as_ref() {
|
||||
pane.set_title(pane_title.into());
|
||||
}
|
||||
if floating_panes_layout.focus.unwrap_or(false) {
|
||||
self.new_focused_pane_id = Some(pane.pid());
|
||||
}
|
||||
self.apply_position_and_size_to_floating_pane(pane, position_and_size)
|
||||
self.apply_position_and_size_to_floating_pane(pane, position_and_size);
|
||||
Ok(())
|
||||
}
|
||||
pub fn apply_position_and_size_to_floating_pane(
|
||||
&mut self,
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ impl Tab {
|
|||
) -> Result<()> {
|
||||
self.swap_layouts
|
||||
.set_base_layout((layout.clone(), floating_panes_layout.clone()));
|
||||
let should_show_floating_panes = LayoutApplier::new(
|
||||
if let Ok(should_show_floating_panes) = LayoutApplier::new(
|
||||
&self.viewport,
|
||||
&self.senders,
|
||||
&self.sixel_image_store,
|
||||
|
|
@ -719,16 +719,19 @@ impl Tab {
|
|||
new_floating_terminal_ids,
|
||||
new_plugin_ids,
|
||||
client_id,
|
||||
)?;
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if should_show_floating_panes && !self.floating_panes.panes_are_visible() {
|
||||
self.toggle_floating_panes(Some(client_id), None)?;
|
||||
} else if !should_show_floating_panes && self.floating_panes.panes_are_visible() {
|
||||
self.toggle_floating_panes(Some(client_id), None)?;
|
||||
) {
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if should_show_floating_panes && !self.floating_panes.panes_are_visible() {
|
||||
self.toggle_floating_panes(Some(client_id), None)
|
||||
.non_fatal();
|
||||
} else if !should_show_floating_panes && self.floating_panes.panes_are_visible() {
|
||||
self.toggle_floating_panes(Some(client_id), None)
|
||||
.non_fatal();
|
||||
}
|
||||
self.tiled_panes.reapply_pane_frames();
|
||||
self.is_pending = false;
|
||||
self.apply_buffered_instructions().non_fatal();
|
||||
}
|
||||
self.tiled_panes.reapply_pane_frames();
|
||||
self.is_pending = false;
|
||||
self.apply_buffered_instructions()?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn swap_layout_info(&self) -> (Option<String>, bool) {
|
||||
|
|
@ -771,7 +774,8 @@ impl Tab {
|
|||
self.styled_underlines,
|
||||
self.explicitly_disable_kitty_keyboard_protocol,
|
||||
)
|
||||
.apply_floating_panes_layout_to_existing_panes(&layout_candidate)?;
|
||||
.apply_floating_panes_layout_to_existing_panes(&layout_candidate)
|
||||
.non_fatal();
|
||||
}
|
||||
self.set_force_render();
|
||||
Ok(())
|
||||
|
|
@ -805,7 +809,8 @@ impl Tab {
|
|||
self.styled_underlines,
|
||||
self.explicitly_disable_kitty_keyboard_protocol,
|
||||
)
|
||||
.apply_tiled_panes_layout_to_existing_panes(&layout_candidate)?;
|
||||
.apply_tiled_panes_layout_to_existing_panes(&layout_candidate)
|
||||
.non_fatal();
|
||||
}
|
||||
self.tiled_panes.reapply_pane_frames();
|
||||
let display_area = *self.display_area.borrow();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue