Tk Source Code

View Ticket
Login
Ticket UUID: d83153578e985b5d9f3bdc279d3d65774c85761
Title: MacOS fullscreen pointer coordinates do not match content
Type: Bug Version: 8.6.4
Submitter: jal_frezie Created on: 2016-07-06 10:05:36
Subsystem: 66. Aqua Window Operations Assigned To: kevin_walzer
Priority: 5 Medium Severity: Severe
Status: Closed Last Modified: 2018-08-12 15:02:19
Resolution: Fixed Closed By: kevin_walzer
    Closed on: 2018-08-12 15:02:19
Description:
MacOS ElCapitan has this great new fullscreen mode that when you maximize a window, it becomes a new workspace all its own, with the menubar hidden untill you hover at the top of the screen. Unfortunately when a TclTk window goes into this mode, the mouse coordinates are reported as being about 20 pixels above where they actually are, so to click on something you actually have to click a little below it. Impossible to work around by checking the OS version and window status, because it also applies to buttons and things where the programmer has no access to the coordinates. There is a black space below the window, so probably everything is being drawn too high, however the reported pointer y coordinate is negative near the top of the screen. Weirdly, the horizontal scrollbar if present does not seem affected. If you click in the black space just below the scroll bar you get a screen click just above it, but if you click right at the bottom at a point you would expect to map onto the scroll bar, nothing happens, and if you click on the scroll bar you get a scrollbar action and a screen click above it. Tested on TclTk 8.5.9 and 8.6.4.
User Comments: kevin_walzer added on 2018-08-12 15:02:19:
Fix committed to trunk and core-8-6-branch with new fullscreen implementation.

kevin_walzer added on 2018-08-05 15:25:05:
Jasper, you may be able to avoid the fullscreen switch altogether by setting a minimum window size.  Check Appleā€™s 10.13 documentation on lmplicit fullscreen.

kevin_walzer added on 2018-08-05 15:05:15:
Jasper, what you are asking for here is a compile-time option, not a runtime option.  By specifying a minimum OS at compile time, that means only APIs that run on that OS are built and my fix is stripped out.  There is no way around that limitation.

jal_frezie added on 2018-08-05 14:29:49:
That's what I found with Tk 8.6.8 -- that enabling support for older versions put back the original bug on all versions. Can you not check the version at runtime, so the same executable will work right on 10.13, and at least work on earlier MacOS?

kevin_walzer added on 2018-08-04 11:29:54:
Jasper, the new code is all wrapped in ifdef's to check for 10.13 or later, and runs in the default fashion otherwise.  I tried building with CFLAGS set to "-mmacosx-version-min=10.10", and the code builds and runs as expected--that is, with the buggy behavior still present. If supporting the older OS is a priority for you, then this will run at least on 10.10. Please test to confirm.

jal_frezie added on 2018-08-04 08:14:33:
I found with the previous 'hackish' fix that it would not apply if Tk was compiled with support for earlier MacOS versions than 10.13. While wishing to thank Kevin very much for his efforts to get support for the native fullscreen mode into the code, I would like to be able to build a TclTk that will at least run on a couple of versions prior to the current one even if the native behaviour with correct mapping of coordinates is only available on 10.13 or later.

kevin_walzer added on 2018-08-04 02:27:36:
Correction: this API is for 10.13 and later.

kevin_walzer added on 2018-08-04 02:15:09:
I have checked in a new branch, mac-fullscreen-test, that aims to replace the current hackish mapping of the fullscreen API to a zoomed state with an actual fullscreen implementation. It is still not perfectly native; internally it maps the native fullscreen API to Tk's own [wm attributes -fullscreen API]. What had eluded me before in looking at this was a way to restore the window to its previous, non-fullscreen state, and I've been able to accomplish this by using an NSStatusItem (one of the little icons that appears opposite the menubar at the top of the screen). I use a native system icon, and it loads when the window is in fullscreen state; clicking on the icon restores the original state and also removes the icon from the menubar. It is not a purely native implementation, but it is clean, preserves screen geometry so that the mouse pointer hits the right spot, and requires no effort from the developer or user--it "just works," as the purely native implementation does. This is designed to work on macOS 10.12 and later because that's when the behavior of the fullscreen API changed on the Mac to be "implicit" -- nearly every window can now assume the fullscreen state. I've love some feedback on this, and will commit this to core-8-6-branch and trunk if no major issues are revealed; I will then close this ticket.

kevin_walzer added on 2018-07-31 01:21:42:
Overriding the toggleFullScreen call is a bit hackish, but it's the only way to ensure behavior that does not completely disrupt user expectations. By setting the window to the zoomed or maximized state, it is enlarged, and Tk retains track of screen geography--the pointer lands in the correct place. I have not found a way to accommodate the fullscreen Mac API and also preserve correct mapping of clicks with the mouse--that behavior is seriously broken with the fullscreen API in Tk, as the screen demo you referenced shows. I welcome a working implementation, but the many, many hours I have spent on this have not yielded one beyond what I committed last year.

chrstphrchvz added on 2018-07-30 22:42:08:

Regarding the approach currently used to prevent fullscreen: it works, but it seems hackish to override the functionality of toggleFullScreen, rather than explicitly inform macOS to simply not allow fullscreen for the window. It also leads to visually inconsistent UI where the green title bar button displays (corner triangles, indicating fullscreen) rather than + (plus, indicating zoom/maximize).

I currently know close to nothing about macOS API, but it looks like something that might be closer to a canonical workaround involves setting NSWindowCollectionBehaviorFullScreenAuxiliary. (Or does that not work?)


chrstphrchvz added on 2018-07-30 20:11:25:

I believe the assignee's commit 31aeb5562201822d422a9ddc86c9618ed4b3a58f (which appeared in 8.6.8) fixes this issue by prevents entering native fullscreen on macOS. I have tested programs on Tcl/Tk 8.6.8 and the green title bar button only causes the window to maximize.

A user of the Tcl::pTk Perl module rediscovered this issue, and provided a screen recording of it:cf. https://rt.cpan.org/Ticket/Display.html?id=125939

Also, as a user-workaround for affected Tk versions, holding Option when clicking the green title bar button will maximize the window rather than enter fullscreen mode.


jal_frezie added on 2016-07-06 11:50:08:
That does indeed fix the problem, and I could probably look out for a resize event then check the new window size against the screen size in order to apply it automatically. It needs to be done again after the window returns to non-fullscreen mode. The oddities with the horizontal scrollbar seem to happen in TclTk 8.5.9 and not 8.6.4. Will post more as I find it out.

kevin_walzer added on 2016-07-06 10:49:10:
The Mac fullscreen API you are referring to is not supported as part of Tk's core, but I can reproduce the issue you are reporting if I set the "fullscreen" attribute of the root window to true via "wm attributes . -fullscreen 1". (Despite the names, Tk's fullscreen API is not related to the Mac API you are evidently referring to.) The coordinates can be correctly set if you first withdraw the main window, set the fullscreen bit, then display it. The code to do so is as follows:

wm withdraw . ; wm attributes . -fullscreen 1; wm deiconify .

Then the coordinates are correct. Please give this a try and confirm. 

I have tried in the past to integrate the Mac fullscreen API (where the window becomes fullscreen and its own workspace if you click on the green window button) with Tk's, but not successfully. Tk cannot track its own state via the Mac API and gets confused about its geometry. I have put together an extension package that provides some level of integration, but have never proposed it for inclusion in the core; that is outside the scope of this bug report.