Qt World Summit: Register Today!

OSX protocol handler without calling ::exec on QCoreApplicaiton/QGuiApplicaiton?

  • I've got a Qt application that can either run as a headless console application (via instancing QCoreApplication and calling exec) or as a full GUI application (via instancing QGuiApplication and calling exec.)

    Basically, if someone clicks on a hyperlink in a document (e.g. Word for OSX) and that link has a particular protocol (e.g. "my_app_protocol: -argument1 value1 -argument2 value2" - url encoded of course) my application will launch, evaluate those arguments and respond accordingly.

    I've got a protocol handler working on Windows, and I've got them on KDE and Gnome on linux - but I'm trying to figure out the best way to do this on OSX - hopefully using Qt and not native code.

    My problem is that I need to retrieve the 'file open' event arguments before knowing whether or not the application should run with a GUI or headless.

    The only thing I can think of at this time is to hack things by creating one or the other, telling it to exec for one second - giving it a chance to handle whatever Apple event created the application instance (it seems that Apple will tell launchd to run your app and then apparently will queue an event for it until you can get it? Seems weird...) And then evaluating the arguments in the handler data and exiting the temporary app instance and then carrying on as normal.

    Naturally this seems like a tremendous 'hack' and I don't know if it will work either...

    I guess I could go the native route - but I'm loathe to introduce objective C code into the project as it complicates things unnecessarily for what I would expect would be a very small return.



  • Lifetime Qt Champion

    @VRHans I don't see why calling QGuiApplicaiton::exec should be a problem: you can create your UI at any time if you need it.

  • @jsulm Well, because I want the arguments in main( void ){} before my application chooses to be either a QCoreApplication or a QGuiApplication.

    This means I'd probably need to create a temporary QGuiApplication object, create a one shot timer for some period of time that simply exited the temporary app's message loop, then called exec on the temporary app object.

    I don't know how long it takes for OSX to make the event available to the application? One second? Two? More?

    What if the machine is under load at the time - is it slower under certain conditions? (Meaning if I determine that it's one second on average, but then fails to work when under load because it takes 1.1 seconds in that case.)

    Whatever that period of time is, users are going to think "Hmmm, why isn't the application starting up as fast as it should?" - especially when just launching the app in a normal fashion (I won't be able to tell if the app was triggered by a user or by the protocol handler...)

    Et cetera. It just seems like a tremendous hack.

    Maybe I'm just doing it wrong and OSX has a way to directly query for an event for my application.

  • Lifetime Qt Champion

    @VRHans " I want the arguments in main( void ){} before my application chooses to be either a QCoreApplication or a QGuiApplication" - you get the arguments for main when your app is starting. So, if it is about those arguments then I don't understand what the problem is?

    int main (int argc, char** argv)
        if (argc > 1) {
            // Assume no UI and use QCoreApplication
        } else {
            // Assume UI mode and use QGuiApplication

  • The arguments from the protocol handler.

    On windows, if an application is launched via protocol handler, the arguments for the protocol handler come in on the command line just like you mentioned above.

    On OSX they do not. On OSX the arguments to a protocol handler are contained in an event that your application must register for and catch. Qt provides some methodology for these events, but there are issues with it as I was querying about above.

  • Well, I was unable to solve this without using a QApplication subclassing hack (one shot timer after 1 second, trigger temporary application object exit, filtering QFileOpenEvent objects...)

    Will assail again at a later date...

Log in to reply