Tk Source Code

View Ticket
Login
Ticket UUID: 2524085333f44fbc19d244a2a96d2eeb04cc7e17
Title: fedora 25: tk scaling returns an invalid value after screen resize
Type: Bug Version: 8.6.6, 8.6.7
Submitter: bll Created on: 2017-12-13 22:17:49
Subsystem: 99. Other Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Open Last Modified: 2018-01-07 10:55:04
Resolution: None Closed By: nobody
    Closed on:
Description:
If 'tk scaling' cannot determine a proper value, it should return the default.

[bll@fedora25 test.dir]$ ../linux/64/tcl/bin/tclsh
% package require Tk
8.6.7
% tk scaling
Inf
% exit

[bll@fedora25 test.dir]$ wish
% info patch
8.6.6
% tk scaling
Inf
% exit
User Comments: fvogel added on 2018-01-07 10:55:04:

Still more digging:

- XkbOpenDisplay() basically is a wrapper on top of XOpenDisplay()

- XOpenDisplay() fills the Display structure with the screen info returned in u.rp, see source code of XOpenDisplay, lines 391-409.

- u.rp is a (xWindowRoot *). u is returned by the display server on the first connection created and sent by XOpenDisplay().

(Also, I forgot to say that when resizing the VM in which Fedora 27 Gnome Wayland is running, I experience freezes of the display. The VM seems healthy but no click or keystroke has any effect. Not always repeatable though.)


fvogel added on 2018-01-07 09:41:07:

More findings:

- The problem really is different from [3141377fff], it is indeed not a duplicate. [3141377fff] deals with the fact the screen structure is not updated while Tk is running even if the screen characteristics are changed. The present ticket shows that on some configurations (read below), after the screen size has been changed, the screen mm size seen by Tk is zero.

- When running wish before any screen resize, the correct screen mm size is seen by Tk in all runs.

- The bug (zero value) happens only in Fedora (here: version 27) with Gnome, that is only with Wayland. Proof: when at the login page I select a "Gnome on xorg" session, that is with X11 instead of Wayland, there is no such zero value in the screen structure.

- When running on Gnome i.e. with Wayland, wish uses the XWayland X11 compatibility layer. See How to debug Wayland problems about how to confirm this.

- On Linux, the screen size is returned by XkbOpenDisplay(), which is implemented outside of Tk.


fvogel added on 2018-01-02 22:16:47:
In tkUnixEvent.c:163, XkbOpenDisplay() returns with no error ("reason" is 0 i.e. XkbOD_Success) and provides a "display" structure that has:

- DisplayWidth(display,DefaultScreen(display)) = 1280   (for instance)

- DisplayWidthMM(display,DefaultScreen(display)) = 0    (unexpected)

XkbOpenDisplay() is implemented in a library outside of Tk.

bll added on 2018-01-02 20:02:38:
It's a bit unfortunate that WidthMMOfScreen() is used in sixteen different places.  I assume other commands will have an issue.

But still, how often does a screen get resized?
It is certainly more common now that VMs are in use.
I personally use the VMs in windowed mode (as I am using them for testing, 
and often try to run more than one at once), but I assume many 
people always run them full-screen.

The risk factors for this ticket must be judged appropriately so that a priority can be assigned.
- only Linux (what are the % breakdowns for Tk use on different platforms?)
- is it only X11/XWayland?  How many Redhat/Fedora users are there?
- only on resize of a screen, which usually means a VM.  How many people
resize their VMs?

fvogel added on 2018-01-02 07:58:52:
Problem reproduced on Fedora 27.

Will investigate.

bll added on 2017-12-16 15:07:50:
On testing, a display/screen resize of the VM does not change the values in the
X11 Screen structure.

However, upon restarting wish, the zero screen mm width is found.

This ticket is not about the incorrect (same) values reported upon
resize, but about starting wish _after_ a resize and
the use of zero as a divisor when the X11/XWayland
interface reports an zero screen mm size.

An assumption could be made that the X11/XWayland interface is doing this
as the display/screen mm width is now unknown to it.

I am imprecise.  It causes my application to crash.

The user doesn't give a damn that the calculation is correct.
The user is expecting a double value, and except in numerical methods, 
the string "Inf" is not a double.   Unexpected behavior is not good,
and "Inf" is not a reasonable value to return for a scaling value.

The suggested change is not a work-around, but a preventative
measure to keep /improper/bad/reporting of unknown width as zero/
X11 interfaces from causing unexpected 
behavior.  This is a good thing.

fvogel added on 2017-12-16 09:23:48:

Well... I disagree.

I really believe is a duplicate of [3141377fff]. When the screen resolution is changed, which is what you're doing when resizing the screen of your VM, then 'winfo xxxx' outputs get wrong. In both the present ticket and in [3141377fff]. But we can disagree on the fact the present ticket is a duplicate or not, no problem.

You say that when the screen mm width is zero, then Tk is crashing. That fact you didn't show. There is no crash (a crash == a segfault) in your report. Instead, Tk returns 'Inf', which is the correct answer given that the screen mm width is (wrongly) zero. A calculation is made and its correct result in that case really is 'Inf'.

Working around this incorrect output result of 'tk scaling' by checking whether the screen mm width is zero or not is not the right thing to do. The right thing to do is to prevent the 'winfo xxxx' values to become wrong (for instance become zero) upon screen resize or resolution change.

Currently the 'winfo xxxx' values are obtained from the window manager at application startup (see calls in TkpOpenDisplay, for each platform).

Then, on Windows we watch the WM_DISPLAYCHANGE event and call TkWinDisplayChanged to update that structure accordingly.

On macOS we get a displayChanged notification and call TkMacOSXDisplayChanged to update the values.

On Linux I didn't find anything is done when the screen parameters change. That is what needs to be added, as opposed to put a plaster on top of the 'tk scaling' computations.


bll added on 2017-12-16 00:20:01:
- This ticket is not a duplicate of the other.
- When, in fact, the screen mm width is zero, Tk can prevent
  a crash by checking WidthMMOfScreen(screenPtr) == zero and
  defaulting tk scaling to a reasonable value.
- Even though the underlying fault is not within Tk, it is nice
  to not have Tk crash.

fvogel added on 2017-12-15 20:41:14:
In what situation should the screen width be zero? Nothing justifies such a situation.

bll added on 2017-12-15 13:19:39:
Well, not quite.  The screen width values are different.

I think this one is a simple fix.
If the screenwidth is 0, either don't change the current tk scaling, or
set the tk scaling to the default value.

Downgraded to minor.

fvogel added on 2017-12-15 07:10:39:

OK, so this is a duplicate of [3141377fff].


bll added on 2017-12-15 00:36:39:
[bll@fedora25 ~]$ wish
% info patch
8.6.6
% winfo screenmmwidth .
303
% winfo screenwidth .
1144
% tk scaling
1.33.....

Ugh. It is working today.

Ahh, then I resize the screen (this is a VM with the virtualbox screen driver),
and it fails.
% winfo screenmmwidth .
0
% winfo screenwidth .
1040

xdpyinfo shows:

screen #0:
  dimensions:    1040x689 pixels (0x0 millimeters)
  resolution:    -2147483648x-2147483648 dots per inch

So it appears that an X11/display driver issue is the underlying problem.

fvogel added on 2017-12-14 20:23:57:

tk scaling returns what is computed here.

So it looks like WidthMMOfScreen(screenPtr) is zero.

What does winfo screenmmwidth . return for you?


bll added on 2017-12-13 23:17:18:
This is with 'gnome-shell' as the window manager.
I have not tested other window managers on Fedora.