iOS WebCore的WebEvent和EventHandler
WebEvent是iOS专有的类,负责封装和携带从UIKit得到的系统事件信息,并由WebKit层的WAKResponder子类传递到WebCore的EventHandler。
UIKit层的逻辑可参考《iOS私有API(三) UIWebView下的手势识别器gestureRecognizer》,WebKit层的相关类可参考《WebCore::Widget浅探》。
开源码中WebEvent的声明为:
typedef enum {
WebEventMouseDown,
WebEventMouseUp,
WebEventMouseMoved,
WebEventScrollWheel,
WebEventKeyDown,
WebEventKeyUp,
WebEventTouchBegin,
WebEventTouchChange,
WebEventTouchEnd,
WebEventTouchCancel
} WebEventType;
typedef enum {
WebEventTouchPhaseBegan,
WebEventTouchPhaseMoved,
WebEventTouchPhaseStationary,
WebEventTouchPhaseEnded,
WebEventTouchPhaseCancelled
} WebEventTouchPhaseType;
// These enum values are copied directly from GSEvent for compatibility.
typedef enum
{
WebEventFlagMaskAlphaShift = 0x00010000,
WebEventFlagMaskShift = 0x00020000,
WebEventFlagMaskControl = 0x00040000,
WebEventFlagMaskAlternate = 0x00080000,
WebEventFlagMaskCommand = 0x00100000,
} WebEventFlagValues;
typedef unsigned WebEventFlags;
// These enum values are copied directly from GSEvent for compatibility.
typedef enum
{
WebEventCharacterSetASCII = 0,
WebEventCharacterSetSymbol = 1,
WebEventCharacterSetDingbats = 2,
WebEventCharacterSetUnicode = 253,
WebEventCharacterSetFunctionKeys = 254,
} WebEventCharacterSet;
@interface WebEvent : NSObject {
@private
WebEventType _type;
CFTimeInterval _timestamp;
CGPoint _locationInWindow;
NSString *_characters;
NSString *_charactersIgnoringModifiers;
WebEventFlags _modifierFlags;
BOOL _keyRepeating;
BOOL _popupVariant;
uint16_t _keyCode;
BOOL _tabKey;
WebEventCharacterSet _characterSet;
float _deltaX;
float _deltaY;
unsigned _touchCount;
NSArray *_touchLocations;
NSArray *_touchIdentifiers;
NSArray *_touchPhases;
BOOL _isGesture;
float _gestureScale;
float _gestureRotation;
}
- (WebEvent *)initWithMouseEventType:(WebEventType)type
timeStamp:(CFTimeInterval)timeStamp
location:(CGPoint)point;
- (WebEvent *)initWithScrollWheelEventWithTimeStamp:(CFTimeInterval)timeStamp
location:(CGPoint)point
deltaX:(float)deltaX
deltaY:(float)deltaY;
- (WebEvent *)initWithTouchEventType:(WebEventType)type
timeStamp:(CFTimeInterval)timeStamp
location:(CGPoint)point
modifiers:(WebEventFlags)modifiers
touchCount:(unsigned)touchCount
touchLocations:(NSArray *)touchLocations
touchIdentifiers:(NSArray *)touchIdentifiers
touchPhases:(NSArray *)touchPhases isGesture:(BOOL)isGesture
gestureScale:(float)gestureScale
gestureRotation:(float)gestureRotation;
- (WebEvent *)initWithKeyEventType:(WebEventType)type
timeStamp:(CFTimeInterval)timeStamp
characters:(NSString *)characters
charactersIgnoringModifiers:(NSString *)charactersIgnoringModifiers
modifiers:(WebEventFlags)modifiers
isRepeating:(BOOL)repeating
isPopupVariant:(BOOL)popupVariant
keyCode:(uint16_t)keyCode
isTabKey:(BOOL)tabKey
characterSet:(WebEventCharacterSet)characterSet;
@property(nonatomic,readonly) WebEventType type;
@property(nonatomic,readonly) CFTimeInterval timestamp;
// Mouse
@property(nonatomic,readonly) CGPoint locationInWindow;
// Keyboard
@property(nonatomic,readonly,retain) NSString *characters;
@property(nonatomic,readonly,retain) NSString *charactersIgnoringModifiers;
@property(nonatomic,readonly) WebEventFlags modifierFlags;
@property(nonatomic,readonly,getter=isKeyRepeating) BOOL keyRepeating;
@property(nonatomic,readonly,getter=isPopupVariant) BOOL popupVariant;
@property(nonatomic,readonly) uint16_t keyCode;
@property(nonatomic,readonly,getter=isTabKey) BOOL tabKey;
@property(nonatomic,readonly) WebEventCharacterSet characterSet;
// Scroll Wheel
@property(nonatomic,readonly) float deltaX;
@property(nonatomic,readonly) float deltaY;
// Touch
@property(nonatomic,readonly) unsigned touchCount;
@property(nonatomic,readonly,retain) NSArray *touchLocations;
@property(nonatomic,readonly,retain) NSArray *touchIdentifiers;
@property(nonatomic,readonly,retain) NSArray *touchPhases;
// Gesture
@property(nonatomic,readonly) BOOL isGesture;
@property(nonatomic,readonly) float gestureScale;
@property(nonatomic,readonly) float gestureRotation;
@end
WebEvent封装了4种事件:鼠标(手指)、键盘、滚轮、触摸,主要通过属性WebEventType type来区分。
鼠标事件主要由单击手势来触发,会产生mouseup,mousemove和mousedown事件。其中单击就是同一RunLoop内连贯的mousedown和mouseup,而mousemove是模拟事件,可触发mouseover消息。
键盘事件发生在编辑框内,按下iOS虚拟键盘的按键就会触发。
滚轮由双指平移手势触发,在输入框内有效。
触摸特指JavaScript监听的touchstart、gesturestart等消息,由UIWebTouchEventsGestureRecognizer来计算。
这些事件触发后,都会在主线程创建WebEvent,然后用GCD技术转到WebThread执行。
开源码的EventHandler.h中有如下几行:
#if PLATFORM(MAC) && defined(__OBJC__)
void mouseDown(WebEvent *);
void mouseUp(WebEvent *);
void mouseMoved(WebEvent *);
bool keyEvent(WebEvent *);
bool wheelEvent(WebEvent *); void touchEvent(WebEvent *); static WebEvent *currentEvent();
#endif
使用xdb也能找到,可是在EventHandler的实现中却找不到,所以 Apple是没有完全公开iOS源码的。
另有一个PlatformEventFactoryIOS.h的文件有如下声明:
class PlatformEventFactory {
public:
static PlatformMouseEvent createPlatformMouseEvent(WebEvent *);
static PlatformWheelEvent createPlatformWheelEvent(WebEvent *);
static PlatformKeyboardEvent createPlatformKeyboardEvent(WebEvent *);
static PlatformTouchEvent createPlatformTouchEvent(WebEvent *);
};
这些函数的作用就是把Objective-C类封装的WebEvent转换成WebCore里C++的PlatformEvent。可以猜测,接受WebEvent型参数的EventHandler函数也就只是简单做这个工作,转换后再直接调用通用的函数就ok了。如:
bool handleMousePressEvent(const PlatformMouseEvent&);
bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(const PlatformWheelEvent&);
void defaultWheelEventHandler(Node*, WheelEvent*); #if ENABLE(GESTURE_EVENTS)
bool handleGestureEvent(const PlatformGestureEvent&);
bool handleGestureTap(const PlatformGestureEvent&, Node* preTargetedNode = 0);
bool handleGestureScrollUpdate(const PlatformGestureEvent&);
#endif
一个堆栈示例:
Thread 4 WebThread, Queue : (null)
#0 0x03385790 in WebCore::EventHandler::mouseMoved(WebCore::PlatformMouseEvent const&) ()
#1 0x0338ae0f in WebCore::EventHandler::mouseMoved(WebEvent*) ()
#2 0x02efd822 in -[WebHTMLView(WebPrivate) mouseMoved:] ()
#3 0x03f6c6ac in -[WAKView _selfHandleEvent:] ()
#4 0x03f6c603 in -[WAKView handleEvent:] ()
#5 0x03f6f94d in -[WAKWindow sendEventSynchronously:] ()
#6 0x03f6f75b in __23-[WAKWindow sendEvent:]_block_invoke ()
#7 0x03f83fe2 in _WebThreadRun ()
#8 0x03f83ee0 in WebThreadRun ()
#9 0x03f6f71c in -[WAKWindow sendEvent:] ()
#10 0x03f6fa0c in __46-[WAKWindow sendMouseMoveEvent:contentChange:]_block_invoke ()
#11 0x03f83fe2 in _WebThreadRun ()
#12 0x03f83ee0 in WebThreadRun ()
#13 0x03f6f9d2 in -[WAKWindow sendMouseMoveEvent:contentChange:] ()
#14 0x0023609d in __64-[UIWebDocumentView(Interaction) _sendMouseMoveAndAttemptClick:]_block_invoke ()
#15 0x03f844ea in HandleRunSource ()
#16 0x0226e33f in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#17 0x0226dd95 in __CFRunLoopDoSources0 ()
#18 0x0228b124 in __CFRunLoopRun ()
#19 0x0228a59f in CFRunLoopRunSpecific ()
#20 0x0228a3eb in CFRunLoopRunInMode ()
#21 0x03f83c30 in RunWebThread(void*) ()
#22 0x05a5c65c in _pthread_body ()
#23 0x05a5c4e6 in _pthread_start ()
其它的Event都差不多,不再赘述了。
iOS WebCore的WebEvent和EventHandler的更多相关文章
- Android webkit 事件传递流程详解
前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...
- Android webkit 事件传递流程通道分析
前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...
- Android webkit keyevent 事件传递过程
前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...
- iOS js 使用与JSContext
JSContext:js执行环境,包含了js执行时所需要的所有函数和对象: js执行时,会在执行环境搜索需要的函数然后执行,或者保存传入的变量或函数: JSContext *jsContext = [ ...
- Summary of Critical and Exploitable iOS Vulnerabilities in 2016
Summary of Critical and Exploitable iOS Vulnerabilities in 2016 Author:Min (Spark) Zheng, Cererdlong ...
- 黑云压城城欲摧 - 2016年iOS公开可利用漏洞总结
黑云压城城欲摧 - 2016年iOS公开可利用漏洞总结 作者:蒸米,耀刺,黑雪 @ Team OverSky 0x00 序 iOS的安全性远比大家的想象中脆弱,除了没有公开的漏洞以外,还有很多已经公开 ...
- iOS 开源项目
在 Github 上 Star 太多了,有时候很难找到自己想要的开源库,所以在此记录下来.便于自己开发使用,也顺便分享给大家. 动画 awesome-ios-animation收集了iOS平台下比较主 ...
- iOS 架构模式--解密 MVC,MVP,MVVM以及VIPER架构
本文由CocoaChina译者lynulzy(社区ID)翻译 作者:Bohdan Orlov 原文:iOS Architecture Patterns 在 iOS 中使用 MVC 架构感觉很奇怪? 迁 ...
- 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native
[源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...
随机推荐
- HDU1029时钟(排序)
题意:是用两个指针的一个模拟时钟的时针和分针.两个指针形成一个角度.角度测量两个指针之间的最小角度.两只手之间的角度是大于或等于0,且小于或等于180度的度量.由于一个序列的五个不同的写入时间,格式为 ...
- cocos2d基础入门
HelloCpp中Classes目录下放开发者自己的类: win32:平台相关,coco2d已默认创建:coco2d-x目录下,samples/cpp/HelloCpp/(工程根目录)图片放置位置:根 ...
- codeforces 569A Music
codeforces 569A Music 解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88890#pro ...
- STL之map和multimap(关联容器)
map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.自动建立Key - value的对应,对于迭代器来说,可以修改实值,而不能修改key. ...
- BZOJ 1620: [Usaco2008 Nov]Time Management 时间管理( 二分答案 )
二分一下答案就好了... --------------------------------------------------------------------------------------- ...
- [Git]自译《Git版本控制管理》——1.介绍(二)_Git诞生
译者前言: 本系列译文为作者利用业余时间翻译,有些疏漏与翻译不到位的地方敬请谅解. 不过也很希望各位读者能给出中肯的建议. 方括号的注释,如[1][2]为译者注. ...
- Spring注解配置
配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...
- Windows Phone 8初学者开发—第2部分:安装Windows Phone SDK 8.0
原文 Windows Phone 8初学者开发—第2部分:安装Windows Phone SDK 8.0 原文地址:http://channel9.msdn.com/Series/Windows-Ph ...
- spring mvc实现ajax 分页
使用到的技术: ·spring 3 mvc ·json ·jquery ·java ·mysql 首先,要了解如何在spring mvc中使用json. 以下主要从Dao和View及Controlle ...
- MyEclipse2014不支持jre1.8吗
myeclipse 2015才支持了java 8 也可以用Eclipse Kepler加插件的形式来支持java 8