Re: Tk hidden binding
by zentara (Cardinal) on Jul 23, 2011 at 21:10 UTC
|
Yeah, you are right. I saw that \x{13} and just thought it was unicode not being properly handled, like maybe your shell settings were en_US instead of en_US.UTF-8, (or some such confusion :-)) But now that I woke up, :-) I think it might have to do with the bindtag order with the way you have control s bindings for both the $mw and the Text widget.
This is about all I can figure out. My guess is the \x{13} is the text widget trying to print the line ( which is normal behavior), but the $mw binding is somehow messing it up. If the below setting of the bindtags dosn't help, I would guess you have a defective Tk installation? Can you reinstall Tk? What version of Tk and Perl are you running? Does the following script give good behavior? I left the "test 4" uncommented. Play with it and see what happens. Otherwise, post a self contained complete mini example that demonstrates the problem. I just diid notice a different behavior for the Text::Undo vs the plain Text widget, and if the widget is Scrolled or not. So you may want to try binding to the REAL text widget, not the Scrolled widget. I noticed with a Scrolled widget, the line gets printed, whearas in the plain widget it does not. Also, can you test your real script with a Scrolled Text instead of a Scrolled TextUndo?
my $t1 = $mw->Scrolled('TextUndo')->pack;
my $t1_real = $t1->Subwidget("scrolled");
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
require Tk::TextUndo;
my $mw = tkinit;
# create a top bar for testing pure $mw focus
my $button = $mw->Button(-text=>'test')->pack();
$mw->bind('<Control-s>', sub { print "main control s \n" });
my $t1 = $mw->Scrolled('TextUndo')->pack;
# uncomment the following sections to get different behavior of the
# bindings, the test 4 is left uncommented to start, to show proper be
+havior
#####################################################
# test 1
# without any Text control s binding, the text widget prints a
# line across the text widget AND a "main control s" to the console
###################################################
# test 2
#if we just add a control s binding to the text widget
# we get main control s, and text control s printed to console,
# and a line printed in the text widget
#$t1->bind('<Control-s>', sub { print "\ttext control s\n"; });
####################################################
#test 3
# we get only text control s to the console and the line,
# but NO main control s
#$t1->bind('<Control-s>', sub { print "\t\tfoo\n"; $_[0]->break });
#####################################################
#test 4
# no line is shown, no line printed, no main control s ,
# just a foo.
#
# the order of bindtags is:
# class name (Tk::Text), window name, ancestral toplevel, "all"
# this modifies the tag list so that the instance binding,
# which includes a call to break(), has higher priority
# than the class binding
$t1->bind('<Control-s>', sub { print "\t\tfoo\n"; $_[0]->break });
$t1->bindtags([($t1->bindtags)[1,0,2,3]]);
MainLoop;
| [reply] [d/l] [select] |
|
Many thanks for your concerned handling of this case and for the time spent. My version of Perl is v5.10.1 (*) built for x86_64-linux-gnu-thread-multi (with 53 registered patches) and Tk installed (by Cpan I think) under /usr/local/lib/perl/5.10.1/Tk.pm seems to be Tk804.029 (as displayed by 'man Tk').
I've run your tests and the results reported below are quite puzzling to me. I won't create another mini example because I think yours is perfectly demonstrative of my problem. Apart from the fact that I still don't know how to solve it I find some ease in not having disturbed you for mere carelessness.
My results for the keypress of <control-s>:
test 4 (the original behaviour of your program):
"main control s\n" is printed to the console when the focus is $mw.
"\t\tfoo\n" is printed in the in the console and "\x{13}" in the text widget when the insertion point is in.
test 3 uncommented (other tests commented out):
"main control s\n" is printed to the console when the focus is $mw.
"\t\tfoo\n" is printed in the in the console and "\x{13}" in the text widget when the insertion point is in.
Behaves as test 4.
test 2 uncommented (other tests commented out):
"main control s\n" is printed to the console when the focus is $mw.
"\ttext control s\nmain control s\n" is printed in the in the console and "\x{13}" in the text widget when the insertion point is in.
test 1 (each test commented out):
"main control s\n" is printed to the console when the focus is $mw.
"main control s\n" is printed in the in the console and "\x{13}" in the text widget when the insertion point is in.
Comment:
If it wouldn't be for test4 which differs deeply, I would think that your newline is replaced by \x{13} in my Tk version. But why should a newline be printed anyway?
| [reply] |
|
I would think that your newline is replaced by \x{13} in my Tk version. But why should a newline be printed anyway?This brings up a good point, what do YOU expect to happen when you press a <control s> in the TextUndo widget? The normal behavior, on my Tk ( version Tk-804.029_500 ) , with no extra bindings associated with it, is to print what appears to be an underscore line segment, not a newline. It is not a dash or hyphen. Repeated presses of <control s> create a continuous line looking like an underscore (at the bottom of the font area).
Do you want this behaviour? If you want to stop all text insertion, with a <control s>, try this and see what happens. I get NO insertion of any kind into the TextUndo
widget. Notice I'm getting the REAL widget, not the Scrolled one.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
require Tk::TextUndo;
# a <control s> in the TextUndo widget produces
# nothing in the Text area, and a foo to the console
my $mw = tkinit;
# create a top bar for testing pure $mw focus
my $button = $mw->Button(-text=>'test')->pack();
$mw->bind('<Control-s>', sub { print "main control s \n" });
my $t = $mw->Scrolled ('TextUndo')->pack;
my $t1 = $t->Subwidget("scrolled"); # get real widget
$t1->bind('<Control-s>', sub { print "\t\tfoo\n"; $_[0]->break });
$t1->bindtags([($t1->bindtags)[1,0,2,3]]);
MainLoop;
To address the point that you saw no difference in binding to a Scrolled or standard TextUndo widget, notice the difference in behavior in this script, where I bind to the Scrolled widget. I get the foo to the console, plus the underscore line gets printed to the TextUndo.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
require Tk::TextUndo;
# when binding to the Scrolled widget, instead
# of the real widget, a line gets printed to the text area
# as well as the foo to the console
my $mw = tkinit;
# create a top bar for testing pure $mw focus
my $button = $mw->Button(-text=>'test')->pack();
$mw->bind('<Control-s>', sub { print "main control s \n" });
my $t1 = $mw->Scrolled ('TextUndo')->pack;
$t1->bind('<Control-s>', sub { print "\t\tfoo\n"; $_[0]->break });
$t1->bindtags([($t1->bindtags)[1,0,2,3]]);
MainLoop;
| [reply] [d/l] [select] |
|
|
| [reply] |
|
See the above 2 examples, in Re^3: Tk hidden binding, in one the Text area print occurs, in the other, it dosn't. The difference is binding to the Subwidget("scrolled") instead.
| [reply] |
Re: Tk hidden binding
by zentara (Cardinal) on Jul 23, 2011 at 13:57 UTC
|
Unicode is still a dark area for me too, but before one of the unicode experts can answer you, try putting one, the other, or both, in your script.
use utf8;
$Tk::encodeFallback=1;
| [reply] [d/l] |
|
Thank you but unfortunately these lines don't impede the insertion.
| [reply] |
|
Besides I don't understand why I should care about Unicode in my program which doesn't deal with special characters.
| [reply] |
Re: Tk hidden binding
by Anonymous Monk on Jul 24, 2011 at 10:28 UTC
|
As far as I can tell, this is a bug in Tk :) Run one of these and type Ctrl+[
perl -MTk -le " tkinit->Text->pack->focus; MainLoop; "
perl -MTk -le ' tkinit->Text->pack->focus; MainLoop; '
or type Ctrl+] and you'll get esc(\033) and gs(\035) respectively
This is a bug
$ perl -MTk -le " print for Tk->VERSION, $^V "
804.0295
v5.12.2
$ perl -MTk -le " print for Tk->VERSION, $] "
804.028
5.008009
Ctrl+g results in bel(\a)
This isn't supposed to happen :)
Checking the Tk bug cue i find Bug #47173 for Tk: "Modifier" key releases don't track key presses correctly
perl/Tk is built upon Tcl/Tk 8.5.7
Tcl/Tk 8.6 doesn't have this problem
#!/usr/bin/perl --
use strict;
use warnings;
use Tcl::pTk;
my $int = new Tcl::pTk;
$int->Eval(<<'EOS');
# pure-tcl code to create widgets (e.g. generated by some GUI builder)
text .e
## http://wiki.tcl.tk/1626#tk_version
.e insert end "tcl_version $tcl_version\n"
.e insert end "tcl_patchLevel $tcl_patchLevel\n"
.e insert end "tk_version $tk_version\n"
.e insert end "tk_patchLevel $tk_patchLevel\n"
.e insert end "tk_library $tk_library\n"
pack .e
EOS
my $e = $int->widget('.e'); # get .e entry into play
$e->insert( "end", "
Tcl::pTk $Tcl::pTk::VERSION
Tcl $Tcl::VERSION
\$^V $^V
\$] $]
");
$int->MainLoop;
__END__
tcl_version 8.6
tcl_patchLevel 8.6b1.2
tk_version 8.6
tk_patchLevel 8.6b1.2
tk_library C:/Tcl8.6/lib/tk8.6
Tcl::pTk 0.85
Tcl 1.02
$^V v5.12.2
$] 5.012002
| [reply] [d/l] [select] |
|
On my Tk (Tk-804.029_500) a <control ]> prints a # character to the Text area. I don't know for sure if this is what is normal or not, I'm running Slackware 1337 for AMD64 , if that makes any difference in keyboard setups.
| [reply] |
|
I don't know for sure if this is what is normal or not, I'm running Slackware 1337 for AMD64 , if that makes any difference in keyboard setups.
I think it is not normal , I've yet to see a toolkit where a text widget does that by default going back some 20 years :)
Nice catch with the subwidget in Re^3: Tk hidden binding, I also get the same thing you describe
| [reply] |
|
|
|
|
It's amazing how things can get complicated quickly. I get \x{1b} and \x{1d}. Thank you for the various informations in your answer.
| [reply] |
|
Hey, thats almost the same thing ;)
$ perl -le " print qq[\033\035] " |od -tacx1
0000000 esc gs cr nl
033 035 \r \n
1b 1d 0d 0a
0000004
| [reply] [d/l] |
|
|