How an Event Enters a Cocoa Application
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 event
Figure 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的更多相关文章
- 深入浅出 Cocoa 之 Core Data(3)- 使用绑定
深入浅出 Cocoa 之 Core Data(3)- 使用绑定 罗朝辉(http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 前面讲解了 Core Data 的框架, ...
- Main event loop
https://developer.apple.com/library/archive/documentation/General/Conceptual/Devpedia-CocoaApp/MainE ...
- Cocoa深入学习:NSOperationQueue、NSRunLoop和线程安全 (转)
目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD .其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实 ...
- 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 ...
- Event List
Created by John Boteler on 2015.01.16 Go to start of metadata About The current up-to-date list of ...
- [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: ...
- 《苹果开发之Cocoa编程》挑战1 创建委托 练习
<苹果开发之Cocoa编程>第4版 P87 新建一个单窗口应用程序,设置某对象为窗口的委托,当用户调整窗口尺寸时,确保窗口高度为宽度的2倍. 需要实现的委托方法为:-(NSSize)win ...
- Cocoa深入学习:NSOperationQueue、NSRunLoop和线程安全
http://blog.cnbluebox.com/blog/2014/07/01/cocoashen-ru-xue-xi-nsoperationqueuehe-nsoperationyuan-li- ...
- Cocoa包管理器之Carthage详解及CocoaPods中心化+Carthage的二进制化
上篇博客详细的聊了CocoaPods的相关内容,今天我们就来介绍另一个Cocoa的包管理器Carthage.在上家公司用Swift开发工程时,用的就是Carthage.Carthage诞生于14年11 ...
随机推荐
- scrapy 动态网页处理——爬取鼠绘海贼王最新漫画
简介 scrapy是基于python的爬虫框架,易于学习与使用.本篇文章主要介绍如何使用scrapy爬取鼠绘漫画网海贼王最新一集的漫画. 源码参见:https://github.com/liudaol ...
- 面试题1-----SVM和LR的异同
1.异(加下划线是工程上的不同) (1)两者损失函数不一样 (2)LR无约束.SVM有约束 (3)SVM仅考虑支持向量. (4)LR的可解释性更强,SVM先投影到更高维分类再投影到低维空间. (5)S ...
- sql修改字段值
update dfw_USER_ACCOUNTS set USER_INTEGRAL="20" where USER_INTEGRAL="17"
- [JSOI2018]战争(闵可夫斯基和)
害怕,可怜几何题 果然不会 题目就是说给你两个凸包,每次询问给你一个向量 \(c\) 问你能不能从两个凸包 \(A\) , \(B\) 里分别找到一个点 \(a\) , \(b\) 满足 \(a+c= ...
- vue项目使用简略总结
1.利用iView Cli搭建项目结构2.搭建完毕之后将proxy.js和'Server.js'放置到node_modules\webpack-dev-server\lib目录下,以实现跨域访问公司平 ...
- join()与os.path.join()的用法
join:连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 os.path.join(): 将多个路径组合后返回 一.函数说明 1.join()函数 语法:‘ ...
- js区分ie不同版本
方法1 js中 if(window.ActiveXObject)//判断浏览器是否属于IE { var browser=navigator.appName var b_version=navigat ...
- System v shm的key
shmget函数用于创建或打开一个共享内存区对象,shmget成功调用会返回一个共享内存区的标识符,供其它的共享内存区操作函数使用. key:用于创建共享内存区的键值,这个在前面其他System IP ...
- POJ 2111
记忆化搜索即可,设DP[I][J]为可到达的最大步数. 输出时用了一种较笨拙的方法,还有一种方法是使用最长上升子序列的方式,挺好,先排序,这让我想起上次BESTCODER的一题 #include &l ...
- HDU 5045 DP+状压
2014 ACM/ICPC Asia Regional Shanghai Online 给出N个人做M道题的正确率,每道题仅仅能由一个人做出,而且当全部人都做出来且仅做出一道题时,做过题的人才干够继续 ...