Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2005-105
$eventId
ID of event: wwdc2005
$eventContentId
ID of session without event part: 105
$eventShortId
Shortened ID of event: wwdc05
$year
Year of session: 2005
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC05 • Session 105

The Tiger HIToolbox

Application Technologies • 1:05:44

Learn about the latest improvements in the HIToolbox framework in Mac OS X Tiger. This session will demonstrate the most recent features including HIArchive, performance advances with deferred updates, HIShape support, new features in HITextView, and more.

Speakers: Eric Schlegel, Bryan Prusha

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Okay, good afternoon. Welcome to session 105, the Tiger HIToolbox. My name's Eric Schlegel. I'm an engineer in the HIToolbox group at Apple. And I'm going to be talking to you today about what's new in the HIToolbox, HI services, and navigation services frameworks. I'm going to emphasize mostly what's new since last year at the developers conference since we did talk about those and what was new in Tiger and those frameworks a bit last year as well.

So to start out with, I'd like to cover some of the things we've been doing since last year. It's been a pretty busy year for the HIToolbox group. We've had a number of deliverables in 2005, starting with Evan Prusha, son of our engineer Brian Prusha, followed by Ewan McLeod, son of our engineer David McLeod. We also have a Fullerton to be named later, son of our engineer Guy Fullerton, coming out soon.

And finally, we have a Rothart to be named later, son of our engineer Kurt Rothart, also coming out soon. So you can see of the six people in this group, four of them are new parents in recent months. And that explains why I'm the one up here on this stage giving you this presentation today. They're all busy taking care of their kids. So we did do one other thing. We shipped Tiger. So that's what I'm going to talk to you about today.

Here's what I'm going to cover today. I'll start with a review from last year, some of the things that we talked about at last year's developers conference that were new in the toolbox already at that point. I'll cover in much more depth what's new this year and the things that we've done since last year. Then Brian Prusa will come up and tell you about the HI archive API, which is a way to save out HI objects of various forms as well as other core foundation data types to memory or to disk.

And also give you a little bit of information about what's new in navigation services. Then I'll be talking a bit about compatibility tips, ways to make your applications run well on Tiger. And then some other changes in Tiger, changes in other parts of the operating system that can still affect your Carbon application. And then finally we'll have some Q&A.

Okay, so what is HIToolbox? At the most literal level, it's a framework. It lives in system library frameworks. But it's not really an application framework, like PowerPlant or AppKit or Mac app or Mac Zoop or many of these others. It's more of a user interface tool kit. It's something you use to build your user interface, but it doesn't have a document architecture or an undo model or things like that. So as we think about what to do with toolbox in the future and where we want to go with it.

We tend to think about who are some of the typical clients for the application toolbox. One of the big clients for the toolbox are developers doing cross-platform development, people writing applications that run both on Mac OS and on Windows, maybe on versions of UNIX or Linux. And these developers have told us commonly that having a procedural API on Mac OS X is a good thing because it gives a good corresponding API for things that they've used on other platforms as well.

Another set of important clients for HIToolbox and the Carbon API are developers using a proprietary or third-party application framework. Often these developers have millions of lines of code that they've already written to their custom framework, and it's very difficult or impossible for them to move to some Apple-provided framework or other third-party frameworks.

Another set of clients are those of you who are still doing development for classic Mac OS. This is getting smaller every year, I know, but there are still a number of people who are doing development that needs to run on classic Mac OS for the education market and for other markets where there's still an installed base of these machines.

and having the ability to write an application that works both on the CarbonLib shared library on classic Mac OS and on the Carbon frameworks on Mac OS X is really valuable to these developers. Another set of clients are those of you who are using a code base that may be incompatible or difficult to use with Objective-C. We have lots of developers still who are using languages such as Lisp, Pascal, Fortran, Modula 2 or Real Basic, languages where it's a little awkward to call into Objective-C but somewhat easier to call into a procedural API such as Carbon.

And finally, but I hope not least, I hope a lot of you use Carbon because you just like it. We've tried hard to build an API that's easy to use and that's enjoyable and that can help you get your job done, and I hope you agree. So we try to keep all of these developer clients in mind as we think about where the toolbox should go in the future.

As we planned the work for Tiger, we thought about some overarching themes to give us some guidelines about what kind of work we wanted to do. And to give you sort of a mental framework for what I'm going to be talking about, I want to cover some of those themes with you so you have an idea of where I'm coming from.

One of the big themes for Tiger in the Toolbox group was to continue the transition to compositing mode. Hopefully you all know by now that compositing mode is a new way of drawing your window content, which we introduced in Mac OS 10.2. And in this mode, all of your window content is drawn as part of a custom control or custom HI view.

[Transcript missing]

Another theme for Tiger was support for voiceover. That's our technology for doing spoken user interfaces. We have sort of two tracks for voiceover. The first track is supporting the accessibility APIs in the toolbox itself and in our standard controls. So we've tried very hard to make sure that all the standard controls, all the standard widgets and user interface provided by HIToolbox is accessible in Tiger. And the other track is providing APIs and Carbon events so that your application can become accessible itself and make your own content accessible.

Fourth theme for Tiger was support for Spotlight. We don't really have any APIs or Carbon events to support Spotlight, but we do have user interface changes so that you can do Spotlight searches directly from within navigation services open and save dialogs. Another theme was to improve Carbon-COCO integration. We know that a lot of you are trying to use Cocoa technologies in your application, and we think that's great.

We want you to continue doing that. We see the future of Mac OS X application development as really being one where applications aren't really Carbon applications or Cocoa applications, they're just Mac OS X applications, and they use whatever API is applicable or suitable for their particular task at hand. So our goal is to make it much easier for you to use Cocoa technologies in a Carbon application and indeed vice versa as well, so that you can choose the right API for the problem you have.

And finally, we want to always continue to solve common developer problems. Those things that you run into every time you build a Mac OS X application using Carbon, the things that are annoying every time you do it. We just want to solve those, get it out of the way, so that you never have to deal with it again.

So a quick review of what we talked about at last year's developers conference for the HIToolbox. We covered resolution independence. As I said, there are three modes, framework scaled mode, app scaled mode, and the default magnified mode. We covered some expanded HIView APIs. We're trying to increase the set of HIView APIs available in HIView.h and make sure that for each API that is in controls.h that still makes sense that you want to have an HIView equivalent of that.

So that instead of having to go back and forth between controls.h and HIView.h and figure out which API set applies in this particular instance, you just have one consistent HIView set that's easy to learn, that makes sense in all cases, makes it easier to document, easier to apply in your applications.

Along with this, we also talked about introducing some APIs to do mouse tracking regions at the HIView level rather than at the window level. A mouse moves into and out of the tracking region are sent directly to the view rather than to the window. And second, if you need to move a view inside your window, say you're scrolling or you're just repositioning a view back and forth, by using the new HIView tracking area APIs in Tiger, the tracking area moves along with the view rather than you having to move it explicitly yourself.

We also talked about some HIShape support. HIShape is a new data type, floating point data type, that replaces the QuickDraw region handle. And we're adopting that across the HIViewManager so that we can use HIShapes to specify control regions, structure regions, content regions, things like that. And finally, a request that we've heard a lot from developers over the last few years is the ability to easily be notified before and after changes to an editing field, and edit text control, let's say.

and we talked about last year that we were introducing some Carbon events that would be sent in these two cases before and after. Those weren't completely functional in last year's release of Tiger, the developer preview release. But the good news is that in Tiger GM, those text change notification events are sent regardless of whatever change is being made to an edit field. They're always being sent. The only exception would be if you explicitly set the text of an edit field with set control data.

But they aren't set in that case because we figure you know what you're doing then. So those text change notifications are fully functional now and I think that will help make your life a lot easier in a lot of different cases. Okay, so now I'm going to go right into what's new from last year. And I'll just go manager by manager and give you some details, some highlights of the things that we think you will want to know about for your Carbon application when you're running on Tiger.

The appearance manager. The thing we're trying to do with the appearance manager is to make sure that the application is running on Tiger. And the purpose of the appearance manager really is to make it easy to use the appearance manager to draw with core graphics and to use core graphics drawing in conjunction with appearance manager drawing. So to that end, we have some new APIs here.

HIThemeSetStrokeColor, HIThemeSetFillColor, and HIThemeSetTextFillColor which take a theme brush or theme text color and put the corresponding color or pattern into a CG context so that you can draw into the context using that theme brush or theme text color. Previously, there wasn't any way to do that. You couldn't do this at all, basically. And if you needed to draw with a theme brush or a theme text color, you pretty much had to fall back to Quick Draw.

Another API we have here is HITHeamBrushCreatCGColor, and that takes a theme brush and gives you back a CGColorRef. The CGColorRef is a core graphics data type that can then be passed around your application. It can be applied to multiple different contexts, and that gives you better performance than using just HITHemeSetFillColor each time, for example, because the CGColorRef encapsulates a lot of the data and avoids some of the performance hit of actually applying and converting a theme brush into the context every time. We also have some appearance manager APIs to draw some of the new controls. We now allow you to draw Panther-style tab controls using the Appearance Manager, for example. That wasn't previously possible. And we have HITHeamDrawSegment to allow drawing a segmented view. Oh dear.

Please ignore the video errors. That's going to be a little difficult though, isn't it? All right, well, I'm going to keep talking. Also, HITHeamDrawTextBox now has some implementation changes so that it can work outside of a 16-bit coordinate range. So if you have a window with a great deal of content, maybe you have a large number of files or a large number of fonts that are being scrolled up and down, HITHeamDrawTextBox can now be used to draw that no matter where you are in that scrolling range.

Well, I can see the slides here, but you can't. So hopefully my explanations will be clear enough. Carbon Event Manager is the next slide I'm on. And first I'd like to point out a new Carbon Event, KEventWindowGetClick modality. And this is an event probably most of your applications won't use, but it's used when you need to customize the behavior of a click -- yay, all right -- of a click in a window behind a modal dialog.

Normally the toolbox will just block that click and emit a sys beep. But in some cases, applications may need to actually customize that behavior. So you can now use this event to actually intercept the click or let it be passed through to the clicked window. We also support a keyboard focus hotkey for putting focus on a drawer window that's attached to the active window. And your application doesn't have to do anything to support that. It's all automatic. It just happens.

Finally, a change to menu command event routing that I want to cover. In previous versions of the OS, when you sent a command event, kEvent command process or kEvent command update status to a submenu and the submenu didn't handle it, the event would then go to the user focus target. In Tiger, we're changing that somewhat so that instead of going directly to the user focus target, the event proceeds up the parent menu chain until there are no parent menus anymore.

Then it goes to the user focus target. That could be particularly useful if you have a menu with a number of hierarchical submenus. Maybe you have a font menu with a bunch of submenus and you want to have the parent menu be able to control some of the command updating and command processing for the submenus. This way you can install your handlers just on the parent menu and not on every submenu. every single submenu as well.

You still see? Yes, you can. Okay, good. HIViewManager. We have some new coordinate conversion APIs, HIPointConvert, HIREctConvert, and HISHapeConvert, which are used to take points, wrecks, and shapes from one view system to another view system. But they can do more than that, because we already had that capability before. They can also go from view coordinates to global coordinates and vice versa. And even more significantly, they support two different global coordinate systems.

They support a pixel-based coordinate system, but also a 72 DPI point-based coordinate system. And especially as your applications are modified to be more resolution independent, you may find that the point-based coordinate system is useful, because that is independent of the actual display hardware and just gives you sort of a virtual coordinate space.

Also, along with the support for HIShape, we now have support for drawing and invalidating views outside of a 16-bit coordinate space. We have additional support for CG images. It's been a very common request from developers to be able to use CG image refs with the standard controls. So, as you can see, we now have support for CG image refs in push buttons, round buttons, bevel buttons, pop-up buttons, data browser headers, and I think a few others as well. Another CG image change in the HIV manager is a new API, HICreateTransformCGImage. Some developers have found when they're writing custom controls that display images that they want to be able to directly imitate the appearance that the toolbox will give when a control is selected or disabled.

So for example, on the left side we have an original image. In the middle we have a disabled image. And on the right side we have that image drawn in a selected state. And previously there wasn't any good way to take a CG image and apply those transforms to it to get the resulting ones. We now have an API to let you do that so that you can write custom views that exactly match the toolbox appearance.

[Transcript missing]

The Data Browser. We've added some long requested features ever since ITunes came out. People have wanted support for alternating row colors in the Data Browser. And we now have support for that built in. Another thing that we have now built into the Data Browser is column dividers. And you can see it's column divider is just a vertical line between columns. Both of those are accessed via a new set of APIs, Data Browser, Get, and Change attributes. So these are just attribute bits like many other Toolbox APIs use.

We have a slight change to the appearance of the popup button cell in a Data Browser cell. The old appearance drew the actual popup button control, which was kind of bulky and didn't really fit into the appearance of a ListView cell very well. So we now have this new buttonless popup menu appearance, which is un-matched.

And it's much sleeker and doesn't really take up as much space and just generally fits into the general table appearance much better. And finally we have some new APIs, Data Browser, Get, and Set Metric, which allow you to change the amount of white space and separation around text and icons in a ListView cell.

Interface Builder has a bunch of new features I want to run through here. Support for the Placker, Window Header, and Segmented Views. You can see those are highlighted in the Interface Builder screenshots here. We have support for Control Text Foreground Colors and Justification, so you can now set those directly inside Interface Builder. Also some new Window Attributes, specifically the resolution independent Window Attributes, the Framework Scaled and Application and scaled attributes, but also in window menu and does not cycle.

Window resizing limits, the minimum and maximum sizes for a window can now be set directly in Interface Builder. And one last feature I want to highlight, which is pretty cool, which is automatic window positioning based on display size. So the problem this is solving is that you're designing your user interface on your 12-inch PowerBook, and you have your window positioned halfway across the screen and two-thirds of the way down, and you run your app on your 12-inch PowerBook, and it works great. That's where the window comes up.

But then you transfer your app over to your desktop system with your 30-inch cinema display, should you be so lucky as to have one. And you run your application and the window is way up there in the top left corner of the screen. And that's because IB is just saving the absolute coordinates of the window bounds and they don't change.

So using this automatic window positioning in the window inspector, there's a new little section there where you set springs and rods on a window. And that can let you specify that a window should be proportionally located on the display where it's loaded relative to its location on the display where it was designed. So if you put the window halfway across and two-thirds of the way down when you design it, and you open it on a much larger display or on a much smaller display, it'll still be at that same proportional location.

The Menu Manager doesn't have any new Carbon events or APIs this year, but it does have some user interface changes that I'd like to highlight so you're not surprised by them. The first one is Menu Bar Type Selection. We now support being able to type select a menu title.

Previously we just supported menu item type selection. So when you first put focus on the menu bar using the keyboard hotkey, only the Apple menu title gets highlighted and the entire menu does not get opened. Then if you type something, type ARR, you'll end up selecting the Arrange menu title.

At this point you can press Return or Enter or Spacebar and the entire menu will open and you can type select. Of course this particular thing isn't quite a Carbon specific thing because since Cocoa also uses the Carbon Menu Manager you get this effect in Cocoa applications as well.

And the other change is Pop-up Menu Selection. This is especially useful if you are using the keyboard to access your menus or to open pop-up menu controls. So if there's a pop-up button control and the menu has a particular item that is checkmarked, when that menu comes up, that particular checkmarked item is going to be pre-highlighted now so that you can use the arrow keys to move directly to the next item or the previous item very easily without having to start from the top or the bottom of the menu.

MLTE, the Multilingual Text Editor or TextEntion, also has some new APIs. There's going to be a whole session about this tomorrow, I think, so you can go and find out more about this, but I'll just give you some highlights here. MLTE now supports the Cocoa Spellchecking Panel, so you can very easily build spellchecking support into your application that uses MLTE.

It also supports the Cocoa Font and Typography Panels. It has some new APIs to let you do more sophisticated scrolling behavior when text is inserted into an MLTE field. It has some new APIs to do more sophisticated undo group support to control how different actions are grouped together and then undone. And finally, some new features to allow you to read from and write to a CFURLRef.

Universal access is sort of a general term for a bunch of different features in Mac OS X that support the use of the operating system by users with disabilities. And one of those features is the zooming feature that is meant for use by users with visual disabilities with low sight abilities. And it magnifies the entire screen by a user-specified amount.

Now the problem, of course, is that if you magnify the entire screen, well, some part of the screen is going to get forced off of the edges of your physical display space. So the question is, how do you actually determine which part of the screen should be displayed on your physical hardware device? For example, let's see, here we have a screenshot from a magnified version of TextEdit.

And you can see the insertion point is kind of right at the right edge of the screen. So if the user were to press the right button, or the right arrow key a few times, that insertion point would move off the right side of the screen, and you'd lose it.

It would be off the physical display hardware. So to prevent that problem, the zooming feature in Universal Access scrolls the entire zoomed area of the screen off to the left to keep that insertion point visible on the physical display device. Now, how does it know where the insertion point is? Well, someone has to tell it. In the case of the built-in operating system, the editing engines, we already do that for you.

So we're already telling the zoom feature where the insertion point is. But if your application offers its own keyboard accessible user interface, then you need to explicitly tell the zoom feature yourself where the current focus of the user's attention is so that the zoom feature can stay focused on that particular point.

So we have some new APIs here. UA Zoom enabled tells you whether the Zoom feature is currently enabled. UA Zoom change focus is what you'll use to give the global coordinates where the user's locus of attention currently is. That's an assertion point or some other way of indicating where the focus is.

So typical uses, if you're writing your own word processor or spreadsheet, these often provide keyboard access to objects inside the document, some kind of other graphical object editor, or really the whole idea is anything where the user isn't using the mouse to indicate where their attention is because the Zoom feature already knows how to track the mouse, but is using some other modality to indicate their attention, which might be keyboard, but it could even be speech or something else like that. In those cases, you'd want to use these APIs to tell the Zoom feature where the area that it should be paying attention to should be.

Okay, Carbon-COCO integration. We've made a bunch of changes here to solve a lot of the common problems that developers run into when using Cocoa technologies inside their Carbon application. One of the biggest ones is the use of unified Core Graphics window levels. Carbon and Cocoa used to use different Core Graphics window levels for floating and modal windows.

We now use the same window levels for those particular types of windows. So that solves a lot of problems where a Carbon window, Carbon floating window, couldn't come in front of a Cocoa floating window and modal dialogs got in front of floating windows or vice versa and things like that.

Those of you who have run into those problems probably appreciate this fix. KHICommandSelectWindow is a command ID for a command event which is sent when you click on a window if that window is using the standard window event handler. We are now sending that command event for all clicks on windows that use the standard window event handler even if the window is already active. That makes sure that if you have a Carbon document window and a Cocoa document window in the same application that the Carbon window is always going to order in front of the Cocoa window when it's clicked.

We've also made some changes that are focus-related. We had seen some problems where if you had, say, the focus on a Carbon document window and you clicked into a COCA floating window, sometimes the focus wouldn't move properly, or maybe it wouldn't move properly back the other direction. So you could wind up with two different blinking insertion points or two different controls in different windows that both drew their focus rings. Properly from one window to another and released by the window that it's leaving.

And also some changes to the standard controls in Carbon so that they only draw focus rings if their owning window is the current user focus window. And finally, auto-release pools are an issue that a lot of developers run into when trying to use Cocoa technology in their applications. Cocoa requires the establishment of an auto-release pool before you call into Cocoa code because it's used for memory management for properly keeping track of objects that need to be released later.

And it was awkward and sometimes really very hard to establish those pools, if you were using, say, run application event loop, because you didn't have any control over that core loop, the core event loop, the toolbox ran that loop for you. So we now establish auto-release pools for you in several cases, including in run application event loop, in run app modal loop for window, modal dialog, and when drawing the content of a compositing window. In all those cases, you can rely on the pool being present.

The Cocoa team as well has made some changes. I'd just like to highlight some of them here. We've improved the behavior of floating windows. Previously, if you had, let's say, a font picker window, a Cocoa font picker window in a Carbon application, that font picker window was essentially treated as a document window to the extent that the Carbon APIs dealt with it, which meant that it would steal activation away from your document windows.

It could become active when your application was active. So that's changed now, and those Cocoa floating windows are now really treated as Carbon floating windows as well. So they don't steal activation, they don't appear in the Windows menu, and they properly hide when the application is hidden as well.

The Cocoa team has also made some changes to improve focus behavior so that the Carbon user focus and the Cocoa key window status properly track each other as they move back and forth. So when the Carbon user focus changes, the key window status changes and vice versa. And finally, if you've tried to use KEvent class application events in your Cocoa application, you may have noticed that your handlers simply weren't called. And that's now been fixed as well so that you can now use KEvent class application events inside a Cocoa app and your handlers will be called.

Okay, one little note here. Due to changes for the auto-release pools and also for the HIArchive API that we're going to be talking about later, the HIToolbox framework now always loads the foundation framework and the Objective-C runtime. That's a change from previous versions of the operating system where those frameworks and runtimes weren't loaded unless you explicitly called code that used them. Well, we are explicitly calling code that uses them now because the auto-release pool API comes from Foundation, and the HIarchive API uses the NSKeedArchiver API from Foundation. So those things are going to be loaded into your applications, but you shouldn't see any runtime changes from that.

And I'd also like to point out one little difference in the implementation is that HIObjects are actually, in a sense, derived from NSObjects now and can be treated as an NSObject at runtime. So although we don't -- we're not currently saying that we officially support this, it is possible to say, you know, "My HIObject retain" or "My HIObject release" using the Objective-C syntax. Okay, that's it for the beginning of my session, and I'd like to bring up Bryan Prusha now, and he's going to talk about some navigation services and HIarchive.

All right, thank you, Eric. I'd like to begin talking about some of the changes that we've made for navigation services in Tiger. The first and most obvious change is support for Spotlight. You can see in the upper right-hand portion of the dialog that we have a search field. and also a finder style scope bar which can be used for narrowing your spotlight search. and support in the sidebar for finder save searches.

And of course, as you support the Navigation Services API, you'll get all of that for free. No code change is necessary. Now, the next thing that we did is added a new API, specifically for filtering in Navigation Services. So traditionally, we've only offered the ability to filter based on an array of OS types.

And this worked for a long time, but, you know, along came Mac OS X and extensions, and that paradigm began to break down. So we wanted to go one step further than just adding extension support. So now with the NavSetFilterTypeIdentifiers API, we've added support for you to pass an array of uniform type identifiers to Navigation Services.

So this has multiple features. It subsumes the behavior of both OS type filtering and extension filtering, as well as offering the advanced uniform type identifier conformance hierarchy. And in addition, UTIs all have a display name. And so we can just provide that for users in the enabled pop-up.

In this case, you can see that I've passed this nav dialog, public.image and public.text. These are meta types in uniform type identifier hierarchy. And so they refer to all types of images and all types of text. So as you can see in the dialogue, because I'm filtering by images, you can see GIFs, pings, all sorts of image formats being filtered at the same time, very simply.

Now let's say I want to sort by text instead. Oh, but wait a second. There's been this longstanding bug where when you change the enable popup, some of the icons will update, but the text doesn't. And this has been confusing for users. And it's kind of subtle. and this subtlety is really part of the main problem. So we've gone ahead and made sure that since we're working with filtering, we wanted to make sure that the nav dialog updates properly in all cases. So your users will no longer have any confusion in this case.

There were 33 duplicates on this bug, so there's at least 30 of you that are happy. All right. That's enough for navigation services right now. I'd like to move on to HIArchive. As has been mentioned a couple times now, HIArchive is a new API for Tiger, and it's wrapped around NSKeyedArchiver that Ali talked about in the previous talk, if you were here for that. So it's a mechanism for taking live objects in memory, whether HI objects, so HIViews, windows, menus, or core foundation property list types, like collections, like arrays, or CFString, CFNumber, things like this, flattening out into a CFData, an architecture-independent binary format.

Now this binary format is very small, compact, does some cool things like string unique-ing, and offers a table of contents for quick access to your objects. Now later on, when you want to pull information back out of the archive, Your objects will all be reinstantiated with the same state they had when they were written out into the archive.

So for a lot of people, the word binary will throw up some alarms. And so I wanted to make sure that you knew that you could use the PLUtil property list utility to convert your binary archives into text XML if you want to use that format. But I highly recommend maintaining the binary format for deployment, just for performance reasons. Now, Interface Builder does not support archive-based nibs at this time. But it will in future releases.

To that end, we've added support in the existing Nib APIs, iBCarbonRuntime, to look into the Nib and see if there is an archive format sitting next to the traditional XML format for interface builders' information. If that exists, it will prefer that. So in a future version of Mac OS X where you can write out archive-based Nibs, those Nibs will be backwards compatible to Tiger.

Let's talk a little bit about how you as a client will use HIarchive. The two main tasks you want to do are encode your data and decode your data, pull all your objects back out. So in order for the encoding step, you'll call HIarchive create for encoding. This will give you an HIarchive ref that is used explicitly in the encoding set of APIs. So don't try and pass it into the decoding APIs. You'll get an error.

Now with this HIarchiveRef, you'll pass each of your objects in turn to HIarchiveEncode's CF type. In addition, you'll pass a string which uses a key, like the key value pairing used in CFDictionary's. This key is important because it will be used to pull information back out later. So when you're done writing all your information into the archive, go ahead and call HIArchive Copy Encoded Data.

This will take all the information that you've written in, squish it down in that nice little binary format, and pass it back to you as a CFData. Now when you have the CFData, you can write it out to disk, put it on a pasteboard, send it to another application, do whatever you want. It's just data.

Now later on, your application will want to pull this back out. If you've written a bunch of views in Windows as your user interface, you'll want to load this up at launch time, something along those lines. So you call HIarchive create for decoding with the CFData that contains your binary HIarchive. This will pass back another HIarchive ref that is used explicitly for the decoding set of APIs.

Then for each one of your objects, call HIarchive copy decoded CF type using the CFString keys that you wrote into the archive to begin with. And then each of your objects one by one will be reinstantiated with the state it had initially. Now the HIarchiveRef is a CF type, so make sure to use call CF release on it when you're done.

I've mentioned that you can use HIarchive with core foundation property list types as well as HIobjects. So let's talk about how you can support the HIarchive protocol in your HIobjects. There are two events, kevent-hiobject-encode and kevent-hiobject-initialize. Each of these will hand you a kevent-param-hia-archive parameter. So this is the HIarchive ref that you will use to write your information into the archive and pull back out later.

So when the client requests for you to encode your data, you'll identify your object's persistent state, And write that into the archive using the APIs that I just went over. And then make sure to call your next event handler so your superclass gets a chance to encode its data. For instance, if you're in HIView, you want to make sure that the base HIView class can write out things like your size and position and title, all those kind of common features.

Then later when the client requests that you pull yourself out of the archive, you'll get the initialize event. Now this is the same initialize event that you are sent normally now when somebody calls HIObjectCreate. The difference being that when you are given the HIarchive ref, you want to instantiate your object from the archive rather than by default. Now, the great thing with writing information out by key is that, first of all, not all of the information has to be there. If a key doesn't exist, assume that you're using the default format. So you can just use a default initializer in that case.

Now, if you have a newer version of your object that writes some information out, you might write out three keys. But if you move that back to an older version of your application that only understands two of those keys, it can just ignore the third key. And so there's a great amount of backwards and forwards compatibility with the archive format. And again, make sure to call your next event handler so that it can have a chance to initialize itself from the archive.

Once you handle the HIarchive protocol, make sure to call hiobject setArchivingIgnored to false. It sounds a little backwards, but it's useful. This tells the toolbox that you handled the archiving protocol, and it knows that it can send these messages to you. The reason why it's settingIgnored to begin with is because clients can call this also.

Typically, you will call this within your initialization event, but clients at any time can call this API on subviews in a window to guarantee that those pieces don't get archived out and can be pulled back and can be initialized later manually. Now, this is important because you want to keep your HIarchive small. The smaller they are, the faster they load from disk. So keep that in mind. Don't write out too much data, only as much data as you really need.

Now, I'll go more in depth on this in a session tomorrow, session 116, building a custom HIV. In that case, we'll be dealing with an HIV specifically, not HIObjects in general. And there will be plenty of sample code available. It's a hands-on session. So the last thing I just want to touch on, if your application-- or in your application you want to edit HIArchives, you might take advantage of the HIObject set custom archive data API. This allows you to add some custom bits to an object that will get written out into the archive automatically. So an interface builder style application might use this to write out initialization parameters.

And so you can check out hiobject.h and hiarchive.h for more documentation on these specific features, as well as documentation on the ADC website. Now with this, I'd like to move to a demo of HIBuilder. HIBuilder is some sample code that we've been working on that takes advantage of the HIarchive APIs.

Now, to begin with, I'd actually like to show you interface builder here. I'm going to create a new nib. We have a window in there, and I will add a menu. I'm just going to make sure we don't have the default information here. Let's do something mildly interesting. Let's add some buttons and so on. All right. I'm saving this to the desktop.

And I'm quitting Interface Builder. Now I'm launching HIBuilder. And HIBuilder has a feature where you can open NIBs. What it does is it does some very simple parsing of the XML data, identifies all the top level objects, and uses the existing IB Carbon runtime APIs to pull the information out. So you can see that we have the menu that I modified and the window with all its pieces. Next, I'm going to save this archive. I'm going to save this archive back into the Nib. I'm going to save it with a special name.

objects.aib. So this mirrors the objects.xib file that it sits next to. Now, again, this is what will cause your existing code, your existing IBCarbon runtime code, to pull your information out of the archive rather than the nib. So you can get some performance enhancements. Now I could just save this archive out separately and load it manually through the HIarchive APIs as well. So I'd like to show you some things you can do with HIArchives that you can't currently do with NIBs. For one thing, you can take all kinds of HI objects and archive them. This is just a base HI object.

and you'll eventually be able to add parameters. We'll be releasing the source code shortly after the developer conference. But because it's an archive, we can also write out core foundation property list types, so strings and arrays and so on. and something that a lot of people have wanted for a long time. This is specifically useful for navigation services. Navigation services has a custom area, and typically, when you mock up your interface in Interface Builder, you have to put all your custom views into a window.

So you pull the window out of the Nib, using the i.b. Carbon Runtime APIs, and then pull out all your custom views, destroy the window, and then take those views and put them into Navigation Services. Now you can just have an HII view as a top-level object. Now I'm going to say it allows subviews.

And now I can just start loading it up with all my custom interface. And so again, I'll save this out to an archive. And then at runtime, I can just messing around with a window. So I hope that gives you an idea of what HIBuilder can do. And again, the sample code will be available shortly after the developer conference. So with that, I'd like to hand things back to Eric.

The last bit of the presentation covers some compatibility tips and other changes in other parts of the operating system that may affect your application. So, compatibility tips are generally things where we have changed something about the implementation or maybe we fixed a bug in the toolbox and we found that this affects applications in ways that they may not have expected because they were not expecting that particular bit of implementation or that particular bug fix to change. They're not generally things where there's a defined behavior in the API that we're changing but more something that happens inadvertently.

The first one of these is a good example of this. Add event types to handler is an API in the Carbon Event Manager that lets you add extra event types to an event handler to be handled by that handler. And it turns out, we found out recently, that this API has had a bug in it since 10.2. It worked properly in 10.0 and 10.1 and we rewrote some stuff in 10.2 and broke the way that it behaves slightly. So that events added to a handler got dispatched in slightly the wrong order.

So we fixed that for Tiger. But it also turns out that some applications have come to depend on the particular behavior that it had in 10.2 and 10.3. These apps were never actually run on 10.0 or 10.1, so they were never tested against the correct behavior. They were only tested against the incorrect behavior.

So I'm not going to go into explicit detail about exactly how this changes the order of event dispatching, because I kind of need a blackboard and a piece of chalk and lots of diagrams to explain it. But we have detail in the HITooLbox release notes about exactly what's changed here. And if you use this API, you probably want to take a look at the release notes and read about exactly what's changed, and that'll help you understand whether it may be affecting your application.

The menu bar window is another example of something that's changed in the implementation that's affecting a lot of applications. The menu bar in Tiger is now drawn into a real window ref using a compositing HIView. The window ref is a compositing window. And that's done so that we can get resolution independence for free for the menu bar because the menu bar window is using framework scaled mode, as I mentioned earlier, and then the toolbox does all the work for making it resolution independent for you.

But a lot of applications don't expect to see a menu bar showing up in their window list right at the top. They think that the first window in the window list is going to be their active document window, for example, which hasn't really ever been a great assumption because you could always have other windows in the window list, say a text services manager bottom line input window or help tag window or various other things. But a lot of apps have gotten away with this so far.

So to maintain compatibility with existing applications, what we're doing here is for the get window list, and get front window of class APIs for existing CFM and Mako applications, we will silently ignore the menu bar window and just skip over it. So you won't see that window come back from those APIs. But if you have a Mako application that you rebuild on Tiger and relink against the Tiger versions of the frameworks, we'll remove those compatibility workarounds on the assumption that you've then had a chance to deal with the problem and fix it in your applications.

So that at that point, get window list and get front window of class will start returning the menu bar window since it is a window and it's in the window list. So if your application is using get window list or get front window of class or the front window API to figure out what the front most document window is or the active document window, we recommend using the active non-floating window or front non-floating window APIs instead.

Another change that's tripped up a few applications is the change to the standard window levels. That are used by the standard window groups. As I mentioned earlier, we're now using the same core graphics window levels as Cocoa. It turns out that some applications have been manually changing the window levels used by the standard window groups. And they aren't expecting us to be changing them as well.

So the message here is if you are changing the window levels of the standard window groups, you probably don't need to do that on Tiger. And also avoid making assumptions about the window levels that are used by the standard window groups. You can call get window group level to find out the level that the toolbox has provided for a window group.

And there's actually some other new APIs to let you find out the window levels that are used when an application is active or inactive because in some cases it can change. And try to dynamically set your own window levels based on the ones that the toolbox is using.

The sending of command events containing the KHICommandSelectWindow event to all windows, even when they're active, if they're clicked, has caused problems for a few apps that handle this event themselves. So the key here probably is that if you handle the KHICommandSelectWindow command ID in your command event handler, check to see if the window is already active.

And if it is already active, you can probably just pass the event through and you don't need to update your own application state. Finally, the HIViewRender API has changed behavior slightly between Panther and Tiger in the sense of how it validates other views that are being drawn in conjunction with the view being the view that was passed to the API. The Tiger behavior is actually more correct in that we validate less of the other views, only the portions of views that actually get redrawn. Panther validated too much.

But again, it turns out that some applications accidentally depended on the Panther behavior. So our recommendation here is twofold. First, we highly recommend that you only use the HIViewRender API with the root view of a window. The root view will have the same validation behavior on both Panther and Tiger. So that will avoid the whole problem.

And second, if you do need to pass a non-root view to HIViewRender, which should be -- which should be extremely rare, just take a look at the release notes which talk in more detail about exactly how the validation behavior has changed and see if that might affect your application.

Some other changes in Tiger that I want to cover here. First, the Carbon Core framework, which provides the Carbon File Manager and many other managers, has a new file copying API, which is the same API that the Finder uses to copy files. And this entirely replaces all the sample code that Apple has released in the past, fs copy object and things like that, for doing file copying.

So we highly recommend that you look at this API and adopt it in your applications if you need to do file copying yourself. And that's because the file copy engine in Tiger knows how to copy some of the metadata that can be attached to a file, such as the extended attributes or the access control lists. And any of your existing file copying code just isn't going to copy that stuff at all, because it was written before APIs existed in order to do that.

So you can use this API in both synchronous and asynchronous modes. In the synchronous mode, you just call fs copy object sync or fs move. And in the asynchronous mode, you create one of these fs operation refs and then run it asynchronously. And you can get progress updates and status notifications in that case as well. Another change in Tiger I'd like to highlight is the status of Quick Draw.

And we've been telling you for quite a while-- and we certainly reiterated it earlier this week at the Graphics and Media State of the Union-- that you want to move off of Quick Draw and start using core graphics. And to make that official in Tiger, Quick Draw is officially deprecated. Its status as an API has become deprecated in Tiger. This doesn't mean we're removing the API entirely. It's still there. Your applications can still call it. They'll still run.

And in fact, it's still there on Mac OS X for Intel as well. But it does mean that we are putting you on notice that we're not going to do any more performance changes or performance enhancements to Quick Draw. Those are all going into core graphics. We're not going to fix any more bugs in Quick Draw, except for things that are absolutely required for compatibility to keep applications running. So what you see right now is what you're going to get for as long as Quick Draw is supported. There's not going to be any improvements there.

So you definitely want to, if you haven't already, start moving off of Quick Draw and onto core graphics. The other big advantage of moving to core graphics, of course, is that it will make it much easier for your application to become resolution independent in the future as well. HImovieView is a new HIview that the QuickTime team has asked me to talk a little about. It's a view that is provided in QuickTime 7 when it's running on Tiger.

and it is now the preferred way to put QuickTime movies into Carbon Windows if you're using one of the standard views built into the system. So it's a full-featured HIView. It's been rewritten to use Carbon events and use all the standard functionality. You can load them from Nib files. You can put them in composited windows.

You can scroll them around inside a scroll view, that sort of stuff. It uses the visual context API in QuickTime 7, so that gives you some performance advantages when you're doing live resizing and really helps the QuickTime playback system leverage the GPU rather than putting the playback on the CPU.

And so just in general, on Tiger you want to be looking at using HIMovieView rather than the older Carbon Movie Control, which is essentially just static at this point and won't see any significant improvements going forward. Coalesced updates is something that the core graphics team has done in Tiger that may have effects on your application.

You may have also heard it called deferred updates. And I want to sort of explain how updates work generally to give you some background here. When you draw into a window, windows are double buffered on Mac OS X, so you're actually drawing into the window's off-screen buffer. And the bits that you've changed don't get displayed on the physical hardware until Core Graphics comes along and takes those bits and sends them out to the display hardware. That's a process called flushing.

Now the flushing process happens in most cases automatically because both HIToolbox and AppKit will automatically flush your windows when you hit the event loop. So if you're calling into the event loop on a regular basis, then all your windows are going to be flushed by default. However, some of your applications may be explicitly flushing as well if you're doing things that draw into a window, but then you don't run the event loop for a while. You need to explicitly flush to make sure those changes come to the screen.

So pre-Tiger, when a flush request happened, Core Graphics immediately grabbed the bits out of the windows off-screen buffer and sent them off to the display hardware. And that's fine, except that if you have lots of applications all doing this at once, you wind up with a serialization effect. So each application has to wait for the flush request of all the other applications that got in before it did. And that can have some significant performance degradation.

So in Tiger, what the Core Graphics team has done is they are now coalescing all these flush requests together. So no matter how many applications you have running, all of their flush requests are going to get batched together, and they'll all be delayed until the next display refresh cycle. And at that point, all of them will be sent out to the display hardware. So this improves performance when you have lots of applications all flushing at once. It eliminates the tearing that may have been seen in the past.

But it can also reduce performance for some applications. Applications that are explicitly flushing and doing so very often can see a reduction in performance due to this. Because previously, once they flushed, if they drew again after the flush, the flush would happen pretty quickly. The drawing operation gets blocked until the flush is finished because you can't draw while Core Graphics is taking the bits out of the window buffer. You need to wait until the buffer has been properly updated off to the display hardware. But as long as the flush happens quickly, your draw operation can continue pretty quickly too.

On Tiger, however, the flush operation gets delayed until the next refresh cycle. And that means your next drawing operation after the flush gets displayed until the next refresh cycle as well. So if you have a loop where you're doing a flush and then a draw and then a flush and then a draw and then a flush and then a draw, a lot of your drawing operations are going to get blocked. And you're going to wind up being held to the display refresh rate where you might have been able to run faster on previous versions of 10.

So because of this potential issue for some applications, the Coalesced Updates feature is only enabled for new applications, Mac OS applications that are linked on Tiger and later. It's not enabled for any existing applications. All of your CFM applications, all of your Mac OS applications that were linked on Panther do not get the Coalesced Updates change.

However, when you take your Mac OS application and relink it on Tiger, you are going to start seeing the effects of Coalesced Updates. So you will need to deal with this as you move So we have some recommendations here for you, for how to best work in a world of coalesced updates. And the first recommendation is pretty simple. Don't flush explicitly if you don't have to. The HIToolbox already is flushing on your behalf. And in most cases, you don't need to flush yourself.

But sometimes you do. And in that case, the next recommendation is just don't flush too frequently. You don't need to flush more often than the display refresh rate. The display isn't going to be redrawn more often than that anyways. So if you flush more often than the display refresh rate, it's not going to do you any good. You're not actually going to see anything that you're flushing anyways.

So you can ask for the display refresh rate for the main display from Core Graphics. And if you need to flush explicitly, just keep track of the time that you last flushed. And if the amount of time since then that has elapsed is less than the display refresh rate, don't flush again. Just wait until that next refresh rate interval has elapsed.

Also, you don't need to draw too often. If your display is refreshing at 80 cycles a second, 80 hertz, and you're drawing at 200 hertz, half of your frames aren't going to show up on the display because they'll get overwritten by the next frame and the user isn't even going to see them.

So you really don't need to draw any faster than the display refresh rate either. Finally, if you want to explore what the effects of coalesced updates may be on your application even before you rebuild it as Mac OS on Tiger, you can use the Quartz Debug application to explicitly turn on coalesced updates for all apps across the system. Now that's not a mode you might typically want to run in, but it's useful for performance testing to just see how your application is going to behave once coalesced updates is enabled for it.

So here's our summary. The goals of the HIToolbox team. Well, we're here for you, basically. We want to address your requests. We want to do the things that you need us to do to make it easy to write your applications. We want to support new technologies as they come out from Apple so that those technologies can be integrated into your applications. In general, we just want to make it easy to write a great Mac OS X application. Carbon's a great API for doing that, and we want to continue to see you writing those Carbon applications.

What we want from you, we want you to write custom HI views. And when you're doing that, we want you to use compositing mode and core graphics. That will give you better performance, and it will make it much easier for your applications to become resolution independent in the future.

We want you to make your application accessible. That's not only for the needs of users with visual disabilities, but as you saw in one of the State of the Union addresses yesterday, accessibility is a really cool feature for other things like scriptability and inspection and being able to introspect about what's going on in an application.

And it can really add a lot of value to your application if it's accessible. And finally, please tell us what you need. We're not mind readers. You may be butting up against this particular problem every day and thinking, darn, haven't they fixed this already? But if you don't tell us about it, we're not going to know. So please, tell us what you need, file bugs, put feature requests in radar as well. We also have this email address for feedback, [email protected].

This replaces an older address, [email protected], which is no longer in service. So if you have specific bugs or specific feature requests, please put those in Radar. But if you just have general conceptual feedback or general questions, this is a great address and we'll try to answer your questions there.

More information can be found in the HIToolbox release notes, which go into a lot of detail about what's changed in the toolbox in Tiger. Those are on developer.apple.com, the most recent versions on developer.apple.com, and also in the Xcode documentation update that was released a month or so ago. There's also a Q&A that DTS has put out about how to use HIMovieView on Tiger.

Let's see. And some other sessions coming up that you may want to go to. Right after this one, it's going to be voiceover and Carbon applications, talking about how to use accessibility to make your Carbon application accessible. There will be a session on HITextView and MLTE and the new features available there in TIGR.

And tomorrow, we'll have an in-depth session on building a custom HIView. And we're going to go into -- we're going to cover a lot of issues that we haven't covered in previous years when we've given sessions about building HIViews, things like doing text input and keyboard focus and accessibility. We have a feedback forum on Thursday where you should all come and tell us what we're doing right and what we're doing wrong. And also the application technologies lab is open all week.

I'm going to be there tonight and I'll probably be there tomorrow night and we'll have other people there during the week. That's not -- despite the title, it's not just about HIView. You can really come in and ask us any kind of HIToolbox question. and we'll see what we can do to help you out.