无法使用 NSOpenGLView 从 nextEventMatchingMask 获取 NSMouseMoved 事件
我正在尝试使用典型的 win 风格事件循环创建一个带有鼠标输入的基本 opengl 窗口。问题是我正在努力尝试生成 NSMouseMoved 事件。以下代码输出有关“鼠标向上”、“鼠标向下”、“鼠标拖动”等的调试信息,但没有“鼠标移动”,即使我已告诉窗口 setAcceptsMouseMovedEvents:YES
。那么,关于如何让鼠标移动在以下示例中工作有什么想法吗?
显然,我创建窗口的方式非常不像可可,但我正在尝试移植一个基于 makefile 的 Windows C++ 代码库,该代码库可以执行一些棘手的线程操作。这就是为什么我坚持使用类似于使用 GetMsg()
的 win32 循环的风格。
另外,为了构建我只是使用:
gcc -o hellogl hellogl.m -framework Foundation -framework Cocoa -framework OpenGL
感谢您的帮助!
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#include <OpenGL/gl.h>
#include <stdlib.h>
@interface BaseWinDelegate : NSWindow<NSWindowDelegate>
@end
@implementation BaseWinDelegate
- (void) windowWillClose:(NSNotification*)notification
{
printf("Closing.\n");
NSEvent * evt = [NSEvent otherEventWithType:NSApplicationDefined
location: NSMakePoint(0,0)
modifierFlags: 0
timestamp: 0.0
windowNumber: 0
context: nil
subtype: 0
data1: 0
data2: 0];
[NSApp postEvent:evt atStart:NO];
}
@end
@interface BaseView : NSOpenGLView
- (void) update;
- (void) drawRect:(NSRect)rect;
- (void) reshape;
@end
@implementation BaseView
- (void) drawRect:(NSRect)rect
{
glClearColor(0.2f,0.2f,0.2f,0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[[self openGLContext] flushBuffer];
}
- (void) update
{
printf("Update.\n");
}
- (void) reshape
{
NSRect rect;
[[self openGLContext] update];
rect = [self bounds];
printf("Reshape - %f, %f\n", rect.size.width,rect.size.height);
}
@end
int main(int argc, const char * argv[])
{
printf("Starting.\n");
NSAutoreleasePool * myPool = [[NSAutoreleasePool alloc] init ];
NSApplicationLoad();
NSRect rect = NSMakeRect(100,100,640,480);
NSWindow * win = [[NSWindow alloc] initWithContentRect:rect
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
backing: NSBackingStoreBuffered
defer: NO];
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFADoubleBuffer,
0
};
NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
BaseView * pView = [[BaseView alloc] initWithFrame:rect pixelFormat:pf];
BaseWinDelegate * myDelegate = [BaseWinDelegate alloc];
[win setDelegate:myDelegate];
[win setContentView: pView];
[win makeKeyAndOrderFront: NSApp];
[win setAcceptsMouseMovedEvents:YES];
do
{
NSEvent * evt = [NSApp nextEventMatchingMask : NSAnyEventMask
untilDate : [NSDate distantFuture]
inMode : NSDefaultRunLoopMode
dequeue : YES ];
NSEventType evtType = [evt type];
if (evtType == NSApplicationDefined)
{
break;
}
printf("%d\n",(int)evtType);
[NSApp sendEvent : evt];
} while (1);
[myPool drain];
return EXIT_SUCCESS;
}
I'm trying to create a basic opengl window with mouse input using a typical win-style event loop. The problem is that I'm pulling my hair out trying to get a NSMouseMoved
event to generate. The following code outputs debug info on Mouse Up, Mouse Down, Mouse Drag, etc but no Mouse Move even though I've told the window setAcceptsMouseMovedEvents:YES
. So, any ideas on how to get mouse move to work in the following example?
Obviously, the way I'm creating the window is very un-cocoa like, but I'm trying to port a makefile-based windows c++ codebase that does some tricky threading things. That's why I'm sticking with a style similar to a win32 loop using GetMsg()
.
Also, to build I'm just using:
gcc -o hellogl hellogl.m -framework Foundation -framework Cocoa -framework OpenGL
Thanks for the help!
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#include <OpenGL/gl.h>
#include <stdlib.h>
@interface BaseWinDelegate : NSWindow<NSWindowDelegate>
@end
@implementation BaseWinDelegate
- (void) windowWillClose:(NSNotification*)notification
{
printf("Closing.\n");
NSEvent * evt = [NSEvent otherEventWithType:NSApplicationDefined
location: NSMakePoint(0,0)
modifierFlags: 0
timestamp: 0.0
windowNumber: 0
context: nil
subtype: 0
data1: 0
data2: 0];
[NSApp postEvent:evt atStart:NO];
}
@end
@interface BaseView : NSOpenGLView
- (void) update;
- (void) drawRect:(NSRect)rect;
- (void) reshape;
@end
@implementation BaseView
- (void) drawRect:(NSRect)rect
{
glClearColor(0.2f,0.2f,0.2f,0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[[self openGLContext] flushBuffer];
}
- (void) update
{
printf("Update.\n");
}
- (void) reshape
{
NSRect rect;
[[self openGLContext] update];
rect = [self bounds];
printf("Reshape - %f, %f\n", rect.size.width,rect.size.height);
}
@end
int main(int argc, const char * argv[])
{
printf("Starting.\n");
NSAutoreleasePool * myPool = [[NSAutoreleasePool alloc] init ];
NSApplicationLoad();
NSRect rect = NSMakeRect(100,100,640,480);
NSWindow * win = [[NSWindow alloc] initWithContentRect:rect
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask
backing: NSBackingStoreBuffered
defer: NO];
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFADoubleBuffer,
0
};
NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
BaseView * pView = [[BaseView alloc] initWithFrame:rect pixelFormat:pf];
BaseWinDelegate * myDelegate = [BaseWinDelegate alloc];
[win setDelegate:myDelegate];
[win setContentView: pView];
[win makeKeyAndOrderFront: NSApp];
[win setAcceptsMouseMovedEvents:YES];
do
{
NSEvent * evt = [NSApp nextEventMatchingMask : NSAnyEventMask
untilDate : [NSDate distantFuture]
inMode : NSDefaultRunLoopMode
dequeue : YES ];
NSEventType evtType = [evt type];
if (evtType == NSApplicationDefined)
{
break;
}
printf("%d\n",(int)evtType);
[NSApp sendEvent : evt];
} while (1);
[myPool drain];
return EXIT_SUCCESS;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,想通了。问题是它不是前台进程。所以添加这段代码就可以解决这个问题。
这可以防止窗口成为关键窗口并发送鼠标移动事件。希望它对其他人有帮助(即喜欢处理自己的事件循环的 0.1% 的人)。
Ok, figured it out. The problem is that it's not a foreground process. So adding this code fixes it.
That was preventing the window from becoming the key window and sending off mouse moved events. Hope it helps someone else (i.e. the 0.1% of people who like to handle their own event loop).