Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bind . <Destroy> executes several times

45 views
Skip to first unread message

Juge

unread,
Sep 11, 2019, 3:33:57 PM9/11/19
to
I wanted to do a routine that will execute if the user presses the window controller "X" to close the GUI, instead of the "Close" button. I used the bind $w <Destroy> but noticed that it executed my prog several times in succession.
Is there a way to limit it to one single execution?

Of course I could set a global boolean variable in the prog that will block all the successive executions with an if sentence, but it does not seem very elegant. I am also not sure whether there is a way to "unbind" the <Destroy> event or whether I simply use a wrong formulation. Any ideas?

Rich

unread,
Sep 11, 2019, 3:43:03 PM9/11/19
to
Juge <jyrki.m...@gmail.com> wrote:
> I wanted to do a routine that will execute if the user presses the
> window controller "X" to close the GUI, instead of the "Close"
> button. I used the bind $w <Destroy> but noticed that it executed my
> prog several times in succession. Is there a way to limit it to one
> single execution?

This is not the command you are looking for.

You are looking for 'wm protocol' and the protocol name WM_DELETE_WINDOW.

Juge

unread,
Sep 11, 2019, 4:26:14 PM9/11/19
to
Am Mittwoch, 11. September 2019 21:43:03 UTC+2 schrieb Rich:
>
> This is not the command you are looking for.
>
> You are looking for 'wm protocol' and the protocol name WM_DELETE_WINDOW.

Ok, how can I catch this and make it execute my proc?

Juge

unread,
Sep 11, 2019, 4:29:51 PM9/11/19
to

Robert Heller

unread,
Sep 11, 2019, 4:50:02 PM9/11/19
to
wm protocol .window WM_DELETE_WINDOW [list myproc .window]

proc myproc {somewidow} {
puts stderr "Opps. $somewidow was closed"
}


--
Robert Heller -- 978-544-6933
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

Mike Griffiths

unread,
Sep 11, 2019, 5:01:06 PM9/11/19
to
Using [bind] should be fine, just be aware that, by default, bindings fire (as per [bindtags] for:
a) the widget itself
b) the widget's class
c) the widget's parent
d) "all"

So every child of "." will trigger bindings on . as well. You can get around this in a few ways:

- Check the class of "." - usually the script name, I believe - and put your <Destroy> binding on that
- Add something new to its bindtags: bindtags . [list MainWindow {*}[bindtags .]] and then [bind MainWindow <Destroy> $yourScript]
- Check that it's actually "." triggering the binding: bind . <Destroy> {if {"%W" eq "." } {script}}

Rich

unread,
Sep 11, 2019, 6:58:40 PM9/11/19
to
Or.... Use the documented method to catch the OS level close button
event:

wm protocol with the protocol name WM_DELETE_WINDOW.

Andreas Leitgeb

unread,
Sep 20, 2019, 3:20:15 AM9/20/19
to
Robert Heller <hel...@deepsoft.com> wrote:
> At Wed, 11 Sep 2019 13:26:11 -0700 (PDT) Juge <jyrki.m...@gmail.com> wrote:
>> Am Mittwoch, 11. September 2019 21:43:03 UTC+2 schrieb Rich:
>> > This is not the command you are looking for.
>> > You are looking for 'wm protocol' and the protocol name WM_DELETE_WINDOW.
>> Ok, how can I catch this and make it execute my proc?
> wm protocol .window WM_DELETE_WINDOW [list myproc .window]
> proc myproc {somewidow} {
> puts stderr "Opps. $somewidow was closed"
> }

This indicates a slight misconception:
The puts shall rather say: "user expressed a wish to close $somewindow"
The code you showed (of course regardless of the actual message) does
not close the window.

Once you register a callback, it is then the callback's responsibility
to either close the window or not-close it (e.g. when there is unsaved
data and user declines some "close anyway?"-popup).

0 new messages