Tk Source Code

View Ticket
Login
Ticket UUID: a9969f7ffd966229c4e6ad9876efc2b3a0cf7274
Title: Usage of deprecated NSWindowDidOrderOnScreenNotification
Type: Support Version: 8.6 / latest
Submitter: anonymous Created on: 2022-12-10 16:03:55
Subsystem: 66. Aqua Window Operations Assigned To: nobody
Priority: 5 Medium Severity: Important
Status: Open Last Modified: 2022-12-12 07:17:37
Resolution: None Closed By: nobody
    Closed on:
Description:
According to Apple NSWindowDidOrderOnScreenNotification is deprecated.

It's still used in https://github.com/tcltk/tk/blob/main/macosx/tkMacOSXWindowEvent.c

The effect was that I couldn't publish my application with the latest Python framework which includes TK 8.6 in the Mac App Store.
User Comments: knx0GKN2dpb added on 2022-12-12 07:17:37:
Thank you very much for your extensive comment.

I'll go ahead with your recommendation and I'm glad that the issue will be resolved also for others which try to release an app with Python framework / TK to Mac App Store in the future.

marc_culler (claiming to be Marc Culler) added on 2022-12-12 03:34:02:

That is completely consistent with what I said. The symbol _NSWindowDidOrderOnScreenNotification is non-public (but not deprecated). They didn't bother to mention it, since they are more than happy to reject your app as often as possible, but the symbol _NSWindowWillOrderOnScreenNotification is almost certainly non-public as well. I am suggesting that you do not need either of these notifications, since for many years they were only used in debugging.

If (as Apple suggests) you delete all references to those two symbols (4 lines or so), recompile the Tk library, and replace the libtk8.6.dylib in your Python framework with the library that you just compiled, then you should be fine. (Well, at least you should be able to move on to the next issue.)

We should remove those references from Tk as well, but that will not help you unless you want to wait until the next release of Tk, and the next release of Python after that release of Tk, before resubmitting your app.

Alternatively, and even better, would be if you could convince Apple to make that API public, on the grounds that it is reasonable, and can be important, for an application to get notified when a window is ordered onto the screen. But my experience suggests that the chances that an individual developer would be able to convince Apple to change anything are infinitesimal. So I would not expect or encourage you to bother with that enhancement request.


anonymous added on 2022-12-12 02:58:20:

This is what Apple told me when rejecting my app:

============8<============

Thank you for your efforts to follow our guidelines. There are still some issues that need your attention.

If you have any questions, we are here to help. Reply to this message in App Store Connect and let us know.

Guideline 2.5.1 - Performance - Software Requirements

Your app uses or references the following non-public or deprecated APIs:

Symbols: _NSWindowDidOrderOnScreenNotification

The use of non-public or deprecated APIs is not permitted on the App Store, as they can lead to a poor user experience should these APIs change and are otherwise not supported on Apple platforms.

Next Steps

It would be appropriate to revise your binary and remove any references to the non-public or deprecated APIs identified above.

If you are using third-party libraries, update to the most recent version of those libraries. If you do not have access to the libraries' source, the following command line tools can help you identify the location of problematic code:

  • The "strings" tool can output a list of the methods the library calls.

  • The "otool -ov" tool will output the Objective-C class structures and their defined methods.

Resources

  • We are constantly reevaluating and identifying non-public APIs that you may have been using for an extended period of time. Always use public APIs and frameworks and ensure they are up to date.

  • If there are no alternatives for providing the functionality your app requires, you can use Feedback Assistant to submit an enhancement request.

============8<============


marc_culler (claiming to be Marc Culler) added on 2022-12-11 17:37:38:

That is too bad. It is also unfortunate, if unsurprising, that Apple is not telling you the whole truth here. There is a way out for you - see below. But before I get to that I want to summarize the result of my research on this.

First, this is not a deprecated notification name. My best guess is that it is a notification which Apple uses internally but does not want to make public for some reason. That is a shame because it is very useful for Tk to be able to be notified when a window becomes visible.

Some key points:

  • I could find no documentation anywhere for this notification.

  • The notification has been used in Tk for a very long time. You can find it being used in Apple's own Tk which includes the copyright:

Copyright 2001-2009, Apple Inc.

  • Using that notification does not raise any deprecation warning, so it is not deprecated and there is no indication at all that its use is in any way restricted.

  • The notification works fine. The fact that Apple regrets having told us about its existence back in 2009 does not make using it into a bug.

The tricky point here is that, prior to 2020 when I realized that it would be useful if Tk could get a notification when a window becomes visible, that notification (and its cousin NSWindowWillOrderOnScreenNotification) were only used when TK_MAC_DEBUG_NOTIFICATIONS is defined. So they would not appear in production code. Again, Apple did not bother to even add a comment indicating that there was anything special about them (other than the obscure but discoverable fact that they need to be declared in the C file, as they do not appear in any header file.)

So what can you do about this? I am assuming that you are using py2app or PyInstaller to build your app. That means that parts of the Python framework which you have installed on your build system are being copied into the app bundle. Included among these parts is a copy of the Tk library which was compiled by macpython and embedded in the Python framework. As I have tested many times, there is no problem with simply replacing that embedded Tk library with a new one which you have recently compiled. (You do need to use Tk 8.6, however, not Tk 8.7.) So you can clone the current tip of Tk 8.6 from the fossil repository; comment out the two lines which register those two notifications (and their declarations); then copy the newly built Tk library into your Python Framework, and rebuild your app.

Something like this:

cd tk
fossil open ../Tk.fossil core-8-6-branch
nano tkMacOSXWindowEvent.c
export CFLAGS="-arch x86_64 -arch arm64 -mmacosx-version-min=10.9"
make -C macosx
cp ../build/tk/Tk.framework/Versions/8.6/Tk /tmp
cd /Library/Frameworks/Python.framework/Versions/3.10/lib
sudo mv libtk8.6.dylib libtk8.6.dylib.orig
sudo mv /tmp/Tk libtk8.6.dylib

(I am suggesting this approach because a fix to Tk will not propogate into the Python distribution until the next release of Tk. But it is easy to build your own Tk.)