[KDE/Mac] QProcess for GUI apps on OSX (Re: closest equivalent to KApplicationPrivate::init() ?)

René J.V. Bertin rjvbertin at gmail.com
Tue Jan 5 10:58:49 UTC 2016


On Monday January 04 2016 23:14:23 David Faure wrote:

>> Yes, of course. You were hinting at that I start drafting a patch for QProcess, no? Or do you have a Mac yourself on which to cook one up?
>
>I'm letting you do this, just providing input.

Ok. Going to let this simmer/ferment/mature a bit then.

>My line above is because you asked "what about the requirements?". So I thought we were talking about features and therefore API (not about implementation).

Ultimately the 2 are linked, no? :)

>Ideally I was hoping for something more feature-based like a flag for "GUI app, bring the window to the front if possible".
>Such a flag would make sense for all platforms where a specific call to QProcess is being made.
>But of course it might be that LaunchServices is so different from the posix way that it's really a bigger switch with lots

It's not that it is so different. My gripe is with the use of the word and concept GUI. I'm going to have to figure out exactly what GUI aspects are only available to app bundles on OS X currently, and to what extent LaunchServices can be used to start regular executables without delegating to Terminal.app.

OTOH, I think that NormalLaunch vs. GUILaunch could do it. That leaves the nature of the application open, and applies the concept to the launch procedure, which is appropriate.
Apologies if this is what you had in mind all along...

>of behaviour differences which cannot be described as a simple feature-based enum. That's unfortunate. Is there any
>chance for a less intrusive solution to make QProcess bring up the window?

The central issue here is the fact that it is near impossible to tell windows from another application what to do, on OS X, and to know when it'll listen to such instructions (which appears to be required here). The only way I found for the calling process to bring the new application to the front involves using AppleScript in a way it wasn't really designed to be used. I doubt that would ever be acceptable for inclusion into Qt, partly because it can only be a polling algorithm, and it requires either invoking an external utility or else linking to AppleScript itself.
It's not impossible though that the service being invoked through AppleScript ("System Events") can also be invoked directly, but I don't think it'd qualify as "less intrusive". More like "reinventing the wheel".

>Otherwise I have another idea, calling the flags NormalLaunch (the current behaviour) and DetachedLaunch.

Or GUILaunch, see above?

>If you look at the way krun.cpp uses QProcess, it answers the above: start, waitForStarted(), getting PID with processId(), and notification of exit with exit code
>(among other things, to terminate startup notification). [1]
>This means startDetached is not good enough, btw, I realize now: we need to get notified when the process exits.

That might be tricky. I don't know if LaunchServices provides such a feature or if one would need to tap into even lower-level stuff like Mach ports (Mach, not Mac ;)). Applications do receive an "about to exit" message though, possibly even a "will exit" message (the difference being that you can prevent the exit in the former whereas the latter is a notification of impending doom). It's possible that Qt already catches that message, in which case it should be possible to emit a signal which can then be used in QProcess. 

>Wild idea:
> startDetached(const QString & program, const QStringList & arguments, 
>                            const QObject * receiver, const char * member,
>                            const QString & workingDirectory = QString(), qint64 * pid = 0)
>

I've been wondering why startDetached() wouldn't return a QProcess instance. No such instance is created internally in the current implementation, but it seems it should be possible to do so, and in that case you can leave much of the krun.cpp implementation unchanged (connect to the same signal).

BTW, I see krun uses KProcess. I wasn't aware of that class; could we use it as a testbed to develop this whole idea before submitting it to Qt? Is there a reason KInit doesn't use KProcess -- it already depends on KIo which depends on KCoreAddons so it wouldn't mean pulling in new dependencies?


>- a new QGuiProcess class, tailored to starting GUI apps:
>    No channel handling.
>    Always start detached (i.e. killing current process won't kill secondary gui app).
>    And always uses LaunchServices on OSX.
>Maybe all the above is just the reasoning that justifies having a separate class, to avoid having methods that don't apply.

Would QGuiProcess inherit QProcess?
There's the issue with LaunchServices delegating to Terminal.app for certain applications, but one could say that's a side-effect users of QGuiProcess will have to take into consideration. But then QGuiProcess would probably have to inherit QProcess.

>[1] (BTW a notification that the process is all up and ready for interaction is, I think, impossible technically, we don't know what the app is doing; anyway, not needed).

It is possible on OS X. Don't ask me how, but it is exactly what the polling in the AppleScript algorithm mentioned above waits for. Checking if the PID is running isn't enough, the process has to be registered somewhere else, and as long as that's not the case (= the app is starting up) it won't listen to the "activate" instruction.

Cheers
René


More information about the kde-mac mailing list