Skip to content

feat(ui): add Mark as Unread/Read menu, configurable unread color, and middle-click close guards - #238

Open
oooseun wants to merge 1 commit into
am-will:mainfrom
oooseun:pr/6-feat-tabs-middle-click-and-unread-menu
Open

oooseun wants to merge 1 commit into
am-will:mainfrom
oooseun:pr/6-feat-tabs-middle-click-and-unread-menu

Conversation

@oooseun

@oooseun oooseun commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Right-click Mark as Unread / Mark as Read: Add context menu actions on both tabs and workspace sidebar rows. Manually marked unread badges persist across passive window focus changes (is_active_notify) and only clear when the user explicitly interacts with the tab/workspace or marks it read.
  • Configurable Unread Indicator Color: Add appearance.unread_color (UnreadColor, defaulting to Amber #f59e0b, with Emerald, Rose, Cyan, and Accent Blue options in Settings -> General) so unread workspace rows, left borders, and tab dots are visually distinct from the active workspace selection highlight.
  • Middle-Click Tab Close Guards: Guard middle-click tab close against active inline tab renames and trigger on button release inside tab bounds (can_middle_click_close_tab).
  • Agent Hook Notification Filtering: Restrict limux-cli agent hook notifications to completion/notification events (Notification, Stop, finished) instead of firing on SessionStart, SessionEnd, UserPromptSubmit, PreToolUse, PostToolUse, SubagentStop, or Cleanup.

@oooseun
oooseun force-pushed the pr/6-feat-tabs-middle-click-and-unread-menu branch from f85fb39 to ca07ade Compare October 14, 2026 21:46
…d middle-click close guards

- Add right-click Mark as Unread / Mark as Read context menu items on tabs and workspace sidebar rows, preserving manual unread state across passive window focus changes while clearing on explicit user actions.
- Add configurable UnreadColor setting (default Amber #f59e0b) so unread indicators stand out from the blue selection highlight.
- Guard middle-click tab close against active inline tab renames and require release inside tab bounds.
- Restrict limux-cli agent hook notifications to completion/notification events instead of firing on session start/end or tool invocations.
@oooseun
oooseun force-pushed the pr/6-feat-tabs-middle-click-and-unread-menu branch from ca07ade to befe567 Compare October 15, 2026 18:25

@bvolpato bvolpato left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the unread controls and close guards. I completed another pass over all five changed files at befe567, including notification, tab-close/move, focus, CLI, and settings paths.

There is one code fix required before merge: preserve independent workspace-level notifications when the last unread tab is removed or read. The inline P2 comment gives the affected path and a concrete regression case. Please also confirm that tab-only notifications still clear when read and that explicit Mark as Read actions clear their intended markers.

The color-dropdown rollback comment is nonblocking and can be handled as a follow-up. It is not part of the merge requirements. No other code blockers were found in this head.

After the unread fix, please run the focused regression, ./scripts/check.sh, and the maintained debug GTK smoke on the revised head. The contributor workflows are now approved and CI is green on this head; the focused unread regression still needs its fix and coverage. I will recheck that revised diff and its results before merging.

if !pane::workspace_has_unread_tabs(&ws_id_unread) {
let mut s = state_for_unread.borrow_mut();
if let Some(ws) = s.workspaces.iter_mut().find(|w| w.id == ws_id_unread) {
ws.unread = false;

@bvolpato bvolpato Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Could you preserve independent workspace notifications when tab unread state changes? workspace.unread also records notifications without a tab target. In an inactive workspace with two terminals, an untargeted notification, and one unread terminal, that terminal exiting invokes on_unread_changed and clears the independent notification even though it was never read. Please keep these unread sources separate. Add a focused regression where the unread terminal exits while the other terminal keeps the workspace open: the workspace notification should remain unread. Also verify a tab-only notification still clears when its last unread tab is read or removed.

let on_changed = input.on_config_changed.clone();
unread_color_dropdown.connect_selected_notify(move |dropdown| {
let unread_color = UnreadColor::from_dropdown_index(dropdown.selected());
apply_config_change(&config, &*on_changed, move |c| {

@bvolpato bvolpato Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking follow-up [P3]: could the color dropdown reflect the effective config when saving fails? handle_config_change restores the previous config and CSS on an error, but this handler discards the value returned by apply_config_change. The dropdown therefore shows a color that was not saved. Synchronizing it with the returned config would match the existing interface controls. A rejected-save check should leave the dropdown on the effective color without another save attempt. This is optional and does not need to be addressed before merging this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants