On Saturday, January 31, 2004, at 10:19 AM, Duncan Rose wrote:
On Saturday, January 31, 2004, at 12:23 AM, Timothy Moore wrote:
On Jan 31, 2004, at 12:34 AM, Duncan Rose wrote:
I think (hope) that the event loop requirements won't be *too* much of an issue. Any threads in an application can be sent events, its just that the run loop needs to be manually started for any threads that aren't the main thread. I'll hopefully have a proof of this by the end of the weekend.
The main issue is that window system events are delivered only to the main thread and really have to be handled there too. AIUI.
I'm not sure what AIUI means 8-) And I'm also not sure in this context what "window system" events means... but under the assumption we're talking about any events generated by the window system, I think that these events get delivered to any thread that is running an event loop (i.e. that has an executing run loop). I'll talk about this a little more since I now consider we're back on topic for any threaded GUI work in Cocoa, which will include any IDE we write irrespective of whether it uses CLIM.
I'll split the events into "send to object" and "send to thread" events. Many mouse events (mouse left / right / other down and up, scroll wheel, drag events) are sent directly to the NSView over which they occurred, irrespective of the thread in which they are running and irrespective of whether that thread has an executing run loop. My experimental back end already responds to those (although I am only passing mouse down / up events onto the rest of McCLIM at the moment).
I think that many of the window events (exposed, resized, zoomed, etc.) are sent to the target window (or to its delegate, at least) irrespective of whether the NSWindow is running in the main thread or has an executing event loop, but I have yet to write handlers for any of these (this is my task for the w/end), so I'm not so sure on this one.
I've looked at this in more detail now and can confirm that these window notifications get sent to the window's delegate irrespective of run loop and threading issues.
Other events are distributed to the main thread by default (I assume at the moment that key down / up and mouse moved events (which have to be explicitly enabled for the window(s) that want them) fall into this category) but can be requested by any thread by it (the thread) starting a run loop.
And I can debunk this. Now that I've fixed a little bit of brain-damage in the back end, key events and mouse motion events are sent direct to the NSWindow, again irrespective of run loop and threading issues.
Run loops can only be started by threads that *COCOA* recognises as multithreaded. OpenMCL spins off posix threads (as is to be expected) which can't by default execute run loops until the application informs the window server that it is a multithreaded Cocoa app, by creating an NSThread instance (which is free to immediately exit without doing anything). The application (and any threads of that application) is then considered to be multiprocessing and threads that do not have executing run loops can start them and process any events in the event queue.
If you're interested, here's the code I use for getting Cocoa to recognise my app as a threaded app in my toy back end:
(unless (ccl::send (ccl::@class ns-thread) 'is-multi-threaded) (ccl::send (ccl::@class ns-thread) :DETACH-NEW-THREAD-SELECTOR (ccl::get-selector-for "setHiddenUntilMouseMoves:") :TO-TARGET (ccl::@class "NSCursor") :WITH-OBJECT nil))
I hope you appreciate the inconsistent usage of @class (an example of the lossage in the code ATM) 8-)
The above may be generally true (or maybe not), but I've now taken this code out of my back end and its behaviour is unchanged. So I now *do not* think that run loops or threading is an issue for Cocoa GUIs.
The general structure of the back end I'm working on as it stands is as follows:
1. Click on the natty bundle icon (making use of the Bosco bundle from Mikel) 2. the application delegate does a (clim-listener:run-listener-process) in the application-did-finish-launching, running CLIM as a separate process 3. All the CLIM infrastructure gubbins gets started, including running the CLIM event loop in yet another thread
When the NSApplication receives events, it distributes them to the NSWindow and NSView subclasses I defined in my McCLIM back end. I think that these calls are made in a different thread again, but I could be wrong. However, I can only assume that even though the window instances are created in a different thread to the main thread, they are still added to the main thread's responder chain.
So at the moment, all I can say is: I don't understand quite what's going on or why, but things seem to be working.
The thing I'm not clear on at the moment, but that I hopefully will be sure about in a couple of days, is a) whether this works at all 8-), and b) whether this can cause events to be passed to multiple handlers (e.g. if my NSView or NSWindow is tied up being drawn when key events arrive in the window server queue, will the main threads run loop get to pull them off the queue before the run loop I started for the thread managing the view / window can do so? Or can *both* run loops consume the event (sounds dodgy if so). Or is the event handling in Cocoa clever enough to know that the thread in which the window / view is running has a run loop started, and ensure that only it gets those events?
I suspect that any run loop can process any events that are of an input type the run loop is sensitive to. The listener is event driven as far as the back end is concerned, which means there's nowhere in the back end that gets run on a regular enough basis to run a run loop. I did try the run loop approach yesterday, but couldn't get it to run in the same thread that was running when mouse down events were handled. This seems not to matter though when all the events *do* get delivered to where I want them delivered.
So I still have a ways to go to understand all this properly, but I'm hoping I'll be done (with working (poor quality!) code and everything) exploring this enough for my needs RSN.
Whilst I can't say my understanding of all this is improving much, I can say that things seem to be working - and that is enough for me for the time being. The only remaining unknown is whether other McCLIM apps, when started from the listener, will behave wrt events. Time will tell 8-)
(I'm also going to experiment with running McCLIM apps after doing a (require "cocoa") from openmcl rather than from the Bosco bundle; just to see if it works. I'd be willing to bet at the moment that it will work).
-Duncan
Thanks for the reference, now I just need to read it and think it over 8-)
-Duncan
Here are the key points. As the user types input, the lisp code is calling read-char or whatever. So the input is "live;" for example as soon as the user finishes one argument of a command the prompt for the next argument can be output. So how can the user edit input? If the user backs the cursor up and makes a change, the editor throws out to a catch tag and restarts the function that was reading input. Now that function sees the edited input...
Tim
On Feb 1, 2004, at 6:58 AM, Duncan Rose wrote:
[snip]
The above may be generally true (or maybe not), but I've now taken this code out of my back end and its behaviour is unchanged. So I now *do not* think that run loops or threading is an issue for Cocoa GUIs.
The general structure of the back end I'm working on as it stands is as follows:
- Click on the natty bundle icon (making use of the Bosco bundle
from Mikel) 2. the application delegate does a (clim-listener:run-listener-process) in the application-did-finish-launching, running CLIM as a separate process 3. All the CLIM infrastructure gubbins gets started, including running the CLIM event loop in yet another thread
When the NSApplication receives events, it distributes them to the NSWindow and NSView subclasses I defined in my McCLIM back end. I think that these calls are made in a different thread again, but I could be wrong. However, I can only assume that even though the window instances are created in a different thread to the main thread, they are still added to the main thread's responder chain.
So at the moment, all I can say is: I don't understand quite what's going on or why, but things seem to be working.
This seems like a pretty good start.
I have a Cocoa system definition that snaps into the McCLIM build system. You can load and build the McCLIM system in the normal way, and also build and load the Cocoa back end. If you do that, a McCLIM.app gets built in the same way that Bosco.app gets built. You can launch McCLIM.app and it starts up with a proper name and Dock icon. The app's runtime loads no nibs; it just sets up the bare minimum Cocoa event-processing environment (because it seems to me that nibfiles are not really congruent with the CLIM way of building interfaces). You can also load and run the CLIM listener--but then things break because the concrete classes that realize CLIM sheets and frames are not working.
It seems like we have sort of two ends of the thing pretty well started; now might be a good time to combine them and check in to the McCLIM project so other people can contribute.
It also seems like we're not that far from having a good start on a CLIM-based IDE if we can get the Listener and Goatee up and limping.
I posted separately that I've packaged a 0.1 release of Clotho. Seems like that's two places to start. I don't see any reason we can't pursue both (and others as well) until it becomes clear that either one is a better idea than the other, or that each has its own use.
On Feb 1, 2004, at 11:58 AM, mikel evins wrote:
It also seems like we're not that far from having a good start on a CLIM-based IDE if we can get the Listener and Goatee up and limping.
This sounds great! Right now it looks like Goatee is kind of a bare-minimum solution; since gilberth is involved in hemlock too, the idea was that hemlock would eventually take over as the the McCLIM editor, leaving goatee for line editing.
If in fact Hemlock becomes the best solution for a native Cocoa editor, is there any reason why we can't simply integrate it into a Cocoa McCLIM? That sounds like a way that the two projects could share a significant base of code.
I posted separately that I've packaged a 0.1 release of Clotho. Seems like that's two places to start. I don't see any reason we can't pursue both (and others as well) until it becomes clear that either one is a better idea than the other, or that each has its own use.
I don't see any reason why there wouldn't be a place for the two to coexist: CLIM for people working on a good (and quite possibly platform-independent) CLIM-model IDE, and Cocoa for those people who want a very Cocoa-ish development environment. There's no law against code sharing when we can :-)
Hopefully even a native Cocoa IDE will be able to load CLIM too, so people can use it for writing CLIM programs. -- Brian Mastenbrook bmastenb@cs.indiana.edu http://cs.indiana.edu/~bmastenb/
On Feb 1, 2004, at 9:07 AM, Brian Mastenbrook wrote:
On Feb 1, 2004, at 11:58 AM, mikel evins wrote:
It also seems like we're not that far from having a good start on a CLIM-based IDE if we can get the Listener and Goatee up and limping.
This sounds great! Right now it looks like Goatee is kind of a bare-minimum solution; since gilberth is involved in hemlock too, the idea was that hemlock would eventually take over as the the McCLIM editor, leaving goatee for line editing.
If in fact Hemlock becomes the best solution for a native Cocoa editor, is there any reason why we can't simply integrate it into a Cocoa McCLIM? That sounds like a way that the two projects could share a significant base of code.
No, and it's my intention that Alpaca and Clotho will also use Hemlock as soon as we can get it working properly. I pinged Gary about the state of his Hemlock conversion project, but I haven't heard back from him yet (which is unusual; perhaps he's offline for a bit).
I posted separately that I've packaged a 0.1 release of Clotho. Seems like that's two places to start. I don't see any reason we can't pursue both (and others as well) until it becomes clear that either one is a better idea than the other, or that each has its own use.
I don't see any reason why there wouldn't be a place for the two to coexist: CLIM for people working on a good (and quite possibly platform-independent) CLIM-model IDE, and Cocoa for those people who want a very Cocoa-ish development environment. There's no law against code sharing when we can :-)
Hopefully even a native Cocoa IDE will be able to load CLIM too, so people can use it for writing CLIM programs.
I agree with all of this.