Description
The changed signal in Gio.Settings is a detailed signal (GObject terminology) that notifies about changes to schema keys accessed via get_*(key) methods.
According to GLib documentation:
This signal supports detailed connections. You can connect to the detailed signal changed::x in order to only receive callbacks when key x changes.
The signal handler always has the same signature regardless of the key name:
(gsettings: Gio.Settings, key: string) => void
Current Expected
The current Settings.SignalSignatures typing includes only predefined detailed signals that match GSettings object properties (not schema keys):
interface SignalSignatures {
changed: (arg0: string) => void;
'changed::backend': (arg0: string) => void;
'changed::delay-apply': (arg0: string) => void;
'changed::path': (arg0: string) => void;
'changed::schema-id': (arg0: string) => void;
// ...
}
Why it's confusing:
- backend, delay-apply, path, schema-id are GSettings object properties, not typical schema keys
- It creates false impression that only these specific keys are supported for detailed signals
- It suggests these property names are expected to be used as schema keys (which would be confusing in practice)
- The pattern implies a closed set, while
changed::* works with any schema key
Problem:
When connecting to changed::${arbitrary_schema_key}, TypeScript cannot infer callback parameter types:
// Type inference fails - parameters have type 'any'
gsettings.connect('changed::my-key', (settings, key) => {
// settings: any
// key: any
});
// Must annotate types manually
gsettings.connect('changed::my-key', (settings: Gio.Settings, key: string) => {
// settings: Gio.Settings
// key: string
});
Expected Behavior
Type inference should work for any changed::* detailed signal, since:
- All detailed signals have the same handler signature
- The pattern
changed::${key} is the standard way to use GSettings API
- Actual schema keys (e.g., criteria, gtk-cursor-blink, custom keys) are far more common than keys named after GSettings properties
Proposed Solution
If TypeScript supports template literal types in this context:
interface SignalSignatures {
changed: (arg0: string) => void;
[key: `changed::${string}`]: (arg0: string) => void;
}
Or at minimum, document the current limitation and remove the misleading predefined changed::backend, etc. variants.
References
Gio C API reference: https://docs.gtk.org/gio/signal.Settings.changed.html
Environment:
- GJS Version: 1.80.2 (GNOME 46)
- Girs packages: @girs/gio-2.0@2.86.0-4.0.0-beta.38
- TypeScript: 5.8.3
Additional Context
Description
The changed signal in
Gio.Settingsis a detailed signal (GObject terminology) that notifies about changes to schema keys accessed viaget_*(key)methods.According to GLib documentation:
The signal handler always has the same signature regardless of the key name:
Current Expected
The current
Settings.SignalSignaturestyping includes only predefined detailed signals that match GSettings object properties (not schema keys):Why it's confusing:
changed::*works with any schema keyProblem:
When connecting to
changed::${arbitrary_schema_key}, TypeScript cannot infer callback parameter types:Expected Behavior
Type inference should work for any
changed::*detailed signal, since:changed::${key}is the standard way to use GSettings APIProposed Solution
If TypeScript supports template literal types in this context:
Or at minimum, document the current limitation and remove the misleading predefined
changed::backend, etc. variants.References
Gio C API reference: https://docs.gtk.org/gio/signal.Settings.changed.html
Environment:
Additional Context