[racket] Plot: plot-new-window never happens?

From: Neil Toronto (neil.toronto at gmail.com)
Date: Thu May 24 23:44:27 EDT 2012

Looks like that mostly works. Here's a problem I ran into: it seems 
that, unless I'm careful in a way I don't understand, the children of a 
frame with a new eventspace receive callbacks before they're fully 
initialized. Here's a simple example:

#lang racket

(require racket/gui)

(define test-editor-canvas%
   (class editor-canvas%
     (init parent)
     (super-new [parent parent])

     (define/override (on-size w h)
       (printf "~v~n" should-this-be-defined?))

     (define should-this-be-defined? #f)))

(define frame
   (let ([new-es (make-eventspace)])
     (parameterize ([current-eventspace new-es])
       (define frame (new frame% [label "bob"] [width 400] [height 400]))
       (new test-editor-canvas% [parent frame])
       frame)))

(send frame show #t)


Most of the time, this prints #<undefined> instead of #f, indicating 
that the test-editor-canvas% instance isn't fully constructed before its 
`on-size' is called. If I move its construction outside the 
`current-eventspace' parameterization, it seems to always print #f as it 
should.

The analogous fix in plot would be a slightly trickier, but it seems 
like I shouldn't have to do it.

Neil ⊥

On 04/18/2012 03:16 AM, Matthew Flatt wrote:
> You could give each frame in its own eventspace.
>
> At Tue, 17 Apr 2012 11:45:20 -0600, Neil Toronto wrote:
>> Would it be possible to change plot so that its windows always behave
>> like this? Could I make it not require cooperation from the program that
>> calls `plot-frame'?
>>
>> This is going to come up every time someone wants to pop up plot windows
>> in a non-GUI, interactive loop.
>>
>> Neil ⊥
>>
>> On 04/17/2012 10:48 AM, Matthew Flatt wrote:
>>> All GUI activity like window drawing happens only in the main thread of
>>> an eventspace. Your program also starts out in the main thread. So,
>>> yes, drawing has to wait until your loop completes.
>>>
>>> One solution is to put your loop in a separate thread. The example
>>> below creates a thread and passes it to `yield' to wait until the
>>> thread is done. The `yield' function is special in that it lets other
>>> GUI activity happen while it waits:
>>>
>>>    #lang at-exp racket
>>>    (require plot
>>>             racket/gui/base)
>>>    (plot-new-window? #t)
>>>    (yield
>>>     (thread
>>>      (lambda ()
>>>        (let loop ()
>>>          (let ((dummy (read)))
>>>            (if (and (number? dummy) (zero? dummy))
>>>                (void)
>>>                (begin
>>>                  (plot (function (λ(x) (* x x)) -2 2))
>>>                  (loop))))))))
>>>
>>> Although the above should work, it's not really a good idea to perform
>>> GUI actions outside of the main thread. So, here's an improved version
>>> that uses `queue-callback' to send the `plot' call back to the main
>>> thread:
>>>
>>>    #lang at-exp racket
>>>    (require plot
>>>             racket/gui/base)
>>>    (plot-new-window? #t)
>>>    (yield
>>>     (thread
>>>      (lambda ()
>>>        (let loop ()
>>>          (let ((dummy (read)))
>>>            (if (and (number? dummy) (zero? dummy))
>>>                (void)
>>>                (begin
>>>                  ;; queue a callback instead of `plot' directly:
>>>                  (queue-callback
>>>                   (lambda ()
>>>                     (plot (function (λ(x) (* x x)) -2 2))))
>>>                  (loop))))))))
>>>
>>> For more information, see
>>>
>>>
>> http://docs.racket-lang.org/gui/windowing-overview.html#(part._eventspaceinfo)
>>>
>>>
>>> At Tue, 17 Apr 2012 10:40:55 -0400, Deren Dohoda wrote:
>>>> I was messing around with a spline utility last night and was using
>>>> the plot-new-window? setting to get a plot. The goal was to share an
>>>> exe with a coworker who doesn't have Racket. Just a command-line app
>>>> but to get the plot to display I needed a window and this seemed
>>>> awesome. The problem is I couldn't get the plot to display when the
>>>> thread was in a procedure. The window would appear but it was like the
>>>> plot backend wasn't free to draw to it. Here's a way to reproduce it
>>>> on v5.2:
>>>>
>>>> #lang at-exp racket
>>>> (require plot)
>>>> (plot-new-window? #t)
>>>> (let loop ()
>>>>     (let ((dummy (read)))
>>>>       (if (and (number? dummy) (zero? dummy))
>>>>           (void)
>>>>           (begin
>>>>             (plot (function (λ(x) (* x x)) -2 2))
>>>>             (loop)))))
>>>>
>>>> So long as you are looping, new windows will appear without plot
>>>> contents. When you finally quit (here by entering the number zero) all
>>>> the plots are drawn in those windows. Any help? Did I do something
>>>> horribly dumb?
>>>>
>>>> Thanks,
>>>> Deren
>>>>
>>>> ____________________
>>>>     Racket Users list:
>>>>     http://lists.racket-lang.org/users
>>>
>>> ____________________
>>>     Racket Users list:
>>>     http://lists.racket-lang.org/users
>>
>> ____________________
>>    Racket Users list:
>>    http://lists.racket-lang.org/users


Posted on the users mailing list.