[KDE/Mac] QSP patch/activator

David Faure faure at kde.org
Sun Jan 10 17:43:25 UTC 2016


On Sunday 10 January 2016 17:04:14 René J.V. Bertin wrote:
> On Saturday December 12 2015 19:32:34 David Faure wrote:
> > I didn't mean switching at runtime. I mean using KF5 in Qt apps.
> > I'm pretty sure we had this discussion already but here we go again:
> > If a pure Qt app (say Scribus) has always saved her config to ~/Library/Preferences (using QSP)
> > and in version 1.42 starts using, say, KIO for network-aware file transfers, then that should have
> > no impact on the location of its config file.
> > With a process-global mode for QSP, e.g. triggered by the "activator", then suddenly in
> > version 1.42 Scribus would get from QSP an XDG path (~/.config), and users would lose
> > their config. There's no reason that using one framework should change Qt's behaviour globally.
> 
> I actually don't think I'd ever seen that argument before.

Yeah, I hinted about it, but never took the time to write it so fully.

> It's true of course, but it takes us to a situation where we have 3 instead of 2 kinds of applications:
> 1) pure Qt applications
> 2) KF5 applications
> 3) Qt applications that use a KF5 framework or two.

And the goal is that 2) and 3) are pretty much the same, there's no reason to treat them differently.
Otherwise where do you draw the line? You say "One or two", does that mean that when you get to three frameworks
you suddenly switch to case 2? Of course not ;)

In the qt5/kf5 world, there is only ONE kind of application: Qt applications.
They might or might not use external libraries outside of Qt itself, and KF5 is such a bunch of libs.

> Maybe I was wrong in ever thinking that there is such a thing as a KF5 application, defined in terms of "uses a specific set of KF5 frameworks". 

Exactly. In all my presentations about KF5, I have said: the main purpose is to get rid of the separation
between "a Qt application" and "a KDE [KF5] application". It's all Qt apps now, with libs.

> This would all have been so much easier if a distinguishing class like KApplication had survived the 4->5 transition. After all, what's a less ambiguous way to define a
> KDE application than one that uses KApplication, KGuiApplication or KCoreApplication (even if those classes are nothing but an infinitely thin wrapper on most platforms) ...

No no no. Please forget about this idea right now.
We didn't spend 4 years making sure that all the frameworks are modular and as inter-dependent as possible
and as "low in the tiers" as possible so that they only depend on Qt if possible, to now re-introduce the mother of
all evil (dependency wise), a central application class.

I'll be very clear: KApplication? Over my dead body.

I know it would be "so much easier" for you because of the approach you have in mind for all this.
But it's so completely contradictory with the actual purpose of KF5, that for sure a different approach has to be found.
One which works with the mindset of "Qt plus a bunch of libs".

> What annoys me in this whole situation is that I'm getting zero feedback from MacPorts (users or developers), 2 or 3 exceptions notwithstanding. I'm pretty sure though that'd change if I were to introduce a QSP patch that creates a hardwired XDG-compliant mode.

Well at least you're getting feedback from me, and this way we can make ensure the "Scribus" (fake) example above
is thought about, before users or developers ever get hit by such a problem.

> > > > But I mean "application A can get QSP native while KF5 gets QSP in XDG mode".
> > > > So ok not per-call, but not process-global either. Something in between: per module.
> 
> Do you remember what you meant with "module" here?

Yes: library, plugin or application.
 
If the developer of one library, plugin or application, wants to install its files in directory X and needs
to tell QStandardPaths that the files are in directory X, then it needs a way to do that *without*
changing the *global* mode of operation of QStandardPaths.

When this is about files installed by that very module itself, then easiest solution is to port to .qrc instead,
as Christoph Cullman has been doing.

I think the issue is mostly about files that other modules will want to look up.

We can imagine a number of theoretical solutions (i.e. without thinking much about the porting effort required) :

- making it possible for QSP to find files in a custom install prefix 
    (the solution with env vars was deemed inappropriate for OSX, IIUC?
    so maybe instead QSP could have a call where a module can register its install prefix - but then it's not relocatable; 
    another solution is some magic that determines the prefix from the install path of the lib, was discussed long ago on k-f-d, though maybe not for OSX)

- installing files where QSP expects them (which means "~/Library/Application Support" when installing as user).
  That doesn't work if you want the ability of having N co-installed KF5 versions like on Linux. How strong a requirement is this?

We've been discussing this for so long that I don't actually remember if I had a different suggestion in the past, to add to this.

> > That requires patching qstandardaths.h.
> 
> That's what I have to do anyway in order to introduce a public switch to toggle between native and XDG-compliant mode.
> 
> So we're getting a point were I have 2 alternatives to my current approach
> 
> 1) introduce a header-based class (say KStandardPaths in kstandardpaths.h) which wraps all relevant QStandardPaths methods such that QSP is first toggled to XDG-compliant mode (or at least that the switch is called first). That class could also be defined by qstandardpaths.h itself (say as QXDGStandardPaths). That's something that might be acceptable to upstream. A local patch could then add a specific preprocessor token to make that headerfile also do a `#define QStandardPaths QXDGStandardPaths`. 
> With that approach one only needs to add a -D compiler option to the software that wants XDG-compliant mode ... but that wouldn't affect any libraries (frameworks).

Well such a wrapper could just do the lookup itself, i.e. no need to toggle any global switch then.
KStandardPaths::locateAll(a,b,c) {
#ifdef Q_OS_OSX
    // look up additional dirs .... which ones btw? $XDG_DATA_DIRS? ok, see below then
    if (found in additional dirs)
       return result;
#endif
    return QStandardPaths::locateAll(a,b,c);
}

What I don't get is ...
if env vars such as $XDG_DATA_DIRS are acceptable (from a user's point of view) on OSX, then why don't we add
support for $QT_DATA_DIRS in QSP (on all platforms, while we're at it) ?

What was refused was $XDG_* because, well, XDG isn't a mac spec.
But I think that a review request that adds support for QT_ named env vars,
and which has better justification than "KDE needs it" would have good chances.

> 2) Introduce a KApplication framework 

la la la I'm not even listening. See top of this mail for why.

You can at least alter this suggestion to not suggest subclassing an app class, this is not needed at all.
All you're after is some init code, which can be done with a class that does the init, or a ctor function, etc.
I'll have some objections to that too (not modular, etc.), but at least I won't have the major objection that
we've been moving away from subclassing QApp so that one can use a class from framework X without
the requirement to suddenly change the main() to use a different type of application. How do you do that
when Qt designer loads a plugin that contains widgets from KTextWidgets? Oops, can't change the app
class.

> [...] I need to flip the toggle [...]

The scribus example proves that a toggle is NOT the way to go, please forget about a global toggle.

> [snipped the rest, which is a continuation into that direction]


My problem with making an actual suggestion is that I don't know how a Macports user expects things
to work. You have Qt installed in whatever (possibly not even from Macports).
You then install application A from macports which depends on frameworks B and C.
They all get installed into /opt/local - or worse, a configurable prefix of the user's choice.
The user starts the app, it's supposed to magically work, without having to set any env var?
Macports compiles the code on the user's machine, right? So if we remove relocatability from
the equation (the ability to `mv /opt/local /something/else`) then install prefixes built into the
compiled code are OK (and we already have some of that). In that case my recommendation is
QStandardPaths::addPrefix(CMAKE_INSTALL_PREFIX) where addPrefix would add (if not already
there) to a list of paths to look into (with suffixes share/ for GenericDataLocation etc.)
I don't know if the Qt mac people would agree or not, but I could try to submit something like that.

All "modules" (frameworks and apps) would need to be patched with such an added line
(or you can start imagining buildsystem hacks to automate it), unless we say that installing
every single module into its own prefix isn't supported (it's how our jenkins setup does it though,
to ensure that things don't get picked up by accident from libs not marked as dependencies).
And this doesn't have to be done in a "central location" in every framework; instead (for those
without a central location) it can be done just before the actual usage of QSP (for *DataLocation
or *ConfigLocation, the rest isn't affected).

Note that I'm not talking about writableLocation() anywhere, because honestly, who cares if
the user's config is in ~/Library/Preferences or ~/.config. I don't see any purpose into adding
"XDG-compliant" code on OSX to ever use ~/.config. Let's just use ~/Library/Preferences/.
Or am I missing something important ?

-- 
David Faure, faure at kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5



More information about the kde-mac mailing list