| Ticket UUID: | a9969f7ffd966229c4e6ad9876efc2b3a0cf7274 | |||
| Title: | Usage of private symbol NSWindowDidOrderOnScreenNotification | |||
| Type: | Support | Version: | 8.6 / latest | |
| Submitter: | anonymous | Created on: | 2022-12-10 16:03:55 | |
| Subsystem: | 66. Aqua Window Operations | Assigned To: | marc_culler | |
| Priority: | 5 Medium | Severity: | Important | |
| Status: | Closed | Last Modified: | 2026-08-19 10:26:46 | |
| Resolution: | Fixed | Closed By: | jan.nijtmans | |
| Closed on: | 2026-08-19 10:26:46 | |||
| 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: |
jan.nijtmans added on 2026-08-19 10:26:46:
Now also [0317cc203151f6cb|backported] to Tk 9.0 jan.nijtmans added on 2026-08-19 10:10:10: Fixed [b4ab44b9225b9f7d|here] (for Tk 9.1) ajkessel added on 2026-06-17 00:23:27: Just wanted to ping on this -- as Tk 9.x gets incorporated into mainline Python, it would be great to find a durable fix. With the current state of affairs, no developer can submit a Tk app to the App Store without building their own patched Tk. This is the main way to distribute applications safely to the Apple ecosystem, so it seems to me important that there be a normal way to do it. marc_culler (claiming to be Marc Culler) added on 2026-05-07 23:25:31: What I had in mind was first to build Tk on macOS 26, which would cause the bad notification to be ignored by the compiler because the code would look like: #if MAC_OS_X_VERSION_MIN_REQUIRED <= 150000 [ ... references to notification ...] #endif and the default value of MAC_OS_X_VERSION_MIN would be 260000 if you don't use any -mmacosx-version-min flags. Then copy the Tk library into your python framework so pyinstaller would use your library instead of the one that came with your python installation from python.org. (Or replace the copy of the library in your app bundle.) But let me look a bit more into the possibility of just removing it altogether by adding some code to update the appearance after every call to: [win makeKeyAndOrderFront:NSApp] (There are 5 of those.) You would still need to replace the Tk library in your python framework or your app, of course, since python.org won't update their Tk for a while. ajkessel added on 2026-05-07 11:43:57: As best I can tell, Apple will reject any app built with this notification and PyInstaller. The App Store apparently is still accessible from much older versions of MacOS, but if the developer can’t submit the app in the first place, then keeping this notification for older MacOS targets won’t help. Is there some solution that allows you to keep the notification on older MacOS targets but strip it for submissions to Apple? My experience is mainly Linux-based so I’m a bit out of my depth here! marc_culler (claiming to be Marc Culler) added on 2026-05-07 03:50:29: I was correct. The notificiation was still being used in macOS 15. So the question is whether it would be OK to only disable the notifications for macOS 26 and newer. marc_culler (claiming to be Marc Culler) added on 2026-05-07 03:22:46: Sadly, the NSWindowDidOrderOnScreenNotification was still in use in macOS 11. I now suspect that it was dropped for macOS 26. Nonetheless, perhaps it would make sense to make the notification and the method available whenever the minimum deployment target is older than macOS 26. marc_culler (claiming to be Marc Culler) added on 2026-05-07 03:00:41: I asked Gemini my questions. It said that the App Store requires apps to be built with XCode 26 and that XCode 26 lists macOS 11 as the oldest compatible OS version. I will test whether the notification is used in macOS 11. Possibly we should make both the notification and the method available only when the minimum deployment target is older than 11.0. marc_culler (claiming to be Marc Culler) added on 2026-05-07 02:50:23: I did the same experiment on macOS 10.13 - replacing the body of the method windowDidBecomeVisible with a call to abort(). When I did that, wish immediately crashed. So the NSWindowDidOrderOnScreenNotification was being used in macOS 10.13. Of course, macOS 10.13 did not support dark mode at all. So this is not a reason to use that notification. Next I will try the same on macOS 10.14, which was the first OS version to support dark mode. Question: What is the oldest OS version for which one can submit an app to the app store? @ajkessel: what is the minimum deployment target for your app? I assume it was not older than 10.15 since Python no longer supports any macOS prior to 10.15. marc_culler (claiming to be Marc Culler) added on 2026-05-07 01:26:50: I attempted to find out whether windowBecameVisible (the callback for the WindowDidOrderOnScreenNotification) is actually used. When I added a print statement in that function I was not able to produce my debug output. So I replaced the body of that method with a call to abort() and ran the full test suite with no crash. So I think that means that the notification WindowDidOrderOnScreenNotification is not used in macOS 26. But we support back to 10.13. Surely the notification was used at some point in time, or it would not exist. I will fire up some VMs and see if I can get the appkit to generate that notification. If not, then the simplest thing to do would be to remove all references to it and remove the callback method as well. marc_culler (claiming to be Marc Culler) added on 2026-05-07 00:45:00: That is because the Aqua theme uses semantic colors but the clam them does not. ajkessel added on 2026-05-06 23:04:14: Note that the light/dark setting only impacts the Tk window if I set the ttk style to ajkessel added on 2026-05-06 22:44:25: Sorry, adding a comment with a proper video link. ajkessel added on 2026-05-06 22:43:52: Actually, it turns out that the light/dark setting does take effect immediately on MacOS. This is with my modified build that comments out NSWindowDidOrderOnScreen and it seems to work fine. Setting aside that my "dark" color scheme looks pretty bad aesthetically, I believe this shows removing that setting does not have an impact on the system light/dark behavior. This is a genealogy app, but the data shown in this recording is fake (families from Game of Thrones), so no PII: https://www.youtube.com/watch?v=fGalI2WBu3s marc_culler (claiming to be Marc Culler) added on 2026-05-06 21:09:39: There are three virtual events that get sent when the effective appearance of a window changes because the Settings Appearance changed. The events are sent in the viewDidChangeEffectiveAppearance method of TKView. <<AppearanceChanged>> has a data string that specifies the current appearance, the current accent color and the current highlight color. There are also <<LightAqua>>, sent when the appearance changes to light, and <<DarkAqua>> which is seht when the appearance changes to dark. Note that the names of those events will be different in 9.1. They were changed because Windows has similar events in 9.1, but of course without the "Aqua". They will be <<LightAppearance>> and <<DarkAppearance>> in 9.1. Your app could bind to those virtual events and make the appropriate color changes in the bound script. Some color changes are automatic, however. If you are using a "semantic color" such as systemTextColor or systemTextBackgroundColor then the RGB values of the color change to match the appearance with no action required from your app. My concern is that the ViewDidChangeEffectiveAppearance method may not be automatically called by the AppKit when a window is first ordered on screen or deminiaturized and that may have been the reason for observing the WindowDidBecomeVisible and making the callback call ViewDidChangeEffectiveAppearance. ajkessel added on 2026-05-06 19:15:11: I was not aware of the dark mode issue. My app checks for light/dark mode on startup and sets the theme accordingly (assuming the user has left their preference as "system" theme). So if the system changes from light to dark mode while the app is open, the theme does not change, although the window decorations do change by the OS. The theme is only set on startup. It sounds like there may be a better built-in way with Tk/Tcl to set the theme to automatically sync with the system light/dark mode. If that's the case, I don't have that implemented currently so haven't tested it. marc_culler (claiming to be Marc Culler) added on 2026-05-06 18:04:15: The NSView method which is the callback for the NSWindowDidOrderOnScreen notification calls viewDidChangeEffectiveAppearance. That method has a very important job with respect to supporting dark mode. It sends the virtual events which notify a window that it has changed from light to dark mode of vice versa. So removing the notification has a huge potential for damage. It could conceivably break Tk support for dark mode. Did you test for this? Does your app support dark mode? One basic check would be to start the app in light mode; iconify a window; use Settings to switch to dark mode; and deiconify the window. Does the window open up in light or dark mode? ajkessel added on 2026-05-06 17:41:51: Sorry, correcting link to new branch: NSWindowDidOrderOnScreenNotification-removal-for-app-store ajkessel added on 2026-05-06 17:40:54: I've checked in a new branch based on core-8-6-branch called https://core.tcl-lang.org/tk/timeline?r=NSWindowDidOrderOnScreenNotification-removal-for-app-store. This is my first time using fossil and I made some mistakes with the first couple of check-ins. Hopefully I have left core-8-6-branch back as it was, but I apologize if I didn't revert properly and hopefully someone can put it back. The new branch just moves NSWindowWillOrderOnScreen to only be included if TK_MAC_DEBUG_NOTIFICATIONS is set. ajkessel added on 2026-05-06 12:01:31: Related discussion on cypthon issue 124111. They've built a beta python3.14.5rc1 with tcltk 9.0.3. I tested it and it works fine for my use case. I then applied my patch to comment out NSWindowWillOrderOnScreen (tweaked for 9.0.3) and that also works fine for me. I understand that you'll need to make other changes to actually drop NSWindowWillOrderOnScreen for broader use but just wanted to chime in here to note my fix for anyone trying to submit to the App Store. I will also update my patch script to be more tcltk-version-agnostic. marc_culler (claiming to be Marc Culler) added on 2026-05-05 19:42:44: I think that explains it. That notification name is not deprecated, but it is not public. I am responsible for adding the declaration in commit 5dc77702e1 on 2020-07-18. I don't remember the details, but I suspect that I just guessed there should exist such a notification because NSWindowWillOrderOnScreen exists and usually Apple provides a pre-notification and a post-notification whose names use Will and Did respectively. When it worked as I assumed it would I did not check further. I think the solution is to move the declaration and the call that uses that notification name into the block of code that is only enabled for debugging. Then we will have to find some other place to check whether the Appearance of a window has changed. I don't think that should be hard. Maybe instead of doing it in a TKWindow method it could be done in TkMapWindow, for example. I guess we had better try to get this into 8.6.18 since that will be the last 8.6 release. ajkessel added on 2026-05-05 18:47:08:
I am only going on the rejection I received from the App Store, which is similar to the one reported by anonymous on this ticket. Here is the full rejection:
I don't know if this deprecation is documented anywhere but it seems Apple believes it is deprecated and will not accept submissions with this symbol. marc_culler (claiming to be Marc Culler) added on 2026-05-05 17:57:57: Sorry, I am still catching up. Some other things I should have mentioned: The notification which is only used for debugging is a related, but different one. Namely NSWindowDidOrderOffScreenNotification We really are using the OnScreenNotification. marc_culler (claiming to be Marc Culler) added on 2026-05-05 17:52:30: nm reports the symbol _NSWindowDidOrderOnScreenNotification as "U" in the
Tk library which ships with python 3.14. That library reports patchlevel
8.6.17.
That symbol is not a function. It is an NString name for a notification
which is still being used in 8.6.18rc0 and in the current tips of the
core-9-0-branch and main. We use it like this:
observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
The windowBecameVisible method doesn't do much. It just checks whether
the Appearance has changed for the window. Probably we could do that
check somewhere else and avoid subscribing to that notification. For
example, we could do the check when we actually order a window on screen.
But how do we know that this symbol is deprecated? Is there a deprecation
notice somewhere? I couldn't find one (and neither could Gemini), and the
symbol is still listed in:
/Library/Developer/CommandLineTools/SDKsMacOSX26.2.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit.tbd
kevin_walzer added on 2026-05-05 16:45:51: There’s also an “extern” declaration of the functions which likely shows up in a binary scan of strings. ajkessel added on 2026-05-05 16:16:59: I missed that the observe call is disabled via #if 0. The question then is whether the earlier declaration extern NSString *NSWindowDidOrderOnScreenNotification; is anything that would show up in a binary compiled with pyinstaller. If not, then this more recent code should survive App Store review. Unfortunately, the MacOS universal2 Python build (which is also necessary for pyinstaller/App Store) is still shipping tcl/tk 8.6. That issue is tracked at https://github.com/python/cpython/issues/124111 kevin_walzer added on 2026-05-05 15:57:28: Looks like these functions are there only for debugging and in fact are stubbed out with #if 0. They can probably be deleted. Marc, what do you think? ajkessel added on 2026-05-05 13:56:00: Jan is right -- there are still two references to NSWindowDidOrderOnScreenNotification in https://core.tcl-lang.org/tk/file?name=macosx/tkMacOSXWindowEvent.c . Is there any reason these references need to stay in the source tree? They will continue to prevent developers from being able to submit Python applications to the App Store. As far as I can tell, those two lines in ./macosx/tkMacOSXWindowEvent.c are the only place this deprecated MacOS API is referenced. jan.nijtmans added on 2026-05-05 07:46:47: > Please use Tk 9.0 (or even 9.1 alpha). Unfortunately, NSWindowDidOrderOnScreenNotification is still used in Tk 9.0 as well... If anyone can find a solution, it's Marc. But I'm not sure it's possible yet. oehhar added on 2026-05-05 05:27:52: As nobody of the Mac-OS users answered. Tk8.6 is end of life. Please use Tk 9.0 (or even 9.1 alpha). Take care, Harald ajkessel added on 2026-05-04 12:46:21: This is still a problem in May 2026. I built a script to automate the process: https://github.com/ajkessel/fix-tk-for-appstore Feedback welcome. 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
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 RequirementsYour app uses or references the following non-public or deprecated APIs: Symbols: 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 StepsIt 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:
Resources
============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:
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:
(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.) | |||
Home
Timeline
Branches
Tags
Forum
Tickets
Download
Wiki