Manage folders from the sidebar: rename, recolour, delete #6

Open
opened 2026-08-19 23:55:17 +00:00 by dusan · 0 comments
Owner

Context

Sessions live in folders, one level deep. Folders are created with Ctrl+Shift+D
or the New menu (win.folder-new in crates/terminalko/src/window.rs), and the
sidebar renders each as an adw::SidebarSection with the folder's name as its
title (rebuild_sidebar).

The model already supports everything needed
(crates/terminalko-config/src/session.rs):

Method What it does
Folder::set_name renames
Folder::set_colour sets the accent sessions inherit
Store::delete_folder(id, keep_sessions) deletes, either keeping its sessions as unfiled or deleting them with it

delete_folder is covered by two tests. Nothing in the UI calls any of them.

The gap

A folder can be created and then never changed: no rename, no colour, no delete.
A typo in a folder name is permanent, and an unwanted folder cannot be removed.

Approach

adw::SidebarSection::set_menu_model exists, so each section can carry its own
menu — and because the menu is built per section, the folder's id can be baked
into the action targets
. That avoids the problem AdwSidebar otherwise has:
connect_setup_menu hands over a SidebarItem, never a section, so there is no
other way to know which folder was clicked.

In rebuild_sidebar, where each section is built:

let section = adw::SidebarSection::new();
section.set_title(Some(&folder.name()));
section.set_menu_model(Some(&folder_menu(folder.id())));

with window actions taking the folder id as a string parameter:

  • win.folder-rename(id) — the same prompt dialog rename_session uses
  • win.folder-colour(id, colour) — a submenu like colour_menu(); note this
    needs two values, so either use a single string such as "id/colour" (as
    session-new-container already does for runtime/name) or a tuple variant
  • win.folder-delete(id) — must ask, and must ask which: deleting a folder
    with sessions in it is two different operations. An AdwAlertDialog with three
    responses (Cancel / Keep sessions / Delete sessions) maps onto
    delete_folder(id, keep_sessions) directly

After any of these, call rebuild_sidebar and refresh_accents — a folder's
colour is inherited by sessions that have none of their own, and open pages show
it.

Acceptance criteria

  • A folder can be renamed, recoloured and deleted from its section's context
    menu, and each survives restarting the application.
  • Deleting a folder that has sessions asks whether to keep them, and both answers
    do what they say — Store::delete_folder already implements both.
  • Recolouring a folder immediately changes the accent of its sessions that have no
    colour of their own, including any page open at the time.
  • Deleting the folder a session is open from does not close that session's page or
    stop it; the session becomes unfiled or is deleted, per the answer.
  • ./build-aux/ci.sh and ./build-aux/smoke.sh pass.
  • docs/spec/session-sidebar.md describes the folder menu.

Notes

  • BSD-2: see CONTRIBUTING.md before consulting any GPL terminal for reference.
  • The tests to extend are in crates/terminalko-config/src/session.rs (headless,
    GSETTINGS_BACKEND=memory) — the model side is already covered, so most new
    tests belong in whatever helper builds the menu.
## Context Sessions live in folders, one level deep. Folders are created with `Ctrl+Shift+D` or the New menu (`win.folder-new` in `crates/terminalko/src/window.rs`), and the sidebar renders each as an `adw::SidebarSection` with the folder's name as its title (`rebuild_sidebar`). The model already supports everything needed (`crates/terminalko-config/src/session.rs`): | Method | What it does | |---|---| | `Folder::set_name` | renames | | `Folder::set_colour` | sets the accent sessions inherit | | `Store::delete_folder(id, keep_sessions)` | deletes, either keeping its sessions as unfiled or deleting them with it | `delete_folder` is covered by two tests. **Nothing in the UI calls any of them.** ## The gap A folder can be created and then never changed: no rename, no colour, no delete. A typo in a folder name is permanent, and an unwanted folder cannot be removed. ## Approach `adw::SidebarSection::set_menu_model` exists, so each section can carry its own menu — and because the menu is built per section, **the folder's id can be baked into the action targets**. That avoids the problem `AdwSidebar` otherwise has: `connect_setup_menu` hands over a `SidebarItem`, never a section, so there is no other way to know which folder was clicked. In `rebuild_sidebar`, where each section is built: ```rust let section = adw::SidebarSection::new(); section.set_title(Some(&folder.name())); section.set_menu_model(Some(&folder_menu(folder.id()))); ``` with window actions taking the folder id as a string parameter: * `win.folder-rename(id)` — the same prompt dialog `rename_session` uses * `win.folder-colour(id, colour)` — a submenu like `colour_menu()`; note this needs **two** values, so either use a single string such as `"id/colour"` (as `session-new-container` already does for `runtime/name`) or a tuple variant * `win.folder-delete(id)` — must ask, and must ask *which*: deleting a folder with sessions in it is two different operations. An `AdwAlertDialog` with three responses (Cancel / Keep sessions / Delete sessions) maps onto `delete_folder(id, keep_sessions)` directly After any of these, call `rebuild_sidebar` and `refresh_accents` — a folder's colour is inherited by sessions that have none of their own, and open pages show it. ## Acceptance criteria - A folder can be renamed, recoloured and deleted from its section's context menu, and each survives restarting the application. - Deleting a folder that has sessions asks whether to keep them, and both answers do what they say — `Store::delete_folder` already implements both. - Recolouring a folder immediately changes the accent of its sessions that have no colour of their own, including any page open at the time. - Deleting the folder a session is open from does not close that session's page or stop it; the session becomes unfiled or is deleted, per the answer. - `./build-aux/ci.sh` and `./build-aux/smoke.sh` pass. - `docs/spec/session-sidebar.md` describes the folder menu. ## Notes - BSD-2: see `CONTRIBUTING.md` before consulting any GPL terminal for reference. - The tests to extend are in `crates/terminalko-config/src/session.rs` (headless, `GSETTINGS_BACKEND=memory`) — the model side is already covered, so most new tests belong in whatever helper builds the menu.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dusan/terminalko#6
No description provided.