Remember expanded cleaner sections across sessions - #2259
namelessweakl1ng wants to merge 2 commits into
Conversation
MohammedAlkindi
left a comment
There was a problem hiding this comment.
Nice feature — this is one I'd use. But I think the restore path never actually fires, and I was able to measure it without a GUI.
The guard and the writer disagree about where the value lives. set_list stores under a section named list/<key>; has_option(option, section='bleachbit') looks for an option named <key> inside the bleachbit section. Nothing ever creates that option, so the guard is always false:
# bleachbit/Options.py
def has_option(self, option, section='bleachbit'):
return self.config.has_option(section, option) # section 'bleachbit'
def set_list(self, key, values):
section = f"list/{key}" # section 'list/expanded_cleaners'
...Round-tripped it directly against bleachbit.Options on Windows 11 (Python 3.13.13), no GTK involved:
before write:
has_option('expanded_cleaners') -> False
get_list('expanded_cleaners') -> None
after set_list(['firefox', 'system']):
has_option('expanded_cleaners') -> False <- the guard this PR uses
get_list('expanded_cleaners') -> ['firefox', 'system'] <- the data is there
sections now present: ['list/expanded_cleaners']
So capture_tree_state() writes correctly and restore_tree_state() returns at the first line every time — the sections would be saved but never re-expanded.
Suggested fix — guard on the accessor that knows about list/ sections:
expanded = options.get_list("expanded_cleaners")
if expanded is None:
return
expanded = set(expanded)Use is None, not a truthiness check, and this is the bit worth being deliberate about: set_list(key, []) produces get_list(key) == [], which is a meaningful state — "the user collapsed everything". if not expanded: return would skip the restore and leave whatever GTK's default expansion is, so collapsing everything wouldn't survive a restart. is None distinguishes "never saved" from "saved as empty", and the else: self.view.collapse_row(path) branch you already have then does the right thing.
Two smaller notes:
model[treeiter][2]appears in both new methods as a bare column index. There's aTreeDisplayModelnearby — if it exposes a named constant for the cleaner-id column, using it would keep these from silently reading the wrong column if the model gains a field.- Worth confirming the save point covers a Windows close (title-bar X /
delete-event) and not just the app's own quit action — on Windows those are easy to route differently, and a state-persistence feature that misses the most common exit path would look intermittent rather than broken.
What I could not do: tests/TestGUI.py is the only file referencing GuiWindow, and it can't run here — PyGObject (gi) isn't installed on this machine and I'm not installing it. So I have not exercised the GTK path at all, and I'm not reporting a suite run as evidence. Everything above is either read from the diff or measured against bleachbit.Options in isolation.
Disclosure: I used an AI assistant while reviewing. The Options round-trip above was executed by me on the Windows machine described; the GTK-side behaviour is reasoned from the diff and explicitly untested.
|
Thanks for catching this. I changed the restore logic to use get_list() with an explicit is None check, so an empty saved list correctly represents a fully collapsed tree. I also tested the updated behavior locally. |
|
@namelessweakl1ng: this needs to be properly rebased |
Summary
This PR remembers the expanded/collapsed state of top-level cleaner sections between application sessions.
Changes
Fixes #2200.