|
Title: Help getting NSKeyUp/Down Events (Cocoa) Post by: Thomas Hiatt on July 20, 2013, 09:21:49 PM I am using Cocoa to make the window and input handling portion of my game on OSX. I am able to get mouse click, scroll, and mouse move events fine with or without a window but I can't get any Key events at all. I try
Code: ns_event = [NSApp nextEventMatchingMask:NSKeyDownMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES] and I try //translate event into non OS-specific event to be handled by game Code: [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent* ns_event) I have tried many different event masks for both of those methods and I never get Key events. I want to be able to get Key events without having any windows. I've been able to get by in ObjectiveC and Cocoa without too much trouble so far but this has me stuck .{ //translate event into non OS-specific event to be handled by game }]; Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: OneSadCookie on July 20, 2013, 09:35:20 PM You don’t want the global event monitor...
Did you try NSAnyEventMask? Is there a good reason you’re trying to use the pull functions rather than simply running the event loop and using NSResponder in the usual manner? Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: ThemsAllTook on July 20, 2013, 09:36:06 PM Hmm, I feel like I should know the answer to this, but I don't... If you subclass NSApplication and override -sendEvent:, does it get called?
Receiving key events without a window is a bit unusual, so I wouldn't be surprised if the normal system APIs don't work as expected. If you can't get it to work another way, you might be able to use CGEventTap (https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html) to capture them. It allows you to intercept events from the system anywhere, even if your application isn't the frontmost one. Edit: OneSadCookie is more knowledgeable about this than I am, so I'd defer to his recommendations. Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: Thomas Hiatt on July 20, 2013, 10:23:39 PM I have tried NSAnyEventMask and it still does not work. I'm not sure how I should be doing it but I want to be able to create windows and manage the event loop in main() like SFML appears to do ( I havent used SFML but looked at the documentation for window managing )
if I just do [NSApp run] then it takes over and does everything on its own. Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: ThemsAllTook on July 20, 2013, 10:27:23 PM SFML is open source (https://github.com/LaurentGomila/SFML). Maybe you'd be able to find some hints in there, or an implementation you could copy.
Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: OneSadCookie on July 20, 2013, 10:48:38 PM It should certainly work, but generally you'll find much lower friction interacting with OSes (particularly Apple ones) if you let them manage the event loop rather than trying to subvert it.
SDL does what you want too. It's not obvious to me from this context, why your code isn't working. Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: Thomas Hiatt on July 21, 2013, 12:32:21 PM I have redesigned everything to be a bit more normal and I still can't get mouseMoved or keyDown events from my windows. I have created this class:
Code: @interface SEWindow : NSWindow <NSWindowDelegate> @end @implementation SEWindow - (void) windowDidResize:(NSNotification *) notification { std::cout << "Window Resized" << std::endl; } - (BOOL) windowShouldClose:(id)sender { std::cout << "Window Should Close" << std::endl; return NO; } - (void) windowDidMiniaturize:(NSNotification *) notification { std::cout << "Window Minimized" << std::endl; } - (void) windowDidDeminiaturize:(NSNotification *) notification { std::cout << "Window Unminimized" << std::endl; } - (void) windowDidMove:(NSNotification *)notification { std::cout << "Window Moved" << std::endl; } - (void)keyDown:(NSEvent *)event { std::cout << "Key Down" << std::endl; } - (void)keyUp:(NSEvent *)event { std::cout << "Key Up" << std::endl; } - (void)mouseDown:(NSEvent *)theEvent { std::cout << "Mouse Down" << std::endl; } - (void)mouseUp:(NSEvent *)theEvent { std::cout << "Mouse Up" << std::endl; } - (void)mouseDragged:(NSEvent *)event { std::cout << "Mouse Dragged" << std::endl; } - (void)mouseMoved:(NSEvent *)event { std::cout << "Mouse Moved" << std::endl; } - (BOOL)acceptsFirstResponder { return YES; } @end I open a window in my main() function with: Code: NSRect ns_frame = NSMakeRect(x, y, width, height); NSUInteger ns_style_mask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask; NSRect ns_rect = [SEWindow contentRectForFrameRect:ns_frame styleMask:ns_style_mask]; SEWindow *ns_window = [[SEWindow alloc] initWithContentRect:ns_rect styleMask:ns_style_mask backing:NSBackingStoreBuffered defer:false]; [ns_window setBackgroundColor:[NSColor blueColor]]; [ns_window makeKeyAndOrderFront:ns_window]; [ns_window setAcceptsMouseMovedEvents:YES]; [ns_window setDelegate:ns_window]; then I have a while loop that does: Code: NSEvent *event; do { event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; [NSApp sendEvent:event]; } while( event != nil ); I think that should allow each window to say when the mouse moves within it or it gets resized etc. I get mouseDragged and mouseUp/Down events and all of the delegate methods are working fine but I do not get keyDown events or mouseMoved events. Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: ThemsAllTook on July 21, 2013, 01:42:52 PM One thing is still missing: An NSView inside the window. Doesn't take too much to create one and add it:
Code: view = [[MyNSViewSubclass alloc] initWithFrame: NSMakeRect(0, 0, windowWidth, windowHeight)]; [window setContentView: view]; [window setInitialFirstResponder: view]; In the view, you can then override -mouseDown:, -mouseMoved:, -keyDown:, etc. and it should all work. If you want a working example, here's one I wrote: http://sacredsoftware.net/svn/misc/StemLibProjects/nsopenglshell/trunk/source/nsopenglshell/ Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: Thomas Hiatt on July 21, 2013, 02:21:09 PM I've actually got it working a different way. I added the code
Code: ProcessSerialNumber psn; if (!GetCurrentProcess(&psn)) { TransformProcessType(&psn, kProcessTransformToForegroundApplication); SetFrontProcess(&psn); } Title: Re: Help getting NSKeyUp/Down Events (Cocoa) Post by: OneSadCookie on July 21, 2013, 03:14:44 PM That wouldn’t be necessary if your application was correctly bundled. But yes, you’ll find that code in SDL and GLFW for exactly this reason.
|