diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkBind.c | 118 | ||||
-rw-r--r-- | generic/tkEntry.c | 10 | ||||
-rw-r--r-- | generic/tkGrab.c | 25 | ||||
-rw-r--r-- | generic/tkInt.h | 5 | ||||
-rw-r--r-- | generic/tkWindow.c | 2 |
5 files changed, 82 insertions, 78 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c index 8ffcc1d..25d919f 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -738,7 +738,6 @@ static int NameToWindow(Tcl_Interp *interp, Tk_Window main, Tcl_Obj *objPtr, Tk_Window *tkwinPtr); static unsigned ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr, TkPattern *patPtr, EventMask *eventMaskPtr); -static void DoWarp(ClientData clientData); static PSList * GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr, Tcl_Obj *object, int onlyConsiderDetailedEvents); static void ClearLookupTable(LookupTables *lookupTables, ClientData object); @@ -4402,17 +4401,6 @@ HandleEventGenerate( } /* - * Now we have constructed the event, inject it into the event handling - * code. - */ - - if (synch) { - Tk_HandleEvent(&event.general); - } else { - Tk_QueueWindowEvent(&event.general, pos); - } - - /* * We only allow warping if the window is mapped. */ @@ -4421,11 +4409,6 @@ HandleEventGenerate( Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, event.general.xmotion.window); - if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) { - Tcl_DoWhenIdle(DoWarp, dispPtr); - dispPtr->flags |= TK_DISPLAY_IN_WARP; - } - if (warpWindow != dispPtr->warpWindow) { if (warpWindow) { Tcl_Preserve(warpWindow); @@ -4438,6 +4421,31 @@ HandleEventGenerate( dispPtr->warpMainwin = mainWin; dispPtr->warpX = event.general.xmotion.x; dispPtr->warpY = event.general.xmotion.y; + + /* + * Warping with respect to a window will be done when Tk_handleEvent + * below will run the event handlers and in particular TkPointerEvent. + * This allows to make grabs and warping work together robustly, that + * is without depending on a precise sequence of events. + * Warping with respect to the whole screen (i.e. dispPtr->warpWindow + * is NULL) is run directly here. + */ + + if (!dispPtr->warpWindow) { + TkpWarpPointer(dispPtr); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + } + } + + /* + * Now we have constructed the event, inject it into the event handling + * code. + */ + + if (synch) { + Tk_HandleEvent(&event.general); + } else { + Tk_QueueWindowEvent(&event.general, pos); } } @@ -4510,46 +4518,47 @@ NameToWindow( /* *------------------------------------------------------------------------- * - * DoWarp -- + * TkDoWarpWrtWin -- * - * Perform Warping of X pointer. Executed as an idle handler only. + * Perform warping of mouse pointer with respect to a window. * * Results: * None * * Side effects: - * X Pointer will move to a new location. + * Mouse pointer moves to a new location. * *------------------------------------------------------------------------- */ -static void -DoWarp( - ClientData clientData) +void +TkDoWarpWrtWin( + TkDisplay *dispPtr) { - TkDisplay *dispPtr = (TkDisplay *)clientData; - - assert(clientData); + assert(dispPtr); /* - * DoWarp was scheduled only if the window was mapped. It needs to be - * still mapped at the time the present idle callback is executed. Also - * one needs to guard against window destruction in the meantime. - * Finally, the case warpWindow == NULL is special in that it means - * the whole screen. + * A NULL warpWindow means warping with respect to the whole screen. + * We want to warp here only if we're warping with respect to a window. */ - if (!dispPtr->warpWindow || - (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None)) { - TkpWarpPointer(dispPtr); - XForceScreenSaver(dispPtr->display, ScreenSaverReset); - } - if (dispPtr->warpWindow) { - Tcl_Release(dispPtr->warpWindow); - dispPtr->warpWindow = NULL; + + /* + * Warping with respect to a window can only be done if the window is + * mapped. This was checked in HandleEvent. The window needs to be + * still mapped at the time the present code is executed. Also + * one needs to guard against window destruction in the meantime, + * which could have happened as a side effect of an event handler. + */ + + if (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None) { + TkpWarpPointer(dispPtr); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + } + Tcl_Release(dispPtr->warpWindow); + dispPtr->warpWindow = NULL; } - dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } /* @@ -5320,35 +5329,6 @@ TkpGetBindingXEvent( /* *---------------------------------------------------------------------- * - * TkpCancelWarp -- - * - * This function cancels an outstanding pointer warp and - * is called during tear down of the display. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkpCancelWarp( - TkDisplay *dispPtr) -{ - assert(dispPtr); - - if (dispPtr->flags & TK_DISPLAY_IN_WARP) { - Tcl_CancelIdleCall(DoWarp, dispPtr); - dispPtr->flags &= ~TK_DISPLAY_IN_WARP; - } -} - -/* - *---------------------------------------------------------------------- - * * TkpDumpPS -- * * Dump given pattern sequence to stdout. diff --git a/generic/tkEntry.c b/generic/tkEntry.c index 5bbad3e..2c5db3e 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -3385,17 +3385,21 @@ EntryValidateChange( if (entryPtr->validateCmd == NULL || entryPtr->validate == VALIDATE_NONE) { + if (entryPtr->flags & VALIDATING) { + entryPtr->flags |= VALIDATE_ABORT; + } return (varValidate ? TCL_ERROR : TCL_OK); } /* - * If we're already validating, then we're hitting a loop condition Return - * and set validate to 0 to disallow further validations and prevent - * current validation from finishing + * If we're already validating, then we're hitting a loop condition. Set + * validate to none to disallow further validations, arrange for flags + * to prevent current validation from finishing, and return. */ if (entryPtr->flags & VALIDATING) { entryPtr->validate = VALIDATE_NONE; + entryPtr->flags |= VALIDATE_ABORT; return (varValidate ? TCL_ERROR : TCL_OK); } diff --git a/generic/tkGrab.c b/generic/tkGrab.c index 012d434..3e4d9db 100644 --- a/generic/tkGrab.c +++ b/generic/tkGrab.c @@ -666,6 +666,9 @@ ReleaseButtonGrab( * This function is called for each pointer-related event, before the * event has been processed. It does various things to make grabs work * correctly. + * Also, this function takes care of warping the mouse pointer with + * respect to a given window, both when there is a grab in effect and + * when there is none. * * Results: * If the return value is 1 it means the event should be processed (event @@ -677,6 +680,7 @@ ReleaseButtonGrab( * Grab state information may be updated. New events may also be pushed * back onto the event queue to replace or augment the one passed in * here. + * The mouse pointer may be moved. * *---------------------------------------------------------------------- */ @@ -773,10 +777,24 @@ TkPointerEvent( return 1; } + if ((eventPtr->type == MotionNotify) && !appGrabbed) { + + /* + * Warp the mouse pointer with respect to window dispPtr->warpWindow + * if such a window was set in HandleEventGenerate. + */ + + TkDoWarpWrtWin(dispPtr); + } + if (!appGrabbed) { return 1; } + /* + * From this point on, there is a grab in effect. + */ + if (eventPtr->type == MotionNotify) { /* * When grabs are active, X reports motion events relative to the @@ -799,6 +817,13 @@ TkPointerEvent( Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD); return 0; } + + /* + * Warp the mouse pointer with respect to window dispPtr->warpWindow + * if such a window was set in HandleEventGenerate. + */ + + TkDoWarpWrtWin(dispPtr); return 1; } diff --git a/generic/tkInt.h b/generic/tkInt.h index f37e2d3..5465a0e 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -576,14 +576,11 @@ typedef struct TkDisplay { * Whether to use input methods for this display * TK_DISPLAY_WM_TRACING: (default off) * Whether we should do wm tracing on this display. - * TK_DISPLAY_IN_WARP: (default off) - * Indicates that we are in a pointer warp */ #define TK_DISPLAY_COLLAPSE_MOTION_EVENTS (1 << 0) #define TK_DISPLAY_USE_IM (1 << 1) #define TK_DISPLAY_WM_TRACING (1 << 3) -#define TK_DISPLAY_IN_WARP (1 << 4) /* * One of the following structures exists for each error handler created by a @@ -1361,8 +1358,8 @@ MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE void TkInitEmbeddedConfigurationInformation( Tcl_Interp *interp); +MODULE_SCOPE void TkDoWarpWrtWin(TkDisplay *dispPtr); MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); -MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr); MODULE_SCOPE int TkListCreateFrame(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *listObj, int toplevel, Tcl_Obj *nameObj); diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 26ae472..9d6c1f4 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -239,8 +239,6 @@ TkCloseDisplay( { TkClipCleanup(dispPtr); - TkpCancelWarp(dispPtr); - if (dispPtr->name != NULL) { ckfree(dispPtr->name); } |