I am trying to create a parameter, current-frame, that allows me to access the 'current frame' in a multiple frame environment. In this case, the 'current frame' is the one under which the user initiated the action which has caused a particular function to run. A very simple example might be as follows:<br>
<br><span style="font-family: courier new,monospace;">#lang scheme/gui</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(define current-frame</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (make-parameter #f))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(define my-frame%</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (class frame%</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (super-instantiate ())</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (field (text-field</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (instantiate text-field%</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> ("Press test button to update:" this))))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (instantiate button%</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> ("Clear" this)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (callback</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (lambda (b e)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (send text-field set-value ""))))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (instantiate button%</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ("Test" this)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (callback</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (lambda (b e)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (update-text-field))))))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(define (update-text-field)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (send (get-field text-field (current-frame))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> set-value (send (current-frame) get-label)))</span><br style="font-family: courier new,monospace;">
<br>The update-text-field function will set the value of the text-field field in the 'current frame' to the label of the 'current frame'. When update-text-field is invoked, I want the value of the current-frame parameter to be the frame where the user clicked the Test button. So, the behavior I want is for the text-field in the frame in which the Test button is clicked to be updated with the label of that frame. [Yes, in this case it would be easy to just pass the frame to update-text-field or any of several other trivial solutions. But, bear with me.]<br>
<br>I have tried various combinations of parameterize and current-frame, with no success. For example:<br><br><span style="font-family: courier new,monospace;">(parameterize ((current-frame (instantiate my-frame%</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> ("Frame 1"))))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (send (current-frame) show #t)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (update-text-field))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(parameterize ((current-eventspace (make-eventspace)))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (parameterize ((current-frame (instantiate my-frame%</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ("Frame 2"))))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (send (current-frame) show #t)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (update-text-field)))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(parameterize ((current-eventspace (make-eventspace)))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (let ((frame-3 (instantiate my-frame%</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> ("Frame 3"))))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (current-frame frame-3)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (send (current-frame) show #t)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (update-text-field)))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(let ((frame-4 (instantiate my-frame%</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ("Frame 4"))))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (current-frame frame-4)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (send (current-frame) show #t)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (update-text-field))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(let ((frame-5 (instantiate my-frame%</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> ("Frame 5"))))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (current-frame frame-5)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (send (current-frame) show #t)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (update-text-field))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;">If you evaluate all of these, then Frame 1, Frame 4, and Frame 5 all share a common eventspace. Clicking the Test button on any of them will result in "Frame 5" being written in the text-field in Frame 5. Clicking the Text button on either Frame 2 or Frame 3, which should be running in their own eventspaces, both give an error "get-field: expected an object, got #f". In all cases, the hard-coded calls to update-text-field that are lexically within the scope (and eventspace) that instantiated the frame work as expected.<br>
<br>I assume the problem is with my mental model of parameters and eventspaces. I had assumed that each eventspace would have, in addition to its event queues, etc, its own execution thread, and copies of any parameters. Since it allows me to parameterize or set the current-frame in a new eventspace, I assume the eventspace 'knows about' my current-frame parameter. What I don't understand is why a call to update-text-field by a frame that I think is running under 'new' eventspace doesn't get a value for the current-frame parameter. So, I understand the behavior of Frames 1, 4, and 5 - or at least they fit my (probably flawed) mental model. But, I don't understand the behavior of Frames 2 and 3, which seems like they would work if my mental model were correct.<br>
<br>I tried to use get-top-level-focus-window, but it doesn't work in my case. This is an analysis application where some functions are very long running and the focus window at the time something is running isn't necessarily what I was thinking of as the 'current frame'.<br>
<br>As an aside, I am basically trying to the replicate the functionality of the *application-frame* (dynamically-scoped) global variable in CLIM.<br>