17 #include <Cocoa/Cocoa.h>
29 @interface FakeCrossingEvent : NSEvent {
30 NSWindow *fQuartzWindow;
31 NSPoint fLocationInWindow;
36 @implementation FakeCrossingEvent
39 - (id) initWithWindow : (NSWindow *) window location : (NSPoint) location
42 assert(window &&
"initWithWindow:location:, parameter 'window' is nil");
44 if (
self = [super init]) {
45 fQuartzWindow = window;
46 fLocationInWindow = location;
55 assert(fQuartzWindow &&
"window, fQuartzWindow is nil");
60 - (NSPoint) locationInWindow
62 assert(fQuartzWindow != nil &&
"locationInWindow, fQuartzWindow is nil");
63 return fLocationInWindow;
67 - (NSTimeInterval) timestamp
84 template<
typename T1,
typename T2>
89 bool operator < (
const KeySymPair &rhs)
const
91 return fFirst < rhs.fFirst;
98 void MapUnicharToKeySym(unichar key,
char *buf, Int_t , UInt_t &rootKeySym)
100 assert(buf != 0 &&
"MapUnicharToKeySym, parameter 'buf' is null");
102 static const KeySymPair<unichar, EKeySym> keyMap[] = {
103 {NSEnterCharacter, kKey_Enter},
104 {NSTabCharacter, kKey_Tab},
105 {NSCarriageReturnCharacter, kKey_Return},
106 {NSBackTabCharacter, kKey_Backtab},
109 {NSDeleteCharacter, kKey_Backspace},
110 {NSUpArrowFunctionKey, kKey_Up},
111 {NSDownArrowFunctionKey, kKey_Down},
112 {NSLeftArrowFunctionKey, kKey_Left},
113 {NSRightArrowFunctionKey, kKey_Right},
114 {NSF1FunctionKey, kKey_F1},
115 {NSF2FunctionKey, kKey_F2},
116 {NSF3FunctionKey, kKey_F3},
117 {NSF4FunctionKey, kKey_F4},
118 {NSF5FunctionKey, kKey_F5},
119 {NSF6FunctionKey, kKey_F6},
120 {NSF7FunctionKey, kKey_F7},
121 {NSF8FunctionKey, kKey_F8},
122 {NSF9FunctionKey, kKey_F8},
123 {NSF10FunctionKey, kKey_F10},
124 {NSF11FunctionKey, kKey_F11},
125 {NSF12FunctionKey, kKey_F12},
126 {NSF13FunctionKey, kKey_F13},
127 {NSF14FunctionKey, kKey_F14},
128 {NSF15FunctionKey, kKey_F15},
129 {NSF16FunctionKey, kKey_F16},
130 {NSF17FunctionKey, kKey_F17},
131 {NSF18FunctionKey, kKey_F18},
132 {NSF19FunctionKey, kKey_F19},
133 {NSF20FunctionKey, kKey_F20},
134 {NSF21FunctionKey, kKey_F21},
135 {NSF22FunctionKey, kKey_F22},
136 {NSF23FunctionKey, kKey_F23},
137 {NSF24FunctionKey, kKey_F24},
138 {NSF25FunctionKey, kKey_F25},
139 {NSF26FunctionKey, kKey_F26},
140 {NSF27FunctionKey, kKey_F27},
141 {NSF28FunctionKey, kKey_F28},
142 {NSF29FunctionKey, kKey_F29},
143 {NSF30FunctionKey, kKey_F30},
144 {NSF31FunctionKey, kKey_F31},
145 {NSF32FunctionKey, kKey_F32},
146 {NSF33FunctionKey, kKey_F33},
147 {NSF34FunctionKey, kKey_F34},
148 {NSF35FunctionKey, kKey_F35},
149 {NSInsertFunctionKey, kKey_Insert},
150 {NSDeleteFunctionKey, kKey_Delete},
151 {NSHomeFunctionKey, kKey_Home},
152 {NSEndFunctionKey, kKey_End},
153 {NSPageUpFunctionKey, kKey_PageUp},
154 {NSPageDownFunctionKey, kKey_PageDown},
155 {NSPrintScreenFunctionKey, kKey_Print},
156 {NSScrollLockFunctionKey, kKey_ScrollLock},
157 {NSPauseFunctionKey, kKey_Pause},
158 {NSSysReqFunctionKey, kKey_SysReq}};
160 const unsigned nEntries =
sizeof keyMap /
sizeof keyMap[0];
164 KeySymPair<unichar, EKeySym> valueToFind = {};
165 valueToFind.fFirst = key;
166 const KeySymPair<unichar, EKeySym> *iter = std::lower_bound(keyMap, keyMap + nEntries, valueToFind);
168 if (iter != keyMap + nEntries && iter->fFirst == key) {
169 buf[0] = key <= 0x7e ? key : 0;
170 rootKeySym = iter->fSecond;
178 Int_t MapKeySymToKeyCode(Int_t keySym)
181 if (keySym >= 0x20 && keySym <= 0x7e)
184 static const KeySymPair<EKeySym, unichar> keyMap[] = {
186 {kKey_Tab, NSTabCharacter},
187 {kKey_Backtab, NSBackTabCharacter},
188 {kKey_Backspace, NSDeleteCharacter},
189 {kKey_Return, NSCarriageReturnCharacter},
190 {kKey_Enter, NSEnterCharacter},
191 {kKey_Insert, NSInsertFunctionKey},
192 {kKey_Delete, NSDeleteFunctionKey},
193 {kKey_Pause, NSPauseFunctionKey},
194 {kKey_Print, NSPrintScreenFunctionKey},
195 {kKey_SysReq, NSSysReqFunctionKey},
196 {kKey_Home, NSHomeFunctionKey},
197 {kKey_End, NSEndFunctionKey},
198 {kKey_Left, NSLeftArrowFunctionKey},
199 {kKey_Up, NSUpArrowFunctionKey},
200 {kKey_Right, NSRightArrowFunctionKey},
201 {kKey_Down, NSDownArrowFunctionKey},
202 {kKey_PageUp, NSPageUpFunctionKey},
203 {kKey_PageDown, NSPageDownFunctionKey},
211 {kKey_ScrollLock, NSScrollLockFunctionKey},
212 {kKey_F1, NSF1FunctionKey},
213 {kKey_F2, NSF2FunctionKey},
214 {kKey_F3, NSF3FunctionKey},
215 {kKey_F4, NSF4FunctionKey},
216 {kKey_F5, NSF5FunctionKey},
217 {kKey_F6, NSF6FunctionKey},
218 {kKey_F7, NSF7FunctionKey},
219 {kKey_F8, NSF8FunctionKey},
220 {kKey_F8, NSF9FunctionKey},
221 {kKey_F10, NSF10FunctionKey},
222 {kKey_F11, NSF11FunctionKey},
223 {kKey_F12, NSF12FunctionKey},
224 {kKey_F13, NSF13FunctionKey},
225 {kKey_F14, NSF14FunctionKey},
226 {kKey_F15, NSF15FunctionKey},
227 {kKey_F16, NSF16FunctionKey},
228 {kKey_F17, NSF17FunctionKey},
229 {kKey_F18, NSF18FunctionKey},
230 {kKey_F19, NSF19FunctionKey},
231 {kKey_F20, NSF20FunctionKey},
232 {kKey_F21, NSF21FunctionKey},
233 {kKey_F22, NSF22FunctionKey},
234 {kKey_F23, NSF23FunctionKey},
235 {kKey_F24, NSF24FunctionKey},
236 {kKey_F25, NSF25FunctionKey},
237 {kKey_F26, NSF26FunctionKey},
238 {kKey_F27, NSF27FunctionKey},
239 {kKey_F28, NSF28FunctionKey},
240 {kKey_F29, NSF29FunctionKey},
241 {kKey_F30, NSF30FunctionKey},
242 {kKey_F31, NSF31FunctionKey},
243 {kKey_F32, NSF32FunctionKey},
244 {kKey_F33, NSF33FunctionKey},
245 {kKey_F34, NSF34FunctionKey},
246 {kKey_F35, NSF35FunctionKey}
249 const unsigned nEntries =
sizeof keyMap /
sizeof keyMap[0];
251 KeySymPair<EKeySym, unichar> valueToFind = {};
252 valueToFind.fFirst =
static_cast<EKeySym
>(keySym);
253 const KeySymPair<EKeySym, unichar> *iter = std::lower_bound(keyMap, keyMap + nEntries, valueToFind);
254 if (iter != keyMap + nEntries && iter->fFirst == keySym)
255 return iter->fSecond;
261 NSUInteger GetCocoaKeyModifiersFromROOTKeyModifiers(UInt_t rootModifiers)
263 NSUInteger cocoaModifiers = 0;
265 if (rootModifiers & kKeyLockMask)
266 cocoaModifiers |= Details::kAlphaShiftKeyMask;
267 if (rootModifiers & kKeyShiftMask)
268 cocoaModifiers |= Details::kShiftKeyMask;
269 if (rootModifiers & kKeyControlMask)
270 cocoaModifiers |= Details::kControlKeyMask;
271 if (rootModifiers & kKeyMod1Mask)
272 cocoaModifiers |= Details::kAlternateKeyMask;
273 if (rootModifiers & kKeyMod2Mask)
274 cocoaModifiers |= Details::kCommandKeyMask;
276 return cocoaModifiers;
280 UInt_t GetKeyboardModifiers()
282 const NSUInteger modifiers = [NSEvent modifierFlags];
284 UInt_t rootModifiers = 0;
285 if (modifiers & Details::kAlphaShiftKeyMask)
286 rootModifiers |= kKeyLockMask;
287 if (modifiers & Details::kShiftKeyMask)
288 rootModifiers |= kKeyShiftMask;
289 if (modifiers & Details::kControlKeyMask)
290 rootModifiers |= kKeyControlMask;
291 if (modifiers & Details::kAlternateKeyMask)
292 rootModifiers |= kKeyMod1Mask;
293 if (modifiers & Details::kCommandKeyMask)
294 rootModifiers |= kKeyMod2Mask;
296 return rootModifiers;
300 UInt_t GetModifiers()
302 UInt_t rootModifiers = GetKeyboardModifiers();
303 const NSUInteger buttons = [NSEvent pressedMouseButtons];
305 rootModifiers |= kButton1Mask;
307 rootModifiers |= kButton3Mask;
308 if (buttons & (1 << 2))
309 rootModifiers |= kButton2Mask;
311 return rootModifiers;
316 #pragma mark - Several aux. functions to extract parameters from Cocoa events.
319 Time_t TimeForCocoaEvent(NSEvent *theEvent)
322 assert(theEvent != nil &&
"TimeForCocoaEvent, parameter 'theEvent' is nil");
324 return [theEvent timestamp] * 1000;
328 Event_t NewX11EventFromCocoaEvent(
unsigned windowID, NSEvent *theEvent)
332 assert(theEvent != nil &&
"NewX11EventFromCocoaEvent, parameter 'theEvent' is nil");
334 Event_t newEvent = {};
335 newEvent.fWindow = windowID;
336 newEvent.fTime = TimeForCocoaEvent(theEvent);
341 void ConvertEventLocationToROOTXY(NSEvent *cocoaEvent, NSView<X11Window> *eventView, Event_t *rootEvent)
346 assert(cocoaEvent != nil &&
"ConvertEventLocationToROOTXY, parameter 'cocoaEvent' is nil");
347 assert(eventView != nil &&
"ConvertEventLocationToROOTXY, parameter 'eventView' is nil");
348 assert(rootEvent != 0 &&
"ConvertEventLocationToROOTXY, parameter 'rootEvent' is null");
350 if (![cocoaEvent window])
351 NSLog(
@"Error in ConvertEventLocationToROOTXY, window property"
352 " of event is nil, can not convert coordinates correctly");
357 const NSPoint screenPoint = ConvertPointFromBaseToScreen([cocoaEvent window], [cocoaEvent locationInWindow]);
358 const NSPoint winPoint = ConvertPointFromScreenToBase(screenPoint, [eventView window]);
359 const NSPoint viewPoint = [eventView convertPoint : winPoint fromView : nil];
361 rootEvent->fX = viewPoint.x;
362 rootEvent->fY = viewPoint.y;
364 rootEvent->fXRoot = GlobalXCocoaToROOT(screenPoint.x);
365 rootEvent->fYRoot = GlobalYCocoaToROOT(screenPoint.y);
369 unsigned GetKeyboardModifiersFromCocoaEvent(NSEvent *theEvent)
371 assert(theEvent != nil &&
"GetKeyboardModifiersFromCocoaEvent, parameter 'event' is nil");
373 const NSUInteger modifiers = [theEvent modifierFlags];
374 unsigned rootModifiers = 0;
375 if (modifiers & Details::kAlphaShiftKeyMask)
376 rootModifiers |= kKeyLockMask;
377 if (modifiers & Details::kShiftKeyMask)
378 rootModifiers |= kKeyShiftMask;
379 if (modifiers & Details::kControlKeyMask)
380 rootModifiers |= kKeyControlMask;
381 if (modifiers & Details::kAlternateKeyMask)
382 rootModifiers |= kKeyMod1Mask;
383 if (modifiers & Details::kCommandKeyMask)
384 rootModifiers |= kKeyMod2Mask;
386 return rootModifiers;
390 unsigned GetModifiersFromCocoaEvent(NSEvent *theEvent)
392 assert(theEvent != nil &&
"GetModifiersFromCocoaEvent, parameter 'event' is nil");
394 unsigned rootModifiers = GetKeyboardModifiersFromCocoaEvent(theEvent);
395 const NSUInteger buttons = [NSEvent pressedMouseButtons];
397 rootModifiers |= kButton1Mask;
399 rootModifiers |= kButton3Mask;
400 if (buttons & (1 << 2))
401 rootModifiers |= kButton2Mask;
403 return rootModifiers;
406 #pragma mark - Misc. aux. functions.
409 bool IsParent(NSView<X11Window> *testParent, NSView<X11Window> *testChild)
411 assert(testParent != nil &&
"IsParent, parameter 'testParent' is nil");
412 assert(testChild != nil &&
"IsParent, parameter 'testChild' is nil");
414 if (testChild.fParentView) {
415 NSView<X11Window> *parent = testChild.fParentView;
417 if(parent == testParent)
419 parent = parent.fParentView;
427 bool IsInBranch(NSView<X11Window> *parent, NSView<X11Window> *child, NSView<X11Window> *testView)
429 assert(child != nil &&
"IsInBranch, parameter 'child' is nil");
430 assert(testView != nil &&
"IsInBranch, parameter 'testView' is nil");
432 if (testView == child || testView == parent)
435 for (NSView<X11Window> *current = child.fParentView; current != parent; current = current.fParentView) {
436 if (current == testView)
447 kAHaveNonRootAncestor,
452 Ancestry FindLowestCommonAncestor(NSView<X11Window> *view1, NSView<X11Window> *view2,
453 NSView<X11Window> **lca)
459 assert(view1 != nil &&
"FindLowestCommonAncestor, parameter 'view1' is nil");
460 assert(view2 != nil &&
"findLowestCommonAncestor, parameter 'view2' is nil");
461 assert(lca != 0 &&
"FindLowestCommonAncestor, parameter 'lca' is null");
463 if (!view1.fParentView)
464 return kAAncestorIsRoot;
466 if (!view2.fParentView)
467 return kAAncestorIsRoot;
469 NSView<X11Window> *
const ancestor = (NSView<X11Window> *)[view1 ancestorSharedWithView : view2];
473 return kAHaveNonRootAncestor;
476 return kAAncestorIsRoot;
480 Ancestry FindRelation(NSView<X11Window> *view1, NSView<X11Window> *view2, NSView<X11Window> **lca)
482 assert(view1 != nil &&
"FindRelation, view1 parameter is nil");
483 assert(view2 != nil &&
"FindRelation, view2 parameter is nil");
484 assert(lca != 0 &&
"FindRelation, lca parameter is nil");
486 if (IsParent(view1, view2))
487 return kAView1IsParent;
489 if (IsParent(view2, view1))
490 return kAView2IsParent;
492 return FindLowestCommonAncestor(view1, view2, lca);
496 NSView<X11Window> *FindViewToPropagateEvent(NSView<X11Window> *viewFrom, Mask_t checkMask)
499 assert(viewFrom != nil &&
"FindViewToPropagateEvent, parameter 'view' is nil");
501 if (viewFrom.fEventMask & checkMask)
504 for (viewFrom = viewFrom.fParentView; viewFrom; viewFrom = viewFrom.fParentView) {
505 if (viewFrom.fEventMask & checkMask)
513 NSView<X11Window> *FindViewToPropagateEvent(NSView<X11Window> *viewFrom, Mask_t checkMask,
514 NSView<X11Window> *grabView, Mask_t grabMask)
521 assert(viewFrom != nil &&
"FindViewToPropagateEvent, parameter 'view' is nil");
523 if (viewFrom.fEventMask & checkMask)
526 for (viewFrom = viewFrom.fParentView; viewFrom; viewFrom = viewFrom.fParentView) {
527 if (viewFrom.fEventMask & checkMask)
531 if (grabView && (grabMask & checkMask))
537 #pragma mark - Aux. 'low-level' functions to generate events and call HandleEvent for a root window.
540 void SendEnterEvent(EventQueue_t &queue, NSView<X11Window> *view, NSEvent *theEvent,
548 assert(view != nil &&
"SendEnterEvent, parameter 'view' is nil");
549 assert(theEvent != nil &&
"SendEnterEvent, parameter 'event' is nil");
550 assert(view.fID != 0 &&
"SendEnterEvent, view.fID is 0");
552 TGWindow *
const window = gClient->GetWindowById(view.fID);
554 #ifdef DEBUG_ROOT_COCOA
555 NSLog(
@"SendEnterEvent, ROOT's widget %u was not found", view.fID);
560 Event_t enterEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
561 enterEvent.fType = kEnterNotify;
562 enterEvent.fCode = detail;
563 enterEvent.fState = GetModifiersFromCocoaEvent(theEvent);
568 ConvertEventLocationToROOTXY(theEvent, view, &enterEvent);
571 queue.push_back(enterEvent);
575 void SendLeaveEvent(EventQueue_t &queue, NSView<X11Window> *view, NSEvent *theEvent,
583 assert(view != nil &&
"SendLeaveEvent, parameter 'view' is nil");
584 assert(theEvent != nil &&
"SendLeaveEvent, parameter 'event' is nil");
585 assert(view.fID != 0 &&
"SendLeaveEvent, view.fID is 0");
587 TGWindow *
const window = gClient->GetWindowById(view.fID);
589 #ifdef DEBUG_ROOT_COCOA
590 NSLog(
@"SendLeaveEvent, ROOT's widget %u was not found", view.fID);
595 Event_t leaveEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
596 leaveEvent.fType = kLeaveNotify;
597 leaveEvent.fCode = detail;
598 leaveEvent.fState = GetModifiersFromCocoaEvent(theEvent);
601 ConvertEventLocationToROOTXY(theEvent, view, &leaveEvent);
603 queue.push_back(leaveEvent);
607 void SendPointerMotionEvent(EventQueue_t &queue, NSView<X11Window> *view, NSEvent *theEvent)
614 assert(view != nil &&
"SendPointerMotionEvent, parameter 'view' is nil");
615 assert(theEvent != nil &&
"SendPointerMotionEvent, parameter 'event' is nil");
616 assert(view.fID != 0 &&
"SendPointerMotionEvent, view.fID is 0");
618 TGWindow *
const window = gClient->GetWindowById(view.fID);
620 #ifdef DEBUG_ROOT_COCOA
621 NSLog(
@"SendPointerMotionEvent, ROOT's widget %u was not found", view.fID);
626 Event_t motionEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
627 motionEvent.fType = kMotionNotify;
628 motionEvent.fState = GetModifiersFromCocoaEvent(theEvent);
630 ConvertEventLocationToROOTXY(theEvent, view, &motionEvent);
632 queue.push_back(motionEvent);
636 void SendButtonPressEvent(EventQueue_t &queue, NSView<X11Window> *view, NSEvent *theEvent,
645 assert(view != nil &&
"SendButtonPressEvent, parameter 'view' is nil");
646 assert(theEvent != nil &&
"SendButtonPressEvent, parameter 'event' is nil");
647 assert(view.fID != 0 &&
"SendButtonPressEvent, view.fID is 0");
649 TGWindow *
const window = gClient->GetWindowById(view.fID);
651 #ifdef DEBUG_ROOT_COCOA
652 NSLog(
@"SendButtonpressEvent, ROOT's widget %u was not found", view.fID);
657 Event_t pressEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
658 pressEvent.fType = kButtonPress;
659 pressEvent.fCode = btn;
660 pressEvent.fState = GetKeyboardModifiersFromCocoaEvent(theEvent);
662 ConvertEventLocationToROOTXY(theEvent, view, &pressEvent);
671 NSPoint viewPoint = {};
672 viewPoint.x = pressEvent.fX;
673 viewPoint.y = pressEvent.fY;
674 for (NSView<X11Window> *child in [view subviews]) {
675 if (!child.fIsOverlapped && [child hitTest : viewPoint]) {
676 pressEvent.fUser[0] = child.fID;
682 queue.push_back(pressEvent);
686 void SendButtonReleaseEvent(EventQueue_t &queue, NSView<X11Window> *view, NSEvent *theEvent,
694 assert(view != nil &&
"SendButtonReleaseEvent, parameter 'view' is nil");
695 assert(theEvent != nil &&
"SendButtonReleaseEvent, parameter 'event' is nil");
696 assert(view.fID != 0 &&
"SendButtonReleaseEvent, view.fID is 0");
698 TGWindow *
const window = gClient->GetWindowById(view.fID);
700 #ifdef DEBUG_ROOT_COCOA
701 NSLog(
@"SendButtonReleaseEvent, ROOT's widget %u was not found", view.fID);
706 Event_t releaseEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
707 releaseEvent.fType = kButtonRelease;
708 releaseEvent.fCode = btn;
709 releaseEvent.fState = GetKeyboardModifiersFromCocoaEvent(theEvent);
711 ConvertEventLocationToROOTXY(theEvent, view, &releaseEvent);
713 queue.push_back(releaseEvent);
717 void SendKeyPressEvent(EventQueue_t &queue, NSView<X11Window> *view, NSView<X11Window> *childView,
718 NSEvent *theEvent, NSPoint windowPoint)
720 assert(view != nil &&
"SendKeyPressEvent, parameter 'view' is nil");
721 assert(theEvent != nil &&
"SendKeyPressEvent, parameter 'event' is nil");
722 assert(view.fID != 0 &&
"SendKeyPressEvent, view.fID is 0");
724 TGWindow *
const window = gClient->GetWindowById(view.fID);
726 #ifdef DEBUG_ROOT_COCOA
727 NSLog(
@"SendKeyPressEvent, ROOT's widget %u was not found", view.fID);
732 Event_t keyPressEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
733 keyPressEvent.fType = kGKeyPress;
734 keyPressEvent.fState = GetKeyboardModifiersFromCocoaEvent(theEvent);
736 NSString *
const characters = [theEvent charactersIgnoringModifiers];
737 assert(characters != nil &&
"SendKeyPressEvent, [theEvent characters] returned nil");
738 assert([characters length] > 0 &&
"SendKeyPressEvent, characters is an empty string");
740 keyPressEvent.fCode = [characters characterAtIndex : 0];
744 const NSPoint viewPoint = [view convertPoint : windowPoint fromView : nil];
747 keyPressEvent.fX = viewPoint.x;
748 keyPressEvent.fY = viewPoint.y;
749 const NSPoint screenPoint = TranslateToScreen(view, viewPoint);
750 keyPressEvent.fXRoot = screenPoint.x;
751 keyPressEvent.fYRoot = screenPoint.y;
754 keyPressEvent.fUser[0] = childView.fID;
757 queue.push_back(keyPressEvent);
761 void SendKeyReleaseEvent(EventQueue_t &queue, NSView<X11Window> *view, NSView<X11Window> *childView,
762 NSEvent *theEvent, NSPoint windowPoint)
764 assert(view != nil &&
"SendKeyReleaseEvent, parameter 'view' is nil");
765 assert(theEvent != nil &&
"SendKeyReleaseEvent, parameter 'event' is nil");
766 assert(view.fID != 0 &&
"SendKeyReleaseEvent, view.fID is 0");
768 TGWindow *
const window = gClient->GetWindowById(view.fID);
770 #ifdef DEBUG_ROOT_COCOA
771 NSLog(
@"SendKeyPressEvent, ROOT's widget %u was not found", view.fID);
776 Event_t keyReleaseEvent = NewX11EventFromCocoaEvent(view.fID, theEvent);
777 keyReleaseEvent.fType = kKeyRelease;
779 keyReleaseEvent.fState = GetKeyboardModifiersFromCocoaEvent(theEvent);
781 NSString *
const characters = [theEvent charactersIgnoringModifiers];
782 assert(characters != nil &&
"SendKeyReleaseEvent, [theEvent characters] returned nil");
783 assert([characters length] > 0 &&
"SendKeyReleaseEvent, characters is an empty string");
784 keyReleaseEvent.fCode = [characters characterAtIndex : 0];
787 const NSPoint viewPoint = [view convertPoint : windowPoint fromView : nil];
788 keyReleaseEvent.fX = viewPoint.x;
789 keyReleaseEvent.fY = viewPoint.y;
790 const NSPoint screenPoint = TranslateToScreen(view, viewPoint);
792 keyReleaseEvent.fXRoot = screenPoint.x;
793 keyReleaseEvent.fYRoot = screenPoint.y;
797 keyReleaseEvent.fUser[0] = childView.fID;
800 queue.push_back(keyReleaseEvent);
805 void SendFocusInEvent(EventQueue_t &queue, NSView<X11Window> *view, EXMagic mode)
807 assert(view != nil &&
"SendFocusInEvent, parameter 'view' is nil");
809 TGWindow *
const window = gClient->GetWindowById(view.fID);
811 #ifdef DEBUG_ROOT_COCOA
812 NSLog(
@"SendFocusInEvent, ROOT's widget %u was not found", view.fID);
817 Event_t focusInEvent = {};
818 focusInEvent.fWindow = view.fID;
819 focusInEvent.fType = kFocusIn;
820 focusInEvent.fCode = mode;
822 queue.push_back(focusInEvent);
826 void SendFocusOutEvent(EventQueue_t &queue, NSView<X11Window> *view, EXMagic mode)
828 assert(view != nil &&
"SendFocusOutEvent, parameter 'view' is nil");
830 TGWindow *
const window = gClient->GetWindowById(view.fID);
832 #ifdef DEBUG_ROOT_COCOA
833 NSLog(
@"SendFocusOutEvent, ROOT's widget %u was not found", view.fID);
838 Event_t focusOutEvent = {};
839 focusOutEvent.fWindow = view.fID;
840 focusOutEvent.fType = kFocusOut;
841 focusOutEvent.fCode = mode;
843 queue.push_back(focusOutEvent);
846 #pragma mark - Aux. functions to send events to view's branch.
849 void SendEnterEventRange(EventQueue_t &queue, NSView<X11Window> *from, NSView<X11Window> *to,
850 NSEvent *theEvent, EXMagic mode)
853 assert(from != nil &&
"SendEnterEventRange, 'from' parameter is nil");
854 assert(to != nil &&
"SendEnterEventRange, 'to' parameter is nil");
855 assert(theEvent != nil &&
"SendEnterEventRange, event parameter is nil");
858 if ([from acceptsCrossingEvents : kEnterWindowMask])
859 SendEnterEvent(queue, from, theEvent, mode);
860 from = from.fParentView;
865 void SendEnterEventClosedRange(EventQueue_t &queue, NSView<X11Window> *from, NSView<X11Window> *to,
866 NSEvent *theEvent, EXMagic mode)
869 assert(from != nil &&
"SendEnterEventClosedRange, 'from' parameter is nil");
870 assert(to != nil &&
"SendEnterEventClosedRange, 'to' parameter is nil");
871 assert(theEvent != nil &&
"SendEnterEventClosedRange, event parameter is nil");
873 SendEnterEventRange(queue, from, to, theEvent, mode);
874 if ([to acceptsCrossingEvents : kEnterWindowMask])
875 SendEnterEvent(queue, to, theEvent, mode);
879 void SendLeaveEventRange(EventQueue_t &queue, NSView<X11Window> *from, NSView<X11Window> *to,
880 NSEvent *theEvent, EXMagic mode)
883 assert(from != nil &&
"SendLeaveEventRange, 'from' parameter is nil");
884 assert(to != nil &&
"SendLeaveEventRange, 'to' parameter is nil");
885 assert(theEvent != nil &&
"SendLeaveEventRange, event parameter is nil");
888 if ([from acceptsCrossingEvents : kLeaveWindowMask])
889 SendLeaveEvent(queue, from, theEvent, mode);
890 from = from.fParentView;
895 void SendLeaveEventClosedRange(EventQueue_t &queue, NSView<X11Window> *from, NSView<X11Window> *to,
896 NSEvent *theEvent, EXMagic mode)
899 assert(from != nil &&
"SendLeaveEventClosedRange, 'from' parameter is nil");
900 assert(to != nil &&
"SendLeaveEventClosedRange, 'to' parameter is nil");
901 assert(theEvent != nil &&
"SendLeaveEventClosedRange, event parameter is nil");
903 SendLeaveEventRange(queue, from, to, theEvent, mode);
904 if ([to acceptsCrossingEvents : kLeaveWindowMask])
905 SendLeaveEvent(queue, to, theEvent, mode);
908 #pragma mark - Top-level crossing event generators.
914 void GenerateCrossingEventChildToParent(EventQueue_t &queue, NSView<X11Window> *parent, NSView<X11Window> *child,
915 NSEvent *theEvent, EXMagic detail)
924 assert(parent != nil &&
"GenerateCrossingEventChildToParent, parameter 'parent' is nil");
925 assert(child != nil &&
"GenerateCrossingEventChildToParent, parameter 'child' is nil");
926 assert(theEvent != nil &&
"GenerateCrossingEventChildToParent, parameter 'event' is nil");
927 assert(child.fParentView != nil &&
928 "GenerateCrossingEventChildToParent, parameter 'child' must have QuartzView* parent");
932 if ([child acceptsCrossingEvents : kLeaveWindowMask])
933 SendLeaveEvent(queue, child, theEvent, detail);
936 SendLeaveEventRange(queue, child.fParentView, parent, theEvent, detail);
939 if ([parent acceptsCrossingEvents : kEnterWindowMask])
940 SendEnterEvent(queue, parent, theEvent, detail);
944 void GenerateCrossingEventParentToChild(EventQueue_t &queue, NSView<X11Window> *parent, NSView<X11Window> *child,
945 NSEvent *theEvent, EXMagic detail)
955 assert(parent != nil &&
"GenerateCrossingEventParentToChild, parameter 'parent' is nil");
956 assert(child != nil &&
"GenerateCrossingEventParentToChild, parameter 'child' is nil");
957 assert(theEvent != nil &&
"GenerateCrossingEventParentToChild, parameter 'event' is nil");
958 assert(child.fParentView != nil &&
959 "GenerateCrossingEventParentToChild, parameter 'child' must have QuartzView* parent");
963 if ([parent acceptsCrossingEvents : kLeaveWindowMask])
964 SendLeaveEvent(queue, parent, theEvent, detail);
967 SendEnterEventRange(queue, child.fParentView, parent, theEvent, detail);
970 if ([child acceptsCrossingEvents : kEnterWindowMask])
971 SendEnterEvent(queue, child, theEvent, detail);
975 void GenerateCrossingEventFromChild1ToChild2(EventQueue_t &queue, NSView<X11Window> *child1, NSView<X11Window> *child2,
976 NSView<X11Window> *ancestor, NSEvent *theEvent, EXMagic detail)
984 assert(child1 != nil &&
"GenerateCrossingEventFromChild1ToChild2, parameter 'child1' is nil");
985 assert(child2 != nil &&
"GenerateCrossingEventFromChild1ToChild2, child2 parameter is nil");
986 assert(theEvent != nil &&
"GenerateCrossingEventFromChild1ToChild2, theEvent parameter is nil");
992 if ([child1 acceptsCrossingEvents : kLeaveWindowMask])
993 SendLeaveEvent(queue, child1, theEvent, detail);
996 if (child1.fParentView)
997 SendLeaveEventClosedRange(queue, child1.fParentView,
998 (NSView<X11Window> *)[[child1 window] contentView], theEvent, detail);
999 if (child2.fParentView)
1000 SendEnterEventClosedRange(queue, child2.fParentView,
1001 (NSView<X11Window> *)[[child2 window] contentView], theEvent, detail);
1003 if (child1.fParentView)
1004 SendLeaveEventRange(queue, child1.fParentView, ancestor, theEvent, detail);
1005 if (child2.fParentView)
1006 SendEnterEventRange(queue, child2.fParentView, ancestor, theEvent, detail);
1009 if ([child2 acceptsCrossingEvents : kEnterWindowMask])
1010 SendEnterEvent(queue, child2, theEvent, detail);
1015 void GenerateCrossingEvents(EventQueue_t &queue, NSView<X11Window> *fromView, NSView<X11Window> *toView,
1016 NSEvent *theEvent, EXMagic detail)
1021 assert(theEvent != nil &&
"GenerateCrossingEvent, event parameter is nil");
1023 if (fromView == toView) {
1038 SendEnterEventClosedRange(queue, toView, (NSView<X11Window> *)[[toView window] contentView],
1040 }
else if (!toView) {
1042 SendLeaveEventClosedRange(queue, fromView, (NSView<X11Window> *)[[fromView window] contentView],
1045 NSView<X11Window> *ancestor = 0;
1046 const Ancestry rel = FindRelation(fromView, toView, &ancestor);
1047 if (rel == kAView1IsParent) {
1058 GenerateCrossingEventParentToChild(queue, fromView, toView, theEvent, detail);
1059 }
else if (rel == kAView2IsParent) {
1070 GenerateCrossingEventChildToParent(queue, toView, fromView, theEvent, detail);
1080 GenerateCrossingEventFromChild1ToChild2(queue, fromView, toView, ancestor, theEvent, detail);
1086 void GenerateCrossingEventForGrabView(EventQueue_t &queue, NSView<X11Window> *fromView, NSView<X11Window> *toView,
1087 NSView<X11Window> *grabView, Mask_t grabEventMask, NSEvent *theEvent)
1092 assert(theEvent != nil &&
"GenerateCrossingEventForGrabView, parameter 'event' is nil");
1093 assert(grabView != nil &&
"GenerateCrossingEventForGrabView, parameter 'grabView' is nil");
1094 assert((fromView != nil || toView != nil) &&
1095 "GenerateCrossingEventForGrabView, both 'toView' and 'fromView' parameters are nil");
1097 if (fromView == toView)
1100 const bool wantsEnter = grabEventMask & kEnterWindowMask;
1101 const bool wantsLeave = grabEventMask & kLeaveWindowMask;
1103 if (fromView == grabView && wantsLeave)
1104 return SendLeaveEvent(queue, grabView, theEvent, kNotifyNormal);
1106 if (toView == grabView && wantsEnter)
1107 return SendEnterEvent(queue, grabView, theEvent, kNotifyNormal);
1112 if (wantsEnter && IsParent(grabView, toView))
1113 SendEnterEvent(queue, grabView, theEvent, kNotifyNormal);
1114 }
else if (!toView) {
1116 if (wantsLeave && IsParent(grabView, fromView))
1117 SendLeaveEvent(queue, grabView, theEvent, kNotifyNormal);
1119 NSView<X11Window> *ancestor = 0;
1120 FindRelation(fromView, toView, &ancestor);
1122 if (IsInBranch(nil, fromView, grabView)) {
1124 SendLeaveEvent(queue, grabView, theEvent, kNotifyNormal);
1125 }
else if (IsInBranch(nil, toView, grabView)) {
1127 SendEnterEvent(queue, grabView, theEvent, kNotifyNormal);
1135 EventTranslator::EventTranslator()
1136 : fViewUnderPointer(nil),
1137 fPointerGrabType(kPGNoGrab),
1140 fButtonGrabView(nil),
1143 fImplicitGrabButton(kAnyButton)
1149 void EventTranslator::GenerateConfigureNotifyEvent(NSView<X11Window> *view,
const NSRect &newFrame)
1151 assert(view != nil &&
"GenerateConfigureNotifyEvent, parameter 'view' is nil");
1153 Event_t newEvent = {};
1154 newEvent.fWindow = view.fID;
1155 newEvent.fType = kConfigureNotify;
1157 newEvent.fX = newFrame.origin.x;
1158 newEvent.fY = newFrame.origin.y;
1160 newEvent.fWidth = newFrame.size.width;
1161 newEvent.fHeight = newFrame.size.height;
1163 TGWindow *
const window = gClient->GetWindowById(view.fID);
1164 if (window) window->HandleEvent(&newEvent);
1168 void EventTranslator::GenerateDestroyNotify(
unsigned )
1174 void EventTranslator::GenerateExposeEvent(NSView<X11Window> *view,
const NSRect &exposedRect)
1176 assert(view != nil &&
"GenerateExposeEvent, parameter 'view' is nil");
1178 Event_t exposeEvent = {};
1179 exposeEvent.fWindow = view.fID;
1180 exposeEvent.fType = kExpose;
1181 exposeEvent.fX = exposedRect.origin.x;
1182 exposeEvent.fY = exposedRect.origin.y;
1183 exposeEvent.fWidth = exposedRect.size.width;
1184 exposeEvent.fHeight = exposedRect.size.height;
1186 TGWindow *
const window = gClient->GetWindowById(view.fID);
1187 assert(window != 0 &&
"GenerateExposeEvent, window was not found");
1188 window->HandleEvent(&exposeEvent);
1192 void EventTranslator::GenerateCrossingEvent(NSEvent *theEvent)
1195 assert(theEvent != nil &&
"GenerateCrossingEvent, parameter 'event' is nil");
1197 fPointerGrabType == kPGNoGrab ? GenerateCrossingEventNoGrab(theEvent) :
1198 GenerateCrossingEventActiveGrab(theEvent);
1202 void EventTranslator::GenerateCrossingEventNoGrab(NSEvent *theEvent)
1204 assert(theEvent &&
"GenerateCrossingEventNoGrab, parameter 'theEvent' is nil");
1206 NSView<X11Window> *
const candidateView = FindViewForPointerEvent(theEvent);
1208 Detail::GenerateCrossingEvents(fEventQueue, fViewUnderPointer, candidateView, theEvent, kNotifyNormal);
1209 fViewUnderPointer = candidateView;
1213 void EventTranslator::GenerateCrossingEventActiveGrab(NSEvent *theEvent)
1215 assert(theEvent != nil &&
"GenerateCrossingEventActiveGrab, parameter 'theEvent' is nil");
1217 NSView<X11Window> *
const candidateView = FindViewForPointerEvent(theEvent);
1224 Detail::GenerateCrossingEvents(fEventQueue, fViewUnderPointer, candidateView,
1225 theEvent, kNotifyNormal);
1226 }
else if (fButtonGrabView && (fViewUnderPointer || candidateView)) {
1230 Detail::GenerateCrossingEventForGrabView(fEventQueue, fViewUnderPointer, candidateView,
1231 fButtonGrabView, fGrabEventMask, theEvent);
1234 fViewUnderPointer = candidateView;
1238 bool EventTranslator::HasPointerGrab()
const
1240 return fPointerGrabType != kPGNoGrab;
1244 void EventTranslator::GeneratePointerMotionEvent(NSEvent *theEvent)
1246 assert(theEvent != nil &&
"GeneratePointerMotionEvent, parameter 'theEvent' is nil");
1250 if (fPointerGrabType == kPGNoGrab)
1251 return GeneratePointerMotionEventNoGrab(theEvent);
1253 return GeneratePointerMotionEventActiveGrab(theEvent);
1257 void EventTranslator::GenerateButtonPressEvent(NSView<X11Window> *eventView, NSEvent *theEvent,
1260 assert(eventView != nil &&
"GenerateButtonPressEvent, parameter 'eventView' is nil");
1261 assert(theEvent != nil &&
"GenerateButtonpressEvent, parameter 'theEvent' is nil");
1263 if (fPointerGrabType == kPGNoGrab)
1264 return GenerateButtonPressEventNoGrab(eventView, theEvent, btn);
1266 return GenerateButtonPressEventActiveGrab(eventView, theEvent, btn);
1270 void EventTranslator::GenerateButtonReleaseEvent(NSView<X11Window> *eventView, NSEvent *theEvent,
1273 assert(eventView != nil &&
"GenerateButtonReleaseEvent, parameter 'eventView' is nil");
1274 assert(theEvent != nil &&
"GenerateButtonReleaseEvent, parameter 'theEvent' is nil");
1276 if (fPointerGrabType == kPGNoGrab)
1277 return GenerateButtonReleaseEventNoGrab(eventView, theEvent, btn);
1279 return GenerateButtonReleaseEventActiveGrab(eventView, theEvent, btn);
1285 void EventTranslator::GenerateKeyPressEvent(NSView<X11Window> *eventView, NSEvent *theEvent)
1287 assert(eventView != nil &&
"GenerateKeyPressEvent, parameter 'eventView' is nil");
1288 assert(theEvent != nil &&
"GenerateKeyPressEvent, parameter 'theEvent' is nil");
1290 if (![[theEvent charactersIgnoringModifiers] length])
1296 !fKeyGrabView ? GenerateKeyPressEventNoGrab(eventView, theEvent) :
1297 GenerateKeyEventActiveGrab(eventView, theEvent);
1301 void EventTranslator::GenerateKeyReleaseEvent(NSView<X11Window> *eventView, NSEvent *theEvent)
1303 assert(eventView != nil &&
"GenerateKeyReleaseEvent, parameter 'eventView' is nil");
1304 assert(theEvent != nil &&
"GenerateKeyReleaseEvent, parameter 'theEvent' is nil");
1306 if (![[theEvent charactersIgnoringModifiers] length])
1312 !fKeyGrabView ? GenerateKeyReleaseEventNoGrab(eventView, theEvent) :
1314 GenerateKeyEventForView(fKeyGrabView, theEvent);
1321 void EventTranslator::GenerateFocusChangeEvent(NSView<X11Window> *eventView)
1323 if (eventView == fFocusView)
1326 if (fFocusView && (fFocusView.fEventMask & kFocusChangeMask))
1327 Detail::SendFocusOutEvent(fEventQueue, fFocusView, kNotifyNormal);
1330 if (eventView.fEventMask & kFocusChangeMask)
1331 Detail::SendFocusInEvent(fEventQueue, eventView, kNotifyNormal);
1333 fFocusView = eventView;
1339 void EventTranslator::SetPointerGrab(NSView<X11Window> *grabView,
unsigned eventMask,
bool ownerEvents)
1341 assert(grabView != nil &&
"SetPointerGrab, parameter 'grabView' is nil");
1343 if (fButtonGrabView) {
1346 [fButtonGrabView cancelGrab];
1351 fImplicitGrabButton = kAnyButton;
1354 fButtonGrabView = grabView;
1355 fPointerGrabType = kPGActiveGrab;
1356 fGrabEventMask = eventMask;
1357 fOwnerEvents = ownerEvents;
1362 if (grabView != fViewUnderPointer) {
1363 const NSPoint location = [[grabView window] mouseLocationOutsideOfEventStream];
1364 const Util::NSScopeGuard<FakeCrossingEvent> event([[FakeCrossingEvent alloc] initWithWindow : [grabView window]
1365 location : location]);
1368 NSLog(
@"EventTranslator::SetPointerGrab, crossing event initialization failed");
1372 Detail::GenerateCrossingEvents(fEventQueue, fViewUnderPointer, grabView, event.Get(), kNotifyGrab);
1376 [fButtonGrabView activateGrab : eventMask ownerEvents : fOwnerEvents];
1380 void EventTranslator::CancelPointerGrab()
1382 if (fButtonGrabView)
1384 [fButtonGrabView cancelGrab];
1388 if (NSView<X11Window> *
const candidateView = FindViewUnderPointer()) {
1389 const NSPoint location = [[candidateView window] mouseLocationOutsideOfEventStream];
1390 const Util::NSScopeGuard<FakeCrossingEvent> event([[FakeCrossingEvent alloc] initWithWindow : [candidateView window]
1391 location : location ]);
1395 NSLog(
@"EventTranslator::CancelPointerGrab, crossing event initialization failed");
1399 Detail::GenerateCrossingEvents(fEventQueue, fButtonGrabView, candidateView, event.Get(), kNotifyUngrab);
1401 fViewUnderPointer = candidateView;
1402 }
else if (fButtonGrabView) {
1405 const NSPoint location = ConvertPointFromScreenToBase([NSEvent mouseLocation], [fButtonGrabView window]);
1407 const Util::NSScopeGuard<FakeCrossingEvent> event([[FakeCrossingEvent alloc] initWithWindow : [fButtonGrabView window]
1408 location : location ]);
1412 NSLog(
@"EventTranslator::CancelPointerGrab, crossing event initialization failed");
1413 fViewUnderPointer = nil;
1417 Detail::GenerateCrossingEvents(fEventQueue, fButtonGrabView, nil, event.Get(), kNotifyUngrab);
1419 fViewUnderPointer = nil;
1423 fImplicitGrabButton = kAnyButton;
1424 fButtonGrabView = nil;
1425 fPointerGrabType = kPGNoGrab;
1427 fOwnerEvents =
true;
1431 void EventTranslator::SetInputFocus(NSView<X11Window> *newFocusView)
1433 if (fFocusView && (fFocusView.fEventMask & kFocusChangeMask))
1434 Detail::SendFocusOutEvent(fEventQueue, fFocusView, kNotifyNormal);
1437 if (newFocusView.fEventMask & kFocusChangeMask)
1438 Detail::SendFocusInEvent(fEventQueue, newFocusView, kNotifyNormal);
1440 fFocusView = newFocusView;
1447 unsigned EventTranslator::GetInputFocus()
const
1450 return fFocusView.fID;
1458 void ClearPointerIfViewIsRelated(NSView<X11Window> *&view, Window_t winID)
1460 NSView<X11Window> *v = view;
1462 for (; v; v = v.fParentView) {
1463 if (v.fID == winID) {
1474 void EventTranslator::CheckUnmappedView(Window_t winID)
1479 if (fButtonGrabView) {
1480 for (NSView<X11Window> *view = fButtonGrabView; view; view = view.fParentView) {
1481 if (view.fID == winID) {
1482 CancelPointerGrab();
1488 if (fViewUnderPointer) {
1489 for (NSView<X11Window> *view = fViewUnderPointer; view; view = view.fParentView) {
1490 if (view.fID == winID) {
1491 NSPoint location = {};
1492 location.x = fViewUnderPointer.fWidth / 2;
1493 location.y = fViewUnderPointer.fHeight / 2;
1494 location = [fViewUnderPointer convertPoint : location toView : nil];
1496 const Util::NSScopeGuard<FakeCrossingEvent> event([[FakeCrossingEvent alloc]
1497 initWithWindow : [fViewUnderPointer window]
1498 location : location]);
1501 NSLog(
@"EventTranslator::CheckUnmappedView, crossing event initialization failed");
1505 Detail::SendLeaveEvent(fEventQueue, fViewUnderPointer, event.Get(), kNotifyNormal);
1506 fViewUnderPointer = nil;
1513 ClearPointerIfViewIsRelated(fFocusView, winID);
1514 ClearPointerIfViewIsRelated(fKeyGrabView, winID);
1518 void EventTranslator::GeneratePointerMotionEventNoGrab(NSEvent *theEvent)
1521 assert(theEvent != nil &&
"GeneratePointerMotionEventNoGrab, parameter 'theEvent' is nil");
1523 const Mask_t maskToTest = [NSEvent pressedMouseButtons] ?
1524 (kPointerMotionMask | kButtonMotionMask) :
1528 if (NSView<X11Window> *candidateView = FindViewForPointerEvent(theEvent)) {
1530 candidateView = Detail::FindViewToPropagateEvent(candidateView, maskToTest);
1532 Detail::SendPointerMotionEvent(fEventQueue, candidateView, theEvent);
1537 void EventTranslator::GeneratePointerMotionEventActiveGrab(NSEvent *theEvent)
1544 if (!fButtonGrabView)
1548 assert(theEvent != nil &&
"GeneratePointerMotionEventActiveGrab, parameter 'theEvent' is nil");
1550 const Mask_t maskToTest = [NSEvent pressedMouseButtons] ?
1551 (kPointerMotionMask | kButtonMotionMask) :
1556 if (NSView<X11Window> *candidateView = FindViewForPointerEvent(theEvent)) {
1557 candidateView = Detail::FindViewToPropagateEvent(candidateView, maskToTest,
1558 fButtonGrabView, fGrabEventMask);
1560 Detail::SendPointerMotionEvent(fEventQueue, candidateView, theEvent);
1564 if (fGrabEventMask & maskToTest)
1565 Detail::SendPointerMotionEvent(fEventQueue, fButtonGrabView, theEvent);
1569 if (fGrabEventMask & maskToTest)
1570 Detail::SendPointerMotionEvent(fEventQueue, fButtonGrabView, theEvent);
1575 void EventTranslator::GenerateButtonPressEventNoGrab(NSView<X11Window> *view, NSEvent *theEvent,
1582 assert(view != nil &&
"GenerateButtonPressEventNoGrab, parameter 'view' is nil");
1583 assert(theEvent != nil &&
"GenerateButtonPressEventNoGrab, parameter 'theEvent' is nil");
1585 FindButtonGrab(view, theEvent, btn);
1587 fImplicitGrabButton = btn;
1592 Detail::GenerateCrossingEvents(fEventQueue, fViewUnderPointer, fButtonGrabView, theEvent, kNotifyGrab);
1595 if (fButtonGrabView) {
1596 if (fPointerGrabType == kPGPassiveGrab)
1597 [fButtonGrabView activatePassiveGrab];
1598 else if (fPointerGrabType == kPGImplicitGrab)
1599 [fButtonGrabView activateImplicitGrab];
1604 if (fButtonGrabView)
1605 Detail::SendButtonPressEvent(fEventQueue, fButtonGrabView, theEvent, btn);
1609 void EventTranslator::GenerateButtonPressEventActiveGrab(NSView<X11Window> * , NSEvent *theEvent,
1615 assert(theEvent != nil &&
"GenerateButtonPressEventActiveGrab, parameter 'theEvent' is nil");
1621 if (!fButtonGrabView)
1625 if (NSView<X11Window> *candidateView = FindViewForPointerEvent(theEvent)) {
1627 candidateView = Detail::FindViewToPropagateEvent(candidateView, kButtonPressMask,
1628 fButtonGrabView, fGrabEventMask);
1631 Detail::SendButtonPressEvent(fEventQueue, candidateView, theEvent, btn);
1633 if (fGrabEventMask & kButtonPressMask)
1634 Detail::SendButtonPressEvent(fEventQueue, fButtonGrabView, theEvent, btn);
1637 if (fGrabEventMask & kButtonPressMask)
1638 Detail::SendButtonPressEvent(fEventQueue, fButtonGrabView, theEvent, btn);
1643 void EventTranslator::GenerateButtonReleaseEventNoGrab(NSView<X11Window> *eventView, NSEvent *theEvent,
1647 assert(eventView != nil &&
"GenerateButtonReleaseEventNoGrab, parameter 'eventView' is nil");
1648 assert(theEvent != nil &&
"GenerateButtonReleaseEventNoGrabm parameter 'theEvent' is nil");
1650 if (NSView<X11Window> *candidateView = Detail::FindViewToPropagateEvent(eventView, kButtonReleaseMask))
1651 Detail::SendButtonReleaseEvent(fEventQueue, candidateView, theEvent, btn);
1655 void EventTranslator::GenerateButtonReleaseEventActiveGrab(NSView<X11Window> *eventView, NSEvent *theEvent,
1660 assert(eventView != nil &&
"GenerateButtonReleaseEventActiveGrab, parameter 'eventView' is nil");
1661 assert(theEvent != nil &&
"GenerateButtonReleaseEventActiveGrab, parameter 'theEvent' is nil");
1663 if (!fButtonGrabView) {
1665 CancelPointerGrab();
1670 const Util::NSStrongReference<NSView<X11Window> *> eventViewGuard(eventView);
1672 if (fButtonGrabView) {
1674 if (NSView<X11Window> *candidateView = FindViewForPointerEvent(theEvent)) {
1675 candidateView = Detail::FindViewToPropagateEvent(candidateView, kButtonReleaseMask,
1676 fButtonGrabView, fGrabEventMask);
1679 Detail::SendButtonReleaseEvent(fEventQueue, candidateView, theEvent, btn);
1680 }
else if (fGrabEventMask & kButtonReleaseMask)
1681 Detail::SendButtonReleaseEvent(fEventQueue, fButtonGrabView, theEvent, btn);
1683 if (fGrabEventMask & kButtonReleaseMask)
1684 Detail::SendButtonReleaseEvent(fEventQueue, fButtonGrabView, theEvent, btn);
1687 CancelPointerGrab();
1690 if (fPointerGrabType == kPGPassiveGrab &&
1691 (btn == fButtonGrabView.fPassiveGrabButton || fButtonGrabView.fPassiveGrabButton == kAnyButton))
1692 CancelPointerGrab();
1694 if (fPointerGrabType == kPGImplicitGrab && btn == fImplicitGrabButton)
1695 CancelPointerGrab();
1699 void EventTranslator::GenerateKeyPressEventNoGrab(NSView<X11Window> *eventView, NSEvent *theEvent)
1701 assert(eventView != nil &&
"GenerateKeyPressEventNoGrab, parameter 'eventView' is nil");
1702 assert(theEvent != nil &&
"GenerateKeyPressEventNoGrab, parameter 'theEvent' is nil");
1703 assert(fFocusView != nil &&
"GenerateKeyPressEventNoGrab, fFocusView is nil");
1705 FindKeyGrabView(eventView, theEvent);
1707 if (!fKeyGrabView) {
1708 NSView<X11Window> *candidateView = fFocusView;
1709 if (Detail::IsParent(fFocusView, eventView)) {
1710 NSView<X11Window> *
const testView = Detail::FindViewToPropagateEvent(eventView, kKeyPressMask);
1712 if (testView && (testView == fFocusView || Detail::IsParent(fFocusView, testView)))
1713 candidateView = testView;
1716 GenerateKeyEventForView(candidateView, theEvent);
1718 GenerateKeyEventForView(fKeyGrabView, theEvent);
1722 void EventTranslator::GenerateKeyEventActiveGrab(NSView<X11Window> *eventView, NSEvent *theEvent)
1724 assert(eventView != nil &&
"GenerateKeyEventActiveGrab, parameter 'eventView' is nil");
1725 assert(theEvent != nil &&
"GenerateKeyEventActiveGrab, parameter 'theEvent' is nil");
1726 assert(fFocusView != nil &&
"GenerateKeyEventActiveGrab, fFocusView is nil");
1728 const Mask_t eventMask = theEvent.type == Details::kKeyDown ? kKeyPressMask : kKeyReleaseMask;
1730 if (Detail::IsParent(fFocusView, eventView) || fFocusView == eventView) {
1731 NSView<X11Window> *
const testView = Detail::FindViewToPropagateEvent(eventView, eventMask);
1732 if (testView && (testView == fFocusView || Detail::IsParent(fFocusView, testView)))
1733 GenerateKeyEventForView(testView, theEvent);
1735 GenerateKeyEventForView(fFocusView, theEvent);
1737 if (theEvent.type == Details::kKeyUp && fKeyGrabView) {
1755 void EventTranslator::GenerateKeyReleaseEventNoGrab(NSView<X11Window> *eventView, NSEvent *theEvent)
1757 assert(eventView != nil &&
"GenerateKeyReleaseEventNoGrab, parameter 'eventView' is nil");
1758 assert(theEvent != nil &&
"GenerateKeyReleaseEventNoGrab, parameter 'theEvent' is nil");
1760 NSView<X11Window> *candidateView = fFocusView;
1762 if (eventView == fFocusView || Detail::IsParent(fFocusView, eventView)) {
1763 NSView<X11Window> *
const testView = Detail::FindViewToPropagateEvent(eventView, kKeyReleaseMask);
1764 if (testView && (testView == fFocusView || Detail::IsParent(fFocusView, testView)))
1765 candidateView = testView;
1768 GenerateKeyEventForView(candidateView, theEvent);
1772 void EventTranslator::GenerateKeyEventForView(NSView<X11Window> *view, NSEvent *theEvent)
1775 assert(view != nil &&
"GenerateKeyEventForView, parameter 'view' is nil");
1776 assert(theEvent != nil &&
"GenerateKeyEventForView, parameter 'theEvent' is nil");
1777 assert((theEvent.type == Details::kKeyDown || theEvent.type == Details::kKeyUp) &&
1778 "GenerateKeyEvenForView, event's type must be keydown or keyup");
1780 const Mask_t eventType = theEvent.type == Details::kKeyDown ? kKeyPressMask : kKeyReleaseMask;
1782 NSView<X11Window> *childView = nil;
1784 NSPoint mousePosition = {};
1785 if (QuartzWindow *
const topLevel = FindWindowUnderPointer())
1786 mousePosition = [topLevel mouseLocationOutsideOfEventStream];
1788 if (eventType == kKeyPressMask)
1789 Detail::SendKeyPressEvent(fEventQueue, view, childView, theEvent, mousePosition);
1791 Detail::SendKeyReleaseEvent(fEventQueue, view, childView, theEvent, mousePosition);
1795 void EventTranslator::FindButtonGrab(NSView<X11Window> *fromView, NSEvent *theEvent, EMouseButton btn)
1799 assert(fromView != nil &&
"FindButtonGrabView, parameter 'fromView' is nil");
1800 assert(theEvent != nil &&
"FindButtonGrabView, parameter 'theEvent' is nil");
1802 assert(fPointerGrabType == kPGNoGrab &&
"FindButtonGrabView, grab is already activated");
1804 const unsigned keyModifiers = Detail::GetKeyboardModifiersFromCocoaEvent(theEvent);
1806 NSView<X11Window> *grabView = 0;
1807 NSView<X11Window> *buttonPressView = 0;
1809 for (NSView<X11Window> *view = fromView; view != nil; view = view.fParentView) {
1811 if (!buttonPressView && (view.fEventMask & kButtonPressMask))
1812 buttonPressView = view;
1815 if (view.fPassiveGrabButton == kAnyButton || view.fPassiveGrabButton == btn) {
1817 if (view.fPassiveGrabKeyModifiers == kAnyModifier || (view.fPassiveGrabKeyModifiers & keyModifiers))
1823 fButtonGrabView = grabView;
1824 fPointerGrabType = kPGPassiveGrab;
1825 fGrabEventMask = grabView.fPassiveGrabEventMask;
1826 fOwnerEvents = grabView.fPassiveGrabOwnerEvents;
1827 }
else if (buttonPressView) {
1829 fButtonGrabView = buttonPressView;
1830 fPointerGrabType = kPGImplicitGrab;
1831 fGrabEventMask = buttonPressView.fEventMask;
1832 fOwnerEvents =
false;
1835 fButtonGrabView = nil;
1836 fPointerGrabType = kPGImplicitGrab;
1838 fOwnerEvents =
false;
1843 void EventTranslator::FindKeyGrabView(NSView<X11Window> *eventView, NSEvent *theEvent)
1845 assert(eventView != nil &&
"FindKeyGrabView, parameter 'eventView' is nil");
1846 assert(theEvent != nil &&
"FindKeyGrabView, parameter 'theEvent' is nil");
1848 NSString *
const characters = [theEvent charactersIgnoringModifiers];
1849 assert(characters != nil &&
"FindKeyGrabView, [theEvent characters] returned nil");
1850 assert([characters length] > 0 &&
"FindKeyGrabView, characters is an empty string");
1852 const unichar keyCode = [characters characterAtIndex : 0];
1853 const NSUInteger modifiers = [theEvent modifierFlags] & Details::kDeviceIndependentModifierFlagsMask;
1855 NSView<X11Window> *currentView = fFocusView;
1856 if (eventView != fFocusView && Detail::IsParent(fFocusView, eventView))
1857 currentView = eventView;
1859 for (; currentView; currentView = currentView.fParentView) {
1860 if ([currentView findPassiveKeyGrab : keyCode modifiers : modifiers])
1861 fKeyGrabView = currentView;