+
+// ========================================================================
+// wxCocoaTrackingRectManager
+// ========================================================================
+
+wxCocoaTrackingRectManager::wxCocoaTrackingRectManager(wxWindow *window)
+: m_window(window)
+{
+ m_isTrackingRectActive = false;
+ m_runLoopObserver = NULL;
+ BuildTrackingRect();
+}
+
+void wxCocoaTrackingRectManager::ClearTrackingRect()
+{
+ if(m_isTrackingRectActive)
+ {
+ [m_window->GetNSView() removeTrackingRect:m_trackingRectTag];
+ m_isTrackingRectActive = false;
+ }
+ // If we were doing periodic events we need to clear those too
+ StopSynthesizingEvents();
+}
+
+void wxCocoaTrackingRectManager::StopSynthesizingEvents()
+{
+ if(m_runLoopObserver != NULL)
+ {
+ CFRunLoopRemoveObserver([[NSRunLoop currentRunLoop] getCFRunLoop], m_runLoopObserver, kCFRunLoopCommonModes);
+ CFRelease(m_runLoopObserver);
+ m_runLoopObserver = NULL;
+ }
+}
+
+void wxCocoaTrackingRectManager::BuildTrackingRect()
+{
+ // Pool here due to lack of one during wx init phase
+ wxAutoNSAutoreleasePool pool;
+
+ wxASSERT_MSG(!m_isTrackingRectActive, wxT("Tracking rect was not cleared"));
+ if([m_window->GetNSView() window] != nil)
+ {
+ m_trackingRectTag = [m_window->GetNSView() addTrackingRect:[m_window->GetNSView() visibleRect] owner:m_window->GetNSView() userData:NULL assumeInside:NO];
+ m_isTrackingRectActive = true;
+ }
+}
+
+static NSPoint s_lastScreenMouseLocation = NSZeroPoint;
+
+static void SynthesizeMouseMovedEvent(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
+{
+ NSPoint screenMouseLocation = [NSEvent mouseLocation];
+ if(screenMouseLocation.x != s_lastScreenMouseLocation.x || screenMouseLocation.y != s_lastScreenMouseLocation.y)
+ {
+ wxCocoaNSView *win = reinterpret_cast<wxCocoaNSView*>(info);
+ win->Cocoa_synthesizeMouseMoved();
+ }
+}
+
+void wxCocoaTrackingRectManager::BeginSynthesizingEvents()
+{
+ CFRunLoopObserverContext observerContext =
+ { 0
+ , static_cast<wxCocoaNSView*>(m_window)
+ , NULL
+ , NULL
+ , NULL
+ };
+ m_runLoopObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, TRUE, 0, SynthesizeMouseMovedEvent, &observerContext);
+ CFRunLoopAddObserver([[NSRunLoop currentRunLoop] getCFRunLoop], m_runLoopObserver, kCFRunLoopCommonModes);
+}
+
+void wxCocoaTrackingRectManager::RebuildTrackingRect()
+{
+ ClearTrackingRect();
+ BuildTrackingRect();
+}
+
+wxCocoaTrackingRectManager::~wxCocoaTrackingRectManager()
+{
+ ClearTrackingRect();
+}
+
+bool wxCocoaTrackingRectManager::IsOwnerOfEvent(NSEvent *anEvent)
+{
+ return m_isTrackingRectActive && (m_trackingRectTag == [anEvent trackingNumber]);
+}
+