summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXMouseEvent.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXMouseEvent.c')
-rw-r--r--macosx/tkMacOSXMouseEvent.c80
1 files changed, 56 insertions, 24 deletions
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 10a615e..cd3eac1 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -26,7 +26,7 @@ typedef struct {
static int GenerateButtonEvent(MouseEventData *medPtr);
static unsigned int ButtonModifiers2State(UInt32 buttonState,
- UInt32 keyModifiers);
+ UInt32 keyModifiers);
#pragma mark TKApplication(TKMouseEvent)
@@ -34,26 +34,41 @@ enum {
NSWindowWillMoveEventType = 20
};
+/*
+ * In OS X 10.6 an NSEvent of type NSMouseMoved would always have a non-Nil
+ * window attribute pointing to the active window. As of 10.8 this behavior
+ * had changed. The new behavior was that if the mouse were ever moved outside
+ * of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
+ * attribute. To work around this the TKApplication remembers the last non-Nil
+ * window that it received in a mouse event. If it receives an NSEvent with a
+ * Nil window attribute then the saved window is used.
+ */
+
@implementation TKApplication(TKMouseEvent)
- (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent {
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
- id win;
- NSEventType type = [theEvent type];
+ NSWindow* eventWindow = [theEvent window];
+ NSEventType eventType = [theEvent type];
#if 0
NSTrackingArea *trackingArea = nil;
NSInteger eventNumber, clickCount, buttonNumber;
#endif
- switch (type) {
+ switch (eventType) {
case NSMouseEntered:
+ /* Remember which window has the mouse. */
+ if (_windowWithMouse) {
+ [_windowWithMouse release];
+ }
+ _windowWithMouse = [theEvent window];
+ if (_windowWithMouse) {
+ [_windowWithMouse retain];
+ }
+ break;
case NSMouseExited:
case NSCursorUpdate:
-#if 0
- trackingArea = [theEvent trackingArea];
- /* fall through */
-#endif
case NSLeftMouseDown:
case NSLeftMouseUp:
case NSRightMouseDown:
@@ -75,24 +90,39 @@ enum {
case NSTabletProximity:
case NSScrollWheel:
break;
-
default: /* Unrecognized mouse event. */
return theEvent;
}
+ /* Remember the window in case we need it next time. */
+ if (eventWindow && eventWindow != _windowWithMouse) {
+ if (_windowWithMouse) {
+ [_windowWithMouse release];
+ }
+ _windowWithMouse = eventWindow;
+ [_windowWithMouse retain];
+ }
+
/* Create an Xevent to add to the Tk queue. */
- win = [theEvent window];
NSPoint global, local = [theEvent locationInWindow];
- if (win) {
- global = [win convertBaseToScreen:local];
- local.y = [win frame].size.height - local.y;
+ if (eventWindow) { /* local will be in window coordinates. */
+ global = [eventWindow convertPointToScreen: local];
+ local.y = [eventWindow frame].size.height - local.y;
global.y = tkMacOSXZeroScreenHeight - global.y;
- } else {
- local.y = tkMacOSXZeroScreenHeight - local.y;
- global = local;
+ } else { /* local will be in screen coordinates. */
+ if (_windowWithMouse ) {
+ eventWindow = _windowWithMouse;
+ global = local;
+ local = [eventWindow convertPointFromScreen: local];
+ local.y = [eventWindow frame].size.height - local.y;
+ global.y = tkMacOSXZeroScreenHeight - global.y;
+ } else { /* We have no window. Use the screen???*/
+ local.y = tkMacOSXZeroScreenHeight - local.y;
+ global = local;
+ }
}
- Window window = TkMacOSXGetXWindow(win);
+ Window window = TkMacOSXGetXWindow(eventWindow);
Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
window) : NULL;
if (!tkwin) {
@@ -120,7 +150,7 @@ enum {
state |= (buttons & ((1<<5) - 1)) << 8;
} else {
if (button < 5) {
- switch (type) {
+ switch (eventType) {
case NSLeftMouseDown:
case NSRightMouseDown:
case NSLeftMouseDragged:
@@ -157,12 +187,12 @@ enum {
state |= Mod4Mask;
}
- if (type != NSScrollWheel) {
+ if (eventType != NSScrollWheel) {
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d", tkwin, global.x, global.y, state);
#endif
Tk_UpdatePointer(tkwin, global.x, global.y, state);
- } else {
+ } else { /* handle scroll wheel event */
CGFloat delta;
int coarseDelta;
XEvent xEvent;
@@ -178,7 +208,8 @@ enum {
delta = [theEvent deltaY];
if (delta != 0.0) {
- coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);
+ coarseDelta = (delta > -1.0 && delta < 1.0) ?
+ (signbit(delta) ? -1 : 1) : lround(delta);
xEvent.xbutton.state = state;
xEvent.xkey.keycode = coarseDelta;
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -186,7 +217,8 @@ enum {
}
delta = [theEvent deltaX];
if (delta != 0.0) {
- coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta);
+ coarseDelta = (delta > -1.0 && delta < 1.0) ?
+ (signbit(delta) ? -1 : 1) : lround(delta);
xEvent.xbutton.state = state | ShiftMask;
xEvent.xkey.keycode = coarseDelta;
xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -357,7 +389,7 @@ XQueryPointer(
if (win) {
NSPoint local;
- local = [win convertScreenToBase:global];
+ local = [win convertPointFromScreen:global];
local.y = [win frame].size.height - local.y;
if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
local.x -= macWin->winPtr->wmInfoPtr->xInParent;
@@ -455,7 +487,7 @@ TkGenerateButtonEvent(
if (win) {
NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
- local = [win convertScreenToBase:local];
+ local = [win convertPointFromScreen:local];
local.y = [win frame].size.height - local.y;
if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
local.x -= macWin->winPtr->wmInfoPtr->xInParent;