How an Event Enters a Cocoa Application

An event is a low-level record of a user action that is usually routed to the application in which the action occurred. A typical event in OS X originates when the user manipulates an input device attached to a computer system, such as a keyboard, mouse, or tablet stylus. When the user presses a key or clicks a button or moves a stylus, the device detects the action and initiates a transfer of data to the device driver associated with it. Through the I/O Kit, the device driver creates a low-level event, puts it in the window server's event queue, and notifies the window server. The window server dispatches the event to the appropriate run-loop port of the target process. From there the event is forwarded to the event-handling mechanism appropriate to the application environment. Figure 1-1 depicts this event-delivery system.

Figure 1-1  The event stream

Note: Applications normally receive events from the keyboard and mouse only when they are in the foreground (that is, active). Although applications running in the background do not normally receive key and mouse events, low-level mechanisms called event taps make it possible for a background application to receive events and act upon them.

Before it dispatches an event to an application, the window server processes it in various ways; it time-stamps it, annotates it with the associated window and process port, and possibly performs other tasks as well. As an example, consider what happens when a user presses a key. The device driver translates the raw scan code into a virtual key code which it then passes off (along with other information about the key-press) to the window server in an event record. The window server has a translation facility that converts the virtual key code into a Unicode character.

In OS X, events are delivered as an asynchronous stream. This event stream proceeds “upward” (in an architectural sense) through the various levels of the system—the hardware to the window server to the Event Manager—until each event reaches its final destination: an application. As it passes through each subsystem, an event may change structure but it still identifies a specific user action.

Note: Lower levels of the system trap and handle some events early in the event stream. These events are never routed to a Cocoa application. These events are generated by reserved keys or key combinations, such as the power and media-eject keys.

Every application has a mechanism specific to its environment for receiving events from the window server. For a Cocoa application, that mechanism is called the main event loop. A run loop, which in Cocoa is an 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 global NSApplication 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.

Figure 1-2  The main event loop, with event source

A Cocoa application is event driven: It fetches an event from the queue, dispatches it to an appropriate object, and, after the event is handled, fetches the next event. With some exceptions (such as modal event loops) an application continues in this pattern until the user quits it. The following section, Event Dispatch, describes how an application fetches and dispatches events.

Events delivered via the event source are not the only kinds of events that enter Cocoa applications. An application can also respond to Apple events, high-level interprocess events typically sent by other processes such as the Finder and Launch Services. For example, when users double-click an application icon to open the application or double-click a document to open the document, an Apple event is sent to the target application. An application also fetches Apple events from the queue but it does not convert them into 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.

Event Dispatch

In the main event loop, the application object (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.

After fetching and converting an event, 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.

The object receiving an event message differs slightly by type of event. For mouse and tablet events, the 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-4illustrate 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).

Figure 1-3  Path of a mouse eventFigure 1-4  Path of a key event (character to insert)

In the preceding paragraph you might have noticed the use of qualifiers such as “in most cases” and “usually.“ The delivery of an event (and especially a key event) in Cocoa can take many different paths depending on the particular kind of event. Some events, many of which are defined by the Application Kit (type 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.

The following sections describe the different paths of the events that can reach your view objects. For detailed information on these event types, read Event Objects and Types.

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html

How an Event Enters a Cocoa Application的更多相关文章

  1. 深入浅出 Cocoa 之 Core Data(3)- 使用绑定

    深入浅出 Cocoa 之 Core Data(3)- 使用绑定 罗朝辉(http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 前面讲解了 Core Data 的框架, ...

  2. Main event loop

    https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/MainE ...

  3. Cocoa深入学习:NSOperationQueue、NSRunLoop和线程安全 (转)

    目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD .其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实 ...

  4. Event List 2

    The list of events can be found in src/switch_event.c in a char array called EVENT_NAMES and is summ ...

  5. Event List

    Created by John Boteler on 2015.01.16 Go to start of metadata   About The current up-to-date list of ...

  6. [BTS] Faulting application name: BTSNTSvc.exe, version: 3.9.469.0, time stamp: 0x4c547e09

    Log Name: ApplicationSource: Application ErrorDate: 8/22/2013 1:28:35 AMEvent ID: 1000Task Category: ...

  7. 《苹果开发之Cocoa编程》挑战1 创建委托 练习

    <苹果开发之Cocoa编程>第4版 P87 新建一个单窗口应用程序,设置某对象为窗口的委托,当用户调整窗口尺寸时,确保窗口高度为宽度的2倍. 需要实现的委托方法为:-(NSSize)win ...

  8. Cocoa深入学习:NSOperationQueue、NSRunLoop和线程安全

    http://blog.cnbluebox.com/blog/2014/07/01/cocoashen-ru-xue-xi-nsoperationqueuehe-nsoperationyuan-li- ...

  9. Cocoa包管理器之Carthage详解及CocoaPods中心化+Carthage的二进制化

    上篇博客详细的聊了CocoaPods的相关内容,今天我们就来介绍另一个Cocoa的包管理器Carthage.在上家公司用Swift开发工程时,用的就是Carthage.Carthage诞生于14年11 ...

随机推荐

  1. 团体程序设计天梯赛-练习集-L1-024. 后天

    L1-024. 后天 如果今天是星期三,后天就是星期五:如果今天是星期六,后天就是星期一.我们用数字1到7对应星期一到星期日.给定某一天,请你输出那天的“后天”是星期几. 输入格式: 输入第一行给出一 ...

  2. MySQL 表与表之间建立关系

    引子:如下图是一张非常寻常的表格,在以前的工作中实常会制作类似的表格,但是今天的数据库内容,将我之前这种传统的制表思路上升了一个层次: 今天核心的内容就是怎样让表与表之间产生关系,在思考这个问题的时候 ...

  3. SyntaxError Non-ASCII character '\xe5' in file

    环境: windows7 Python 2.7.16 在源码中添加注释之后报错如下: (WeChat) E:\WorkHome\Wechat>python firstBlood.py Trace ...

  4. C语言提高 (4) 第四天 数组与数组作为参数时的数组指针

    1昨日回顾 const int 和 int const是一样的 const char *p;值不变 char * const p; 指针不能变 编译器对参数的退化: 第三种模型: 三级指针 三级指针局 ...

  5. mDNS 原理的简单理解

    转自:http://www.binkery.com/post/318.html mDNS 原理的简单理解 mDNS multicast DNS , 使用5353端口. 在局域网内,你要通过一台主机和其 ...

  6. iview datepicker 选择的时间少一天

    使用iview的datepicker时间选择器发现获取的value值是比实际要少一天,严格来说应该是时间格式不一样,datepicker获取的时间是UTC时间格式,也就是:yyyy-MM-ddTHH: ...

  7. P1422 小玉家的电费

    ... 题目描述 夏天到了,各家各户的用电量都增加了许多,相应的电费也交的更多了.小玉家今天收到了一份电费通知单.小玉看到上面写:据闽价电[2006]27号规定,月用电量在150千瓦时及以下部分按每千 ...

  8. Zend 官方框架增加 Swoole 协程支持 !

    前言 Zend Framework 是 PHP 的官方框架,随着 Zend-Expressive-Swoole 0.2.2 的发布,率先支持了 Swoole 4 的协程功能,现在可以仅通过一个配置即可 ...

  9. 如何指定GCC的默认头文件路径

    如何指定GCC的默认头文件路径 网上偶搜得之,以之为宝:)原地址:http://blog.chinaunix.net/u/28781/showart.php?id=401631============ ...

  10. 深入了解Spring中的容器

    1.创建Bean的3种方式 1.1使用构造器创建bean实例 这是最常见的方式,如果不采用构造注入,bean类需要有默认构造函数.如果采用构造注入,则需要配置xml文件的<constructor ...