New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GUI for GSettings #467
GUI for GSettings #467
Conversation
Hi! Nice, thank you for working on this! Haven't played with the Preferences stuff yet, but looks like you might need to have a PreferencesPage as a child of that PreferencesWindow first (...also, the |
You need to have the settings.ui file defined in the gresource schema, like this:
|
So now the settings window is working and the updated GSettings properties are loaded on next startup. I would like to make them reloaded during the execution of Spot, as many applications do. Based on my understanding, players and some other components make use of My idea is to put a |
…-add-gsettings-gui
Neat! Given that most if not all settings require a restart, it is not that big of a deal if we don't manage these settings through the shared AppState -- but you can absolutely do that if you want :) As for persisting those settings, there's an example of that in settings.rs -- you could do it from pretty much anywhere I think. |
Well, yes, it seems we don't have to put the settings in AppState and PlayerNotifier is capable of make the player change its own settings (still I'm investigating).
Currently I'm binding the widgets to gsettings directly. The document on Gio.Settings says changing settings wakes up their backends (e.g. dconf) and lets them do lots of work, but I'm not quite sure how we have to care about this since many users won't fidget with this kind of settings. |
I've just pushed the latest commit, which allows us to apply new settings without restarting. The problem, however, is that the window cannot be closed twice. This bug has been there since I created an empty PreferencesWindow and is pretty weird... |
It's a known issue, you need to have hide-on-close enabled on the PreferencesWindow. |
Yeah, hide-on-close did the trick! It seems it is working as expected. If you are going to make changs in color scheme handling in anytime soon, I'm willing to fix GUI in accordance with it (though I don't see what to do exactly). |
Hi! been a little busy but I'll have a look :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice work!! I'll try to be more reactive to questions and feedback as you go through the review!
src/app/state/settings_state.rs
Outdated
} | ||
|
||
#[derive(Default)] | ||
pub struct SettingsState {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could store the Settings here as mentioned at some point :)
That way, the action could have no payload with it (just ChangePlayerSettings
) and whenever that action is dispatched, we just do self.settings = SpotSettings::new_from_gsettings()
since it's already synced probably?
that way you don't have to do the mapping from the Adwaita widgets to SpotSettings everytime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Moved SpotSettings into SettingsState and SettingsWindow use it whenever possible, while there are still some redundant SpotSettings::new_from_gsettings()
calls from the player and update_with
handlers for SettingsState.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am nitpicking a bit, but I think one action is enough here, and the state should decide whether to return no event or vec![SettingsEvent::PlayerSettingsChanged]
if the player part of the settings have changed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set_player_settings
still has to emit PlaybackAction::Stop
to stop playing (otherwise there will be some inconsistency in UI), so the two same if
s are put in update_with
and Settings::new
. It's not a nitpick because I had the same concern, just thought of avoiding the duplicate ifs at first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you're right absolutely!
Looking good!! :) one last comment above and a couple of compilation warnings to fix but otherwise it looks good to me! |
src/app/state/settings_state.rs
Outdated
fn update_with(&mut self, action: std::borrow::Cow<Self::Action>) -> Vec<Self::Event> { | ||
match action.into_owned() { | ||
SettingsAction::ChangeSettings => { | ||
let old_settings = self.settings.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn update_with(&mut self, action: std::borrow::Cow<Self::Action>) -> Vec<Self::Event> {
match action.into_owned() {
SettingsAction::ChangeSettings => {
- let old_settings = self.settings.clone();
- self.settings = SpotSettings::new_from_gsettings().unwrap_or_default();
- if self.settings.player_settings == old_settings.player_settings {
- vec![]
- } else {
+ let old_settings = &self.settings;
+ let new_settings = SpotSettings::new_from_gsettings().unwrap_or_default();
+ let player_settings_changed =
+ new_settings.player_settings != old_settings.player_settings;
+ self.settings = new_settings;
+ if player_settings_changed {
vec![SettingsEvent::PlayerSettingsChanged.into()]
+ } else {
+ vec![]
}
}
}
(you can avoid the extra clone here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in the latest commit :)
one last thing I just realized: source files should be tracked in src/meson.build, otherwise meson sometimes does not pick up on changes |
Great work! I can't wait for this to me merged :) |
Thank you for your work and patience through the review! Merging this :) |
Learned a lot from this PR... I really appreciate reviews & advice! |
I'm working on #142 and trying to create the UI first (see
components/settings/
) then to integrate it with some structs insrc/settings.rs
.Currently I am stuck at how to handle the
AdwPreferencesWindow
. I have set up XML file with some widgets, added a button in the user menu, but an empty window is shown: