From: Kevin W. <kw...@co...> - 2014-07-25 18:32:28
|
Hi all, I'm writing to report on a couple of significant commits I have made to Tk/Mac on both trunk and core-8-5-branch. The first commit is based on an extensive patch provided by Marc Culler that fixes alpha rendering in images under Tk Cocoa; some changes in 10.9 Mavericks broke rendering of the alpha channel in images, so transparency was no longer displayed (instead just ugly black shapes for shadows, or nothing at all). Marc re-worked several functions to restore this functionality, and I appreciate his work. Thanks so much to him for taking the time to submit, re-work, and then re-submit the patch. The second change involves removing several function calls into private, undocumented Cocoa drawing methods. Some of these changes may be a bit controversial, as they carry a performance penalty in certain contexts, but I believe they are important and I wanted to explain why I have made them. As designed, Tk Cocoa attempts to map an X11 style of window drawing onto the Cocoa graphics/windowing API. We're all aware that this is not a seamless mapping. To improve the drawing performance and make the rendering a bit cleaner, Daniel Steffen borrowed some techniques from WebKit that involve calling into private, undocumented API's to give Tk better, more fine-grained control of drawing in response to X11-style "Expose" events. Apple has always warned against using undocumented API's as they are unsupported and subject to change. However, in 2009, when Daniel was working on the Cocoa port, this seemed a very reasonable optimization to make, as the example of WebKit was already out there, and the relevant private API's had not been changed for several years. Also, Apple did not take any action against accessing private API's beyond discouraging it as unsupported and occasionally changing the API's in question. More recently, however, Apple has taken a harder line on using undocumented API's by making it more difficult to distribute apps that make use of such calls; these apps are not allowed in the Mac App Store, which has become the main way of distributing apps on the Mac platform. For instance, in the case of my own apps, this has prevented me from shipping up-to-date Tk code with my apps, because the app store restrictions forbid it. I have worked around the issue by linking to the version of Tk bundled with the operating system, which on my machine is 8.5.9. (This loophole exists because Apple-installed libraries are exempted from their rules on private API's.) Such workarounds are inherently fragile, however, as they are dependent on Apple continuing to ship Tk with the operating system. If Apple were to stop distributing Tk with OS X, then no app making use of Tk as currently designed would be able to access Apple's main distribution channel. These changes in the Mac platform, combined with my general discomfort with Tk accessing unsupported API's when other open-source languages and frameworks do not, have led me to conclude that these calls need to be removed. And that's what I've done. In some cases, the removal of these calls causes no issue at all. A few of the calls focused on accessing the "resize grip" on the lower corner of a window. Apple removed the "resize grip" from windows in 10.7, so there is no need for private API access here at all. In other cases, there may be a performance hit in drawing especially complex interfaces. I commented out an entire class designed by Daniel that accesses private NSWindow/NSView API's, based on the example of WebKit. My initial fear was that this would prevent drawing from occurring at all, but that's not the case. I've done a fair amount of testing with the widget demo, my own apps, and a couple of third-party apps that link to Tk, and in virtually every context windows and widgets draw as expected and with no noticeable change in rendering. Images display fine, buttons work as expected, and text scrolls without any delay. Redraw of the window in response to resizing also works OK. The one area where I did notice a significant difference was in the widget demo where a text widget is drawn with a large number of embedded widgets, buttons, etc. There is lag in drawing the widgets when the text is scrolled. Unfortunately, I haven't found any way to replace the calls to private API's with equally optimized public API's; I assume that's why the private calls are there in the first place. Because I've only found very limited cases of regression in the drawing performance, I am willing to accept these in the service of removing the calls to private API's. The private API access simply places unacceptable limitations on distributing any app linking to Tk on the Mac, and more generally gives Apple too much control over Tk's functionality; calling private API's is not a good foundation for a GUI toolkit. I've made the commits to core-8-5-branch in time for these changes to make it into the upcoming release of Tcl/Tk 8.5.16, and whenever a new release of 8.6 is made. Let me know if you have questions or concerns. Thanks, Kevin -- Kevin Walzer Code by Kevin/Mobile Code by Kevin http://www.codebykevin.com http://www.wtmobilesoftware.com |