Ticket UUID: | c95d4691ff8723b47c820081ce50688cf04911f7 | |||
Title: | winfo screenheight w/dual monitors returns the screen height of the primary display | |||
Type: | Bug | Version: | 8.6.3 | |
Submitter: | anonymous | Created on: | 2015-01-11 00:36:05 | |
Subsystem: | 68. Win Window Operations | Assigned To: | nobody | |
Priority: | 5 Medium | Severity: | Minor | |
Status: | Open | Last Modified: | 2016-08-22 13:54:08 | |
Resolution: | Wont Fix | Closed By: | nobody | |
Closed on: | ||||
Description: |
On windows, if a window is placed in the second monitor's display area, and [winfo screenheight .win2] is called, the screenheight returned is the first monitor's height, not the second monitor's. Likewise for screenwidth. | |||
User Comments: |
oehhar added on 2016-08-22 13:54:08:
For me, the current behavior is correct and I recomment to change the ticket state to "wont fix". The ticket is for windows only. On windows with multiple monitors, you get a big virtual screen over all monitors, which may be checked by the winfo v* commands. The current physical screen is lalways the primary monitor. One may use "wm geometry" to check the screen one is on. There are ambiguities and room for enhancement, but this will break any compatibility. This would be an RFE requiring a TIP. - Harald fvogel added on 2016-08-15 10:20:41: Discussion run in May/June 2016 on the Tcl Core List. Stalled since June 06, 2016 where it was said that some stuff Tk feature should be dropped. This needs a TIP I can't write because I have no clear idea of what needs to be done/dropped. See last email of the thread. Giving up. fvogel added on 2016-07-30 18:48:24: The issue this bug is dealing with was brought again on comp.lang.tcl. fvogel added on 2016-05-31 18:54:55: Interesting observation in [4face822b0]. fvogel added on 2016-05-25 19:27:11: For me: francois@TM:~$ xrandr --output eDP-1 --mode 1920x1080 --fb 3000x2000 --panning 2500x1500 francois@TM:~$ /home/francois/Documents/tcltk/fossil/tcltk/bin/wish8.6 % winfo screenwidth . 3000 % winfo screenheight . 2000 % winfo vrootwidth . 3000 % winfo vrootheight . 2000 So yes, the arguments from --fb are returned in both [winfo screenxxx ] and [winfo vrootxxx ] in this single panning screen case. I *think* this is correct (extract from the Ubuntu documentation: https://wiki.ubuntu.com/X/Config/Resolution ): "If you want to have a panning viewport, i.e., a virtual screen that's bigger than your physical screen that moves when you move the mouse to the edge ("zoomed in" view) specify the desired physical resolution with --mode and the virtual screen size with --fb and panning area (typically same as virtual screen size) with --panning." Anyway, if the above would be considered as a bug it should be the object of a distinct ticket I think. anonymous (claiming to be [email protected]) added on 2016-05-24 00:15:40: Sorry, all the ticket e-mails go to spam in a different e-mail account, and I have to remember to check. On Linux, I was not testing the usual case of two monitors -- that's probably correct -- it's just a bigger screen. If you do (with changes for your setup): xrandr --output LVDS-0 --mode 1366x768 --fb 5464x3072 --panning 5464x3072 it creates a big virtual screen with a 1366x768 viewport (size of my laptop screen). This is a single monitor setup, _not_ two monitors. This used to be much more common -- hardly anyone uses it anymore. So the question is, in this situation, would you want the screen height/width to return 5464x3072 (the size of the entire virtual screen), or 1366x768 (the size of the viewport). I probably do not understand the original intention of the difference between a virtual root window vs. a screen. I could see vroot w/h as 5464x3072 and screen w/h as 1366x768. But returning the size of the entire virtual screen is probably also valid. fvogel added on 2016-05-22 15:41:01: BTW, this is the output of xrandr showing my display configuration on Debian 8: Screen 0: minimum 320 x 200, current 3200 x 1080, maximum 8192 x 8192 eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 194mm 1920x1080 59.99*+ 59.96 40.03 1680x1050 59.95 1400x1050 59.98 1280x1024 59.89 1280x960 59.94 1152x864 59.96 1024x768 59.92 800x600 59.86 640x480 59.38 720x400 59.55 640x400 59.95 640x350 59.77 VGA-1 connected 1280x1024+1920+0 (normal left inverted right x axis y axis) 338mm x 270mm 1280x1024 60.02*+ 75.02 1280x960 60.00 1280x800 74.93 59.81 1152x864 75.00 1280x768 74.89 59.87 1024x768 75.08 70.07 60.00 1024x576 59.97 832x624 74.55 800x600 72.19 75.00 60.32 56.25 848x480 60.00 640x480 75.00 72.81 66.67 60.00 720x400 70.08 DP-1 disconnected (normal left inverted right x axis y axis) DP-2 disconnected (normal left inverted right x axis y axis) Now looking at if it's possible to create TWO screens, one on each output reported as conncected by xrandr fvogel added on 2016-05-22 15:36:49: Another way to check the display configuration on Linux is to issue: xdpyinfo Among other info, this reports the number of screens of the display. Here is an extract of my output (Debian 8, primary physical monitor is the laptop one featuring 1920x180 pixels, secondary physical monitor is a VGA screen featuring 1280x1024 pixels) : <snip> default screen number: 0 number of screens: 1 screen #0: dimensions: 3200x1080 pixels (847x285 millimeters) <snip> So in my current configuration there really is a single screen made of two monitors ==> no bug on Linux fvogel added on 2016-05-22 14:43:40: Brad, about your comment below dated 2016-04-23 16:51:07: I don't see this as wrong. With xrandr you set one *single* big screen, not two. The two monitors make up a single screen as far as the X server is concerned. On Linux I have made a bit of research in the code, and it's quite simple: XOpenDisplay() does the entire job, checks for different screens presence and so on. You can check how many screens it finds by applying the following little patch: Index: generic/tkWindow.c ================================================================== --- generic/tkWindow.c +++ generic/tkWindow.c @@ -530,10 +530,11 @@ if ((strncmp(dispPtr->name, screenName, length) == 0) && (dispPtr->name[length] == '\0')) { break; } } +printf("ScreenCount(dispPtr->display): %d\n", ScreenCount(dispPtr->display)); if (screenId >= ScreenCount(dispPtr->display)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad screen number \"%d\"", screenId)); Tcl_SetErrorCode(interp, "TK", "DISPLAY", "SCREEN_NUMBER", NULL); return NULL; I have now built a real (i.e. not in a VM) Linux Debian 8 configuration with two monitors just to investigate the present ticket, and like you I only have one screen reported by X. I think that configuring X differently, so that instead of one big screen it sees two separate screens should be possible (how? tune xorg.conf?) Then in Tk the behaviour should be already OK with no change in the Tk code. I do not think Tk has a bug (in the Linux implementation). fvogel added on 2016-04-24 20:28:35: Committed [671c976f] in branch "multiscreens": - Tk now knows about all screens (monitors), not only about the primary one - screenheight and screenwidth, and all values that depend on them, are now correct for each monitor as long as the windows are created with explicit -screen parameter - resolution changes are now tracked correctly by Tk for each monitor With this commit the following script is now working as expected: package require Tk winfo screenheight . ; # info from primary monitor winfo screen . ; # :0.0 toplevel .t -screen :0.1 winfo screen .t ; # :0.1 (NEW!) winfo screenheight .t ; # info from secondary monitor (NEW!) <change secondary monitor resolution> winfo screenheight .t ; # updated info from secondary monitor (NEW!) <TODO>: - Find a way to test all this without false alarms (when there is a single monitor attached) - When moving a window from one screen to another, should its screen info "follow"? - Fix this problem on Linux and MacOSX as well. fvogel added on 2016-04-24 15:06:37: Again with line breaks where they belong in the code extract: package require Tk winfo screenheight . ; # info from primary monitor <move the "." window to the second monitor> winfo screenheight . ; # info from second monitor <change second monitor resolution> winfo screenheight . ; # updated info from second monitor winfo screen . toplevel .t -screen :0.1 winfo screen .t winfo screenheight .t fvogel added on 2016-04-24 15:05:17: Second thoughts on my side regarding how to fix the issue reported in the ticket. The root problem raised by the present ticket is much more general than just a wrong returned value from [winfo]. My fix [38168e2176] is not really correct/complete. It makes Tk request the width and height of the correct monitor so that the returned values for [winfo screenwidth/screenheight ...] is the right one. But the problem is that is does not update the screens sizes cached internally in Tk in the Tk_Display structure. As a consequence, all what is based on these sizes in Tk is still broken. I have started thinking afresh regarding this ticket and am currently working on a different approach: Tk already has (more or less) support for multiple screens, but the number of such screens is set once and for all to 1 when opening the display. The idea is then to make Tk fully support several screens (aka monitors) by allowing display->nscreens to be larger than 1, and add the required for loops on screens whenever needed. This could sound hard but in fact it is not so difficult. Then the screen identifier attached to any window needs to be updated whenever this window changes screen. Also feasible. And screen characteristics shall be updated whenever the monitor resolution, colors... changes. Fine. The net result is that we will then get correct results for incantations like: package require Tk winfo screenheight . ; # info from primary monitor <move the "." window to the second monitor> winfo screenheight . ; # info from second monitor <change second monitor resolution> winfo screenheight . ; # updated info from second monitor winfo screen . toplevel .t -screen :0.1 winfo screen .t winfo screenheight .t Addressing this ticket this way will fix the general issue, which is that Tk is just not aware of multiple monitors. Then, all the other places where a potentially wrong monitor size is used in Tk (see one of my previous posts in the present ticket) will be automatically fixed because the correct size of each monitor will now be cached in the (several, no longer just one) screens element of Tk_Display. All the above I'm working on considers Win for the moment. I didn't look at other platforms implementation so far. anonymous (claiming to be [email protected]) added on 2016-04-23 17:06:42: Windows with the primary as a smaller screen: F:\>tclsh z.tcl vrootwidth:1824 monitor 1 vrootheight:778 screenwidth:800 screenheight:600 vrootwidth:1824 monitor 2 vrootheight:778 screenwidth:800 screenheight:600 anonymous (claiming to be [email protected]) added on 2016-04-23 16:51:07: Ok, Linux is definitely broken. Single monitor, big virtual screen. bll-tecra:bll$ xrandr --output LVDS-0 --mode 1366x768 --fb 5464x3072 --panning 5464x3072 bll-tecra:bll$ cd bll-tecra:bll$ tclsh $HOME/vbox*/z.tcl vrootwidth:5464 vrootheight:3072 screenwidth:5464 screenheight:3072 screen width and height should be 1366x768! The output does not match the documentation. anonymous (claiming to be [email protected]) added on 2016-04-23 16:29:59: Sorry, I just ran the windows test with whatever sizes from the VM. Here it is with normal monitor sizes, 1024x768 and 800x600. I am not using any code from the fossil repo. F:\>tclsh z.tcl First monitor vrootwidth:1824 vrootheight:768 screenwidth:1024 screenheight:768 vrootwidth:1824 Moved the window to the second monitor vrootheight:768 screenwidth:1024 screenheight:768 Linux acts just like FreeBSD as I expected. I am just worried about breaking something. Otherwise I completely agree with you -- I would like to have "screen" imply the current monitor. fvogel added on 2016-04-23 12:41:33: Many thanks for your feedback! FreeBSD and Linux: Your test on FreeBSD is clear to me. FreeBSD also has the same issue as Windows regarding screenwidth/height. Linux is probably not different but if you can check that would be appreciated, thanks. OK, I will (maybe) look at this for Linux later. Windows: Regarding Windows, I don't understand your results. Was your check with the same monitors as for FreeBSD? You do not give the resolution of each monitor, and their relative arrangement in space. Besides, I hope your test didn't run from the bug fix branch "bug-c95d4691ff"? Because (I believe) I have fixed screenwidth/height for Windows in that branch and you should get the correct screenwidth/height depending on what monitor the window you pass is displayed. Or does my fix not work for you perhaps? Finally, about "wonder if "fixing" windows would break everybody's code": I don't think so. It's the opposite: people's code is broken now and fixing [winfo screenwidth/height ...] would fix their code. In my opinion, [winfo screenwidth/height ...] should return the size of the monitor on which the given window is displayed (there exist fallbacks in the API to deal with the case when the window is partially displayed on several monitors). Note that I'm not discussing the introduction of new commands to get the monitors resolution, because that is precisely the job of the existing [winfo screenwidth/height ...], which get it wrong except when considering the primary monitor. Currently it appears that people use [winfo screenwidth/height ...] to get numbers that are correct when they mean the primary monitor, or probably wrong when using another monitor. In the latter case, it only matters when the second monitor has different resolution than the primary one. This is not always the case. And when it has different resolution, it is usually not *very* different because people get monitors more or less at the pace of technology changes. Nobody I think has a virtual screen composed of a 1920x1080 full HD monitor and aside of it a 640x480 VGA oldie. Therefore people's applications using [winfo screenwidth/height ...] currently just work based on: - chance: all monitors have the same resolution - approximation: wrong results are only slightly wrong anonymous (claiming to be [email protected]) added on 2016-04-23 01:30:10: With a 1024x768 and a 800x600 monitor (FreeBSD 10.1 in a VM, mate desktop): freebsd101:bll$ ./z.tcl # same on both monitors vrootwidth:1824 vrootheight:768 screenwidth:1824 screenheight:768 vroot/screen both indicate the full size of the "screen", not the current monitor. And with the mixed sizes, the 768 is correct. It would probably be nice if there was an additional function to get the size of the current monitor, but there are workarounds for that. Windows, both monitor 1 and monitor 2: F:\>tclsh z.tcl vrootwidth:2001 vrootheight:675 screenwidth:1086 screenheight:665 I wonder if "fixing" windows would break everybody's code. Though it is not nice that windows and other OSs act differently. If you want, I can verify Linux at a later time when I have access to my other VMs or other monitor. fvogel added on 2016-04-22 22:17:59: I think there are further places where the size of a potentially wrong monitor is used in Tk: Full screen on Windows, see bug [4face822b0b3d0cb8383c5cf46ff2099715846fa] Full screen on MacOSX (perhaps?) and so on... Basically, everywhere WidthOfScreen() and HeightOfScreen() are used. Regarding WidthMMOfScreen() and HeightMMOfScreen() I'm wondering. Fixing all this needs careful analysis because, on Windows at least there seems to be a single *display* featuring a single *screen*, but this screen may be shown on several *monitors*. fvogel added on 2016-04-21 16:37:08: Fix proposed here: [38168e2176] (changes for Windows only since the present ticket was opened for Win). Review requested please, regarding code organization in the different modules. For instance, is the MODULE_SCOPE trick best for platform-specific Tkp... functions? And a question: do we have the same problem for Linux and/or for OSX? I cannot check this myself, for both platforms. fvogel added on 2016-04-20 20:14:54: On Windows, [winfo screenwidth/screenheight ...] receive values in TkWinDisplayChanged(). These values are obtained through GetDeviceCaps. MSDN documents it: "On a multiple monitor system, if hdc is the desktop, GetDeviceCaps returns the capabilities of the primary monitor. If you want info for other monitors, you must use the multi-monitor APIs or CreateDC to get a HDC for the device context (DC) of a specific monitor." oehhar added on 2015-02-25 16:53:40: I can confirm that the screenwidth/height are always those of the primary screen. With WIn 8.1 64bit, TCL8.6.3 on: Laptop screen: 1280x720 Attached LCD: 1920x1080 I get: Virtual Screen: 3840x1080 and as screenwidth/height the size of the first screen defined in windows. This is independent on the physical window position. anonymous (claiming to be [email protected]) added on 2015-01-11 04:26:19: #!/usr/bin/tclsh package require Tk variable vars variable d set d { vrw vrootwidth vrh vrootheight vrx vrootx vry vrooty sw screenwidth sh screenheight } proc getstuff { } { variable vars variable d dict for {k v} $d { set dv [winfo $v .] set vars($k) $dv } } dict for {k v} $d { set vars($k) {} ttk::label .l$k -text $v ttk::label .$k -textvariable vars($k) grid .l$k .$k grid configure .l$k -sticky e grid configure .$k -sticky e } ttk::button .b -text {Click Me!} -command getstuff grid .b -columnspan 2 -sticky e |