# What is the proper way to close a dialog box?

**URL:** <https://racket.discourse.group/t/what-is-the-proper-way-to-close-a-dialog-box/1233>\
**Category:** Questions & Answers\
**Tags:** gui\
**Created:** [August 15, 2022, 5:59pm UTC](https://racket.discourse.group/t/what-is-the-proper-way-to-close-a-dialog-box/1233 "2022-08-15T17:59:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [August 15, 2022, 5:59pm UTC](https://racket.discourse.group/t/what-is-the-proper-way-to-close-a-dialog-box/1233/1 "2022-08-15T17:59:41Z")

</div>

What is the proper way to close a dialog box?

I admit I haven't read everything in the GUI library yet and I'm trying to learn as I go, but I feel like I must be overcomplicating something here. I looked at the code for `get-text-from-user` and when the time comes to close the dialog it simply does `(send dlg show #f)` I feel like there should be a difference between "hide this thing" and "it's okay to garbage collect this thing".

I have the following code, which I was expecting would:

1. Show a dialog box with text field, 'Ok', and 'Cancel' buttons
2. Wait until one of the buttons is clicked
3. Put the value of the field (or #f) onto an async channel
4. Close the dialog

It does all of that except for the 'close the dialog' part, which makes me think that `on-close` is a thing that is used by the close process and will not actually trigger the close process. What is the right way to do it?

```scheme
#lang racket/gui

(require racket/async-channel)

(define ch (make-async-channel))

; Create a dialog
(define dialog (instantiate dialog% ("Example")))

; Add a text field to the dialog
(define txt-field
  (new text-field% [parent dialog] [label "Your name"]))

; Add a horizontal panel to the dialog, with centering for buttons
(define panel (new horizontal-panel% [parent dialog]
                   [alignment '(center center)]))

; Add Cancel and Ok buttons to the horizontal panel
(new button%
     [parent panel]
     [label "Cancel"]
     [callback (λ (btn ctl-evt)
                 (displayln (format "callback for 'Cancel'. btn: ~v. ctl-evt: ~v" btn ctl-evt))
                 (async-channel-put ch #f)
                 (send dialog on-close))
               ])
(new button%
     [parent panel]
     [label "Ok"]
     [callback (λ (btn ctl-evt)
                 (displayln (format "callback for 'Ok'. btn: ~v. ctl-evt: ~v" btn ctl-evt))
                 (async-channel-put ch (send txt-field get-value))
                 (send dialog on-close))])

(when (system-position-ok-before-cancel?)
  (send panel change-children reverse))

(thread
 (thunk
  (let loop ()
    (displayln (sync ch))
    (loop)))) 

; Show the dialog
(send dialog show #t)

```

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [August 15, 2022, 6:48pm UTC](https://racket.discourse.group/t/what-is-the-proper-way-to-close-a-dialog-box/1233/2 "2022-08-15T18:48:38Z")

</div>

[https://docs.racket-lang.org/gui/top-level-window\_\_\_.html#%28meth.\_%28%28%28lib.\_mred%2Fmain..rkt%29.\_top-level-window~3c~25~3e%29.\_on-close%29%29](https://docs.racket-lang.org/gui/top-level-window___.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._top-level-window~3c~25~3e%29._on-close%29%29)

The `on-close` method is more like a cleanup-handler just before the dialog is closed.

I have an example of a mixin which closes a dialog, though: [https://github.com/benknoble/frosthaven-manager/blob/main/gui/mixins.rkt](https://github.com/benknoble/frosthaven-manager/blob/main/gui/mixins.rkt) (well, really it passes a procedure to a callback; the procedure is used to close the dialog). Effectively it is

```scheme
(when (… can-close?)
(… on-close)
(… show #f))

```

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [August 15, 2022, 6:49pm UTC](https://racket.discourse.group/t/what-is-the-proper-way-to-close-a-dialog-box/1233/3 "2022-08-15T18:49:05Z")

</div>

As I understand it, a window receives `on-close` when it is about to close.  
But sending the message `on-close` to the window doesn't make the window close.

I would use `(send dlg show #f)` as you suggest, followed by a strategically placed `(set! dlg #f)`.  
Eventually the garbage collector will reclaim the resources used by the dialog.

I belive the show/hide mechanism is in place to make it more efficient to "reuse" windows.
