From a6c78109ec048c2c92578fc5b1de44043c7ee6cc Mon Sep 17 00:00:00 2001 From: das Date: Mon, 9 Jul 2007 08:32:11 +0000 Subject: * macosx/tkMacOSXWindowEvent.c (Tk_MacOSXIsAppInFront): use process mgr * macosx/tkMacOSXMouseEvent.c: to determine if app is in front instead of relying on activate/deactivate events (which may arrive after this info is needed, e.g. during window drag/click activation); replace other process mgr use to get this info with calls to Tk_MacOSXIsAppInFront(). * macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): correct window click activation, titlebar click handling and background window dragging/growing in the presence of grabs or window-/app-modal windows; fix window click activation bringing all other app windows to front. --- ChangeLog | 17 ++++ macosx/tkMacOSXMouseEvent.c | 224 +++++++++++++++++++++++++------------------ macosx/tkMacOSXWindowEvent.c | 27 +++--- 3 files changed, 163 insertions(+), 105 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0400478..320dec9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-07-09 Daniel Steffen + + * macosx/tkMacOSXWindowEvent.c (Tk_MacOSXIsAppInFront): use process mgr + * macosx/tkMacOSXMouseEvent.c: to determine if + app is in front instead of relying on activate/deactivate events (which + may arrive after this info is needed, e.g. during window drag/click + activation); replace other process mgr use to get this info with calls + to Tk_MacOSXIsAppInFront(). + + * macosx/tkMacOSXMouseEvent.c (TkMacOSXProcessMouseEvent): correct + window click activation, titlebar click handling and background window + dragging/growing in the presence of grabs or window-/app-modal windows; + fix window click activation bringing all other app windows to front. + + * macosx/tkMacOSXDraw.c (TkPutImage): handle non-native XImage byte and + bit orders; reverse bits via xBitReverseTable instead of InvertByte(). + 2007-07-04 Jeff Hobbs * macosx/tkMacOSXXStubs.c (DestroyImage): Fixed crash in release diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index 61871a5..bf1e3ae 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -54,7 +54,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.6.2.21 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.6.2.22 2007/07/09 08:32:12 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -83,13 +83,15 @@ 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, Boolean isFrontProcess); +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); @@ -121,8 +123,7 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) TkDisplay * dispPtr; OSStatus err; MouseEventData mouseEventData, * medPtr = &mouseEventData; - ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - Boolean isFrontProcess = true; + int isFrontProcess; switch (eventPtr->eKind) { case kEventMouseDown: @@ -163,7 +164,8 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) return false; } if (eventPtr->eKind == kEventMouseDown) { - if (IsWindowPathSelectEvent(medPtr->whichWin, eventPtr->eventRef)) { + if (IsWindowActive(medPtr->whichWin) && IsWindowPathSelectEvent( + medPtr->whichWin, eventPtr->eventRef)) { ChkErr(WindowPathSelect, medPtr->whichWin, NULL, NULL); return false; } @@ -178,10 +180,7 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) } } } - err = ChkErr(GetFrontProcess, &frontPsn); - if (err == noErr) { - ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); - } + isFrontProcess = Tk_MacOSXIsAppInFront(); if (isFrontProcess) { medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(), GetCurrentEventKeyModifiers()); @@ -271,36 +270,29 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) if (!(TkpIsWindowFloating(medPtr->whichWin)) && (medPtr->whichWin != medPtr->activeNonFloating || !isFrontProcess)) { - Tk_Window grabWin = TkMacOSXGetCapture(); - if (!grabWin) { - int grabState = TkGrabState((TkWindow*)tkwin); - if (grabState != TK_GRAB_NONE && grabState != TK_GRAB_IN_TREE) { - /* Now we want to set the focus to the local grabWin */ + 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); - grabWin = (Tk_Window) (((TkWindow*)tkwin)->dispPtr->grabWinPtr); BringWindowForward(TkMacOSXDrawableWindow( - ((TkWindow*)grabWin)->window), isFrontProcess); - statusPtr->stopProcessing = 1; + ((TkWindow*)grabWin)->window), isFrontProcess, + frontWindowOnly); return false; } } - if (grabWin && grabWin != tkwin) { - TkWindow * tkw, * grb; - tkw = (TkWindow *)tkwin; - grb = (TkWindow *)grabWin; - /* Now we want to set the focus to the global grabWin */ - TkMacOSXSetEatButtonUp(true); - BringWindowForward(TkMacOSXDrawableWindow( - ((TkWindow*)grabWin)->window), isFrontProcess); - statusPtr->stopProcessing = 1; - return false; - } /* * Clicks in the titlebar widgets are handled without bringing the * window forward. */ if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { + statusPtr->stopProcessing = 1; return result; } else { /* @@ -313,11 +305,10 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) * Allow background window dragging & growing with Command * down. */ - if (!((medPtr->windowPart == inDrag || - medPtr->windowPart == inGrow) && - medPtr->state & Mod1Mask)) { + if (!cmdDragGrow) { TkMacOSXSetEatButtonUp(true); - BringWindowForward(medPtr->whichWin, isFrontProcess); + BringWindowForward(medPtr->whichWin, isFrontProcess, + frontWindowOnly); } /* * Allow dragging & growing of windows that were/are in the @@ -331,6 +322,7 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) } } else { if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { + statusPtr->stopProcessing = 1; return result; } } @@ -399,42 +391,67 @@ TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) int HandleWindowTitlebarMouseDown(MouseEventData * medPtr, Tk_Window tkwin) { - int result = 0; + int result = INT_MAX; - TkMacOSXTrackingLoop(1); switch (medPtr->windowPart) { case inGoAway: - if (TrackGoAway(medPtr->whichWin, medPtr->global)) { - if (tkwin) { - TkGenWMDestroyEvent(tkwin); - result = 1; - } - } - break; case inCollapseBox: - if (TrackBox(medPtr->whichWin, medPtr->global, medPtr->windowPart)) { - if (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); + if (!IsWindowActive(medPtr->whichWin)) { + WindowRef frontWindow = FrontNonFloatingWindow(); + WindowModality frontWindowModality = kWindowModalityNone; + + if (frontWindow && frontWindow != medPtr->whichWin) { + ChkErr(GetWindowModality, frontWindow, + &frontWindowModality, NULL); + } + if (frontWindowModality == kWindowModalityAppModal) { + result = 0; + } } break; default: result = -1; break; } - TkMacOSXTrackingLoop(0); + + 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; } @@ -527,18 +544,27 @@ GeneratePollingEvents(MouseEventData * medPtr) static void BringWindowForward( WindowRef wRef, - Boolean isFrontProcess) + 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) { + SelectWindow(wRef); + } else { + frontWindowOnly = 0; + } + } if (!isFrontProcess) { ProcessSerialNumber ourPsn = {0, kCurrentProcess}; - ChkErr(SetFrontProcess, &ourPsn); - } - - if (!TkpIsWindowFloating(wRef)) { - if (IsValidWindowPtr(wRef)) { - SelectWindow(wRef); - } + ChkErr(SetFrontProcessWithOptions, &ourPsn, frontWindowOnly ? + kSetFrontProcessFrontWindowOnly : 0); } } @@ -547,8 +573,8 @@ BringWindowForward( * * TkMacOSXBringWindowForward -- * - * Bring this background window to the front (wrapper around - * BringWindowForward()). + * 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. @@ -563,15 +589,48 @@ void TkMacOSXBringWindowForward( WindowRef wRef) { - OSStatus err; - ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - Boolean isFrontProcess = true; + TkDisplay *dispPtr = TkGetDisplayList(); + Tk_Window tkwin = Tk_IdToWindow(dispPtr->display,TkMacOSXGetXWindow(wRef)); + Tk_Window grabWin = GetGrabWindowForWindow(tkwin); - err = ChkErr(GetFrontProcess, &frontPsn); - if (err == noErr) { - ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); + if (grabWin && grabWin != tkwin) { + wRef = TkMacOSXDrawableWindow(((TkWindow*)grabWin)->window); } - BringWindowForward(wRef, isFrontProcess); + 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); + } + } + + return grabWin; } /* @@ -694,16 +753,8 @@ EventModifiers TkMacOSXModifierState(void) { UInt32 keyModifiers; - Boolean isFrontProcess = false; - - if (GetCurrentEvent()) { - ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - OSStatus err = ChkErr(GetFrontProcess, &frontPsn); + int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront()); - if (err == noErr) { - ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); - } - } keyModifiers = isFrontProcess ? GetCurrentEventKeyModifiers() : GetCurrentKeyModifiers(); @@ -731,16 +782,7 @@ unsigned int TkMacOSXButtonKeyState(void) { UInt32 buttonState = 0, keyModifiers; - Boolean isFrontProcess = false; - - if (GetCurrentEvent()) { - ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - OSStatus err = ChkErr(GetFrontProcess, &frontPsn); - - if (err == noErr) { - ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); - } - } + int isFrontProcess = (GetCurrentEvent() && Tk_MacOSXIsAppInFront()); if (!TkMacOSXGetEatButtonUp()) { buttonState = isFrontProcess ? GetCurrentEventButtonState() : diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c index 37139f3..f909f32 100644 --- a/macosx/tkMacOSXWindowEvent.c +++ b/macosx/tkMacOSXWindowEvent.c @@ -54,7 +54,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXWindowEvent.c,v 1.3.2.24 2007/06/29 03:22:02 das Exp $ + * RCS: @(#) $Id: tkMacOSXWindowEvent.c,v 1.3.2.25 2007/07/09 08:32:12 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -69,14 +69,6 @@ */ /* - * Declarations of global variables defined in this file. - */ - -static int tkMacOSXAppInFront = true; /* Boolean variable for determining if - * we are the frontmost app. Only set - * in TkMacOSXProcessApplicationEvent - */ -/* * Declaration of functions used only in this file */ @@ -99,7 +91,7 @@ static void ClearPort(CGrafPtr port, RgnHandle updateRgn); * 0. * * Side effects: - * Hide or reveal floating windows, and set tkMacOSXAppInFront. + * Hide or reveal floating windows. * *---------------------------------------------------------------------- */ @@ -121,12 +113,10 @@ TkMacOSXProcessApplicationEvent( switch (eventPtr->eKind) { case kEventAppActivated: - tkMacOSXAppInFront = true; ShowFloatingWindows(); break; case kEventAppDeactivated: TkSuspendClipboard(); - tkMacOSXAppInFront = false; HideFloatingWindows(); break; case kEventAppQuit: @@ -335,10 +325,10 @@ TkMacOSXProcessWindowEvent( } break; case kEventWindowDragStarted: - TkMacOSXTrackingLoop(1); if (!(TkMacOSXModifierState() & cmdKey)) { TkMacOSXBringWindowForward(whichWindow); } + TkMacOSXTrackingLoop(1); break; case kEventWindowDragCompleted: { Rect maxBounds, bounds, strWidths; @@ -925,7 +915,16 @@ TkWmProtocolEventProc( int Tk_MacOSXIsAppInFront(void) { - return tkMacOSXAppInFront; + OSStatus err; + ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; + Boolean isFrontProcess = true; + + err = ChkErr(GetFrontProcess, &frontPsn); + if (err == noErr) { + ChkErr(SameProcess, &frontPsn, &ourPsn, &isFrontProcess); + } + + return (isFrontProcess == true); } /* -- cgit v0.12