Skip to content

Conversation

@evertonstz
Copy link

Implement GSettings to save and restore the window size in terminal grid dimensions on Linux. Include the necessary schema and update the application to handle window state management.

My solution is similar to how ptyxis does it in gnome.

@evertonstz evertonstz requested a review from a team as a code owner November 2, 2025 01:36
<schemalist>
<schema id="com.mitchellh.ghostty" path="/com/mitchellh/ghostty/">
<key name="window-size" type="(uu)">
<default>(0, 0)</default>
Copy link
Author

Choose a reason for hiding this comment

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

By setting the initial value to (0, 0) we allow the terminal to first lauch with the default size, on close we will replace the (0, 0) with the default size (110, 25) or the current size, if the user resized his terminal in this first launch

--prefix /app
--search-prefix /app
--system $PWD/vendor/p
- glib-compile-schemas /app/share/glib-2.0/schemas
Copy link
Author

Choose a reason for hiding this comment

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

For package managers this should be handled automatically, but the AppImage maintainer will probably need to run glib-compile-schemas when packaging.

schema_id,
@intFromBool(false),
) orelse {
log.info("GSettings schema '{s}' not installed, window state will not persist", .{schema_id});
Copy link
Author

Choose a reason for hiding this comment

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

Fails gracefully if the GSettings schema is not present (ex: appimage maintainer forgot to compile), in the failure case Ghostty will just have its current behaviour of not restoring or saving its size!

@evertonstz evertonstz changed the title Add GSettings support for window state persistence gtk: add GSettings support for window state persistence Nov 2, 2025
Copy link
Member

@pluiedev pluiedev left a comment

Choose a reason for hiding this comment

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

Looks good overall

--prefix /app
--search-prefix /app
--system $PWD/vendor/p
- glib-compile-schemas /app/share/glib-2.0/schemas
Copy link
Member

Choose a reason for hiding this comment

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

This should be something we can do within the Zig build system. Meson does it automatically, for example.

Copy link
Contributor

@mitchellh mitchellh left a comment

Choose a reason for hiding this comment

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

Looks good generally. Some questions that I plan on researching myself, but feel free to provide some color as well to help me:

  1. How does versioning work? In macOS, it's standard to put a "version" monotonic Int into the settings schema so that you can provide upgrade paths or ignore unknown versions. This also lets you change structure. Do we need that here? Seems like we would but I'm not sure if GSettings provides another way.

  2. I think the compiled schema is something we'd want to put in our dist tarball and it doesn't look like we're doing it here.

  3. Not required for this PR: but is there any way we can localize the description string? Asking since we already localize many other things in GTK.

@evertonstz
Copy link
Author

evertonstz commented Nov 3, 2025

Looks good generally. Some questions that I plan on researching myself, but feel free to provide some color as well to help me:

  1. How does versioning work? In macOS, it's standard to put a "version" monotonic Int into the settings schema so that you can provide upgrade paths or ignore unknown versions. This also lets you change structure. Do we need that here? Seems like we would but I'm not sure if GSettings provides another way.

As far as I am aware GGSettings does not have a built-in, automated schema versioning mechanism with explicit version numbers in the schema files themselves, instead they are managed via some best practices to make or life easier:

  • Adding new keys as optional, mark old unused keys as deprecated;
  • Avoid rename, changing the type or removing old keys;

In case of breaking changes:

  • Ship both schemas
  • Add a migration logic that will check if the old schema still has user-set values. If so, read them and write them to the new schema's keys, then reset the old keys to their defaults (or remove them).

eg:

<!-- Old key - deprecated -->
<key name="window-size" type="(uu)" deprecated="true">
  <default>(0, 0)</default>
</key>

<!-- New key with different structure -->
<key name="window-state-v2" type="a{sv}">
  <default>{}</default>
</key>

Kinda of a pain in the ass if you ask me, but its the gnome way :<

  1. I think the compiled schema is something we'd want to put in our dist tarball and it doesn't look like we're doing it here.

If making glib-compile-schemas a build-time dep is not a problem, I think we can do it, but package managers typically handle schema compilation automatically via post-install hooks and we are already shipping the schema source, so that can be an option too, if we keep it as it is we would probably just need to update in PACKAGING.md that package managers should run glib-compile-schemas post-install hook and we should be fine. I think its a common practice to do that.

  1. Not required for this PR: but is there any way we can localize the description string? Asking since we already localize many other things in GTK.

Yes! GSettings supports localization using gettext:

  • Mark translatable strings with underscore, eg: <_summary> and <_description> tags
  • Extract strings to the .pot file
  • Translators add them to .po files
  • GSettings automatically uses localized strings at runtime

eg:

<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="com.mitchellh.ghostty">
  <schema id="com.mitchellh.ghostty" path="/com/mitchellh/ghostty/">
    <key name="window-size" type="(uu)">
      <default>(0, 0)</default>
      <_summary>Last window size</_summary>
      <_description>
        The last window size in terminal columns and rows. This is used to
        restore the window size when window-save-state is enabled. A value
        of (0, 0) means no size has been saved yet.
      </_description>
    </key>
  </schema>
</schemalist>

The strings will show in English until translations are added. If interested I can update the PR to let the schema ready for translation.

Thinking better about it, it is not that simple because I will actually need to convert the xml to a template to fill in the schema-id via build time from the current build_config.bundle_id, it is possible but I will need to thinker with it a bit more to get to a viable solution :>

@evertonstz
Copy link
Author

  1. Not required for this PR: but is there any way we can localize the description string? Asking since we already localize many other things in GTK.

I managed to get translations working for the GSchemas, but it needed some changes in how mo files are generated, I made a draft PR at #9464 using the current PR as base, so it can be reviewed after we merge this one.

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.

3 participants