I am new to Tk and I would like to know if the issue in question is normal Tk behavior or not.
In short: I have a Perl / Tk (Tk version 804.028) script that uses two Tk :: ExecuteCommand (v1.6) widgets. Such objects have the execute_command method, which uses a specific fileevent callback to read the stdout executable and returns after it completes. It is solved using waitVariable. But it seems that if two ExecuteCommand start together, they return only when it returns more slowly. I can expect faster to return right after completion.
I did a small Perl / Tk script test to demonstrate the problem:
#!/usr/bin/perl use strict; use warnings; use Tk; use Tk::ROText; my $MAIN = new MainWindow -title => "TEST"; my $text = $MAIN->Scrolled('ROText')->pack(qw/-expand 1 -fill both/); sub pr { # Write into ROText widget $text->insert('end', join '', @_); $text->yview('end'); } pr "Tk version ", Tk->VERSION, "\n"; my @v = (100, 200); sub doo { # Button callback my ($rv, $txt) = @_; pr "B4 wait: $txt, ref=$rv, val=", $$rv, "\n"; $MAIN->waitVariable($rv); pr "Aft wait: $txt, ref=$rv, val=", $$rv, "\n"; } $MAIN->Button(-text => 'Do 0', -command => [\&doo, \$v[0], "Do 0" ] )->pack(qw/-expand 1 -side left -fill both/); $MAIN->Button(-text => 'Stop 0', -command => [sub {++$v[0]; pr "Stop 0\n";} ] )->pack(qw/-expand 1 -side left -fill both/); $MAIN->Button(-text => 'Do 1', -command => [\&doo, \$v[1], "Do 1" ] )->pack(qw/-expand 1 -side left -fill both/); $MAIN->Button(-text => 'Stop 1', -command => [sub {++$v[1]; pr "Stop 1\n";} ] )->pack(qw/-expand 1 -side left -fill both/); MainLoop();
This draws a ROText widget and 4 buttons ([Do 0] [Stop 0] [Do 1] [Stop 1]) (see attached image). By pressing the "To" button, it calls the doo function, which waits until the assigned scalar is changed. Variables change when the Stop button is pressed.
If the buttons are pressed in the order of [Do 0] [Stop 0] [Do 1] [Stop 1], the output appears normal (see lines 2-7). But if the "tasks" started in parallel, both callbacks end only if both of them are stopped. Therefore, pressing the buttons in [Do 0] [Do 1] [Stop 0] [Stop 1] (see Lines 8-13) gives a strange result (see Figure).

My expectation of the second test was that the first callback function returns immediately after pressing the first Stop button. Therefore, I think the conclusion should be:
B4 wait: Do 0, ref=SCALAR(0x9970560), val=101 B4 wait: Do 1, ref=SCALAR(0x9970bfc), val=201 Stop 0 Aft wait: Do 0, ref=SCALAR(0x9970560), val=102 Stop 1 Aft wait: Do 1, ref=SCALAR(0x9970bfc), val=202
It runs on a Linux machine.
Am I missing something? Thanks in advance!
UPDATE
To get around this waitVariable problem, I rewrote this widget to use callbacks instead (thanks Tantalus!). Now execute_command returns immediately. There are two callbacks: one for Cancel, one for Done. The caller is now informed through these callbacks. Anyway, I read somewhere (I canโt find the source now) that waiting a long time in the callback is not a good idea in Tk. The new solution matches this.
Thank you for your help!