QSP patch/activator (Review Request 126125: [OS X] make KDE's trash use the OS X trash)

René J.V. Bertin rjvbertin at gmail.com
Sun Jan 10 16:04:14 UTC 2016


On Saturday December 12 2015 19:32:34 David Faure wrote:

Somehow I never got around to answering this. Also directing this back to the lists.


> 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. 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.

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". 
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) ...

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.

> > > 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?

> 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).

2) Introduce a KApplication framework with the specific mission statement of setting up things appropriately so that applications can be part of some sort of KDE universe - whatever that may mean on the different (non-Plasma) platforms.
There is 1 problem with this: all applications do not instantiate Q*Application as the 1st thing in their main() routine, so an implementation that toggles the QSP in the K*Application ctor wouldn't affect QSP calls made before that ctor is called.

Both alternatives thus have a problem in the extent of their QSP control. So each time I think of alternative solutions to my current implementation, I come back to the fact that I need to flip the toggle
a) at an appropriate time before main is called (or at least as the 1st thing in main)
b) OR I need to define a global bool variable that is then used in a wrapped QSP call or in an explicit call to the QSP mode toggle function, hopefully before any "unprotected" calls are made to a QSP location function.

In other words, we'd still be looking at an additional link module if I want to reduce the complexity (and maintenance burden) of distribution QSP/XDG patches, esp. if those patches are to target applications and no longer only the frameworks.
That makes me lean to alternative (2) and (a) above. A KApplication framework could contain both an initialisation routine or a private class that gets a global, static instance; either of those options provide an early way to call the QSP toggle switch with a value that can be defined when the *framework* is built. The K*Application ctors could then call that toggle again with a value that is defined when the *application* is built. Patching applications would be as "simple" as ensuring that the appropriate K*Application class is used instead of Q*Application: #include k*application.h after q*application.h, 
and link with the KApplication binary where needed.
This has the big advantage over my current approach that it's much easier to determine where to patch (every file that includes a reference to the Q*Application class); and once that's done the linker won't tolerate any omissions of the binary. One (big) disadvantage is that the number of entities to patch will continue to grow, and it'd include all autotests...
Edit: I forgot about static methods from those Q*Application classes ... an egrep search on 'QApplication|QGuiApplication|QCoreApplication' found hits in 1084 files from the 5.17.0 frameworks sources; evidently those wouldn't all have to be patched and I clearly need to think of a more specific search strategy! A pattern like 'QApplication[^:>]|QGuiApplication[^:>]|QCoreApplication[^:>]|class.*Q[AGC].*pplication' still catches 458 files, and turned up things like

```
    //If we are not a QApplication, means that we are a QGuiApplication, then we do nothing.
    if (!qobject_cast<QApplication *>(QCoreApplication::instance())) {
        return;
    }
```

which suggest it might not be a wise idea to just `#define QApplication KApplication` :-/

And I suppose that a proposition to bring back KApplication and family wouldn't be exactly welcomed by the KDE community, even if it were to be in a purely optional framework?

BTW: am I right that in my current approach I actually can contend myself with adding the link module only to the Tier1 frameworks rather than to all frameworks? All Tier >1 frameworks depend on at least 1 Tier1 framework (directly or indirectly), correct?

Cheers (and thanks for any further constructive feedback),
René


More information about the Kde-frameworks-devel mailing list