{"action":"created","comment":{"url":"https://api.github.com/repos/cappuccino/cappuccino/pulls/comments/47981314","id":47981314,"diff_hunk":"@@ -3844,6 +3819,393 @@ var interpolate = function(fromValue, toValue, progress)\n \n @end\n \n+@implementation CPWindow (TrackingAreaAdditions)\n+\n+- (void)_addTrackingAreaView:(CPView)aView\n+{\n+    var trackingAreas = [aView trackingAreas];\n+    \n+    for (var i = 0; i < trackingAreas.length; i++)\n+        [self _addTrackingArea:trackingAreas[i]];\n+}\n+\n+- (void)_removeTrackingAreaView:(CPView)aView\n+{\n+    var trackingAreas = [aView trackingAreas];\n+    \n+    for (var i = 0; i < trackingAreas.length; i++)\n+        [self _removeTrackingArea:trackingAreas[i]];\n+}\n+\n+- (void)_addTrackingArea:(CPTrackingArea)trackingArea\n+{\n+    var trackingAreaView = [trackingArea view];\n+    \n+    if (![_trackingAreaViews containsObject:trackingAreaView])\n+        [_trackingAreaViews addObject:trackingAreaView];\n+    \n+    // If CPTrackingAssumeInside option is set, put the tracking area in the _mouseEnteredStack\n+    \n+    if ([trackingArea options] & CPTrackingAssumeInside)\n+        [_mouseEnteredStack addObject:trackingArea];\n+}\n+\n+- (void)_removeTrackingArea:(CPTrackingArea)trackingArea\n+{\n+    // If mouse is in the tracking area, we remove it from the stack to avoid to fire a future mouseExited event\n+    \n+    [_mouseEnteredStack removeObjectIdenticalTo:trackingArea];\n+    \n+    var trackingAreaView = [trackingArea view];\n+    \n+    [_trackingAreaViews removeObjectIdenticalTo:trackingAreaView];\n+}\n+\n+- (void)_handleTrackingAreaEvent:(CPEvent)anEvent","path":"AppKit/CPWindow/CPWindow.j","position":176,"original_position":176,"commit_id":"8f15266f0a5111fb07b31fd9f329863a1138b8a7","original_commit_id":"8f15266f0a5111fb07b31fd9f329863a1138b8a7","user":{"login":"aparajita","id":22218,"avatar_url":"https://avatars.githubusercontent.com/u/22218?v=3","gravatar_id":"","url":"https://api.github.com/users/aparajita","html_url":"https://github.com/aparajita","followers_url":"https://api.github.com/users/aparajita/followers","following_url":"https://api.github.com/users/aparajita/following{/other_user}","gists_url":"https://api.github.com/users/aparajita/gists{/gist_id}","starred_url":"https://api.github.com/users/aparajita/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aparajita/subscriptions","organizations_url":"https://api.github.com/users/aparajita/orgs","repos_url":"https://api.github.com/users/aparajita/repos","events_url":"https://api.github.com/users/aparajita/events{/privacy}","received_events_url":"https://api.github.com/users/aparajita/received_events","type":"User","site_admin":false},"body":"I'm looking at this method and it needs to be factored, it's way too big. I'd like to split it up into at least 3 methods: \r\n\r\n- `for (var i = 0; i < _trackingAreaViews.length; i++)`\r\n- `for (var i = 0; i < _mouseEnteredStack.length; i++)`\r\n- Code within `if (nbCursorUpdates > 0)`","created_at":"2015-12-18T00:28:29Z","updated_at":"2015-12-18T00:28:29Z","html_url":"https://github.com/cappuccino/cappuccino/pull/2395#discussion_r47981314","pull_request_url":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395","_links":{"self":{"href":"https://api.github.com/repos/cappuccino/cappuccino/pulls/comments/47981314"},"html":{"href":"https://github.com/cappuccino/cappuccino/pull/2395#discussion_r47981314"},"pull_request":{"href":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395"}}},"pull_request":{"url":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395","id":49954847,"html_url":"https://github.com/cappuccino/cappuccino/pull/2395","diff_url":"https://github.com/cappuccino/cappuccino/pull/2395.diff","patch_url":"https://github.com/cappuccino/cappuccino/pull/2395.patch","issue_url":"https://api.github.com/repos/cappuccino/cappuccino/issues/2395","number":2395,"state":"open","locked":false,"title":"Implementation of CPTrackingArea","user":{"login":"didierkorthoudt","id":2394110,"avatar_url":"https://avatars.githubusercontent.com/u/2394110?v=3","gravatar_id":"","url":"https://api.github.com/users/didierkorthoudt","html_url":"https://github.com/didierkorthoudt","followers_url":"https://api.github.com/users/didierkorthoudt/followers","following_url":"https://api.github.com/users/didierkorthoudt/following{/other_user}","gists_url":"https://api.github.com/users/didierkorthoudt/gists{/gist_id}","starred_url":"https://api.github.com/users/didierkorthoudt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/didierkorthoudt/subscriptions","organizations_url":"https://api.github.com/users/didierkorthoudt/orgs","repos_url":"https://api.github.com/users/didierkorthoudt/repos","events_url":"https://api.github.com/users/didierkorthoudt/events{/privacy}","received_events_url":"https://api.github.com/users/didierkorthoudt/received_events","type":"User","site_admin":false},"body":"This PR introduces the CPTrackingArea class (mirroring Cocoa's NSTrackingArea) and a new mouseEntered, mouseExited, mouseMoved management in order to reduce spread mouse events.\r\n\r\nUsing CPTrackingArea is simple : if your CPView subclass needs to receive mouseEntered and/or mouseExited and/or mouseMoved, use CPView's addTrackingArea (usually, one does this in initWithFrame and/or awakeFromCib methods) and provide a valid CPTrackingArea object.\r\n\r\nSee Cocoa documentation for complete description. Please note that CPTrackingCursorUpdate option is not yet implemented.\r\n\r\nThis PR impacts those classes : \r\n- CPControl : addition of a simple CPTrackingArea object to receive mouseEntered and mouseExited\r\n- CPEvent : addition of a new event constructor (enterExitEventWithType) and a new accessor for getting the CPTrackingArea that fired the event\r\n- CPSplitView : addition of a simple CPTrackingArea object to receive mouseEntered, mouseExited and mouseMoved\r\n- CPTableHeaderView : addition of a simple CPTrackingArea object to receive mouseEntered, mouseExited and mouseMoved\r\n- CPView : addition of addTrackingArea, removeTrackingArea and trackingAreas methods\r\n- CPWindow : rewriting of the sendEvent method and addition of some private methods\r\n\r\nA simple test case has shown that less than 10% of mouse movement events were relevant with current processing and 100% with this PR.\r\n\r\nBecause this PR changes event management, you have to check if some of your CPView subclasses are overwriting mouseEntered, mouseExited and/or mouseMoved. If so, just add a tracking area like this one : \r\n\r\n```\r\n        [self addTrackingArea:[[CPTrackingArea alloc] initWithRect:CGRectMakeZero()\r\n                                                           options:CPTrackingMouseEnteredAndExited | CPTrackingMouseMoved | CPTrackingActiveInKeyWindow | CPTrackingInVisibleRect\r\n                                                             owner:self\r\n                                                          userInfo:nil]];\r\n```\r\n(omit the CPTrackingMouseMoved option if not needed)\r\n\r\nThe CPTrackingInVisibleRect will ensure that whenever your view frame changes, the tracking rect used remains synced.\r\n\r\nSome remarks : \r\n- owner can be whatever object you want if it implements mouseEntered, mouseExited and/or mouseMoved methods\r\n- you can pass a dictionary as userInfo and get it back via [[anEvent trackingArea] userInfo]\r\n- a view can have multiple tracking areas\r\n- a tracking area can't be attached to multiple views (Cocoa doesn't complain about this, Cappuccino does)\r\n","created_at":"2015-11-06T13:45:14Z","updated_at":"2015-12-18T00:28:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0a04891e2a0b1b192407a26ef8636683fa93cf04","assignee":{"login":"aparajita","id":22218,"avatar_url":"https://avatars.githubusercontent.com/u/22218?v=3","gravatar_id":"","url":"https://api.github.com/users/aparajita","html_url":"https://github.com/aparajita","followers_url":"https://api.github.com/users/aparajita/followers","following_url":"https://api.github.com/users/aparajita/following{/other_user}","gists_url":"https://api.github.com/users/aparajita/gists{/gist_id}","starred_url":"https://api.github.com/users/aparajita/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aparajita/subscriptions","organizations_url":"https://api.github.com/users/aparajita/orgs","repos_url":"https://api.github.com/users/aparajita/repos","events_url":"https://api.github.com/users/aparajita/events{/privacy}","received_events_url":"https://api.github.com/users/aparajita/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/cappuccino/cappuccino/milestones/4","html_url":"https://github.com/cappuccino/cappuccino/milestones/Someday","labels_url":"https://api.github.com/repos/cappuccino/cappuccino/milestones/4/labels","id":107283,"number":4,"title":"Someday","description":"","creator":{"login":"aparajita","id":22218,"avatar_url":"https://avatars.githubusercontent.com/u/22218?v=3","gravatar_id":"","url":"https://api.github.com/users/aparajita","html_url":"https://github.com/aparajita","followers_url":"https://api.github.com/users/aparajita/followers","following_url":"https://api.github.com/users/aparajita/following{/other_user}","gists_url":"https://api.github.com/users/aparajita/gists{/gist_id}","starred_url":"https://api.github.com/users/aparajita/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aparajita/subscriptions","organizations_url":"https://api.github.com/users/aparajita/orgs","repos_url":"https://api.github.com/users/aparajita/repos","events_url":"https://api.github.com/users/aparajita/events{/privacy}","received_events_url":"https://api.github.com/users/aparajita/received_events","type":"User","site_admin":false},"open_issues":92,"closed_issues":988,"state":"open","created_at":"2012-04-12T21:50:28Z","updated_at":"2015-12-11T04:20:48Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395/commits","review_comments_url":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395/comments","review_comment_url":"https://api.github.com/repos/cappuccino/cappuccino/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cappuccino/cappuccino/issues/2395/comments","statuses_url":"https://api.github.com/repos/cappuccino/cappuccino/statuses/8f15266f0a5111fb07b31fd9f329863a1138b8a7","head":{"label":"didierkorthoudt:CPTrackingArea","ref":"CPTrackingArea","sha":"8f15266f0a5111fb07b31fd9f329863a1138b8a7","user":{"login":"didierkorthoudt","id":2394110,"avatar_url":"https://avatars.githubusercontent.com/u/2394110?v=3","gravatar_id":"","url":"https://api.github.com/users/didierkorthoudt","html_url":"https://github.com/didierkorthoudt","followers_url":"https://api.github.com/users/didierkorthoudt/followers","following_url":"https://api.github.com/users/didierkorthoudt/following{/other_user}","gists_url":"https://api.github.com/users/didierkorthoudt/gists{/gist_id}","starred_url":"https://api.github.com/users/didierkorthoudt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/didierkorthoudt/subscriptions","organizations_url":"https://api.github.com/users/didierkorthoudt/orgs","repos_url":"https://api.github.com/users/didierkorthoudt/repos","events_url":"https://api.github.com/users/didierkorthoudt/events{/privacy}","received_events_url":"https://api.github.com/users/didierkorthoudt/received_events","type":"User","site_admin":false},"repo":{"id":45237623,"name":"cappuccino","full_name":"didierkorthoudt/cappuccino","owner":{"login":"didierkorthoudt","id":2394110,"avatar_url":"https://avatars.githubusercontent.com/u/2394110?v=3","gravatar_id":"","url":"https://api.github.com/users/didierkorthoudt","html_url":"https://github.com/didierkorthoudt","followers_url":"https://api.github.com/users/didierkorthoudt/followers","following_url":"https://api.github.com/users/didierkorthoudt/following{/other_user}","gists_url":"https://api.github.com/users/didierkorthoudt/gists{/gist_id}","starred_url":"https://api.github.com/users/didierkorthoudt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/didierkorthoudt/subscriptions","organizations_url":"https://api.github.com/users/didierkorthoudt/orgs","repos_url":"https://api.github.com/users/didierkorthoudt/repos","events_url":"https://api.github.com/users/didierkorthoudt/events{/privacy}","received_events_url":"https://api.github.com/users/didierkorthoudt/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/didierkorthoudt/cappuccino","description":"Web Application Framework in JavaScript and Objective-J","fork":true,"url":"https://api.github.com/repos/didierkorthoudt/cappuccino","forks_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/forks","keys_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/keys{/key_id}","collaborators_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/teams","hooks_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/hooks","issue_events_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/issues/events{/number}","events_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/events","assignees_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/assignees{/user}","branches_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/branches{/branch}","tags_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/tags","blobs_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/git/refs{/sha}","trees_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/git/trees{/sha}","statuses_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/statuses/{sha}","languages_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/languages","stargazers_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/stargazers","contributors_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/contributors","subscribers_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/subscribers","subscription_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/subscription","commits_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/commits{/sha}","git_commits_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/git/commits{/sha}","comments_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/comments{/number}","issue_comment_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/issues/comments{/number}","contents_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/contents/{+path}","compare_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/compare/{base}...{head}","merges_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/merges","archive_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/downloads","issues_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/issues{/number}","pulls_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/pulls{/number}","milestones_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/milestones{/number}","notifications_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/labels{/name}","releases_url":"https://api.github.com/repos/didierkorthoudt/cappuccino/releases{/id}","created_at":"2015-10-30T08:13:29Z","updated_at":"2015-10-30T08:13:47Z","pushed_at":"2015-12-17T20:48:35Z","git_url":"git://github.com/didierkorthoudt/cappuccino.git","ssh_url":"git@github.com:didierkorthoudt/cappuccino.git","clone_url":"https://github.com/didierkorthoudt/cappuccino.git","svn_url":"https://github.com/didierkorthoudt/cappuccino","homepage":"http://cappuccino-project.org","size":46750,"stargazers_count":0,"watchers_count":0,"language":"Objective-J","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"cappuccino:master","ref":"master","sha":"5e94aaa2cb15896f6323436bbcef6c1cd08e90bc","user":{"login":"cappuccino","id":16595,"avatar_url":"https://avatars.githubusercontent.com/u/16595?v=3","gravatar_id":"","url":"https://api.github.com/users/cappuccino","html_url":"https://github.com/cappuccino","followers_url":"https://api.github.com/users/cappuccino/followers","following_url":"https://api.github.com/users/cappuccino/following{/other_user}","gists_url":"https://api.github.com/users/cappuccino/gists{/gist_id}","starred_url":"https://api.github.com/users/cappuccino/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cappuccino/subscriptions","organizations_url":"https://api.github.com/users/cappuccino/orgs","repos_url":"https://api.github.com/users/cappuccino/repos","events_url":"https://api.github.com/users/cappuccino/events{/privacy}","received_events_url":"https://api.github.com/users/cappuccino/received_events","type":"Organization","site_admin":false},"repo":{"id":49107,"name":"cappuccino","full_name":"cappuccino/cappuccino","owner":{"login":"cappuccino","id":16595,"avatar_url":"https://avatars.githubusercontent.com/u/16595?v=3","gravatar_id":"","url":"https://api.github.com/users/cappuccino","html_url":"https://github.com/cappuccino","followers_url":"https://api.github.com/users/cappuccino/followers","following_url":"https://api.github.com/users/cappuccino/following{/other_user}","gists_url":"https://api.github.com/users/cappuccino/gists{/gist_id}","starred_url":"https://api.github.com/users/cappuccino/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cappuccino/subscriptions","organizations_url":"https://api.github.com/users/cappuccino/orgs","repos_url":"https://api.github.com/users/cappuccino/repos","events_url":"https://api.github.com/users/cappuccino/events{/privacy}","received_events_url":"https://api.github.com/users/cappuccino/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cappuccino/cappuccino","description":"Web Application Framework in JavaScript and Objective-J","fork":false,"url":"https://api.github.com/repos/cappuccino/cappuccino","forks_url":"https://api.github.com/repos/cappuccino/cappuccino/forks","keys_url":"https://api.github.com/repos/cappuccino/cappuccino/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cappuccino/cappuccino/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cappuccino/cappuccino/teams","hooks_url":"https://api.github.com/repos/cappuccino/cappuccino/hooks","issue_events_url":"https://api.github.com/repos/cappuccino/cappuccino/issues/events{/number}","events_url":"https://api.github.com/repos/cappuccino/cappuccino/events","assignees_url":"https://api.github.com/repos/cappuccino/cappuccino/assignees{/user}","branches_url":"https://api.github.com/repos/cappuccino/cappuccino/branches{/branch}","tags_url":"https://api.github.com/repos/cappuccino/cappuccino/tags","blobs_url":"https://api.github.com/repos/cappuccino/cappuccino/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cappuccino/cappuccino/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cappuccino/cappuccino/git/refs{/sha}","trees_url":"https://api.github.com/repos/cappuccino/cappuccino/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cappuccino/cappuccino/statuses/{sha}","languages_url":"https://api.github.com/repos/cappuccino/cappuccino/languages","stargazers_url":"https://api.github.com/repos/cappuccino/cappuccino/stargazers","contributors_url":"https://api.github.com/repos/cappuccino/cappuccino/contributors","subscribers_url":"https://api.github.com/repos/cappuccino/cappuccino/subscribers","subscription_url":"https://api.github.com/repos/cappuccino/cappuccino/subscription","commits_url":"https://api.github.com/repos/cappuccino/cappuccino/commits{/sha}","git_commits_url":"https://api.github.com/repos/cappuccino/cappuccino/git/commits{/sha}","comments_url":"https://api.github.com/repos/cappuccino/cappuccino/comments{/number}","issue_comment_url":"https://api.github.com/repos/cappuccino/cappuccino/issues/comments{/number}","contents_url":"https://api.github.com/repos/cappuccino/cappuccino/contents/{+path}","compare_url":"https://api.github.com/repos/cappuccino/cappuccino/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cappuccino/cappuccino/merges","archive_url":"https://api.github.com/repos/cappuccino/cappuccino/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cappuccino/cappuccino/downloads","issues_url":"https://api.github.com/repos/cappuccino/cappuccino/issues{/number}","pulls_url":"https://api.github.com/repos/cappuccino/cappuccino/pulls{/number}","milestones_url":"https://api.github.com/repos/cappuccino/cappuccino/milestones{/number}","notifications_url":"https://api.github.com/repos/cappuccino/cappuccino/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cappuccino/cappuccino/labels{/name}","releases_url":"https://api.github.com/repos/cappuccino/cappuccino/releases{/id}","created_at":"2008-09-04T10:43:35Z","updated_at":"2015-12-17T09:41:02Z","pushed_at":"2015-12-17T20:48:37Z","git_url":"git://github.com/cappuccino/cappuccino.git","ssh_url":"git@github.com:cappuccino/cappuccino.git","clone_url":"https://github.com/cappuccino/cappuccino.git","svn_url":"https://github.com/cappuccino/cappuccino","homepage":"http://cappuccino-project.org","size":48976,"stargazers_count":2103,"watchers_count":2103,"language":"Objective-J","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":344,"mirror_url":null,"open_issues_count":120,"forks":344,"open_issues":120,"watchers":2103,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395"},"html":{"href":"https://github.com/cappuccino/cappuccino/pull/2395"},"issue":{"href":"https://api.github.com/repos/cappuccino/cappuccino/issues/2395"},"comments":{"href":"https://api.github.com/repos/cappuccino/cappuccino/issues/2395/comments"},"review_comments":{"href":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395/comments"},"review_comment":{"href":"https://api.github.com/repos/cappuccino/cappuccino/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cappuccino/cappuccino/pulls/2395/commits"},"statuses":{"href":"https://api.github.com/repos/cappuccino/cappuccino/statuses/8f15266f0a5111fb07b31fd9f329863a1138b8a7"}}}}