Issue #225: a closed Comments panel stays closed when picking comment tools (#501)

Picking any comment tool opened the Comments panel whenever no right panel
was open, so closing it was undone by the next tool switch. Now closing
Comments (its close button or the rail icon) is remembered, across restarts,
and comment tools leave it closed until the user opens it again (rail, View
menu, Comments ▸ list, or a Reply action). Switching to or closing another
panel doesn't count. Opening a document with comments still shows them, as
Acrobat does.


Claude-Session: https://claude.ai/code/session_01VNJqS2dEQawHJn1qTRJiKp

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hal Goff
2026-10-09 09:14:27 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 966bd0ffce
commit 7d9cc53472
6 changed files with 70 additions and 7 deletions
+5 -1
View File
@@ -2001,7 +2001,11 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
let field_props = field_props.then(|| view.prepare.selected.clone()).flatten();
match canvas_action {
Some(comments::CanvasAction::Edit(e)) => view.pending_edit = Some(*e),
Some(comments::CanvasAction::OpenComments) => app.right = Some(RightPanel::Comments),
// `choose_right_panel` would borrow all of `app` while `view` is held; same effect.
Some(comments::CanvasAction::OpenComments) => {
app.right = Some(RightPanel::Comments);
app.comments_panel_closed = false;
}
Some(comments::CanvasAction::Properties(p, i)) => open_props = Some((p, i)),
None => {}
}
+2 -2
View File
@@ -240,7 +240,7 @@ fn main_menu(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
(RightPanel::Compare, tl!("Compare")),
] {
if ui.radio(app.right == Some(p), tl!(label)).clicked() {
app.right = Some(p);
app.choose_right_panel(Some(p));
}
}
});
@@ -278,7 +278,7 @@ pub fn right_rail(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
ui.painter().circle_filled(c, 3.0, t.accent);
}
if r.clicked() {
app.right = if selected { None } else { Some(panel) };
app.choose_right_panel(if selected { None } else { Some(panel) });
}
};
rail_button(ui, RightPanel::Comments, "message-square-text", "Comments", has_comments);
+3 -3
View File
@@ -180,13 +180,13 @@ impl PdfCraftApp {
"view.theme.system" => self.set_theme_preference(ThemePreference::System),
"view.theme.light" => self.set_theme_preference(ThemePreference::Light),
"view.theme.dark" => self.set_theme_preference(ThemePreference::Dark),
"comment.list" => self.right = Some(RightPanel::Comments),
"comment.list" => self.choose_right_panel(Some(RightPanel::Comments)),
tool if crate::comments::CommentTool::from_command(tool).is_some() => {
let Some(tool) = crate::comments::CommentTool::from_command(tool) else { return false };
self.comment_prefs.group_tool[tool.group()] = tool;
self.quick_tool = crate::QuickTool::Comment(tool);
// Acrobat opens the Comments panel with the commenting tools.
if self.right.is_none() {
// Acrobat opens the Comments panel with the commenting tools, unless the user closed it.
if self.right.is_none() && !self.comments_panel_closed {
self.right = Some(RightPanel::Comments);
}
// A text selection made before picking a markup tool is marked right away.
+19
View File
@@ -356,6 +356,9 @@ pub struct PdfCraftApp {
pub left: LeftPanel,
pub left_open: bool,
pub right: Option<RightPanel>,
/// The user closed the Comments panel, so picking a comment tool leaves it closed until they
/// open it again (#225). Remembered across restarts.
pub comments_panel_closed: bool,
pub quick_tool: QuickTool,
/// The tool to go back to when Space, held for a temporary Hand, is released.
space_hand: Option<QuickTool>,
@@ -602,6 +605,7 @@ impl PdfCraftApp {
left: LeftPanel::AllTools,
left_open: true,
right: None,
comments_panel_closed: false,
quick_tool: QuickTool::Select,
space_hand: None,
comment_prefs: Default::default(),
@@ -1165,6 +1169,17 @@ impl PdfCraftApp {
};
}
/// Opens a right panel, or closes it with `None`, because the user chose to. Closing Comments
/// keeps comment tools from reopening it; opening it again lets them (#225).
pub fn choose_right_panel(&mut self, panel: Option<RightPanel>) {
if panel == Some(RightPanel::Comments) {
self.comments_panel_closed = false;
} else if panel.is_none() && self.right == Some(RightPanel::Comments) {
self.comments_panel_closed = true;
}
self.right = panel;
}
/// Serialize the user's persistent state (recent files, theme). Local only.
pub fn persist(&self) -> String {
let trusted: Vec<String> = self.session.trusted_certificates().iter().map(pdfcraft_engine::sign::x509::to_pem).collect();
@@ -1190,6 +1205,7 @@ impl PdfCraftApp {
"javascript": self.session.javascript(),
"actions": actions_ui::encode(&self.custom_actions),
"combine_columns": self.combine_columns.to_json(),
"comments_panel_closed": self.comments_panel_closed,
})
.to_string()
}
@@ -1217,6 +1233,9 @@ impl PdfCraftApp {
if let Some(on) = v["highlight_fields"].as_bool() {
self.view_defaults.highlight_fields = on;
}
if let Some(closed) = v["comments_panel_closed"].as_bool() {
self.comments_panel_closed = closed;
}
if let Some(defaults) = v["default_zoom"].as_str().and_then(|zoom| self.view_defaults.with_zoom(zoom)) {
self.view_defaults = defaults;
}
+1 -1
View File
@@ -584,7 +584,7 @@ pub fn right_panel(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
});
}
if close {
app.right = None;
app.choose_right_panel(None);
}
if let Some(e) = panel_edit {
app.apply_edit(e);
+40
View File
@@ -600,3 +600,43 @@ fn the_opacity_set_for_a_tool_goes_into_its_new_comments() {
h.run_steps(2);
h.get_by_label("Opacity");
}
/// #225: comment tools open the Comments panel until the user closes it; then it stays closed,
/// across restarts, until they open it again.
#[test]
fn a_closed_comments_panel_stays_closed_when_picking_comment_tools() {
use pdfcraft_ui_egui::RightPanel;
let mut h = harness(|_| {});
assert_eq!(h.state().right, None);
assert!(h.state_mut().execute("comment.highlight"));
h.run_steps(2);
assert_eq!(h.state().right, Some(RightPanel::Comments), "Acrobat opens Comments with the tools");
h.get_by_label("Close").click();
h.run_steps(2);
assert_eq!(h.state().right, None);
for tool in ["select", "comment.underline", "comment.note", "comment.highlight"] {
if tool == "select" {
h.state_mut().quick_tool = QuickTool::Select;
} else {
assert!(h.state_mut().execute(tool));
}
h.run_steps(2);
assert_eq!(h.state().right, None, "{tool} reopened the closed Comments panel");
}
let mut again = PdfCraftApp::new();
again.restore(&h.state().persist());
assert!(again.comments_panel_closed, "the choice survives a restart");
// Opening it again from the rail lets the tools open it once more.
h.get_by_label("Comments").click();
h.run_steps(2);
assert_eq!(h.state().right, Some(RightPanel::Comments));
assert!(!h.state().comments_panel_closed);
// What the rail and View menu call; "Bookmarks" labels two controls on screen.
h.state_mut().choose_right_panel(Some(RightPanel::Bookmarks));
h.state_mut().choose_right_panel(None);
h.run_steps(2);
assert!(!h.state().comments_panel_closed, "switching to and closing another panel isn't closing Comments");
assert!(h.state_mut().execute("comment.strikeout"));
h.run_steps(2);
assert_eq!(h.state().right, Some(RightPanel::Comments));
}