Skip to content

feat: decouple window and column dimensions in config - #692

Open
mvanhorn wants to merge 1 commit into
cboxdoerfer:masterfrom
mvanhorn:feat/659-decouple-window-column-dims
Open

feat: decouple window and column dimensions in config#692
mvanhorn wants to merge 1 commit into
cboxdoerfer:masterfrom
mvanhorn:feat/659-decouple-window-column-dims

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Jun 9, 2026

Copy link
Copy Markdown

Summary

Stores volatile window/column geometry in a separate file under the XDG cache directory (~/.cache/fsearch/window.conf) instead of mixing it into the main settings file (~/.config/fsearch/fsearch.conf).

Why this matters (#659)

Users who version-control their dotfiles get noisy git diffs every time they resize the window or a column, because FSearch writes machine-specific geometry into the same file as substantive settings. Other apps (e.g. KeePassXC, cited in the issue) keep essential settings in ~/.config and volatile layout state in ~/.cache. The maintainer greenlit this direction ("That's a great idea. Added to the TODO list.").

Changes

  • Moved the volatile geometry keys out of the settings sections into a new CACHE_WINDOW_SECTION: window_width, window_height, and the six *_column_width and five *_column_pos keys.
  • restore_window_size, restore_column_config, restore_sort_order, the show_*_column booleans, sort_by, and sort_ascending stay in the main config file, since those are deliberate user choices rather than machine-specific geometry.
  • Added config_build_cache_path() / config_build_cache_dir() / config_make_cache_dir() helpers that mirror the existing config-path helpers but are rooted at g_get_user_cache_dir().
  • config_save() writes the geometry to a second GKeyFile under [Window] in the cache file. The main settings save is unaffected by a cache-write failure.
  • config_load() reads geometry from window.conf. If that file is absent, it falls back to reading legacy geometry keys from the [Interface] section of fsearch.conf, so existing users keep their layout on first launch after upgrading (one-time migration; the next save relocates it to the cache file).
  • Graceful degradation: if the cache directory is unwritable, the geometry is written back into the main config file as a fallback so it is never silently lost; the legacy-load path picks it back up.
  • config_load_default() applies the geometry defaults.

Testing

Added src/tests/test_config.c (registered in src/tests/meson.build) covering:

  • Round-trip: after save, fsearch.conf contains no window_width/*_column_width keys while window.conf does, and geometry values round-trip through a reload.
  • Migration: a pre-existing fsearch.conf with legacy [Interface] geometry and no window.conf loads those values, and a subsequent save relocates them to the cache file.
  • Cache-unwritable fallback: when the cache directory cannot be created, the main save still succeeds and geometry is preserved in fsearch.conf, then loads back correctly.

All three tests pass locally (built and run against glib-2.0).

Fixes #659

AI was used for assistance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread src/fsearch_config.c
};

static const char *config_file_name = "fsearch.conf";
static const char *cache_file_name = "window.conf";

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

In case other state options will be added in the future, I think it makes more sense to name the file something like state.ini. .ini also seems more suitable for a state file than .conf.

Comment thread src/fsearch_config.c
g_assert(cache_key_file);

gchar cache_path[PATH_MAX] = "";
config_build_cache_path(cache_path, sizeof(cache_path));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

On systems with GLIB >= 2.72 there's also support for g_get_user_state_dir (), which we should prefer over g_get_user_cache(). So we should try to load in the following order:

  1. user state dir
  2. user cache dir
  3. user config dir

Comment thread src/fsearch_config.c
CONF_STR(sort_by, "Name"),
};

static const FsearchKeyData CACHE_WINDOW_SECTION[] = {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Let's use STATE instead of CACHE throughout this PR.

Comment thread src/fsearch_config.c

CONFIG_SAVE_SECTION(cache_key_file, "Window", CACHE_WINDOW_SECTION, config);

if (config_make_cache_dir()) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Here we should also prefer to use the g_get_user_state_dir() if our GLIB_VERSION supports it, and only use cache and config dirs as fallback.

@cboxdoerfer cboxdoerfer left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thx for the 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.

Decouple window/column dimensions from rest of config

2 participants