Setting Attributes for the Window’s Image

Nearly every window has a corresponding display window device in the window server. The window device holds the window’s drawn image, and has two attributes determined by the window server and many attributes that the window controls. The window server assigns the window device a unique identifier (within an application). This is the window number, and it can be accessed using the windowNumber method. Each window also has a graphics state that most of its views share for drawing (views can create their own as well). The gState method returns its identifier. The attributes under direct window control are the following:

Specifying How To Store the Window’s Image

A window device’s backing store type determines how the window’s image is stored. It’s set when the window is initialized and can be one of three types.

A buffered window device renders all drawing into a display buffer and then flushes it to the screen. Always drawing to the buffer produces very smooth display, but can require significant amounts of memory. Buffered windows are best for displaying material that must be redrawn often, such as text. You must also use buffered windows if you want your windows to support transparency.

A retained window device also uses a buffer, but draws directly to the screen where possible and to the buffer for any portions that are obscured.

A nonretained window device has no buffer at all, and must redraw portions as they’re exposed. Further, this redrawing is suspended when the window’s display mechanism is preempted. For example, if the user drags a window across a nonretained window, the nonretained window is “erased” and isn’t redrawn until the user releases the mouse.

Both retained and nonretained windows are also subject to a flashing effect as individual drawing operations are performed, but their results do get to the screen more quickly than those of buffered windows.

You can change the backing store type between buffered and retained after initialization using the setBackingType: method.

Specifying Where To Store the Window’s Image

The window server chooses whether to place the backing store for a buffered window in main memory or video memory. It will choose the location that provides the best overall performance. You can query the window server to determine where your window’s backing store is located using the preferredBackingLocation method.

You may choose to set a preferred location for a Window’s backing store using the setPreferredBackingLocation: method. While the window server is not required to respect this preferred backing location, it will attempt to do so. You should not change the preferred backing location without testing how it affects the performance of your application.

Specifying When the Window’s Image Is Created

The defer argument to the initializer specifies whether the window creates its window device immediately or only when it’s moved on screen. Deferring creation of the window device can offer some performance gain for windows that aren’t displayed immediately because it reduces the amount of work that needs to be performed up front. Deferring creation of the window device is particularly useful when creation of the window itself can’t be deferred or when an window is needed for purposes other than displaying content. Submenus with key equivalents, for example, must exist for the key equivalents to work, but may never actually be displayed.

Specifying Whether the Window’s Image Persists When Offscreen

Memory can also be saved by destroying the window device when the window is removed from the screen. The setOneShot: method controls this behavior. One-shot window devices exist only when their windows are onscreen.

Specifying the Depth Limit for the Window’s Image

Like the display hardware, a window device’s buffer has a depth, or a limit to the memory allotted each pixel. Buffered and retained windows start out with the same depth as the main display or 16 bits, whichever is deeper. These settings stay in effect unless changed using the setDepthLimit: method, which takes as an argument a window depth limit created using the NSBestDepth function.

Specifying Whether the Depth Limit Changes to the Screen’s Capacity

Keeping a window’s depth at its richest preserves the displayed image, but may incur unnecessary memory overhead when the window buffer depth is deeper than the screen depth. You can use the setDynamicDepthLimit: method to tell a window to match the depth of the screen it’s on. When it’s moved to a new screen, a window with a dynamic depth limit adjusts its buffer to the new depth before redrawing. Making a window’s depth limit dynamic overrides the limit set using setDepthLimit:, and removing the dynamic limit reverts the window to the default limit.

Specifying Whether Window Content Can Be Read or Written by Another Process

The contents of your window can be made available to other processes. By default, the contents of your window can be read but not written to by other processes. This allows system services to work with your window’s contents and also allows other applications to capture a snapshot of your windows contents.

You can override the default behavior using the setSharingType: method. Changing the sharing type to NSWindowSharingNone prevents other systems from capturing your window’s image data. If you do this, however, your window will not be able to participate in a number of system services; therefore, this setting should be used with caution. If you set your window’s sharing type to NSWindowSharingReadWrite, other processes can both read and modify the window’s content.