summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2010-01-06 14:58:29 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2010-01-06 14:58:29 (GMT)
commit1a6ac30b077e52ba1da9ac22a8d38356ece00cec (patch)
tree26bd34fc1fc835f2a79bdefdc48e6aff6bbd207f
parentef7b2a248d85365c8bfc78d1ef62475638b1a6bc (diff)
downloadtk-1a6ac30b077e52ba1da9ac22a8d38356ece00cec.zip
tk-1a6ac30b077e52ba1da9ac22a8d38356ece00cec.tar.gz
tk-1a6ac30b077e52ba1da9ac22a8d38356ece00cec.tar.bz2
[Bug 2926819]: Factor out the pointer warping code a bit better and extend it
to work on OSX too.
-rw-r--r--ChangeLog8
-rw-r--r--carbon/tkMacOSXMouseEvent.c36
-rw-r--r--generic/tkBind.c22
-rw-r--r--generic/tkInt.h7
-rw-r--r--generic/tkWindow.c4
-rw-r--r--macosx/tkMacOSXMouseEvent.c36
-rw-r--r--unix/tkUnixEvent.c18
-rw-r--r--win/tkWinPointer.c16
8 files changed, 129 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index a7824f1..2ec6e79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2010-01-06 Donal K. Fellows <dkf@users.sf.net>
+ * generic/tkBind.c (HandleEventGenerate, DoWarp): [Bug 2926819]:
+ * generic/tkInt.h (TkDisplay): Factor out the pointer
+ * generic/tkWindow.c (GetScreen): warping code a bit
+ * carbon/tkMacOSXMouseEvent.c (TkpWarpPointer): better and extend it
+ * macosx/tkMacOSXMouseEvent.c (TkpWarpPointer): to work on OSX too.
+ * unix/tkUnixEvent.c (TkpWarpPointer):
+ * win/tkWinPointer.c (TkpWarpPointer):
+
* unix/tkUnixWm.c (TkWmMapWindow): [Bug 1163496]: Allow windows to be
* tests/wm.test (wm-transient-8.1): set to be transients for withdrawn
masters correctly.
diff --git a/carbon/tkMacOSXMouseEvent.c b/carbon/tkMacOSXMouseEvent.c
index b9e54f5..a653073 100644
--- a/carbon/tkMacOSXMouseEvent.c
+++ b/carbon/tkMacOSXMouseEvent.c
@@ -48,7 +48,7 @@
* permission to use and distribute the software in accordance with the
* terms specified in this license.
*
- * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.2 2009/06/29 14:35:01 das Exp $
+ * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.3 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkMacOSXPrivate.h"
@@ -1148,6 +1148,40 @@ GenerateToolbarButtonEvent(
return true;
}
+void
+TkpWarpPointer(
+ TkDisplay *dispPtr)
+{
+ CGPoint pt;
+ UInt32 buttonState;
+
+ 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;
+ }
+
+ /*
+ * 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.
+ */
+
+ 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: c
diff --git a/generic/tkBind.c b/generic/tkBind.c
index 1dafaa2..4821513 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkBind.c,v 1.59 2010/01/02 22:52:38 dkf Exp $
+ * RCS: @(#) $Id: tkBind.c,v 1.60 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkInt.h"
@@ -3360,7 +3360,8 @@ HandleEventGenerate(
event.general.xkey.y_root = -1;
}
- if (event.general.xany.type == FocusIn || event.general.xany.type == FocusOut) {
+ if (event.general.xany.type == FocusIn
+ || event.general.xany.type == FocusOut) {
event.general.xany.send_event = GENERATED_FOCUS_EVENT_MAGIC;
}
@@ -3544,7 +3545,8 @@ HandleEventGenerate(
"\"", NULL);
return TCL_ERROR;
}
- if (!(flags & KEY) || (event.general.xkey.type == MouseWheelEvent)) {
+ if (!(flags & KEY)
+ || (event.general.xkey.type == MouseWheelEvent)) {
goto badopt;
}
break;
@@ -3817,12 +3819,14 @@ HandleEventGenerate(
Tcl_DoWhenIdle(DoWarp, dispPtr);
dispPtr->flags |= TK_DISPLAY_IN_WARP;
}
- dispPtr->warpWindow = event.general.xany.window;
- dispPtr->warpX = event.general.xkey.x;
- dispPtr->warpY = event.general.xkey.y;
+ dispPtr->warpWindow = Tk_IdToWindow(Tk_Display(mainWin),
+ event.general.xmotion.window);
+ dispPtr->warpMainwin = mainWin;
+ dispPtr->warpX = event.general.xmotion.x;
+ dispPtr->warpY = event.general.xmotion.y;
}
-done:
+ done:
Tcl_ResetResult(interp);
return TCL_OK;
}
@@ -3888,9 +3892,7 @@ DoWarp(
{
TkDisplay *dispPtr = clientData;
- XWarpPointer(dispPtr->display, (Window) None,
- (Window) dispPtr->warpWindow, 0, 0, 0, 0,
- (int) dispPtr->warpX, (int) dispPtr->warpY);
+ TkpWarpPointer(dispPtr);
XForceScreenSaver(dispPtr->display, ScreenSaverReset);
dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}
diff --git a/generic/tkInt.h b/generic/tkInt.h
index 73297d8..83ccbae 100644
--- a/generic/tkInt.h
+++ b/generic/tkInt.h
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: $Id: tkInt.h,v 1.117 2010/01/02 11:07:56 dkf Exp $
+ * RCS: $Id: tkInt.h,v 1.118 2010/01/06 14:58:30 dkf Exp $
*/
#ifndef _TKINT
@@ -506,7 +506,9 @@ typedef struct TkDisplay {
* display. */
Window mouseButtonWindow; /* Window the button state was set in, added
* in Tk 8.4. */
- Window warpWindow;
+ Tk_Window warpWindow;
+ Tk_Window warpMainwin; /* For finding the root window for warping
+ * purposes. */
int warpX;
int warpY;
@@ -1242,6 +1244,7 @@ MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp,
ClientData clientData);
MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp,
ClientData clientData);
+MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr);
/*
* Unsupported commands.
diff --git a/generic/tkWindow.c b/generic/tkWindow.c
index c023507..5080cc0 100644
--- a/generic/tkWindow.c
+++ b/generic/tkWindow.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWindow.c,v 1.106 2009/12/12 00:10:45 nijtmans Exp $
+ * RCS: @(#) $Id: tkWindow.c,v 1.107 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkInt.h"
@@ -508,7 +508,7 @@ GetScreen(
dispPtr->lastEventTime = CurrentTime;
dispPtr->bindInfoStale = 1;
dispPtr->cursorFont = None;
- dispPtr->warpWindow = None;
+ dispPtr->warpWindow = NULL;
dispPtr->multipleAtom = None;
/*
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 06b35b2..b5caf5a 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.37 2009/07/06 20:29:21 dkf Exp $
+ * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.38 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkMacOSXPrivate.h"
@@ -537,6 +537,40 @@ GenerateButtonEvent(
return true;
}
+void
+TkpWarpPointer(
+ TkDisplay *dispPtr)
+{
+ CGPoint pt;
+ UInt32 buttonState;
+
+ 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;
+ }
+
+ /*
+ * 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.
+ */
+
+ 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
diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c
index 4542876..a4bdb23 100644
--- a/unix/tkUnixEvent.c
+++ b/unix/tkUnixEvent.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkUnixEvent.c,v 1.34 2010/01/02 11:07:56 dkf Exp $
+ * RCS: @(#) $Id: tkUnixEvent.c,v 1.35 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkUnixInt.h"
@@ -696,6 +696,22 @@ error:
}
#endif /* TK_USE_INPUT_METHODS */
+void
+TkpWarpPointer(
+ TkDisplay *dispPtr)
+{
+ Window w; /* Which window to warp relative to. */
+
+ if (dispPtr->warpWindow != NULL) {
+ w = Tk_WindowId(dispPtr->warpWindow);
+ } else {
+ w = RootWindow(dispPtr->display,
+ Tk_ScreenNumber(dispPtr->warpMainwin));
+ }
+ XWarpPointer(dispPtr->display, None, w, 0, 0, 0, 0,
+ (int) dispPtr->warpX, (int) dispPtr->warpY);
+}
+
/*
* Local Variables:
* mode: c
diff --git a/win/tkWinPointer.c b/win/tkWinPointer.c
index 6788c71..86c0f53 100644
--- a/win/tkWinPointer.c
+++ b/win/tkWinPointer.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinPointer.c,v 1.10 2005/12/02 00:19:04 dkf Exp $
+ * RCS: @(#) $Id: tkWinPointer.c,v 1.11 2010/01/06 14:58:30 dkf Exp $
*/
#include "tkWinInt.h"
@@ -362,6 +362,20 @@ XWarpPointer(
GetWindowRect(Tk_GetHWND(dest_w), &r);
SetCursorPos(r.left+dest_x, r.top+dest_y);
}
+
+void
+TkpWarpPointer(
+ TkDisplay *dispPtr)
+{
+ if (dispPtr->warpWindow) {
+ RECT r;
+
+ GetWindowRect(Tk_GetHWND(Tk_WindowId(dispPtr->warpWindow)), &r);
+ SetCursorPos(r.left + dispPtr->warpX, r.top + dispPtr->warpY);
+ } else {
+ SetCursorPos(dispPtr->warpX, dispPtr->warpY);
+ }
+}
/*
*----------------------------------------------------------------------