-
Notifications
You must be signed in to change notification settings - Fork 38.3k
qt: Add -guisettingsdir option #17636
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
Conversation
hebasto
left a comment
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.
Concept ACK 96a1caf
src/qt/bitcoin.cpp
Outdated
| QApplication::setOrganizationName(QAPP_ORG_NAME); | ||
| QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN); | ||
| QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT); | ||
| if (gArgs.IsArgSet("-guisettings") && gArgs.GetArg("-guisettings", "") != "") { |
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.
Is it possible to test this logic in UTs?
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.
Good question. I'm not an expert with the test framework but we could run bitcoin-qt --guisettings=/a/custom/path/ and see if /a/custom/path/Bitcoin/Bitcoin-Qt.conf exists.
The problem with the Qt tests is that they test the actual GUI like clicking buttons. This belongs more to a startup test, don't know if this exists
1b24214 to
9336f4c
Compare
|
I prefer #15936 in the long run. Maybe this makes sense as an intermediary step... but unsure (could also be a maintenance burden since this needs to go away with #15936 very likely). Pinging @ryanofsky. |
|
@jonasschnelli #15936 is something different. |
promag
left a comment
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 understand the OP motivation, not sure if the new argument is the best. Specifying a directory gives the impression that multiple files could be stored there.
How about supporting specifying the filename like =my_settings_1.ini? This could be an absolute path or relative to datadir?
src/qt/bitcoin.cpp
Outdated
| QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT); | ||
| if (gArgs.GetArg("-guisettings", "") != "") { | ||
| QSettings::setDefaultFormat(QSettings::IniFormat); | ||
| QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, QString::fromStdString(gArgs.GetArg("-guisettings", ""))); |
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.
This should have some check, could be an invalid or read only path and then it wouldn't work as expected.
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.
Sure that is that important? If the path does not exists it will create the directory recursively, if the user has no permission it will fallback to the default. Don't know if it is that much required to check for writing privileges.
|
Concept ACK. This seems at least marginally useful and I don't see drawbacks. It could use better documentation and error checking though. Documentation: should specified path be a file or directory path, or are both accepted? Error checking: it'd be nice to trigger InitErrors if specified location can't be opened or isn't writeable. It'd also be nice to trigger an init error if I'm also not sure if there are caveats to using re: #17636 (comment) This PR is compatible with #15936, but #15936 will make it less practically useful because #15936 moves shared But even after #15936, |
That's a design choice. Other files should be stored there like |
0547a06 to
feed664
Compare
Is it even possible to add GUI related stuff to the
On UNIX system it just works fine as |
No, but that isn't obvious. I'm suggesting it should trigger an init error unless that's difficult, because most command line arguments do work in the config file and the fact that this is setting is silently ignored is just a quirk of the current implementation, and not something I was expecting, or would expect a user to know about. I think it would be pretty easy to add an error with a new Lines 141 to 147 in 35eda63
I'll take your word for it but this seems to contradict the documentation which mentions differences between IniFormat and NativeFormat on unix, like the fact that they use different file extensions, and warns about IniFormat returning everything as a strings. But if there's no issue that's great. |
|
@ryanofsky Indeed the file extensions are different but the files are the same so it doesn't matter: |
Question is how values are read, not really how they are written. e.g. is |
src/qt/bitcoin.cpp
Outdated
| static void SetupUIArgs() | ||
| { | ||
| gArgs.AddArg("-choosedatadir", strprintf("Choose data directory on startup (default: %u)", DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); | ||
| gArgs.AddArg("-guisettings=<path>", "Choose a custom data directory especially for the Qt Settings", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); |
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.
Note that due to initialization order constraints, this option can only be provided on the command line.
It won't work in the configuration file because at that time, QSettings was already parsed.
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 are wrong.
Take a look at src/qt/bitcoin.cpp line 451.
There you'll see that SetupUIArgs() is executed before the PR feature.
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.
re: #17636 (comment)
I concluded the same as Wladimir based on the fact that readConfigFiles is called after GetArg("-guisettings"), so presumably it could not affect the result of the earlier call.
|
Concept ~0 on this. If there are actual users that have use for this, I'm okay with it (it doesn't add that much complexity), but, it's use is pretty constrained and this is heavily initialization-order dependent, and yet another thing to test when testing setting reading. |
|
This definitely needs a test of some kind. |
|
@laanwj Maybe I overlooked it but I haven't found any Qt tests which test CLI args. Is it really that worth to implement a complete new system just for that? |
ryanofsky
left a comment
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.
Is it really that worth to implement a complete new system just for that?
I think it would be great to have a new test for this, not just for this feature but also because the framework could be extended to verify other init behavior. But you are right that there isn't currently an easy way to write tests covering the GuiMain function, so I personally don't think one needs to be added in this PR.
Perhaps the easiest test to write would be a python test invoking bitcoin-qt with QT_QPA_PLATFORM=minimal and -guisettings=path, calling the stop rpc right away, and checking for the ini file in the filesystem. I don't think it would be too hard to write a C++ unit test either, but it'd probably require breaking up the GuiMain function which might be overkill here.
My main feedback for this PR is still to add better error checking and documentation: #17636 (comment)
src/qt/bitcoin.cpp
Outdated
| static void SetupUIArgs() | ||
| { | ||
| gArgs.AddArg("-choosedatadir", strprintf("Choose data directory on startup (default: %u)", DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI); | ||
| gArgs.AddArg("-guisettings=<path>", "Choose a custom data directory especially for the Qt Settings", ArgsManager::ALLOW_ANY, OptionsCategory::GUI); |
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.
re: #17636 (comment)
I concluded the same as Wladimir based on the fact that readConfigFiles is called after GetArg("-guisettings"), so presumably it could not affect the result of the earlier call.
|
Concept ACK. Looks useful. Built & tested a bit - changing values to switch between two .ini files does change language, window position, listening, etc. |
2110a77 to
1d00c8e
Compare
d76d202 to
5266efa
Compare
|
Push, as I changed the title and added the dir suffix |
I doubt this is good enough. Consider this setup: Now imagine Consider taking @ryanofsky suggestion about using |
No, bitcoin-qt doesn't necessarily know where the datadir is and the intro screen opens again. Also I wouldn't call this a direct issue of this PR... |
This PR is not about data dir ( |
|
I was talking about the Qt settings. The data dir path is set in the Qt settings. Sorry if you understood it wrong |
|
utACK 5266efa |
It doesn't matter, you can remove Anyways, I am not talking theoretically, I ACTAULLY tested your code and reproduced issue when invalid If I set invalid |
I bet that 99.99% percent of users will notice it if the blockchain gets re-downloaded (modaloverlay) opens again, etc. |
bitcoin-qt shows me that overlay every day I launch it, as it has to keep up after being offline for the night. I just instinctively close window to minimize it without bothering much... Anyway, this is only one of possible surprises user can get once |
|
Tested, Approach NACK, due to insufficient error handling which is inconsistent when compared to |
|
From IRC
IMO adding this with no error checking is adding a slightly useful feature that's a big footgun in practice. I don't want to block this change if other people want it, but would just again recommend error checking: #17636 (comment) so there aren't silent failures and silently discarded settings with this |
|
Rebased on 5bf45fe, |
5266efa to
a45f901
Compare
|
The client now checks if the custom config file is accessible. If not, it returns an error. If it is not accessible but it is the first time you run bitcoin-qt (datadir does not exists), it will create the config at that location. If this fails it also returns an error. |
| std::fstream f; | ||
| f.open(settingspath.c_str()); | ||
| // File could not be opened | ||
| if (f.fail()) { |
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.
Any reason not to use QFile? In that case would be more "straightforward" - no need to convert QString to std::string.
| // File could not be opened | ||
| if (f.fail()) { | ||
| QMessageBox::critical(nullptr, PACKAGE_NAME, | ||
| QObject::tr("Error: Cannot open config file at \"%1\"").arg(QString::fromStdString(qt_settings_path))); |
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.
IMHO that message could be more concrete - that config file is a bit goo vague. Maybe mentioning GUI settings file would be more informative (since it's for -guisettingsdir).
luke-jr
left a comment
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.
If it is not accessible but it is the first time you run bitcoin-qt (datadir does not exists), it will create the config at that location.
I don't see code for this...?
|
Thanks for your review @luke-jr
This is covered by the Qt library itself |
1d2c07b to
187f968
Compare
Qt doesn't know if |
|
Is it intentional that changing the guisettingsdir to an empty folder, once you have a datadir setup (say after IBD), will not work? |
|
Tested a bit and does not work as expected: Tried on an existing node/datadir (where I previously created a folder Same for creating a new datadir: |
|
@jonasschnelli Ok, I will have a look at this somewhere this weekend |
|
Progress here seems to have stalled, and this doesn't yet seem to work as intended. There have also been multiple requests for tests, and none have been added. I'm going to close this and suggest re-opening your changes in the gui repo if you are still interested in working on them, as aside from |

Short Description
This PR makes it possible to change the Qt relevant config files in a custom directory
Motivation
There are multiple usecases where it could be useful, for example when you use Bitcoin Core on a USB stick, you can keep the config files there as well. My motivation was that I don't need to move my production bitcoin-qt config file to a different place because I don't want that an unstable bulid corrupts my datadir. Currently I need to delete my config or reset the datadir path every time I switch between productive to development. With this I can have a config directory for my productive use and one for my development use.
Showcase
Having a directory called
/home/emil/testconfand running bitcoin-qt will result in this hier:/home/emil/testconf/Bitcoin/Bitcoin-Qt.conf. The Bitcoin subdirectory is a feature, not a bug to make it possible to keep other Qt config files there without colliding. If the the user has no permissions, it won't save anything, if the dir does not exists it will be created.