Skip to content

GSTheme: follow the theme default in an application that did not change theme - #950

Merged
fredkiefer merged 4 commits into
gnustep:masterfrom
probonopd:fix-theme-follows-default
Oct 18, 2026
Merged

fredkiefer merged 4 commits into
gnustep:masterfrom
probonopd:fix-theme-follows-default

Conversation

@probonopd

Copy link
Copy Markdown
Contributor

An application that starts with the default theme never follows a later change of the GSTheme default: the observer of NSUserDefaultsDidChangeNotification is registered in +setTheme:, in the branch that is taken only when the theme really changes, and at start-up +defaultsDidChange: does not reach that branch when the default names the theme which is already current. Only a restart picks a new theme up. This is the part of #431 that #827 names in its own description and leaves open.

The test pins the GSTheme default to GNUstep before GSTheme is first used, lays down a theme bundle with no code in it, switches the default to that bundle and posts the notification.

Before:

$ cd Tests && gnustep-tests gui/GSTheme
--- Running tests in gui/GSTheme ---

gui/GSTheme/followsDefault.m:
Failed test:     followsDefault.m:100 ... the theme changes with the default (got GNUstep)

      2 Passed tests
      1 Failed test

After:

$ cd Tests && gnustep-tests gui/GSTheme
--- Running tests in gui/GSTheme ---

      3 Passed tests

All OK!

+initialize now registers the observer before it establishes the theme the defaults name; +setTheme: still removes and re-adds it around a switch, so it stays registered exactly once. gui/NSColor, gui/NSAppearance and gui/NSWindow give the same results with and without the change (45/4, 35/16 and 16/13 here).

cc @pkgdemon

…ge theme

An application that started with the default theme kept it for the rest
of its run, whatever the user later chose: +initialize establishes the
theme by calling +defaultsDidChange:, which reaches +setTheme: only when
the theme actually changes, and +setTheme: is where the observer of
NSUserDefaultsDidChangeNotification is registered.  An application on the
default theme therefore never watched the default it was meant to follow,
and only a restart picked a new theme up.  This is the part of gnustep#431 that
gnustep#827 left open, which it names in its own description.

The observer is now registered when GSTheme initialises, before the
theme named by the defaults is established.  +setTheme: still removes and
re-adds it around a switch, so it stays registered exactly once.

Refs gnustep#431
@rmottola

rmottola commented Oct 7, 2026

Copy link
Copy Markdown
Member

I ping @rfm who worked on the previous theme switching. I did test and we have a regression, setting a theme in system preferences never changes other applications. But I am sure it was fixed, because that was the actual test.

@pkgdemon

pkgdemon commented Oct 8, 2026 •

Copy link
Copy Markdown

I ping @rfm who worked on the previous theme switching. I did test and we have a regression, setting a theme in system preferences never changes other applications. But I am sure it was fixed, because that was the actual test.

For what it's worth I had to do something like this to apps-systempreferences to make it work for me from System Preferences @rmottola

gnustep/apps-systempreferences@master...pkgdemon:apps-systempreferences:master

I am not sure what I did there is the best fix. I used Claude to come up with it in a hurry just as an experiment but here it is in action if to see what it would look like.

https://www.youtube.com/watch?v=wB0PVTdTZ-g

There were also some necessary fixes for apps-gworkspace to retheme some elements in real time. I am not 100% sure they are still necessary now.

gnustep/apps-gworkspace@master...pkgdemon:apps-gworkspace:master

Just wanted to share in case it helps reveal anything...

@rmottola

rmottola commented Oct 8, 2026

Copy link
Copy Markdown
Member

@pkgdemon that is a hack, the the default theme should work as not set. In our original test with @rfm it was not needed. Also, remember, when you start up the first time domain name is not set. Setting the default should revert to the clean state.

@rfm rfm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This remedies a trivial oversight by me: yes the GSTheme class should register itself as an observer for defaults updates when it is initialised.

rfm added 2 commits October 8, 2026 13:07
Removed previous observer management for theme changes.
Remove unnecessary observer removal from notification center when changing themes.
@rfm

rfm commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

But ... the code in +setTheme: was wrong: we don't need to remove (or re-register) the class as an observer for defaults changes if we have already registered it in +initialize

@probonopd

Copy link
Copy Markdown
Contributor Author

@rfm would you like me to change this PR? If so, how? Or is it obsolete now given your commits? Thanks for looking into this.

@rfm

rfm commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

I updated/extended your PR. It still needs to be approved by Fred. And you might like to see if my changes make sense to you, or if you notice anything missed.

@fredkiefer
fredkiefer merged commit 1a41486 into gnustep:master Oct 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants