I have a very simple Racket GUI:
(define frame (new frame% [label "Goodbye, World!"]))
(define msg (new message% [parent frame]
[label "No events so far..."]))
(new button% [parent frame]
[label "Click Me"]
(callback (lambda (button event)
(send msg set-label "Button click"))))
(send frame show #t)
This works as expected - producing a button which responds to events - if I run it directly. However, if I run it in a sandbox as part of another Racket GUI application:
(define/public (set-content content)
(parameterize ([sandbox-gui-available #t])
(let ((evaluator (make-evaluator 'racket/gui)))
(evaluator content))))
... where content
is the Racket source above, then the frame displays when set-content
is called:
... but doesn't respond to events like clicks.
I suspect I'm missing something obvious here but the docs suggest the new GUI should get its own eventspace, so this feels like it should work.
CodePudding user response:
I think this is a bug in the sandbox's GUI support. When GUI mode is enabled, it creates an eventspace and runs the evaluation loop in that eventspace's handler thread. But the evaluation loop blocks on a channel waiting for things to evaluate, so it blocks the eventspace from handling actual GUI events.
A workaround is to run (current-eventspace (make-eventspace))
in the evaluator before doing anything else that involves the current eventspace, like creating a frame.