Draft: 💍 One Ring to Bind all Preferences
This MR is a draft proposal for one-ringing (à la Tolkien) the preferences usage we have throughout Krita.
One of the key concerns voiced by @rempt since I started collaborating with Krita was "we don't have a single source of truth!". Back when I did the G'MIC plugin-i-fication in !581 (merged), this bit us hard because G'MIC did its own changes to QCoreApplication
. This issue, and more, was documented in T14815. I started working on it a year ago, but left it at that for lack of reliable tooling to trace all the usages of preferences. Thanks to @dragonmux's mentoring, and my clangd/GCC/MSVC toolkits, I could go back to it and tackle this whole!
The core of this MR is a superclass of KisConfig
, KisConfigBase
. KisConfigBase
is intended, once ready and verified, to serve as a lightweight, fully PIMPL'd abstraction to whatever backend we might use in the future.
But the refactor doesn't stop there. As part of the refactor, I have:
- removed the mutability of
KisConfig
- set proper compiler-verifiable constness for all the setters
- audited all usages of
KisConfig
and, where possible, replaced with cheaperconst KisConfigBase
instances - removed the possibility of initializing non-const, read-only instances. (this will now trigger a hard assertion!)
- introduce the new abstraction to the GUI controls
- cleaned up all inclusions of
KSharedConfig
,KConfigGroup
,KConfig
, andKisConfig
(in case this one wasn't obvious😅 )
This MR was created as a draft and without a milestone because it is a really invasive change.
So please bring the pitchforks, torches, and chainsaws, and let's review it!
Questions (that I remember right now)
-
We use a whole lot of read-write
KConfigGroup
/KSharedConfig
instances, I guess to sidestep KisConfig, but the tradeoff is that there are no obvious semantics as to thesync()
calls.- Do you intend to force a
sync()
to storage on each destruction, or just rely on KConfig's synchronization? (Which, BTW, is a no-op on all platforms except for Linux due to its reliance on D-Bus.)
- Do you intend to force a
-
The controls that were forked from KDE (mainly those in xmlgui) willy-nilly instance the configuration and then feed it back to KDE's innards, which breaks the concern-separation model I'm using for this refactor.
- Do you think we should put the elbow grease and subclass
KConfigBase
for these cases?
- Do you think we should put the elbow grease and subclass
-
Key features that lock us in to KDE at present are:
- a clear synchronization mechanism
- T <-> QVariant automatic conversion
QSettings
, conversely, let us use whatever the underlying OS provides, and presents a fully cross-platform, sync-able abstractions.- Do you think we should put the elbow grease to remove our reliance on both the above items?
Test Plan
Build Krita. Run tests and use Krita.
Formalities Checklist
-
I confirmed this builds. -
I confirmed Krita ran and the relevant functions work. -
I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!) -
I made sure my commits build individually and have good descriptions as per KDE guidelines. -
I made sure my code conforms to the standards set in the HACKING file. -
I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy.
/cc @rempt