NSRunLoop
object, enables a process to receive input from various sources. By default, every thread in OS X has its own run loop, and the run loop of the main thread of a Cocoa application is called the main event loop. What especially distinguishes the main event loop is an input source called the event source, which is constructed when the globalNSApplication
object (NSApp
) is initialized. The event source consists of a port for receiving events from the window server and a FIFO queue—the event queue—for holding those events until the application can process them, as shown in Figure 1-2.NSEvent
objects. Instead an Apple event is handled directly by an event handler. When an application launches, it automatically registers several event handlers for this purpose. For more on Apple events and event handlers, see Apple Events Programming Guide.NSApp
) continuously gets the next (topmost) event in the event queue, converts it to an NSEvent
object, and dispatches it toward its final destination. It performs this fetching of events by invoking the nextEventMatchingMask:untilDate:inMode:dequeue:
method in a closed loop. When there are no events in the event queue, this method blocks, resuming only when there are more events to process. NSApp
performs the first stage of event dispatching in the sendEvent:
method. In most cases NSApp
merely forwards the event to the window in which the user action occurred by invoking the sendEvent:
method of that NSWindow
object. The window object then dispatches most events to the NSView
object associated with the user action in an NSResponder
message such as mouseDown:
or keyDown:
. An event message includes as its sole argument an NSEvent
object describing the event. NSWindow
object dispatches the event to the view over which the user pressed the mouse or stylus button. It dispatches most key events to the first responder of the key window. Figure 1-3 and Figure 1-4 illustrate these different general delivery paths. The destination view may decide not to handle the event, instead passing it up the responder chain (see The Responder Chain).NSAppKitDefined
), have to do with actions controlled by a window or the application object itself. Examples of these events are those related to activating, deactivating, hiding, and showing the application. NSApp
filters out these events early in its dispatch routine and handles them itself. NSWindow
object in its sendEvent:
A late night drive mac os. method forwards mouse events to the view over which the user action involving the mouse occurred. It identifies the view to receive the event by invoking the NSView
method hitTest:
, which returns the lowest descendant that contains the cursor location of the event (this is usually the topmost view displayed). The window object forwards the mouse event to this view by sending it a mouse-related NSResponder
message specific to its exact type, such as mouseDown:
, mouseDragged:
, or rightMouseUp:
, On (left) mouse-down events, the window object also asks the receiving view whether it is willing to become first responder for subsequent key events and action messages. NSEventType
constants and NSResponder
methods—by mouse button (left, right, or other) and direction of click (up or down). Mouse-dragged and mouse-up events are typically sent to the same view that received the most recent mouse-down event. Mouse-moved events are sent to the first responder. Mouse-down, mouse-dragged, mouse-up, and mouse-moved events can occur only in certain situations relative to other mouse events: acceptsFirstMouse:
method of NSView
to return YES
.NSWindow
method setAcceptsMouseMovedEvents:
. Tracking rectangles, described in Other Event Dispatching, are a less expensive way of following the mouse’s location.NSResponder
mouse-event method, a subclass of NSView
can interpret a mouse event as a cue to perform a certain action, such as sending a target-action message, selecting a graphic element, redrawing itself at a different location, and so on. Each event method includes as its sole parameter an NSEvent
object from which the view can obtain information about the event. For example, the view can use the locationInWindow
to locate the mouse cursor’s hot spot in the coordinate system of the receiver’s window. To convert it to the view’s coordinate system, use convertPoint:fromView:
with a nil
view argument. From here, you can use mouse:inRect:
to determine whether the click occurred in an interesting area.NSWindow
object representing the window in which the tablet event occurred forwards the event to the view under the cursor. However, there are two kinds of tablet events, proximity events and pointer events. The former are generally native tablet events (of type NSTabletProximity
) generated when the stylus moves into and out of proximity to the tablet. Tablet pointer events occur between proximity-entering and proximity-leaving tablet events and indicate such things as stylus direction, pressure, and button click. Pointer events are generally subtypes of mouse events. Refer to Handling Tablet Events for more information.NSEvent
objects and the order and way these types of events are handled.performKeyEquivalent:
message until an object returns YES
. If the message isn’t handled by an object in the view hierarchy, NSApp
then sends it to the menus in the menu bar. Some Cocoa classes, such as NSButton
, NSMenu
, NSMatrix
, and NSSavePanel
provide default implementations.NSWindow
interprets certain keys as commands to move control to a different interface object, to simulate a mouse click on it, and so on. For example, pressing the Tab key moves input focus to the next object; Shift-Tab reverses the direction; pressing the space bar simulates a click on a button. The order of interface objects controlled through this mechanism is specified by a key view loop. You can set up the key view loop in Interface Builder and you can manipulate the key view loop programmatically through the setNextKeyView:
and nextKeyView
methods of NSView
.NSResponder
class) that are per-view functional interpretations of physical keystrokes (as identified by the constant returned by the characters
method of NSEvent
). In other words, keyboard actions are bound to physical keys through the key bindings mechanism described in Text System Defaults and Key Bindings. For example, pageDown:
, moveToBeginningOfLine:
, and capitalizeWord:
are methods invoked by keyboard actions when the bound key is pressed. Such actions are sent to the first responder, and the methods handling these actions can be implemented in that view or in a superview further up the responder chain. sendEvent:
message. The window object invokes the keyDown:
method in the first responder, from whence the key event travels up the responder chain until it is handled. At this point, the key event can be either one or more Unicode character to be inserted into a view’s displayed text , a key or key combination to be specially interpreted, or a keyboard-action event.NSWindow
object monitors tracking-rectangle events and dispatches these events directly to the owning object in mouseEntered:
and mouseExited:
messages. The owner is specified in the second parameter of the NSTrackingArea
method initWithRect:options:owner:userInfo:
and the NSView
methodaddTrackingRect:owner:userData:assumeInside:
. Using Tracking-Area Objects describes how to set up tracking rectangles and handle the related events. NSPeriodic
) are generated by the application at a specified frequency and placed in the event queue. However, unlike most other types of events, periodic events aren’t dispatched using the sendEvent:
mechanism of NSApplication
and NSWindow
. Instead the object registering for the periodic events typically retrieves them in a modal event loop using the nextEventMatchingMask:untilDate:inMode:dequeue:
method. See Other Types of Events for more information about periodic events.mouseDown:
and keyDown:
—to an NSResponder
object for handling. NSResponder
objects are also expected to handle another kind of message: action messages. Actions are commands that objects, usually NSControl
or NSMenu
objects, give to the application object to dispatch as messages to a particular target or to any target that’s willing to respond to them. The methods invoked by action messages have a specific signature: a single parameter holding a reference to the object initiating the action message; by convention, the name of this parameter is sender. For example, sendEvent:
method of NSApplication
. Action messages, on the other hand, are dispatched by the sendAction:to:from:
method of the global application object (NSApp
) to their proper destinations. mouseDown:
and mouseUp:
) are sent as a result. The control and its associated cell handle the mouseUp:
message (in part) by sending the application object a sendAction:to:from:
message. The first argument is the selector identifying the action method to invoke. The second is the intended recipient of the message, called the target, which can be nil
. The final argument is usually the object invoking sendAction:to:from:
, thus indicating which object initiated the action message. The target of an action message can send messages back to sender to get further information. A similar sequence occurs for menus and menu items. For more on the architecture of controls and cells (and menus and menu items) see The Core App Design in Mac App Programming Guide.nil
, the action is simply sent directly to that object; this is called a targeted action message. In the case of an untargeted action message (that is, the target parameter is nil
), sendAction:to:from:
searches up the full responder chain (starting with the first responder) for an object that implements the action method specified. If it finds one, it sends the message to that object with the initiator of the action message as the sole argument. The receiver of the action message can then query the sender for additional information. You can find the recipient of an untargeted action message without actually sending the message using targetForAction:
. NSResponder
provides declarations and default implementations for all of them. Most action messages, however, are defined by custom classes and can’t be predicted. However, NSResponder
does declare a number of keyboard action methods, such as pageDown:
, moveToBeginningOfDocument:
, and cancelOperation:
. These action methods are typically bound to specific keys using the key-bindings mechanism and are meant to perform cursor movement, text operations, and similar operations.NSResponder
method tryToPerform:with:
. This method checks the receiver to see if it responds to the selector provided, if so invoking the message. If not, it sends tryToPerform:with:
to its next responder. NSWindow
and NSApplication
override this method to include their delegates, but they don’t link individual responder chains in the way that the sendAction:to:from:
method does. Similar to tryToPerform:with:
is doCommandBySelector:
, which takes a method selector and tries to find a responder that implements it. If none is found, the method causes the hardware to beep.NSResponder
declares a number of action messages, it doesn’t actually implement them. You should never send an action message directly to a responder object of an unknown class. Always use the NSApplication
method sendAction:to:from:
, the NSResponder
methods tryToPerform:with:
or doCommandBySelector:
, or check that the target responds using the NSObject
method respondsToSelector:
.NSResponder
class. NSApplication
, NSWindow
, NSDrawer
, NSWindowController
, NSView
and the many descendants of these classes in the Application Kit inherit from NSResponder
. This class defines the programmatic interface for the reception of event messages and many action messages. It also defines the general structure of responder behavior. Within the responder chain there is a first responder and a sequence of next respondersNSWindow
object’s first responder is initially itself; however, you can set, programmatically and in Interface Builder, the object that is made first responder when the window is first placed on-screen. NSWindow
object receives a mouse-down event, it automatically tries to make the NSView
object under the event the first responder. It does so by asking the view whether it wants to become first responder, using the acceptsFirstResponder
method defined by this class. This method returns NO
by default; responder subclasses that need to be first responder must override it to return YES
. The acceptsFirstResponder
method is also invoked when the user changes the first responder through the keyboard interface control feature.makeFirstResponder:
to an NSWindow
object. This message initiates a kind of protocol in which one object loses its first responder status and another gains it. See Setting the First Responder for further information.NSPanel
object presents a variation of first-responder behavior that permits panels to present a user interface that doesn’t take away key focus from the main window. If the panel object representing an inactive window and returning YES
from becomesKeyOnlyIfNeeded
receives a mouse-down event, it attempts to make the view object under the mouse pointer the first responder, but only if that object returns YES
in acceptsFirstResponder
and needsPanelToBecomeKey
.NSMouseMoved
) are always sent to the first responder, not to the view under the mouse.nextResponder
method, which returns this object, is the essential mechanism of the responder chain. Figure 1-7 shows the sequence of next responders.addSubview:
method of NSView
automatically sets the receiver as the new subview’s superview. If you interpose a different responder between views, be sure to verify and potentially fix the responder chain after adding or removing views from the view hierarchy.NSResponder
method setNextResponder:
and you can examine it (or traverse it) with nextResponder
.NSWindow
object first delivers the message to. The default responder chain for a key event message begins with the first responder in a window; the default responder chain for a mouse or tablet event begins with the view on which the user event occurred. From there the event, if not handled, proceeds up the view hierarchy to the NSWindow
object representing the window itself. The first responder is typically the “selected” view object within the window, and its next responder is its containing view (also called its superview), and so on up to the NSWindow
object. If an NSWindowController
object is managing the window, it becomes the final next responder. You can insert other responders between NSView
objects and even above the NSWindow
object near the top of the chain. These inserted responders receive both event and action messages. If no object is found to handle the event, the last responder in the chain invokes noResponderFor:
, which for a key-down event simply beeps. Event-handling objects (subclasses of NSWindow
and NSView
) can override this method to perform additional steps as needed. NSWindowController
objects for its windowsNSResponder
)NSApp
NSResponder
)NSWindow
object and the NSApplication
object give their delegates a chance to handle action messages as though they were responders, even though a delegate isn’t formally in the responder chain (that is, a nextResponder
message to a window or application object doesn’t return the delegate). NSResponder
)NSResponder
)NSApp
NSResponder
)NSWindowController
object for window management. In the latter case, the default main-window responder chain consists of the following responders and delegates:NSWindowController
object (which inherits from NSResponder
)NSApp
NSWindowController
object (which inherits from NSResponder
)NSDocument
object (if different from the main window’s delegate)NSApp
NSDocumentController
object, which does not inherit from NSResponder
)nil
target, an NSMenu
searches different responder chains depending on whether the menu object represents the application menu or a context menu. For the application menu, NSMenu
consults the full responder chain—that is, first key, then main window—to find an object that implements the menu item’s action method and (if it implements it) returns YES
from validateMenuItem:
. For a context menu, the search is restricted to the responder chain of the window in which the context menu was displayed, starting with the associated view. validateToolbarItem:
.validRequestorForSendType:returnType:
messages along the full responder chain to check for objects that are eligible for services offered by other applications.NSResponder
methods presentError:modalForWindow:delegate:didPresentSelector:contextInfo:
and presentError:
.