eserte / perl-tk

the perl module Tk
https://metacpan.org/release/Tk
Other
44 stars 31 forks source link

Scrolled emits warnings when scrollbar is dragged and locale-set decimal separator is "," #107

Open scfc opened 1 month ago

scfc commented 1 month ago

On Fedora 39, with perl-Tk-804.036-13.fc39.x86_64, the test script scrollbar-test.pl:

#!/usr/bin/perl -w

use strict;
use utf8;
use warnings;

use Tk;

my $MW = new MainWindow (-title => 'Test');
my $Listbox = $MW->Scrolled ('Listbox', -scrollbars => 'oe', -height => 0, -width => 0, -selectmode => 'multiple');
foreach my $i (1..1000) {
    $Listbox->insert ('end', 'Test entry #' . $i);
}
$Listbox->grid (-sticky => 'nesw', -row => 0, -column => 0);
$MW->gridRowconfigure (0, -weight => 1);
$MW->gridColumnconfigure (1, -weight => 1);
Tk::MainLoop ();

will emit warnings of the type:

Argument "0,00102881" isn't numeric in addition (+) at ../blib/lib/Tk/Scrollbar.pm (autosplit into ../blib/lib/auto/Tk/Scrollbar/Drag.al) line 293.
Argument "0,00514403" isn't numeric in addition (+) at ../blib/lib/Tk/Scrollbar.pm (autosplit into ../blib/lib/auto/Tk/Scrollbar/Drag.al) line 293.
Argument "0,0133745" isn't numeric in addition (+) at ../blib/lib/Tk/Scrollbar.pm (autosplit into ../blib/lib/auto/Tk/Scrollbar/Drag.al) line 293.
Argument "0,0246914" isn't numeric in addition (+) at ../blib/lib/Tk/Scrollbar.pm (autosplit into ../blib/lib/auto/Tk/Scrollbar/Drag.al) line 293.
Argument "0,0442387" isn't numeric in addition (+) at ../blib/lib/Tk/Scrollbar.pm (autosplit into ../blib/lib/auto/Tk/Scrollbar/Drag.al) line 293.
[…]

to stderr when the scrollbar is dragged up and down and the locale's decimal separator is "," (e. g. LC_NUMERIC=de_DE.UTF-8 perl scrollbar-test.pl). If the locale's decimal separator is "." (e. g. LC_NUMERIC=en_GB.UTF-8 perl scrollbar-test.pl), no warnings are emitted.

scfc commented 4 weeks ago

Further musings: The cause of the warning is that pTk/mTk/generic/tkScrollbar.c's ScrollbarWidgetCmd() uses sprintf() to set the return value for delta. sprintf() will honour the locale setting.

So my first instinct was that all numerical values "obviously" have to be specified in the C locale and all calls to sprintf() and scanf() just have to be wrapped with uselocale(). Well, with Tcl, this assumption seems to be not so clear.

My second idea was to be clever and just parse the returned value with POSIX::strtod() which honours the locale setting as well. For debugging, I added:

 use Data::Dumper;
 print STDERR Dumper $delta;
 use POSIX;
 print STDERR Dumper (POSIX::strtod($delta));

after the call to $w->delta() in /usr/lib64/perl5/vendor_perl/auto/Tk/Scrollbar/Drag.al, and a funny thing happened: The first value returned by $w->delta() was in the user-set locale, all subsequent values in the C locale. WTF?

So I moved use POSIX; to the top of Drag.al directly beneath package Tk::Scrollbar; and all values returned by $w->delta() were in the C locale. WTAF?

(Sidenote: As a casual Perl user, I found it "impossible" to a) use the Perl debugger on autoloaded/autosplit files and b) make my test script use the local repository instead of the system's module. For the latter, perl -Iblib/lib -Iblib/arch scrollbar-test.pl complained about Can't locate Tk/AddScrollbars.pm in @INC (you may need to install the Tk::AddScrollbars module) (@INC entries checked: blib/lib blib/arch /usr/local/lib64/perl5/5.38 /usr/local/share/perl5/5.38 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at blib/lib/Tk/Widget.pm line 270..)