perl-tk icon indicating copy to clipboard operation
perl-tk copied to clipboard

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

Open scfc opened this issue 1 year ago • 2 comments

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 avatar Aug 10 '24 09:08 scfc

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..)

scfc avatar Aug 14 '24 08:08 scfc

I can confirm the same happening under Windows 11 with German locale!

Argument "0,317073" isn't numeric in addition (+) at ..\blib\lib\Tk\Scrollbar.pm (autosplit into ..\blib\lib\auto\Tk\Scrollbar\Drag.al) line 293. Argument "0,292683" isn't numeric in addition (+) at ..\blib\lib\Tk\Scrollbar.pm (autosplit into ..\blib\lib\auto\Tk\Scrollbar\Drag.al) line 293. Argument "0,268293" isn't numeric in addition (+) at ..\blib\lib\Tk\Scrollbar.pm (autosplit into ..\blib\lib\auto\Tk\Scrollbar\Drag.al) line 293. Argument "0,243902" isn't numeric in addition (+) at ..\blib\lib\Tk\Scrollbar.pm (autosplit into ..\blib\lib\auto\Tk\Scrollbar\Drag.al) line 293. Argument "0,219512" isn't numeric in addition (+) at ..\blib\lib\Tk\Scrollbar.pm (autosplit into ..\blib\lib\auto\Tk\Scrollbar\Drag.al) line 293.

A workaround is setting the locale within the Perl program to English:

use POSIX qw(setlocale LC_ALL); setlocale(LC_ALL, 'en_US.UTF-8');

A fix would be a simple regex substituting "," with "." in Scrollbar.pm. From my understanding $delta is the problem. So: $delta =~ s/,/./g;

Digioso avatar Jan 08 '25 14:01 Digioso