Mouse Cursor on Windows XP
by Paul Comitz · in Torque Game Engine · 04/16/2005 (6:38 am) · 61 replies
Greetings,
Can anyone explain the unusual behavior of the mouse cursor on Windows XP? For example,
the cursor is not visible when moved to the title bar. If the cursor is moved
straight up, it "get stuck" in the Torque window and the OS cursor appears after
moving past the title bar.
Also, when the Torque window loses focus and subsequently regains focus it seems to get confused and jumps to a default location of some kind. Sometimes this location of part way off the screen.
I suspect these are well known Torque "features" but I haven't seen anything about them anywhere.
TIA for any responses.
Can anyone explain the unusual behavior of the mouse cursor on Windows XP? For example,
the cursor is not visible when moved to the title bar. If the cursor is moved
straight up, it "get stuck" in the Torque window and the OS cursor appears after
moving past the title bar.
Also, when the Torque window loses focus and subsequently regains focus it seems to get confused and jumps to a default location of some kind. Sometimes this location of part way off the screen.
I suspect these are well known Torque "features" but I haven't seen anything about them anywhere.
TIA for any responses.
#42
Brandon.
05/02/2005 (5:36 pm)
@Ed: The gain focus in strange location appears fixed in openGL, but directX is still having issues. I went ahead and updated the directX driver to set the window according to the variable in the prefs file, and am currently working on tracking down the regain focus in strange place bug. I would like to find the strange place bug before posting the resource, so if you come across any answers, let me know and I can either give you what I have so far or vise versa for the resource. Thanks for offering your help!Brandon.
#43
05/02/2005 (8:40 pm)
No problem Brandon... I'm glad to help. I'll let you know as soon as I can get my Windows build environment set up to compile TGE 1.3 and add the changes posted here.
#44
Brandon.
05/02/2005 (9:52 pm)
@Ed: Sounds great! Just an update... The openGL is still doing the strange location stuff... I thought it was not, but it is.Brandon.
#45
Do you have any idea where the "center the cursor on receive focus" code might be? That's probably the place to start pokin'.... ;)
05/02/2005 (10:09 pm)
Ben hinted at the problem in a post above. It seems to have something to do with the way the code centers the mouse cursor in the window when the app gets focus... my guess is that the centering of the cursor serves no real purpose and can be omitted. It causes our "reposition the window" problem because the mouse position is changed while we're in "grab mode" on the titlebar. It doesn't seem to occur when clicking on other window decorations (still outside the client area).Do you have any idea where the "center the cursor on receive focus" code might be? That's probably the place to start pokin'.... ;)
#46
The last 2 lines in the setMouseClipping code block of the platformWin32\winWindow.cc file.
That seems to fix all those annoying windowed TGE issues. I'll go ahead and post this as a resource as well as the directX set initial position addon.
B--
05/02/2005 (10:47 pm)
@Ed: You were pretty darn close! The fix I found was to comment out the the else block that calls the SetCursorPos in the setMouseClipping. Here is the code snippet:if(windowLocked)
{
POINT p;
GetCursorPos(&p);
lastCursorPos.set(p.x - r.left, p.y - r.top);
ClipCursor(&r);
S32 centerX = (r.right + r.left) >> 1;
S32 centerY = (r.bottom + r.top) >> 1;
SetCursorPos(centerX, centerY);
}
//else
//SetCursorPos(lastCursorPos.x + r.left, lastCursorPos.y + r.top);The last 2 lines in the setMouseClipping code block of the platformWin32\winWindow.cc file.
That seems to fix all those annoying windowed TGE issues. I'll go ahead and post this as a resource as well as the directX set initial position addon.
B--
#47
05/03/2005 (7:19 am)
Nice work guys! Can't wait to try this out later.
#48
05/03/2005 (7:56 am)
Excellent! I'll try this ASAP! Glad I could help!
#50
05/08/2005 (11:32 am)
Great work guys, thanks a lot--it's things like this that make Torque "work"--bringing back the experience and expertise of the community into the core engine!
#51
to another application while in "look mode" ie: no torque cursor, then it is jumping to a spot on the screen when TGE regains focus. I'm going to mess with it this evening to see if I can iron that one out as well.
B--
05/08/2005 (11:58 am)
Small Update: I just found another small problem... If you lose application focus by hitting the windows key or B--
#52
I can understand why you might want to center up the mouse cursor, but I still haven't found where along the way a window set position gets called? But this does seem to fix the problem, and I have not noticed any strange side effects, so there ya go!
B--
05/08/2005 (2:25 pm)
To fix the above mentioned problem: Comment out the other SetCrusorPos command above the else also.if(windowLocked)
{
POINT p;
GetCursorPos(&p);
lastCursorPos.set(p.x - r.left, p.y - r.top);
ClipCursor(&r);
S32 centerX = (r.right + r.left) >> 1;
S32 centerY = (r.bottom + r.top) >> 1;
//SetCursorPos(centerX, centerY); <------COMMENT OUT THIS LINE
}
//else
//SetCursorPos(lastCursorPos.x + r.left, lastCursorPos.y + r.top);I can understand why you might want to center up the mouse cursor, but I still haven't found where along the way a window set position gets called? But this does seem to fix the problem, and I have not noticed any strange side effects, so there ya go!
B--
#53
05/08/2005 (3:19 pm)
Does that work OK when you're moving the mouse a lot in first person view?
#54
B--
05/08/2005 (4:54 pm)
@Ben: That was my concern also. I thought that the mouse might "leave" the app window if not re-centered. It doesn't though. In fact, when you press f11 the mouse centers, and I've tested it windowed and full screen for about 5 minutes running and spinning without any ill effects. I've got a track stick for a pointer on the laptop, so you can really crank on it and spin the view around at warp speed. No problems here.B--
#55
05/08/2005 (6:17 pm)
Pretty awesome. I'm looking forward to integrating this fix. :)
#56
B--
05/08/2005 (6:48 pm)
@Ben: OK, I did find one small problem with the last update. When you start a mission you are looking straight down. Not major, but I'll see if I can correct that also.B--
#57
For some background, commenting out both the SetCursorPos lines had one small side effect of your missions starting with your character looking at his feet. Not major, but still annoying! So I put the SetPosition commands back, and fixed it another way. We only needed to skip the first render frame when the app gains focus again, so I just used an additional variable to keep track of that first frame.
Here ya go: At the start of winWindow add this variable.
Now go to the setMouseClipping code block and make these changes:
Then go to the windowProc code block and make these changes to the WM_ACTIVATE code block:
Ok, so with this fix we don't take any operations out of the code, but instead we keep track of the application losing and gaining focus and then apply the SetCursorPosition after the first rendered frame window since focus change.
I never looked hard enough to find out why in the first frame rendered from app focus ends up moving the window... Who knows, but this fixes all the problems I have found.
B--
05/08/2005 (8:39 pm)
Update: Ok... After playing around with the source for a little while, here is the (hopefully) final fix to all the problems.For some background, commenting out both the SetCursorPos lines had one small side effect of your missions starting with your character looking at his feet. Not major, but still annoying! So I put the SetPosition commands back, and fixed it another way. We only needed to skip the first render frame when the app gains focus again, so I just used an additional variable to keep track of that first frame.
Here ya go: At the start of winWindow add this variable.
static BYTE keyboardState[256]; static bool mouseButtonState[3]; static bool capsLockDown = false; static S32 modifierKeys = 0; static bool windowActive = true; //----Addition here static bool windowNotActive = false; //---- static Point2I lastCursorPos(0,0); static Point2I windowSize; static HANDLE gMutexHandle = NULL;
Now go to the setMouseClipping code block and make these changes:
S32 centerX = (r.right + r.left) >> 1;
S32 centerY = (r.bottom + r.top) >> 1;
//<---- Add the IF switch to the SetCursorPos routine
if(!windowNotActive) SetCursorPos(centerX, centerY);
//<----
}
else
//<---- Add the IF switch to the SetCursorPos Here also!
if(!windowNotActive) SetCursorPos(lastCursorPos.x + r.left, lastCursorPos.y + r.top);
//<----
}Then go to the windowProc code block and make these changes to the WM_ACTIVATE code block:
case WM_ACTIVATE:
windowActive = LOWORD(wParam) != WA_INACTIVE;
if ( windowActive )
{
//---- ADD THIS HERE!
setMouseClipping();
windowNotActive = false;
//---- END CHANGE
Game->refreshWindow();
Input::activate();
}
else
{
//---- CHANGES HERE
setMouseClipping();
windowNotActive = true;
//----END CHANGES
DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
if ( !mgr || !mgr->isMouseActive() )
{
// Deactivate all the mouse triggers:
for ( U32 i = 0; i < 3; i++ )
{
if ( mouseButtonState[i] )
mouseButtonEvent( SI_BREAK, KEY_BUTTON0 + i );
}
}
Input::deactivate();
}
//---- COMMENT THIS LINE OUT
//setMouseClipping();
//----
break;Ok, so with this fix we don't take any operations out of the code, but instead we keep track of the application losing and gaining focus and then apply the SetCursorPosition after the first rendered frame window since focus change.
I never looked hard enough to find out why in the first frame rendered from app focus ends up moving the window... Who knows, but this fixes all the problems I have found.
B--
#58
07/25/2005 (11:30 pm)
Ok, integrated this stuff into 1.4. Thanks guys!
#59
07/26/2005 (8:56 am)
Great... thanks!
#60
01/03/2006 (3:37 pm)
A quick note- this all seems to work except for the case qhere your window has context-sensitive actions like minimize, close, etc. If you right-click on the application icon on the task bar, and move the mouse over the context-sensitive menu, the window belives it has regained focus and the mouse cursor goes invisible. Has anyone fixed this?
Torque Owner EddieRay
I'll certainly do anything I can to help with these issues... including making sure the "grab the titlebar and the window goes off-screen" issue that I was talking about above. I still need to check to see if the proposed "hidden cursor" fix also fixes that issue...
Thanks,
Ed