Re: [Gtk-osx-users] Notes on handling Apple events with gtk_osxapplication and PyGTK
- From: Richard Procter <richard n procter gmail com>
- To: GTK+-2 OSX Users <gtk-osx-users lists sourceforge net>
- Subject: Re: [Gtk-osx-users] Notes on handling Apple events with gtk_osxapplication and PyGTK
- Date: Mon, 30 Aug 2010 17:10:28 +1200
On 27/08/2010, at 9:20 AM, Richard Procter wrote:
> On 27/08/2010, at 4:14 AM, John Ralls wrote:
>> Rather, it sounds like the notification handler isn't turned on
>> until NSApplication::FinshedLaunching is called, and that OSX
>> doesn't queue the notification until then. I'll have to dig into
>> that a bit, but ISTM the event loop is going to be required for
>> properly handling the notification.
>
> Yes. Since writing, I've dug into it a little further and decided the
> most convenient thing from the point of view of the user is for the
> signal to be emitted only after ready() has been called as otherwise
> all sorts of hoop jumping is required. The docs suggest there is a
> way to holdoff the OS X notification on startup, if I'm reading them
> right, which I'm looking into more deeply at the moment.
I've found the problem. I ran some tests in the weekend, and
gtk_osxapplication was doing the right thing no matter how long I
delayed the call to OSXApplication.ready() whether via a sleep() call
or just spin-waiting. So the problem was not a race condition as I had
assumed, and due to something in my initialisation code.
Looking at the appropriate docs(*), when the user indicates they want
to open a document in the Finder, OS X injects the appropriate
high-level Apple Event into the application's event queue. As far as
I can tell, all events, whether Apple Events or low-level input
device events, are received asynchronously by the NSApplication via
a Mach port and placed on a single FIFO to be processed by the
application's event loop.
So what was my initialisation code doing? It turns out that my app was
explicitly flushing the gtk event queue in order to post a splash
screen and show the main window to provide some immediate feedback for
the user before doing some stuff and calling gtk.main() later on(**):
the AppleEvent on the event queue was processed as a side-effect(***)
and never got to invoke my signal handler, which was attached
afterwards.
So my immediate problem is solved, which is great.
I think it would help prevent this gotcha biting people in future, to
add a note to the signal docs pointing out that Apple Events are
processed like any other on the gtk event queue.
Just thinking though the possibilites, another approach would be to
buffer AppleEvents until OSXApplication.ready() is invoked, possibly
by adding a hook to the core gdk-quartz event loop to enable the
OSXApplication object to vet and filter the events passed to the
NSApp. It may well be difficult to do this cleanly though and I
haven't taken the time to think it through or think of
better approaches.
regards,
Richard.
(*) References:
- Apple Events Programming Guide:
http://developer.apple.com/legacy/mac/library/documentation/
AppleScript/Conceptual/AppleEvents/AppleEvents.pdf
- How an Event Eneters a Cocoa Application: http://
developer.apple.com/mac/library/documentation/Cocoa/Conceptual/
EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/
doc/uid/10000060i-CH3-SW1
(**) via
while gtk.events_pending():
gtk.main_iteration()
(***) see gdk/gdkeventloop-quartz.c: gdk_event_dispatch() and
gdkevents-quartz.c: _gdk_events_queue(), where the NSApp gets passed
anything that gdk doesn't know how to deal with.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]