summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXMouseEvent.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXMouseEvent.c')
-rw-r--r--macosx/tkMacOSXMouseEvent.c1134
1 files changed, 283 insertions, 851 deletions
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 6220d32..b5caf5a 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -1,60 +1,16 @@
/*
* tkMacOSXMouseEvent.c --
*
- * This file implements functions that decode & handle mouse events
- * on MacOS X.
+ * 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.34 2007/12/13 15:27:10 dgp Exp $
+ * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.38 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkMacOSXPrivate.h"
@@ -63,698 +19,200 @@
#include "tkMacOSXDebug.h"
typedef struct {
- WindowRef whichWin;
- WindowRef activeNonFloating;
- WindowPartCode windowPart;
- unsigned int state;
- long delta;
- Window window;
- Point global;
- Point local;
+ unsigned int state;
+ long delta;
+ Window window;
+ Point global;
+ 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 */
+static int GenerateButtonEvent(MouseEventData *medPtr);
+static unsigned int ButtonModifiers2State(UInt32 buttonState,
+ UInt32 keyModifiers);
-/*
- * 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);
+#pragma mark TKApplication(TKMouseEvent)
-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.
- *
- *----------------------------------------------------------------------
- */
+enum {
+ NSWindowWillMoveEventType = 20
+};
-MODULE_SCOPE int
-TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr)
+@implementation TKApplication(TKMouseEvent)
+- (NSEvent *) tkProcessMouseEvent: (NSEvent *) theEvent
{
- 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;
- break;
- }
- 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;
+#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
- 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;
+ 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];
}
- return res;
- }
- TkMacOSXSetEatButtonUp(false);
- if (medPtr->whichWin) {
- /*
- * We got a mouse down in a window
- * 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.
- */
+#endif
- if (!(TkpIsWindowFloating(medPtr->whichWin))
- && (medPtr->whichWin != medPtr->activeNonFloating
- || !isFrontProcess)) {
- int frontWindowOnly = 1;
- int cmdDragGrow = ((medPtr->windowPart == inDrag ||
- medPtr->windowPart == inGrow) && medPtr->state & Mod1Mask);
+ case NSTabletPoint:
+ case NSTabletProximity:
- if (!cmdDragGrow) {
- Tk_Window grabWin = GetGrabWindowForWindow(tkwin);
+ case NSScrollWheel:
+ win = [self windowWithWindowNumber:[theEvent windowNumber]];
+ break;
- frontWindowOnly = !grabWin;
- if (grabWin && grabWin != tkwin) {
- TkMacOSXSetEatButtonUp(true);
- BringWindowForward(TkMacOSXDrawableWindow(
- ((TkWindow*)grabWin)->window), isFrontProcess,
- frontWindowOnly);
- return false;
- }
- }
+ default:
+ return theEvent;
+ break;
+ }
- /*
- * Clicks in the titlebar widgets are handled without bringing the
- * window forward.
- */
- if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
- statusPtr->stopProcessing = 1;
- return result;
- } else {
- /*
- * 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);
- }
- /*
- * Allow dragging & growing of windows that were/are in the
- * background.
- */
- if (!(medPtr->windowPart == inDrag ||
- medPtr->windowPart == inGrow)) {
- return false;
- }
- }
- }
- } else {
- if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) {
- statusPtr->stopProcessing = 1;
- return result;
- }
- }
- switch (medPtr->windowPart) {
- case inDrag: {
- WindowAttributes attributes;
+ NSPoint global, local = [theEvent locationInWindow];
- 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);
- if (EqualPt(where, where2)) {
- return false;
- }
- return 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!
- */
- if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) {
- statusPtr->stopProcessing = 1;
- return true;
- } else {
- return GenerateButtonEvent(medPtr);
- }
- break;
- case inContent:
- return GenerateButtonEvent(medPtr);
- break;
- default:
- return false;
- break;
- }
+ if (win) {
+ global = [win convertBaseToScreen:local];
+ local.y = [win frame].size.height - local.y;
+ global.y = tkMacOSXZeroScreenHeight - global.y;
+ } else {
+ local.y = tkMacOSXZeroScreenHeight - local.y;
+ global = local;
}
- 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.
- *
- *----------------------------------------------------------------------
- */
-int
-HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin)
-{
- int result = INT_MAX;
+ Window window = TkMacOSXGetXWindow(win);
+ Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display,
+ window) : NULL;
+ if (!tkwin) {
+ tkwin = TkMacOSXGetCapture();
+ }
+ if (!tkwin) {
+ return theEvent;
+ }
- switch (medPtr->windowPart) {
- case inGoAway:
- case inCollapseBox:
- case inZoomIn:
- case inZoomOut:
- case inToolbarButton:
- if (!IsWindowActive(medPtr->whichWin)) {
- WindowRef frontWindow = FrontNonFloatingWindow();
- WindowModality frontWindowModality = kWindowModalityNone;
+ /*
+ 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 (frontWindow && frontWindow != medPtr->whichWin) {
- ChkErr(GetWindowModality, frontWindow,
- &frontWindowModality, NULL);
- }
- if (frontWindowModality == kWindowModalityAppModal) {
- result = 0;
- }
- }
+ 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:
- result = -1;
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.
- *
- *----------------------------------------------------------------------
- */
+ NSUInteger modifiers = [theEvent modifierFlags];
-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;
- } 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.
- */
-
- 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);
- }
+ if (modifiers & NSAlphaShiftKeyMask) {
+ state |= LockMask;
}
-
- /*
- * 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);
- }
- }
- }
- }
- SelectWindow(wRef);
- } else {
- frontWindowOnly = 0;
- }
+ if (modifiers & NSShiftKeyMask) {
+ state |= ShiftMask;
}
- if (!isFrontProcess) {
- ProcessSerialNumber ourPsn = {0, kCurrentProcess};
-
- ChkErr(SetFrontProcessWithOptions, &ourPsn, frontWindowOnly ?
- kSetFrontProcessFrontWindowOnly : 0);
+ if (modifiers & NSControlKeyMask) {
+ state |= ControlMask;
}
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * 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 & NSCommandKeyMask) {
+ state |= Mod1Mask; /* command key */
}
- 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 & NSAlternateKeyMask) {
+ state |= Mod2Mask; /* option key */
}
-
- 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 & NSNumericPadKeyMask) {
+ state |= Mod3Mask;
}
-
- /*
- * The following call will generate the appropiate X events and
- * adjust any state that Tk must remember.
- */
-
- if (!tkwin) {
- tkwin = TkMacOSXGetCapture();
+ if (modifiers & NSFunctionKeyMask) {
+ state |= Mod4Mask;
}
- if (!tkwin) {
- return false;
+
+ 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);
+ }
}
- 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:
- * Returns the flag indicating if we need to eat the
- * next mouse up event
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-int
-TkMacOSXGetEatButtonUp(void)
-{
- return gEatButtonUp;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXSetEatButtonUp --
- *
- * Results:
- * None.
- *
- * Side effects:
- * Sets the flag indicating if we need to eat the
- * next mouse up event
- *
- *----------------------------------------------------------------------
- */
-void
-TkMacOSXSetEatButtonUp(int f)
-{
- gEatButtonUp = f;
+ return theEvent;
}
+@end
+
+#pragma mark -
/*
*----------------------------------------------------------------------
@@ -781,7 +239,7 @@ TkMacOSXModifierState(void)
keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() :
GetCurrentKeyModifiers();
- return (EventModifiers)(keyModifiers & USHRT_MAX);
+ return (EventModifiers) (keyModifiers & USHRT_MAX);
}
/*
@@ -792,8 +250,8 @@ TkMacOSXModifierState(void)
* Returns the current state of the button & modifier keys.
*
* Results:
- * A bitwise inclusive OR of a subset of the following:
- * Button1Mask, ShiftMask, LockMask, ControlMask, Mod*Mask.
+ * A bitwise inclusive OR of a subset of the following: Button1Mask,
+ * ShiftMask, LockMask, ControlMask, Mod*Mask.
*
* Side effects:
* None.
@@ -807,10 +265,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();
@@ -835,11 +291,16 @@ TkMacOSXButtonKeyState(void)
*/
static unsigned int
-ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers)
+ButtonModifiers2State(
+ UInt32 buttonState,
+ UInt32 keyModifiers)
{
unsigned int state;
- /* Tk supports at most 5 buttons */
+ /*
+ * Tk supports at most 5 buttons.
+ */
+
state = (buttonState & ((1<<5) - 1)) << 8;
if (keyModifiers & alphaLock) {
@@ -873,12 +334,12 @@ ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers)
* XQueryPointer --
*
* Check the current state of the mouse. This is not a complete
- * implementation of this function. It only computes the root
- * coordinates and the current mask.
+ * implementation of this function. It only computes the root coordinates
+ * and the current mask.
*
* Results:
- * Sets root_x_return, root_y_return, and mask_return. Returns
- * true on success.
+ * Sets root_x_return, root_y_return, and mask_return. Returns true on
+ * success.
*
* Side effects:
* None.
@@ -888,71 +349,42 @@ ButtonModifiers2State(UInt32 buttonState, UInt32 keyModifiers)
Bool
XQueryPointer(
- Display* display,
+ Display *display,
Window w,
- Window* root_return,
- Window* child_return,
- int* root_x_return,
- int* root_y_return,
- int* win_x_return,
- int* win_y_return,
- unsigned int* mask_return)
+ Window *root_return,
+ Window *child_return,
+ int *root_x_return,
+ int *root_y_return,
+ int *win_x_return,
+ int *win_y_return,
+ 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;
- 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;
+ MacDrawable *macWin = (MacDrawable *) w;
+ NSWindow *win = TkMacOSXDrawableWindow(w);
- ChkErr(GetWindowStructureWidths, whichWin, &widths);
- local.h -= widths.left;
- local.v -= widths.top;
- }
- } else {
- local = where;
- if (whichWin) {
- QDGlobalToLocalPoint(GetWindowPort(whichWin), &local);
+ if (win) {
+ NSPoint 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) {
@@ -966,35 +398,34 @@ XQueryPointer(
*
* TkGenerateButtonEventForXPointer --
*
- * This procedure generates an X button event for the current
- * pointer state as reported by XQueryPointer().
+ * This procedure generates an X button event for the current pointer
+ * state as reported by XQueryPointer().
*
* Results:
* True if event(s) are generated - false otherwise.
*
* Side effects:
- * Additional events may be place on the Tk event queue.
- * Grab state may also change.
+ * Additional events may be place on the Tk event queue. Grab state may
+ * also change.
*
*----------------------------------------------------------------------
*/
MODULE_SCOPE int
TkGenerateButtonEventForXPointer(
- Window window) /* X Window containing button event. */
+ Window window) /* X Window containing button event. */
{
MouseEventData med;
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);
}
@@ -1004,27 +435,29 @@ TkGenerateButtonEventForXPointer(
*
* TkGenerateButtonEvent --
*
- * Given a global x & y position and the button key status this
- * procedure generates the appropiate X button event. It also
- * handles the state changes needed to implement implicit grabs.
+ * Given a global x & y position and the button key status this procedure
+ * generates the appropiate X button event. It also handles the state
+ * changes needed to implement implicit grabs.
*
* Results:
- * True if event(s) are generated - false otherwise.
+ * True if event(s) are generated, false otherwise.
*
* Side effects:
- * Additional events may be place on the Tk event queue.
- * Grab state may also change.
+ * Additional events may be place on the Tk event queue. Grab state may
+ * also change.
*
*----------------------------------------------------------------------
*/
int
TkGenerateButtonEvent(
- int x, /* X location of mouse */
- int y, /* Y location of mouse */
- Window window, /* X Window containing button event. */
- unsigned int state) /* Button Key state suitable for X event */
+ int x, /* X location of mouse, */
+ int y, /* Y location of mouse. */
+ 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));
@@ -1032,10 +465,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);
}
@@ -1045,21 +488,22 @@ TkGenerateButtonEvent(
*
* GenerateButtonEvent --
*
- * Generate an X button event from a MouseEventData structure.
- * Handles the state changes needed to implement implicit grabs.
+ * Generate an X button event from a MouseEventData structure. Handles
+ * the state changes needed to implement implicit grabs.
*
* Results:
* True if event(s) are generated - false otherwise.
*
* Side effects:
- * Additional events may be place on the Tk event queue.
- * Grab state may also change.
+ * Additional events may be place on the Tk event queue. Grab state may
+ * also change.
*
*----------------------------------------------------------------------
*/
static int
-GenerateButtonEvent(MouseEventData * medPtr)
+GenerateButtonEvent(
+ MouseEventData *medPtr)
{
Tk_Window tkwin;
int dummy;
@@ -1067,11 +511,12 @@ GenerateButtonEvent(MouseEventData * medPtr)
#if UNUSED
/*
- * ButtonDown events will always occur in the front
- * window. ButtonUp events, however, may occur anywhere
- * on the screen. ButtonUp events should only be sent
- * to Tk if in the front window or during an implicit grab.
+ * ButtonDown events will always occur in the front window. ButtonUp
+ * events, however, may occur anywhere on the screen. ButtonUp events
+ * should only be sent to Tk if in the front window or during an implicit
+ * grab.
*/
+
if ((medPtr->activeNonFloating == NULL)
|| ((!(TkpIsWindowFloating(medPtr->whichWin))
&& (medPtr->activeNonFloating != medPtr->whichWin))
@@ -1089,61 +534,48 @@ GenerateButtonEvent(MouseEventData * medPtr)
}
Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state);
-
return true;
}
-/*
- *----------------------------------------------------------------------
- *
- * 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)
+void
+TkpWarpPointer(
+ TkDisplay *dispPtr)
{
- Tk_Window rootwin, tkwin = NULL;
- TkDisplay *dispPtr;
- TkWindow *winPtr;
- XVirtualEvent event;
+ CGPoint pt;
+ UInt32 buttonState;
- 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;
+ if (dispPtr->warpWindow) {
+ int x, y;
+
+ Tk_GetRootCoords(dispPtr->warpWindow, &x, &y);
+ pt.x = x + dispPtr->warpX;
+ pt.y = y + dispPtr->warpY;
+ } else {
+ pt.x = dispPtr->warpX;
+ pt.y = dispPtr->warpY;
}
- 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");
+ /*
+ * Tell the OSX core to generate the events to make it happen. This is
+ * fairly ugly, but means that under most circumstances we'll register all
+ * the events that would normally be generated correctly. If we use
+ * CGWarpMouseCursorPosition instead, strange things happen.
+ */
- Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
- return true;
+ buttonState = (GetCurrentEvent() && Tk_MacOSXIsAppInFront())
+ ? GetCurrentEventButtonState() : GetCurrentButtonState();
+
+ CGPostMouseEvent(pt, 1 /* generate motion events */, 5,
+ buttonState&1 ? 1 : 0, buttonState&2 ? 1 : 0,
+ buttonState&4 ? 1 : 0, buttonState&8 ? 1 : 0,
+ buttonState&16 ? 1 : 0);
}
+
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */