General • 47:15
In this virtual grab bag of topics developers gain valuable insight on why, when, and how to create a Mac OS X screen saver or System Preferences pane. We'll also learn how to leverage new Disk image capabilities and the Mac OS X Installer.
Speakers: John Geleynse, Mike Trent, Robert Bowers, Maxym Runov, Grace Kvamme, Jean-Pierre Ciudad
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it may have transcription errors.
Well, good afternoon. Welcome to session 8, 008. No, 004. I'm sorry. Didn't look at the screen. 004, unfortunately not 007. I'm John Glunze, User Experience Evangelist here at Apple. And this session is a fun grab bag session of sort of misfit toys, you know, the land of misfit toys. These are some great technologies that just needed a home at WWDC, and each of them doesn't have enough content for its own full session, and yet they're very important in terms of you providing a great user experience with your product. Now, screensavers doesn't apply specifically to your product, but it still is part of the Mac OS X user experience, and it's just a fun thing to know about. And so we thought we would talk about it. And we called this session actually originally Mac OS X party favors. You know, lots of good things you get at the end of a party, birthday party. So the first favor we're going to talk about is the Mac OS X screensaver, how to write a screensaver. And I think it's just a fun diversion. You know, when you're sick of writing your real product, just get off and write a really cool screensaver. It would be really cool.
Finally, Mac OS X. Finally, we have a Macintosh operating system that can really do some very cool screensavers. Then favor number two, the second topic we're going to touch on is the preference pane. How to write a system preference pane. A system preferences application lets you add third-party preference panes, and there's some really specific cases where you'd want to do this, and so perhaps you fall into that category in terms of what your company does, and so we're going to tell you how to do that and when to do that. Third-party favor is just to talk about the disk image. Disk images are the preferred format for distributing software over the Internet and for distributing software on Mac OS X, so we'll talk about that. We'll talk about the new user experience with the disk image, package format in Mac OS in Jaguar. And then we'll move on to an update about the Mac OS X installer and some of our other tools like around the installer like Packagemaker. So to get started, I want to introduce Mike Trent, who's going to talk to you about Mac OS X screensaver. Mike. Thanks. Thanks, John.
All right, well, let's talk about screensavers on Mac OS X. First of all, we all know what a screensaver is, right? Screensavers are entertaining graphics demos, like slideshows or virtual fish tanks, that run when you're away from your computer. The screensavers can have more serious uses, too, such as displaying marketing material. For example, the Apple retail stores use screensavers to display product demos and attract loops when people aren't using their machines.
Well, ironically, one thing screensavers don't do is actually save your screen, right? This is especially true now that we all have flat-panel displays. At least I hope you all have a flat-panel display. um um So in Jaguar, we're going to start using the term screen effect to refer to things like screensavers to help clear up some of this confusion. But for the purpose of this talk, let's just call it a screensaver. We all know what that is.
So Mac OS X has a built-in screensaver system. This is great, because now you don't have to learn how to write your own anymore. You don't have to know how to patch into the OS. You can just focus on writing your own module to do your own screensaver effect. The screensaver system is built around a Cocoa-based framework, but you don't need to know much about Cocoa or Objective-C to write a screensaver. For the most part, you can focus on the graphics libraries you're already familiar with right now. Thank you. The screensaver engine is a normal Mac OS X application. The screensaver engine is the software that does all the real work for your screensaver. It runs the graphics and all of that.
Because it's a normal Mac OS X application, it runs in its own address space. This means that your screensaver can't interfere with the system at large, nor can the system interfere with you. you. So that's exciting. So screensaver modules are really bundles that encapsulate executable code and other resources. The screensaver modules and the screensaver engine communicate using a central framework called the screensaver framework. So what can the screensaver framework do for you? The screensaver framework supplies two Cocoa objects you can use in your screensaver module. The first object is called screensaver view.
Screensaver view is responsible for drawing to the screen and handling user input. Every screensaver module will inherit from this object. It is the heart of a screensaver module. The second object, screensaverDefaults, is a utility for managing user preferences. We'll talk more about that in a minute. Right now let's focus on screensaverView. Again, screensaverView is responsible for drawing to the screen and handling user input. It turns out, Cocoa provides an object that's great for doing exactly this, called NSView. By building on top of NSView, we can provide screensaver modules with a rich, interactive drawing environment basically for free. Now, screensaver view supplies some screensaver-specific features as well, such as managing an animation timer.
If screensaver view is responsible for drawing to the screen, how do you draw with screensaver view? One nice thing about views is you can configure them to handle graphics commands from a variety of graphics libraries. This means with a little bit of setup work, you can call directly into the graphics library you're most comfortable with right now. This might be Quick Draw, or this might be OpenGL, or whatever. There are a couple of places where you can patch into your module's animation loop to do your drawing, and I'll show you some examples of both in a minute.
In the past, you've had to worry about drawing across multiple monitors. One of the great things about the screensaver in Mac OS X is it handles multi-monitor issues for you automatically. All you have to do is worry about drawing in your screensaver view, and the system will make the results appear across multiple monitors in a consistent manner. If necessary, your module can set your screen device, sorry, your screen depth using Core Graphics Direct Display API. Remember, though, if you're going to change the user's monitor settings, please change them back when you're done.
So that's drawing with screensaver view. Now, screensaver view, as I said, is also responsible for handling user input. So normally, user events wake the screensaver, right? Well, maybe you want to write a video game in your screensaver, or maybe you want a screensaver that responds to mouse movement. It turns out that writing an interactive screensaver in Mac OS X is very easy. The screensaver engine will hook your module into its event loop directly, so you can listen for and override specific user events. Now, this comes with a word of caution.
If you're going to override user events, Please make sure the user understands how to wake the screensaver. You don't want to trap someone in your module wondering how to get out. Most unpleasant. In addition to drawing to the screen and handling user input, screensaver view is responsible for some screensaver-specific features, like I've said before, like managing your animation loop. It also supplies some methods for managing your runtime environment.
So that's screen saver view. Let's talk about how the framework can help you manage your user settings in a screen saver. So your module can supply a configure panel the user can use to customize the module's behavior. You can design this panel in Interface Builder, like any window, and then supply that panel to the system on demand. The system will display your panel as a sheet in the system press application, like in the screenshot here.
The framework supplies an object called screensaver defaults for working with system preferences. With your user's preferences, I'm sorry. Screensaver defaults It works with your information. It saves your preferences, makes them available to any application that loads your module. This might be the system preferences application. It might be the screen saver engine application.
It might be a third-party screen saver engine. Some already exist. Now, Foundation also comes with an object for working with user preferences called NSUserDefaults, but you should avoid using NSUserDefaults in your screensaver. NSUserDefaults stores information on a per-application basis, and this means that your settings won't be available to all apps that load your module.
So that's the screensaver framework. Let's see some demos. There's nothing like a good demo. So... I have two demos for you today. The first is a simple demo using Can we get machine four? Oh, great. Sorry. I'm looking at the wrong place. So I have two demos for you today. The first is a simple demo using QuickDraw, and the second will be a more sophisticated screensaver example using OpenGL. In the first example, I'll show you how easy it is to make a screensaver module. So, in fact, Project Builder does most of the tedious work for us. I'm just going to create a new project here, and there's a template for screensavers. Thank you.
We're going to call this Shapes. Project Builder has created a couple files for us automatically. These files are for our Screen Saver View subclass. I've said before that Screen Saver View is responsible for drawing to the screen and handling user input. We have to override this object. Every module has this object. I'm not all that fast at typing, so I'm just going to copy and paste from a cheat sheet here.
I hope that's okay. I want to draw using Quick Draw. In order to do that, I have to configure my environment to accept QuickDraw commands. I'll begin by installing a QuickDraw view inside of my screensaver view. In order to do that, I need an instance variable in my object. I'll do that here. I'll switch to our implementation. Because we're going to be working with QuickDraw, we need to have some header files that predefine the QuickDraw commands we want to use. I'm going to paste in the application services umbrella framework header to get us started. and Now we need to install our QuickDrawView. Once we've installed the QuickDrawView, we can begin sending QuickDraw commands, drawing commands, to our screen saver. So I will do that in our initializer, which is a method called initWithFrameIsPreview, and I'll walk through that here. This is a two-step process. The first process, we allocate our QuickDrawView object, and the second step, we simply install it.
Now, in order to do drawing, we're going to do some drawing in Animate One Frame. Animate One Frame is called by the screensaver system many times a second. You can use this to update your module's state, or you can do drawing. This is especially true of a simple module. Because this module is simple, I'm going to just do all of my drawing here and animate one frame.
and be done with it. So what am I doing here? First of all, we lock focus on our Quickdraw view. This means that the Quickdraw view is the main view. It's going to respond-- it's going to receive all the drawing commands that we issue from this point forward. It's analogous to setting the port in Quickdraw, for example.
Then we'll pick a random color. Now, the screensaver framework provides some macros for working with random numbers. These macros use the underlying random API in the system. You can use them if you like. You don't need to use them. One benefit of using them is the screensaver will set your random seed automatically. Because I think they're convenient, I will set them myself.
I will use them myself, I'm sorry. So we'll set a random color using RGB4 color. We're going to pick a random rectangle, again, using our random number macros. And then finally we just draw an oval. How easy is that? Then we unlock focus. We're good to go. That's all there is to it. We can build this example and install it. Now to save time, I've pre-compiled this on the system, and we can fire up System Preferences here.
All right, now as promised, here is shapes, and it draws random ovals on the screen. Excellent, thank you. Thank you. The second example I have for you is, as I said, a more feature-rich OpenGL module. I have one here called Alphabet. Alphabet draws a number of letters on the screen and then transitions them off with a variety of nifty fade effects, some expand, some whatever. It looks like we're running in a software renderer for OpenGL today, but that's okay. You get the idea.
So this module is fancy. It has a configure panel. We can use that to change some of our settings. The alphabet also can listen to the keyboard. This is kind of fun. So... we can actually inject letters on the screen by typing them on the keyboard. I'm gonna let some of these fade away here. I'm gonna hold down Shift-M, and a whole bunch of Shift-Ms will appear on the screen, capital M's. So, and I'll type my password or whatever. Oh, I can't, oh, it's all here. So, great. When I move the mouse, the screen server wakes up. Once it's finished printing all the letters I typed on the screen.
There we go. Let's see what that code looks like. Thank you. get rid of this here over here. Since this is a much larger example, I factored a lot of the code out into other files. I don't want to go into great detail about this module, so I'm going to instead focus simply on our screensaver view subclass. We're going to compare and contrast that with our first example. Like our first example, we install a graphic library-specific subview in our view. In this case, we're installing an OpenGL view.
And again, if we go to our initializer, we see it works basically the same way. Here I create our OpenGL view, and then we install it in our screensaver view. Fairly straightforward. Now, because we're working with the configure panel, we need to save and retrieve user preferences. And we're using the screensaver defaults object to do that for me. And here we pre-declare some default values for the screensaver for the case where the user hasn't set up their settings yet. Thank you.
Now, in our first example, our quick draw example, we did all of our drawing in animate one frame. Well, in this example, I'm doing all of our drawing in draw rect. Draw rect is supplied by the NSView object, and it's called whenever the system thinks it needs to redraw your view.
So our strategy here is to draw our entire scene in DrawRect and then periodically invalidate our view so the system knows to redraw it. This way we make the system responsible for doing all of our drawing. And this is more consistent with the way AppKit, for example, does its drawing. This means in AnimateOneFrame, we simply take care of our module state. This state includes things like creating letters, injecting them onto the screen. every screensaver has to have some kind of nice Easter egg. Otherwise, you know, why even bother? and And then, for example, we can remove letters from the screen. And when we're done with all of that, we invalidate the view, telling the system to repaint the screen so our changes take effect. So that's how we draw in Alphabet. But Alphabet also responds to user events, such as typing on the keyboard. Thank you. We do that simply by saying we're interested in key down events, and if we get one, we just inject the letter on the screen. And, of course, we invalidate the view so the system knows to repaint.
Now, it might be that we aren't interested in user events. Remember, that was a checkbox. Maybe the user hasn't checked that yet. In that case, we pass the event up the responder chain so the next person can handle the event. And this will probably wake the screensaver. Thank you.
hopefully make the screensaver even better. So we do the same with the shift key. So that's how we handle user input. Fairly simple. Now, again, Alphabet has a configure sheet. We tell the screensaver that we, in fact, do have a screensaver sheet, and we make it available to the screensaver on demand. Now, I factored most of this code out into another file, an object called Alphabet Panel Controller, and I won't go into great detail here. Ultimately, the screensaver view is responsible for supplying the sheet to the screensaver system.
Again, we use screensaver defaults when working with preferences to make sure our preferences are available to every app that loads our module. Just to prove to you this is actually OpenGL, I know it was kind of slow on the screen. Maybe you think I've played some tricks. I've, in fact, factored all of our OpenGL code into a format that's similar to what OpenGL programmers are familiar with, basically the GLUT libraries or GLUT. I'm not sure how to say that.
So here we initialize our OpenGL state using standard OpenGL. Here we'll display our screen. And if for some reason our display changes, we can reshape all fairly familiar to OpenGL programmers. Thank you. So that's Alphabet View, the screensaver view subclass for Alphabet. And hopefully that's enough to get you started. You see how easy it is to make a screensaver module, first of all, and making a feature-rich screensaver module isn't all that hard either. So that's my demo. Thanks. Thank you.
So the system looks for screensavers in a couple of locations, basically in the library screensavers directory. All screensaver modules are identified by a specific file extension. We don't currently have a type or creator reserved for screensaver modules, but we may reserve some in the future. So that's all there is to know about screensaver modules. I hope you all have fun writing them. You can start writing them today. And now I would like to introduce Robert Bowers to talk to you about the system preference panels.
starting off with a screw-up. That's a really good way to go. So, what are preference panes? Well, preference panes are plug-ins in the system preferences application. I can't imagine you've used Mac OS X without encountering system preferences or the pref panes Apple already provides. Preference panes on Mac OS X fit a very specific user model of user interaction. They provide cross-context configuration or even if it's not truly cross-context, at least from a user perspective, it's a system-wide setting. A prime example of that being hardware configuration.
The architecture for system preferences is fairly straightforward. It's a CFBundle. There's a preference pane framework that handles the communication between the owning system preference application and your specific preference pane. And, in fact, your specific preference pane has to inherit from the pref pane class. It's worth noting that your preference pane doesn't have any special access to the system over and above a normal application on Mac OS X.
This is an important point to reiterate. On Mac OS 9, there were occasions where what you wanted to do really needed to be a control panel. That's not true on 10. There is no specific secret hidden access into the OS that you get by being a pref pane. It really is purely an HI affordance, a presentation mechanism for the user to find certain controls.
In fact, to drill on that point just a little bit further, the recommended storage mechanism that you use for whatever settings the user might be making in your pref pane is CFPreferences. But there's no requirement on that whatsoever. You can frankly do just about anything on the back end of the pref pane that you want, whether that's writing settings out to a file or stashing variables in NVRAM or whatever wacky settings you want to do.
Ah, my favorite topic. So let's talk about why not to make a pref pane, because there's actually a number of reasons when people start to make a pref pane that we sort of encourage them to back up a little bit. So let's talk about those a little bit. So I said earlier that our user model for preference panes is that, therefore, cross-context configuration. So settings that belong to one specific application don't fit well in system preferences.
Finder preferences, mail preferences, iMovie preferences are all good examples of things not to put in system preferences. Now, there are occasionally a couple of gotchas there because there is this whole concept of user-perceived settings. So it seems like back in Mac OS 10.0, we had the desktop picture and finder preferences, which ended up being an odd fit because from a user perspective, that's really a machine setting. that's cross-context of all applications, regardless of the technical implementation on the back end. So that was a case where we specifically pulled that functionality into system preferences. Thank you. Another good time not to do a pref pain when doing real work. Again, there's this user concept that a preference pain is fairly lightweight, ephemeral settings. You shouldn't be able to do any real damage with it.
I've picked this radio button. I've picked that radio button. It's all sort of whimsy. So anytime you're in a pref pain and you're writing code that feels like it's doing real work, something's probably wrong. You probably shouldn't really be doing a pref pain. So examples, burning CDs or DVDs, ripping MP3s, doing Sherlock searches, these are all things that just don't fit well in the user's mental model of what constitutes a pref pain.
When you're simply providing status or feedback, PrefPains really aren't a good venue for that. Doing doclings or even a standalone application with a window that provides status is a much better mechanism. When you're doing something that uses an application document model, sort of the traditional Macintosh document management, address book, iMovie, these things don't fit well in a pref pane. And this last one is sort of important.
When doing something irreversible, again, the user perception for pref panes is it's sort of hard to shoot yourself in the foot with a pref pane. So if you're doing something that there's no way to undo or easily switch back, then a pref pane is a really bad fit. Installing a software update would be a bad thing to do. Now, that's actually an interesting case to talk about just a little bit because, of course, we have a pref pane for software updates.
But if you look carefully, we sort of have an escape there. The pref pane is really only about scheduling when the software updates get executed. When we actually find new software and it gets ready to install, that gets launched in a separate application altogether, and that's one of the reasons why.
So let's talk about HI just briefly. There are a couple of nuances to keep in mind. Here's what system preferences looks like these days. So you may have noticed one of the issues about system preferences is that all of the pref panes have a fixed width. You just don't have much control over that. That's the way the UI is implemented. Now, you can certainly customize your own view and have a smaller view, and we'll just center it in the NSView for the pref pane. Or you can make it bigger, and we can truncate it, but there's just not much point in messing with it. You might as well stick with a fixed width. Prefpanes can have variable height, but within reason.
The Aqua UI is really designed to fit a minimum screen dimension of 800 by 600. I think that's the original iBook screen dimensions. Let's say you've got 600 pixels of height, and then you subtract some space for the menu bar and some more space for the dock, and you don't have a lot of room there. You've got some room for variation there, but not a ton.
And in general, pref panes, like any other application running on Mac OS X, really should abide by the Aqua human interface guidelines. So I'm going to bring up to stage Maxime Runoff to do a brief demo on how to create your own pref pane and then I'll be back in a moment.
Hello, my name is Maxim Ornov, and I would like to show you how simple it is to create a preference pane. The easiest way to do that is to use Project Builder, which has a number of templates for this kind of things. As you can see, in your project window, there is a list of templates.
And here it is, preference pane, next to screensaver. Thank you. So let's give it a name. Template provides you with the standard elements of preference pain bundle, such as resources, and a subclass of NSPreferencePain, which you can customize for your needs. Here's the subclass. Let's add a method here.
Now let's open up a.amp file and write some code. For this demo, I'm going to write very simple PrevPaint, so I'll just put an S beep here. Now we can build user interface. I'm going to use Interface Builder which is a standard tool to design user interface and to establish connections between user interface elements and the code. First thing I'm going to do, I'm going to import our header file that interface builder will know about our class and what it can do.
Now I'm going to set our class to be owner of the Nib file. Nib file provided by the template already has a window which is used as a main view for preference pane. For this demo, preference pane is going to have only one button. So let's place it there and let's connect it to our method.
That's it, pretty simple. Let's go back to project builder and build it. If I didn't forget anything, it should build just fine. Of course, your preference pane will be more complicated than this. *laughter* Okay, it's built. The last thing to do is to install preference pane into one of standard locations searched by system preference. For this demo, I'm going to put it into library preference folder within users into preference pane folder within users library folder. So here's our build results, pref pane, drag it there. Now let's launch system preference. Here it is, our preference pane. Here is our beep. Pretty simple. Good luck. Back to you, Robert.
Thanks, Maxime. Okay, a couple of things to point out that Maxime talked about or briefly touched upon. There are a couple of keys in your pref panes property list that you'll want to look at closely. If you'll remember the, or if you can remember the existing system preferences in Mac OS X, there are some pref pane names that have actually wrapped to multiple lines. This might be an issue for your specific pref pane, Specifically, if you're worried about localization, you may find that in English your pref pane fits on one line just fine, but you localize it to some language and suddenly it needs two or three lines. So there is a value in the plist, the NSPrefPaneIconLabel, that will let you support wrapping the name to multiple lines if need be. There's also the CFBundleIconFile, which points to what your pref pane icon should look like in system preferences. And then, of course, there's the CFBundle identifier, which helps distinguish your pref pane from all other prefs in the system preferences application. Amen.
Maxime mentioned briefly the installation locations for preferences. Not unlike the story with screensavers, it basically follows the library preference panes folder. There are three locations. There's system library preference panes. That's really reserved for Apple pref panes only. We're trying to... solve this user issue that we had on Mac OS 9 where the confusion between Apple provided products and third party products got a little onerous. So we really have one install location for all of the Apple pref panes and we try and keep that reserved.
There's library preference panes, which is where all pref panes get installed that you want available for all users on the machine. And then there's tilde library pref panes for the currently logged in user only. I want to point out an example of a third-party pref pain that exists today.
So here's a pref called docdisk. So there it is. Very straightforward. Follows the Aqua UI. Works just like a dream. Even works on the latest build. So that's about it. Prefpanes are lots of fun, very straightforward, very easy to get into. I would encourage you all, again, be careful when you decide to do a prefpane. Make sure you're doing something that fits the user's model of when a prefpane should be utilized. And don't do any work.
Once again, I hit the button twice. Next, I'm going to bring up Grace Kwame, and she's going to talk to you about disk images. Great. Thanks, Robert. I should have walked off first. That's okay. Thank you. Grace Palmy and I'm an internet product manager at Apple. And I'm going to talk a little bit about what you do after you've finished your app and you're ready to distribute it over the internet. Thank you.
So let's talk a little bit about the goals. Obviously, we want downloads to be as easy and full proof as possible for the user. Currently, they could be more easy and a little bit more full proof. The process now is where a user clicks to download. They have a file on their desktop, which they then have to decompress, install, and then remove from their desktop.
So it's quite a lot of steps. One of the things that we're trying to do with this process is to minimize the number of steps and to get it down as few as possible. We also want to lead the user through the process so that they have quite a lot of success in getting what they want to do done. And then lastly, obviously security is an important feature. We want to try to prevent any viruses from being installed on the user's system or chosen horses. is.
Let's talk about the proposed process for the user. Again, we're trying to minimize the number of steps that they have to go through. Really, it's a three-step process, only two of which the user has to interact with. First thing is to click to download. And then second, we propose bringing up an RU-SURB dialog box so that nothing can be installed automatically on the user system. And then lastly, we'll do an install or copy to the applications folder. So what this means is the user never has to hunt around on their system for the file that was downloaded. They never have to decompress the file. We do that automatically for them. And they never have to clean up their system from unnecessary files. We move that automatically to the trash for them.
So how do we propose that we do this and what tools are we making available to do it? There's a couple things that are possible for bundling your application. The first one is application bundles, and the second is installer packages. Application bundles are recommended that you use them whenever possible. And that's, as many of you know, because you can just drag and drop them into your applications folder. They don't need to be installed. And those can be created with PackageMaker.
Installer packages are sometimes necessary because your app may need to have different files located on a variety of different places on the system. And in addition to installation, they'll display a licensing agreement. They'll let the user decide where to install if you want that to be a possibility. And to create them, you use Apple's installer. I'm not going to go into depth into these two tools because Jean-Pierre after me will do that.
The third tool that you have at your disposal is disk images. And similar to stuff it or zip it files, disk images archive files and compress them. But the difference with disk images in Jaguar is that we'll enable post-download actions. What do I mean by this? Some of the new features that we're implementing for Jaguar are things that will enable this process that I described earlier. So displaying the RUsure dialog box, copying the app packages to an applications folder, launching the installer, opening documents-- and this could be if the thing that the user has downloaded is a document-- or if you need to add more detailed instructions to your installation, you could launch a document at that point. It will also move disk images to the trash.
So some of you may be wondering, how do I create a disk image? Well, if you haven't ever done this before, it's very simple. Use disk copy to do that, which you would find in your Utilities folder. You simply create a blank image. You customize the size and formats of your image so that it's big enough for your particular app. You simply drag your files to that image. Specify any post-download actions that you might want, and that will be in the GUI or in a command line. And then format it as read-only because you don't want the user modifying your disk image.
So that's basically it. It's a very simple process, and we hope both for the user and for you. To recap, the process that we suggest for the user could be down to two steps-- clicking to download and then clicking an Are You Sure dialog box. And we would do all the work behind the scenes-- downloading the file, decompressing it, putting it the right place and removing any unnecessary files.
The only time where a third step might be necessary is if you're doing an installation and the user would go through the regular installation process. So that's disk images. I'm going to take questions later, but at this point, I'm going to bring up Jean-Pierre Ciudad to talk a little bit more about PackageMaker and the installer.
Thank you, Grace. So my name is Jean-Pierre Suidane. I'm going to talk to you today about the MacWest Installer. So as you know, the Mac OS X installer was initially designed to install the operating system. Now with Jaguar, we are trying to address some of the features that we were asked to do for application installs. In Jaguar, we've done a lot of bug fixes. We've added a lot of new features, and we've improved also the main tool used to create packages, which is Package Maker. I'm going to talk to you today about a few of these bug fixes and package maker features. So, bug fixes. The first one is modification dates. I don't know if some of you noticed, but when you install a package on top of Mac OS X using the Apple installer today, the files do not appear right away in the finder window. I wish I could have blamed it on the finder, but unfortunately, this is a installer bug, a bad installer bug, so we fixed that. We now changed the modification date of the enclosing folders that we're touching, causing the finder to basically refresh the window and the files appear right away. We've also added a flag to the package. When the flag is turned on, basically, the installer will only update existing languages that are installed. So, for example, if you've installed an application in German and in French and you're now updating to your new version, you will only update German and French. And you won't end up with 200 languages -- well, not maybe 3, 30, or 13. We're also going to re-enable multiple simultaneous installations. So you will be able to double-click several packages, well, one after the other. And they will open in three separate windows. And they will all install concurrently. If they required some optimization, the optimization will only occur at the end of the third package.
We're also adding a flag to the package that will allow you to tell the installer to follow symlinks. So I know that's something we had a lot of requests for that, so we're doing it for Jaguar. It will be off by default, and the reason for that is because we want to stay compatible with the old packages. We're also adding a new flag in the package that will allow you to specify the admin level of authorization. now, if you say that the package requires authorization for installation, every single user will be asked to authenticate and we will install as root. We're going to add a flag that requires only admin privileges. So for example, if you're installing something in /applications. And what will happen is that when that flag is set, if the user is already an admin user, you won't be asked to authenticate and the installer will just go through.
New features. Oh, too quick. New features. File hinting. File hinting is the ability to specify some special handling instructions for certain files. For example, if you are installing a configuration file and there is already a configuration file existing, you might not want to override it if the user has changed it. That could be a hint. We are going to provide you with a fixed number of hints that you will be able to use.
For example, do not override a modified file. Another hint be, for example, to say that you want to save this configuration file and still replace it with your new file. We're going to have a fixed number of these, and they will be documented, of course. We're also going to provide you with the ability to find the application bundles to upgrade. If the user moved their mail.app somewhere else, you will be able to find it before installing. And when I say you, I mean you, the developer, will be able to provide some instructions on how to find the application. And that will be the application that you will be upgrading. We're also going to allow you to customize the background window of the installer. Right now, it's the picture of a CD-ROM with a big X on it. So we're going going to allow you to change that. And overall, we're improving the package format. The package is now going to be a standard CFBundle. All the information that we store in there will be in plist. So it will be adopting basically Cocoa and Foundation.
it worked. PackageMaker. Just a little correction I noticed in the previous slide. PackageMaker is the tool you use to create installer packages. When you want to put your application into a package, you would use PackageMaker and you wouldn't use the installer. PackageMaker will be used to create new style packages and meta packages. I mentioned to you that we're improving the package format. We definitely encourage you to use this new package format because all new features we're adding on the installer will be available only to new package and meta packages.
PackageMaker will now verify the package validity, so it will double, you will be able to import a package, you will be able to make sure that basically everything is correct. So all the necessary files are there, all the scripts have the executable bit set, and things like that. We are planning to add support for all known flags. I've been talking about three or four flags that we're adding to the package format. All these flags will be documented PackageMaker, you will have online help and you will be able to know what it's about. We're also planning to add support for file hinting, so all the hints that we will be able to implement by the time we ship Jaguar will be documented in PackageMaker. We're also providing a command line tool. This is important if you're having built scripts and you want to directly create your package.
PackageMaker is a work in progress. So as we go, we will improve it. And we will ship it via the developer CD. So it's not something that's going to be shipping only on OS releases. We're planning to improve it. And also, we're planning to implement a lot of your feedback.
In conclusion, drag install is always the best way to install an application in the applications folder. So you should only use installer packages if you are planning to install something somewhere else. We have some future plans, of course. It's difficult for me to talk about it in detail, but we're looking at things like, of course, better tools. We're looking at things like package management. We're looking at removing packages and things like that. And of course, if you have some feedback, please email John Galenzi, which is going to come back to the podium right now. Thank you.
Okay, well, let's just look at the roadmap. Again, if you came in late and you were wondering what in the world screensavers had to do with PackageMaker, the answer is nothing. This session was four different topics. The last two that were related, the first two that were completely unrelated.
you know, in case you're wondering. So here's a bunch of sessions this week that relate to sort of the user experience overall. Some that were this morning. Today we talked about screen savers and system preference panels, how to do that, or panes. You need to know how to write software in Cocoa, and if you don't know how to do that, there's some good Cocoa sessions to go to.
Using Interface Builder, if you've never used that tool, you need to learn how to use that tool before you can create the UI for a system pref pane, So if you have any feedback on this session or any of the content provided here, or if there's something about the APIs that we've talked about today that you would like to see enhanced, or, you know, you need some assistance with any of this stuff, feel free to contact me in developer relations, and I can drive your issues back into engineering and try to get them resolved or addressed, or I can also try to get the answers to any questions that you've got.