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’s returned by the windowNumber
method. Each window also has a graphics state that most NSView
objects share for drawing (views can create their own as well). The gState
method returns its identifier. The attributes under direct window control are:
Backing store type, described in “Setting How To Store the Window’s Image”
Backing location, described in “Specifying Where To Store the Window’s Image”
Window device creation, described in “Setting When the Window’s Image is Created”
One shot, described in “Setting Whether the Window’s Image Persists When Off-Screen”
Depth limit, described in “Setting the Depth Limit for the Window’s Image”
Dynamic depth limit, described in “Setting Whether the Depth Limit Changes to the Screen’s Capacity”
Content sharing, described in “Specifying Whether Window Content Can Be Read or Written by Another Process.”
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.
The Window Server chooses where to place the backing store for a buffered window, either in main memory or stored directly in 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 backingLocation:
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.
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.
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.
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.
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.
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. However your window will also not be able to participate in a number of system services, so this setting should be used with caution. If you set your window sharing type to NSWindowSharingReadWrite
, other processes can both read and modify the window’s content.
© 2002, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-02-04)