問題描述
停靠欄下的窗口化opengl遊戲中的雙光標 (Double cursor in windowed opengl game under dock)
I created game in opengl and i have problem with double cursor (my and system) in windowed mode. I hide system cursor and use only my cursor in game.
When window is under dock and i move cursor over dock (cursor is still inside window) system cursor is shown. From this moment i have double cursor (my and system).
I try three solutions:
- Use events when cursor is over and when cursor is out dock, but i didn't find such events :(
- Use events when system cursor is unhide or hide, but i didn't find such events, too :(
- Get information about hide cursor count. When i make "CGDisplayHideCursor" hide cursor count is decrement. When cursor is unhide over dock i don't know about it because i havn't any event, but i could check in my timer if cursor should be hide so i could hide it, but in this way i will have many times hide cursor, so i don't know about cursor hide count and i don't make correctly unhide :(
Maybe this should be solved in completely different way.
‑‑‑‑‑
參考解法
方法 1:
you could try any of the following:
- Do not display game cursor in windowed mode (although that might not be ok for your game)
- Make the game window top‑most so it is above the dock (not sure it is possible on mac)
- Do not allow your game window to render anything under the dock, so the user does not need to click there (or do not allow your game window to be positioned under the dock in the first place)
- Use timer to poll cursor screen coordinates to determine whether the cursor is over dock or not
This is not strictly a programming problem, but a usability problem. You should decide what you want the user to do and implement that. I believe it is ok to not display game cursor in windowed mode (unless you are writing e.g. a strategy game where you need many different cursors).
方法 2:
Instead of dorking with CGDisplayHideCursor, with its mysterious unreadable hide count, the solution is to set up a cursor rect covering your whole window with a transparent cursor. This is really robust ‑ it reliably hides the cursor when the mouse is inside the window and shows it at all other times.
I eventually figured this out by looking at the Simple DirectMedia Layer (SDL) 2 source code ‑ here is a working minimal example extracted from there.
Override resetCursorRects in your NSView subclass implementation:
static NSCursor* invisibleCursor()
{
static NSCursor *invisibleCursor = NULL;
if (!invisibleCursor) {
/* RAW 16x16 transparent GIF */
static unsigned char cursorBytes[] = {
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
0x01, 0x00, 0x00, 0x01, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x10, 0x00, 0x00, 0x02, 0x0E, 0x8C, 0x8F, 0xA9, 0xCB, 0xED,
0x0F, 0xA3, 0x9C, 0xB4, 0xDA, 0x8B, 0xB3, 0x3E, 0x05, 0x00, 0x3B
};
NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
length:sizeof(cursorBytes)
freeWhenDone:NO];
NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
hotSpot:NSZeroPoint];
}
return invisibleCursor;
}
‑ (void)resetCursorRects
{
[super resetCursorRects];
[self addCursorRect:[self bounds] cursor:invisibleCursor()];
}
(by Chudziutki、the swine、manylegged)