summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXMouseEvent.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXMouseEvent.c')
-rw-r--r--macosx/tkMacOSXMouseEvent.c985
1 files changed, 187 insertions, 798 deletions
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 04fa202..a910447 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -4,51 +4,13 @@
* This file implements functions that decode & handle mouse events on
* MacOS X.
*
- * Copyright 2001, Apple Computer, Inc.
- * Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright 2001-2009, Apple Inc.
+ * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * The following terms apply to all files originating from Apple
- * Computer, Inc. ("Apple") and associated with the software unless
- * explicitly disclaimed in individual files.
- *
- * Apple hereby grants permission to use, copy, modify, distribute, and
- * license this software and its documentation for any purpose, provided
- * that existing copyright notices are retained in all copies and that
- * this notice is included verbatim in any distributions. No written
- * agreement, license, or royalty fee is required for any of the
- * authorized uses. Modifications to this software may be copyrighted by
- * their authors and need not follow the licensing terms described here,
- * provided that the new terms are clearly indicated on the first page of
- * each file where they apply.
- *
- * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE SOFTWARE
- * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS
- * DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF APPLE OR THE
- * AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. APPLE,
- * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
- * NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
- * APPLE,THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
- * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * GOVERNMENT USE: If you are acquiring this software on behalf of the
- * U.S. government, the Government shall have only "Restricted Rights" in
- * the software and related documentation as defined in the Federal
- * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are
- * acquiring the software on behalf of the Department of Defense, the
- * software shall be classified as "Commercial Computer Software" and the
- * Government shall have only "Restricted Rights" as defined in Clause
- * 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
- * authors grant the U.S. Government and others acting in its behalf
- * permission to use and distribute the software in accordance with the
- * terms specified in this license.
- *
- * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.35 2008/10/27 11:55:45 dkf Exp $
+ * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.36 2009/06/29 14:35:01 das Exp $
*/
#include "tkMacOSXPrivate.h"
@@ -57,9 +19,6 @@
#include "tkMacOSXDebug.h"
typedef struct {
- WindowRef whichWin;
- WindowRef activeNonFloating;
- WindowPartCode windowPart;
unsigned int state;
long delta;
Window window;
@@ -67,684 +26,191 @@ typedef struct {
Point local;
} MouseEventData;
-/*
- * Declarations of static variables used in this file.
- */
-
-static int gEatButtonUp = 0; /* 1 if we need to eat the next up event. */
-
-/*
- * Declarations of functions used only in this file.
- */
-
-static void BringWindowForward(WindowRef wRef, int isFrontProcess,
- int frontWindowOnly);
-static int GeneratePollingEvents(MouseEventData *medPtr);
-static int GenerateMouseWheelEvent(MouseEventData *medPtr);
static int GenerateButtonEvent(MouseEventData *medPtr);
-static int GenerateToolbarButtonEvent(MouseEventData *medPtr);
-static int HandleWindowTitlebarMouseDown(MouseEventData *medPtr,
- Tk_Window tkwin);
static unsigned int ButtonModifiers2State(UInt32 buttonState,
UInt32 keyModifiers);
-static Tk_Window GetGrabWindowForWindow(Tk_Window tkwin);
-static int TkMacOSXGetEatButtonUp(void);
-static void TkMacOSXSetEatButtonUp(int f);
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXProcessMouseEvent --
- *
- * This routine processes the event in eventPtr, and generates the
- * appropriate Tk events from it.
- *
- * Results:
- * True if event(s) are generated - false otherwise.
- *
- * Side effects:
- * Additional events may be place on the Tk event queue.
- *
- *----------------------------------------------------------------------
- */
-
-MODULE_SCOPE int
-TkMacOSXProcessMouseEvent(
- TkMacOSXEvent *eventPtr,
- MacEventStatus *statusPtr)
-{
- Tk_Window tkwin;
- Point where, where2;
- int result;
- TkDisplay *dispPtr;
- OSStatus err;
- MouseEventData mouseEventData, *medPtr = &mouseEventData;
- int isFrontProcess;
-
- switch (eventPtr->eKind) {
- case kEventMouseDown:
- case kEventMouseUp:
- case kEventMouseMoved:
- case kEventMouseDragged:
- case kEventMouseWheelMoved:
- break;
- default:
- return false;
- }
-
- err = ChkErr(GetEventParameter, eventPtr->eventRef,
- kEventParamMouseLocation, typeQDPoint, NULL, sizeof(where), NULL,
- &where);
- if (err != noErr) {
- GetGlobalMouse(&where);
- }
-
- err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowRef,
- typeWindowRef, NULL, sizeof(WindowRef), NULL, &medPtr->whichWin);
- if (err == noErr) {
- err = ChkErr(GetEventParameter, eventPtr->eventRef,
- kEventParamWindowPartCode, typeWindowPartCode, NULL,
- sizeof(WindowPartCode), NULL, &medPtr->windowPart);
- }
- if (err != noErr) {
- medPtr->windowPart = FindWindow(where, &medPtr->whichWin);
- }
- medPtr->window = TkMacOSXGetXWindow(medPtr->whichWin);
- if (medPtr->whichWin != NULL && medPtr->window == None) {
- return false;
- }
- if (eventPtr->eKind == kEventMouseDown) {
- if (IsWindowActive(medPtr->whichWin) && IsWindowPathSelectEvent(
- medPtr->whichWin, eventPtr->eventRef)) {
- ChkErr(WindowPathSelect, medPtr->whichWin, NULL, NULL);
- return false;
- }
- if (medPtr->windowPart == inProxyIcon) {
- TkMacOSXTrackingLoop(1);
- err = ChkErr(TrackWindowProxyDrag, medPtr->whichWin, where);
- TkMacOSXTrackingLoop(0);
- if (err == errUserWantsToDragWindow) {
- medPtr->windowPart = inDrag;
- } else {
- return false;
- }
- }
- }
- isFrontProcess = Tk_MacOSXIsAppInFront();
- if (isFrontProcess) {
- medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(),
- GetCurrentEventKeyModifiers());
- } else {
- medPtr->state = ButtonModifiers2State(GetCurrentButtonState(),
- GetCurrentKeyModifiers());
- }
- medPtr->global = where;
- err = ChkErr(GetEventParameter, eventPtr->eventRef,
- kEventParamWindowMouseLocation, typeQDPoint, NULL,
- sizeof(Point), NULL, &medPtr->local);
- if (err == noErr) {
- if (medPtr->whichWin) {
- Rect widths;
-
- GetWindowStructureWidths(medPtr->whichWin, &widths);
- medPtr->local.h -= widths.left;
- medPtr->local.v -= widths.top;
- }
- } else {
- medPtr->local = where;
- if (medPtr->whichWin) {
- QDGlobalToLocalPoint(GetWindowPort(medPtr->whichWin),
- &medPtr->local);
- }
- }
- medPtr->activeNonFloating = ActiveNonFloatingWindow();
- dispPtr = TkGetDisplayList();
- tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
-
- if (eventPtr->eKind != kEventMouseDown) {
- int res = false;
-
- switch (eventPtr->eKind) {
- case kEventMouseUp:
- /*
- * The window manager only needs to know about mouse down events
- * and sometimes we need to "eat" the mouse up. Otherwise, we just
- * pass the event to Tk.
- */
-
- if (TkMacOSXGetEatButtonUp()) {
- TkMacOSXSetEatButtonUp(false);
- } else {
- res = GenerateButtonEvent(medPtr);
- }
- break;
- case kEventMouseWheelMoved:
- err = ChkErr(GetEventParameter, eventPtr->eventRef,
- kEventParamMouseWheelDelta, typeLongInteger, NULL,
- sizeof(long), NULL, &medPtr->delta);
- if (err != noErr ) {
- statusPtr->err = 1;
- } else {
- EventMouseWheelAxis axis;
-
- err = ChkErr(GetEventParameter, eventPtr->eventRef,
- kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL,
- sizeof(EventMouseWheelAxis), NULL, &axis);
- if (err == noErr && axis == kEventMouseWheelAxisX) {
- medPtr->state |= ShiftMask;
- }
- res = GenerateMouseWheelEvent(medPtr);
- }
- break;
- case kEventMouseMoved:
- case kEventMouseDragged:
- res = GeneratePollingEvents(medPtr);
- break;
- default:
- Tcl_Panic("Unknown mouse event !");
- }
- if (res) {
- statusPtr->stopProcessing = 1;
- }
- return res;
- }
-
- TkMacOSXSetEatButtonUp(false);
- if (!medPtr->whichWin) {
- return false;
- }
-
- /*
- * We got a mouse down in a window, so see if this is the activate click.
- * This click moves the window forward. We don't want the corresponding
- * mouse-up to be reported to the application or else it will mess up some
- * Tk scripts.
- */
-
- if (!(TkpIsWindowFloating(medPtr->whichWin))
- && (medPtr->whichWin != medPtr->activeNonFloating
- || !isFrontProcess)) {
- int frontWindowOnly = 1;
- int cmdDragGrow = ((medPtr->windowPart == inDrag ||
- medPtr->windowPart == inGrow) && medPtr->state & Mod1Mask);
-
- if (!cmdDragGrow) {
- Tk_Window grabWin = GetGrabWindowForWindow(tkwin);
-
- frontWindowOnly = !grabWin;
- if (grabWin && grabWin != tkwin) {
- TkMacOSXSetEatButtonUp(true);
- BringWindowForward(TkMacOSXDrawableWindow(
- ((TkWindow *) grabWin)->window), isFrontProcess,
- frontWindowOnly);
- return false;
- }
- }
-
- /*
- * Clicks in the titlebar widgets are handled without bringing the
- * window forward.
- */
-
- result = HandleWindowTitlebarMouseDown(medPtr, tkwin);
- if (result != -1) {
- statusPtr->stopProcessing = 1;
- return result;
- }
-
- /*
- * Only windows with the kWindowNoActivatesAttribute can receive mouse
- * events in the background.
- */
-
- if (!(((TkWindow *)tkwin)->wmInfoPtr->attributes &
- kWindowNoActivatesAttribute)) {
- /*
- * Allow background window dragging & growing with Command down.
- */
- if (!cmdDragGrow) {
- TkMacOSXSetEatButtonUp(true);
- BringWindowForward(medPtr->whichWin, isFrontProcess,
- frontWindowOnly);
- }
+#pragma mark TKApplication(TKMouseEvent)
- /*
- * Allow dragging & growing of windows that were/are in the
- * background.
- */
+enum {
+ NSWindowWillMoveEventType = 20
+};
- if (!(medPtr->windowPart == inDrag ||
- medPtr->windowPart == inGrow)) {
- return false;
- }
- }
- } else {
- result = HandleWindowTitlebarMouseDown(medPtr, tkwin);
- if (result != -1) {
- statusPtr->stopProcessing = 1;
- return result;
- }
- }
-
- switch (medPtr->windowPart) {
- case inDrag: {
- WindowAttributes attributes;
-
- GetWindowAttributes(medPtr->whichWin, &attributes);
- if (!(attributes & kWindowAsyncDragAttribute)) {
- TkMacOSXTrackingLoop(1);
- DragWindow(medPtr->whichWin, where, NULL);
- TkMacOSXTrackingLoop(0);
- where2.h = where2.v = 0;
- QDLocalToGlobalPoint(GetWindowPort(medPtr->whichWin), &where2);
- return (EqualPt(where, where2)) ? false : true;
- }
- break;
- }
- case inGrow:
- /*
- * Generally the content region is the domain of Tk sub-windows.
- * However, one exception is the grow region. A button down in this
- * area will be handled by the window manager. Note: this means that
- * Tk may not get button down events in this area!
- */
+@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];
+#if 0
+ NSTrackingArea *trackingArea = nil;
+ NSInteger eventNumber, clickCount, buttonNumber;
+#endif
- if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) {
- statusPtr->stopProcessing = 1;
- return true;
+ switch (type) {
+ case NSMouseEntered:
+ case NSMouseExited:
+ case NSCursorUpdate:
+#if 0
+ trackingArea = [theEvent trackingArea];
+#endif
+ /* fall through */
+ case NSLeftMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseDown:
+ case NSRightMouseUp:
+ case NSOtherMouseDown:
+ case NSOtherMouseUp:
+
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+
+ case NSMouseMoved:
+#if 0
+ eventNumber = [theEvent eventNumber];
+ if (!trackingArea) {
+ clickCount = [theEvent clickCount];
+ buttonNumber = [theEvent buttonNumber];
}
- case inContent:
- return GenerateButtonEvent(medPtr);
- }
- return false;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * HandleWindowTitlebarMouseDown --
- *
- * Handle clicks in window titlebar.
- *
- * Results:
- * 1 if event was handled, 0 if event was not handled, -1 if MouseDown
- * was not in window titlebar.
- *
- * Side effects:
- * Additional events may be place on the Tk event queue.
- *
- *----------------------------------------------------------------------
- */
+#endif
-int
-HandleWindowTitlebarMouseDown(
- MouseEventData *medPtr,
- Tk_Window tkwin)
-{
- int result = INT_MAX;
+ case NSTabletPoint:
+ case NSTabletProximity:
- switch (medPtr->windowPart) {
- case inGoAway:
- case inCollapseBox:
- case inZoomIn:
- case inZoomOut:
- case inToolbarButton:
- if (!IsWindowActive(medPtr->whichWin)) {
- WindowRef frontWindow = FrontNonFloatingWindow();
- WindowModality frontWindowModality = kWindowModalityNone;
+ case NSScrollWheel:
+ win = [self windowWithWindowNumber:[theEvent windowNumber]];
+ break;
- if (frontWindow && frontWindow != medPtr->whichWin) {
- ChkErr(GetWindowModality, frontWindow,
- &frontWindowModality, NULL);
- }
- if (frontWindowModality == kWindowModalityAppModal) {
- result = 0;
- }
- }
- break;
default:
- result = -1;
+ return theEvent;
break;
}
-
- if (result == INT_MAX) {
- result = 0;
- TkMacOSXTrackingLoop(1);
- switch (medPtr->windowPart) {
- case inGoAway:
- if (TrackGoAway(medPtr->whichWin, medPtr->global) && tkwin) {
- TkGenWMDestroyEvent(tkwin);
- result = 1;
- }
- break;
- case inCollapseBox:
- if (TrackBox(medPtr->whichWin, medPtr->global,
- medPtr->windowPart) && tkwin) {
- TkpWmSetState((TkWindow *) tkwin, IconicState);
- result = 1;
- }
- break;
- case inZoomIn:
- case inZoomOut:
- if (TrackBox(medPtr->whichWin, medPtr->global,
- medPtr->windowPart)) {
- result = TkMacOSXZoomToplevel(medPtr->whichWin,
- medPtr->windowPart);
- }
- break;
- case inToolbarButton:
- if (TrackBox(medPtr->whichWin, medPtr->global,
- medPtr->windowPart)) {
- result = GenerateToolbarButtonEvent(medPtr);
- }
- break;
- }
- TkMacOSXTrackingLoop(0);
- }
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * GeneratePollingEvents --
- *
- * This function polls the mouse position and generates X Motion, Enter &
- * Leave events. The cursor is also updated at this time.
- *
- * Results:
- * True if event(s) are generated - false otherwise.
- *
- * Side effects:
- * Additional events may be place on the Tk event queue. The cursor may
- * be changed.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-GeneratePollingEvents(
- MouseEventData *medPtr)
-{
- Tk_Window tkwin, rootwin, grabWin;
- int local_x, local_y;
- TkDisplay *dispPtr;
-
- grabWin = TkMacOSXGetCapture();
-
- if ((!TkpIsWindowFloating(medPtr->whichWin)
- && (medPtr->activeNonFloating != medPtr->whichWin))) {
- /*
- * If the window for this event is not floating, and is not the active
- * non-floating window, don't generate polling events. We don't send
- * events to backgrounded windows. So either send it to the grabWin,
- * or NULL if there is no grabWin.
- */
-
- tkwin = grabWin;
+ NSPoint global, local = [theEvent locationInWindow];
+ if (win) {
+ global = [win convertBaseToScreen:local];
+ local.y = [win frame].size.height - local.y;
+ global.y = tkMacOSXZeroScreenHeight - global.y;
} else {
- /*
- * First check whether the toplevel containing this mouse event is the
- * grab window. If not, then send the event to the grab window.
- * Otherwise, set tkWin to the subwindow which most closely contains
- * the mouse event.
- */
+ local.y = tkMacOSXZeroScreenHeight - local.y;
+ global = local;
+ }
- dispPtr = TkGetDisplayList();
- rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
- if ((rootwin == NULL)
- || ((grabWin != NULL) && (rootwin != grabWin))) {
- tkwin = grabWin;
- } else {
- tkwin = Tk_TopCoordsToWindow(rootwin, medPtr->local.h,
- medPtr->local.v, &local_x, &local_y);
- }
+ Window window = TkMacOSXGetXWindow(win);
+ Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
+ window) : NULL;
+ if (!tkwin) {
+ tkwin = TkMacOSXGetCapture();
+ }
+ if (!tkwin) {
+ return theEvent;
}
/*
- * The following call will generate the appropiate X events and adjust any
- * state that Tk must remember.
- */
-
- Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v,
- medPtr->state);
- return true;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * BringWindowForward --
- *
- * Bring this background window to the front.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The window is brought forward.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-BringWindowForward(
- WindowRef wRef,
- int isFrontProcess,
- int frontWindowOnly)
-{
- if (wRef && !TkpIsWindowFloating(wRef) && IsValidWindowPtr(wRef)) {
- WindowRef frontWindow = FrontNonFloatingWindow();
- WindowModality frontWindowModality = kWindowModalityNone;
-
- if (frontWindow && frontWindow != wRef) {
- ChkErr(GetWindowModality, frontWindow, &frontWindowModality, NULL);
- }
- if (frontWindowModality != kWindowModalityAppModal) {
- Window window = TkMacOSXGetXWindow(wRef);
-
- if (window != None) {
- TkDisplay *dispPtr = TkGetDisplayList();
- TkWindow *winPtr = (TkWindow *)
- Tk_IdToWindow(dispPtr->display, window);
-
- if (winPtr && winPtr->wmInfoPtr &&
- winPtr->wmInfoPtr->master != None) {
- TkWindow *masterWinPtr = (TkWindow *)Tk_IdToWindow(
- dispPtr->display, winPtr->wmInfoPtr->master);
-
- if (masterWinPtr && masterWinPtr->window != None &&
- TkMacOSXHostToplevelExists(masterWinPtr)) {
- WindowRef masterMacWin =
- TkMacOSXDrawableWindow(masterWinPtr->window);
-
- if (masterMacWin) {
- BringToFront(masterMacWin);
- }
- }
- }
+ MacDrawable *macWin = (MacDrawable *) window;
+ NSView *view = TkMacOSXDrawableView(macWin);
+ local = [view convertPoint:local fromView:nil];
+ local.y = NSHeight([view bounds]) - local.y;
+ */
+ TkWindow *winPtr = (TkWindow *) tkwin;
+ local.x -= winPtr->wmInfoPtr->xInParent;
+ local.y -= winPtr->wmInfoPtr->yInParent;
+
+ int win_x, win_y;
+ tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y,
+ &win_x, &win_y);
+
+ unsigned int state = 0;
+ NSInteger button = [theEvent buttonNumber];
+ EventRef eventRef = (EventRef)[theEvent eventRef];
+ UInt32 buttons;
+ OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord,
+ typeUInt32, NULL, sizeof(UInt32), NULL, &buttons);
+ if (err == noErr) {
+ state |= (buttons & ((1<<5) - 1)) << 8;
+ } else {
+ if (button < 5) {
+ switch (type) {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDown:
+ state |= 1 << (button + 8);
+ break;
+ default:
+ break;
}
- SelectWindow(wRef);
- } else {
- frontWindowOnly = 0;
}
}
- if (!isFrontProcess) {
- ProcessSerialNumber ourPsn = {0, kCurrentProcess};
+ NSUInteger modifiers = [theEvent modifierFlags];
- ChkErr(SetFrontProcessWithOptions, &ourPsn,
- frontWindowOnly ? kSetFrontProcessFrontWindowOnly : 0);
+ if (modifiers & NSAlphaShiftKeyMask) {
+ state |= LockMask;
}
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXBringWindowForward --
- *
- * Bring this window to the front in response to a mouse click. If a grab
- * is in effect, bring the grab window to the front instead.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The window is brought forward.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkMacOSXBringWindowForward(
- WindowRef wRef)
-{
- TkDisplay *dispPtr = TkGetDisplayList();
- Tk_Window tkwin =
- Tk_IdToWindow(dispPtr->display, TkMacOSXGetXWindow(wRef));
- Tk_Window grabWin = GetGrabWindowForWindow(tkwin);
-
- if (grabWin && grabWin != tkwin) {
- wRef = TkMacOSXDrawableWindow(((TkWindow *) grabWin)->window);
+ if (modifiers & NSShiftKeyMask) {
+ state |= ShiftMask;
}
- TkMacOSXSetEatButtonUp(true);
- BringWindowForward(wRef, Tk_MacOSXIsAppInFront(), !grabWin);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * GetGrabWindowForWindow --
- *
- * Get the grab window for the given window, if any.
- *
- * Results:
- * Grab Tk_Window or None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Tk_Window
-GetGrabWindowForWindow(
- Tk_Window tkwin)
-{
- Tk_Window grabWin = TkMacOSXGetCapture();
-
- if (!grabWin) {
- int grabState = TkGrabState((TkWindow *) tkwin);
-
- if (grabState != TK_GRAB_NONE && grabState != TK_GRAB_IN_TREE) {
- grabWin = (Tk_Window) (((TkWindow *) tkwin)->dispPtr->grabWinPtr);
- }
+ if (modifiers & NSControlKeyMask) {
+ state |= ControlMask;
}
-
- return grabWin;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * GenerateMouseWheelEvent --
- *
- * Generates a "MouseWheel" Tk event.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Places a mousewheel event on the event queue.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-GenerateMouseWheelEvent(
- MouseEventData *medPtr)
-{
- Tk_Window tkwin, rootwin;
- TkDisplay *dispPtr;
- TkWindow *winPtr;
- XEvent xEvent;
-
- dispPtr = TkGetDisplayList();
- rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
- if (rootwin == NULL) {
- tkwin = NULL;
- } else {
- tkwin = Tk_TopCoordsToWindow(rootwin, medPtr->local.h,
- medPtr->local.v, &xEvent.xbutton.x, &xEvent.xbutton.y);
+ if (modifiers & NSCommandKeyMask) {
+ state |= Mod1Mask; /* command key */
}
-
- /*
- * The following call will generate the appropiate X events and adjust any
- * state that Tk must remember.
- */
-
- if (!tkwin) {
- tkwin = TkMacOSXGetCapture();
+ if (modifiers & NSAlternateKeyMask) {
+ state |= Mod2Mask; /* option key */
}
- if (!tkwin) {
- return false;
+ if (modifiers & NSNumericPadKeyMask) {
+ state |= Mod3Mask;
+ }
+ if (modifiers & NSFunctionKeyMask) {
+ state |= Mod4Mask;
}
- winPtr = (TkWindow *) tkwin;
- xEvent.type = MouseWheelEvent;
- xEvent.xkey.keycode = medPtr->delta;
- xEvent.xbutton.x_root = medPtr->global.h;
- xEvent.xbutton.y_root = medPtr->global.v;
- xEvent.xbutton.state = medPtr->state;
- xEvent.xany.serial = LastKnownRequestProcessed(winPtr->display);
- xEvent.xany.send_event = false;
- xEvent.xany.display = winPtr->display;
- xEvent.xany.window = Tk_WindowId(winPtr);
- Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
- return true;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXGetEatButtonUp --
- *
- * Results:
- * Return the flag indicating if we need to eat the next mouse up event.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
+ if (type != 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 {
+ CGFloat delta;
+ int coarseDelta;
+ XEvent xEvent;
+
+ xEvent.type = MouseWheelEvent;
+ xEvent.xbutton.x = local.x;
+ xEvent.xbutton.y = local.y;
+ xEvent.xbutton.x_root = global.x;
+ xEvent.xbutton.y_root = global.y;
+ xEvent.xany.send_event = false;
+ xEvent.xany.display = Tk_Display(tkwin);
+ xEvent.xany.window = Tk_WindowId(tkwin);
+
+ delta = [theEvent deltaY];
+ if (delta != 0.0) {
+ 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));
+ Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
+ }
+ delta = [theEvent deltaX];
+ if (delta != 0.0) {
+ 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));
+ Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
+ }
+ }
-int
-TkMacOSXGetEatButtonUp(void)
-{
- return gEatButtonUp;
+ return theEvent;
}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXSetEatButtonUp --
- *
- * Results:
- * None.
- *
- * Side effects:
- * Sets the flag indicating if we need to eat the next mouse up event
- *
- *----------------------------------------------------------------------
- */
+@end
-void
-TkMacOSXSetEatButtonUp(
- int f)
-{
- gEatButtonUp = f;
-}
+#pragma mark -
/*
*----------------------------------------------------------------------
@@ -797,10 +263,8 @@ TkMacOSXButtonKeyState(void)
UInt32 buttonState = 0, keyModifiers;
int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront());
- if (!TkMacOSXGetEatButtonUp()) {
- buttonState = isFrontProcess ? GetCurrentEventButtonState() :
- GetCurrentButtonState();
- }
+ buttonState = isFrontProcess ? GetCurrentEventButtonState() :
+ GetCurrentButtonState();
keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
GetCurrentKeyModifiers();
@@ -894,61 +358,31 @@ XQueryPointer(
unsigned int *mask_return)
{
int getGlobal = (root_x_return && root_y_return);
- int getLocal = (win_x_return && win_y_return);
+ int getLocal = (win_x_return && win_y_return && w != None);
if (getGlobal || getLocal) {
- Point where, local;
- OSStatus err = noErr;
- int gotMouseLoc = 0;
- EventRef ev = GetCurrentEvent();
+ NSPoint global = [NSEvent mouseLocation];
- if (ev && getLocal) {
- err = ChkErr(GetEventParameter, ev, kEventParamWindowMouseLocation,
- typeQDPoint, NULL, sizeof(Point), NULL, &local);
- gotMouseLoc = (err == noErr);
- }
- if (getGlobal || !gotMouseLoc) {
- if (ev) {
- err = ChkErr(GetEventParameter, ev, kEventParamMouseLocation,
- typeQDPoint, NULL, sizeof(Point), NULL, &where);
- }
- if (!ev || err != noErr) {
- GetGlobalMouse(&where);
- }
- }
if (getLocal) {
- WindowRef whichWin;
+ MacDrawable *macWin = (MacDrawable *) w;
+ NSWindow *win = TkMacOSXDrawableWindow(w);
- if (ev) {
- err = ChkErr(GetEventParameter, ev, kEventParamWindowRef,
- typeWindowRef, NULL, sizeof(WindowRef), NULL,
- &whichWin);
- }
- if (!ev || err != noErr) {
- FindWindow(where, &whichWin);
- }
- if (gotMouseLoc) {
- if (whichWin) {
- Rect widths;
+ if (win) {
+ NSPoint local;
- ChkErr(GetWindowStructureWidths, whichWin, &widths);
- local.h -= widths.left;
- local.v -= widths.top;
- }
- } else {
- local = where;
- if (whichWin) {
- QDGlobalToLocalPoint(GetWindowPort(whichWin), &local);
+ local = [win convertScreenToBase:global];
+ local.y = [win frame].size.height - local.y;
+ if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
+ local.x -= macWin->winPtr->wmInfoPtr->xInParent;
+ local.y -= macWin->winPtr->wmInfoPtr->yInParent;
}
+ *win_x_return = local.x;
+ *win_y_return = local.y;
}
}
if (getGlobal) {
- *root_x_return = where.h;
- *root_y_return = where.v;
- }
- if (getLocal) {
- *win_x_return = local.h;
- *win_y_return = local.v;
+ *root_x_return = global.x;
+ *root_y_return = tkMacOSXZeroScreenHeight - global.y;
}
}
if (mask_return) {
@@ -983,14 +417,13 @@ TkGenerateButtonEventForXPointer(
int global_x, global_y, local_x, local_y;
bzero(&med, sizeof(MouseEventData));
- XQueryPointer(NULL, None, NULL, NULL, &global_x, &global_y,
+ XQueryPointer(NULL, window, NULL, NULL, &global_x, &global_y,
&local_x, &local_y, &med.state);
med.global.h = global_x;
med.global.v = global_y;
med.local.h = local_x;
med.local.v = local_y;
med.window = window;
- med.activeNonFloating = ActiveNonFloatingWindow();
return GenerateButtonEvent(&med);
}
@@ -1021,6 +454,8 @@ TkGenerateButtonEvent(
Window window, /* X Window containing button event. */
unsigned int state) /* Button Key state suitable for X event. */
{
+ MacDrawable *macWin = (MacDrawable *) window;
+ NSWindow *win = TkMacOSXDrawableWindow(window);
MouseEventData med;
bzero(&med, sizeof(MouseEventData));
@@ -1028,10 +463,20 @@ TkGenerateButtonEvent(
med.window = window;
med.global.h = x;
med.global.v = y;
- FindWindow(med.global, &med.whichWin);
- med.activeNonFloating = ActiveNonFloatingWindow();
med.local = med.global;
- QDGlobalToLocalPoint(GetWindowPort(med.whichWin), &med.local);
+
+ if (win) {
+ NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
+
+ local = [win convertScreenToBase:local];
+ local.y = [win frame].size.height - local.y;
+ if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
+ local.x -= macWin->winPtr->wmInfoPtr->xInParent;
+ local.y -= macWin->winPtr->wmInfoPtr->yInParent;
+ }
+ med.local.h = local.x;
+ med.local.v = tkMacOSXZeroScreenHeight - local.y;
+ }
return GenerateButtonEvent(&med);
}
@@ -1091,62 +536,6 @@ GenerateButtonEvent(
}
/*
- *----------------------------------------------------------------------
- *
- * GenerateToolbarButtonEvent --
- *
- * Generates a "ToolbarButton" virtual event. This can be used to manage
- * disappearing toolbars.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Places a virtual event on the event queue.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-GenerateToolbarButtonEvent(
- MouseEventData *medPtr)
-{
- Tk_Window rootwin, tkwin = NULL;
- TkDisplay *dispPtr;
- TkWindow *winPtr;
- XVirtualEvent event;
-
- dispPtr = TkGetDisplayList();
- rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window);
- if (rootwin) {
- tkwin = Tk_TopCoordsToWindow(rootwin,
- medPtr->local.h, medPtr->local.v, &event.x, &event.y);
- }
- if (!tkwin) {
- return true;
- }
- winPtr = (TkWindow *) tkwin;
-
- bzero(&event, sizeof(XVirtualEvent));
- event.type = VirtualEvent;
- event.serial = LastKnownRequestProcessed(winPtr->display);
- event.send_event = false;
- event.display = winPtr->display;
- event.event = winPtr->window;
- event.root = XRootWindow(winPtr->display, 0);
- event.subwindow = None;
- event.time = TkpGetMS();
- event.x_root = medPtr->global.h;
- event.y_root = medPtr->global.v;
- event.state = medPtr->state;
- event.same_screen = true;
- event.name = Tk_GetUid("ToolbarButton");
-
- Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
- return true;
-}
-
-/*
* Local Variables:
* mode: c
* c-basic-offset: 4