Какао nextEventMatchingMask не получает событие NSMouseMoved - PullRequest
0 голосов
/ 02 апреля 2010

Я создал локальный цикл обработки событий и обнаружил окно без полей (производное от NSPanel), Я обнаружил в цикле событий, что событие NSMouseMoved не получено, хотя я могу получать события нажатия кнопки мыши вверх / вниз.

Что я должен сделать, чтобы получить события NSMouseMoved? Я обнаружил, что создание плавающего окна в качестве ключевого окна может принимать события NSMouseMoved, но я не хочу менять ключевое окно. И кажется, что это возможно, потому что я обнаружил, что после нажатия значка тестового приложения на панели системных док-станций я могу получать события перемещения мыши, и ключевое окно / главное окно остаются неизменными.

Вот мой тестовый код: (Создайте проект приложения Cocoa с именами FloatWindowTest и поместите кнопку для связи с onClick: IBAction). Заранее спасибо!

-Jonny

#import "FloatWindowTestAppDelegate.h"

@interface FloatWindow : NSPanel
@end

@interface FloatWindowContentView : NSView
@end

@implementation FloatWindowTestAppDelegate

@synthesize window;

- (void)delayedAction:(id)sender
{
    // What does this function do?
    // 1. create a float window
    // 2. create a local event loop
    // 3. print out the events got from nextEventMatchingMask.
    // 4. send it to float window.

    // What is the problem?
    // In local event loop, althrough the event mask has set NSMouseMovedMask
    // there's no mouse moved messages received.
    //

    FloatWindow* floatWindow = [[FloatWindow alloc] init];

    NSEvent* event = [NSApp currentEvent];
    NSPoint screenOrigin = [[self window] convertBaseToScreen:[event locationInWindow]];    
    [floatWindow setFrameTopLeftPoint:screenOrigin];
    [floatWindow orderFront:nil];


    //Making the float window as Key window will work, however
    //change active window is not anticipated.
    //[floatWindow makeKeyAndOrderFront:nil];

    BOOL done = NO;
    while (!done) 
    {
        NSAutoreleasePool* pool = [NSAutoreleasePool new];
        NSUInteger eventMask = NSLeftMouseDownMask|
        NSLeftMouseUpMask|
        NSMouseMovedMask|
        NSMouseEnteredMask|
        NSMouseExitedMask|
        NSLeftMouseDraggedMask;

        NSEvent* event = [NSApp nextEventMatchingMask:eventMask 
                                            untilDate:[NSDate distantFuture]
                                               inMode:NSDefaultRunLoopMode 
                                              dequeue:YES];

        //why I cannot get NSMouseMoved event??
        NSLog(@"new event %@", [event description]);
        [floatWindow sendEvent:event];
        [pool drain];
    }

    [floatWindow release];
    return;
}

-(IBAction)onClick:(id)sender
{
    //Tried to postpone the local event loop
    //after return from button's mouse tracking loop.
    //but not fixes this problem.
    [[NSRunLoop currentRunLoop]
           performSelector:@selector(delayedAction:) 
                    target:self 
                  argument:nil 
                     order:0 
                     modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
}
@end



@implementation FloatWindow

- (id)init
{
    NSRect contentRect = NSMakeRect(200,300,200,300);
    self = [super initWithContentRect:contentRect
                            styleMask:NSTitledWindowMask
                              backing:NSBackingStoreBuffered 
                                defer:YES];

    if (self) {
        [self setLevel:NSFloatingWindowLevel];

        NSRect frameRect = [self frameRectForContentRect:contentRect];
        NSView* view = [[[FloatWindowContentView alloc] 
                         initWithFrame:frameRect] autorelease];
        [self setContentView:view];

        [self setAcceptsMouseMovedEvents:YES];
        [self setIgnoresMouseEvents:NO];
    }    
    return self;                        
}

- (BOOL)becomesKeyOnlyIfNeeded
{
    return YES;
}

- (void)becomeMainWindow
{
    NSLog(@"becomeMainWindow");
    [super becomeMainWindow];
}

- (void)becomeKeyWindow
{
    NSLog(@"becomeKeyWindow");
    [super becomeKeyWindow];
}

@end

@implementation FloatWindowContentView

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
    return YES;
}

- (BOOL)acceptsFirstResponder
{   
    return YES;
}

- (id)initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];
    if (self) {
        NSTrackingArea* area;
        area = [[NSTrackingArea alloc] initWithRect:frameRect
                                            options:NSTrackingActiveAlways|
                                                    NSTrackingMouseMoved|
                                                    NSTrackingMouseEnteredAndExited 
                                              owner:self 
                                           userInfo:nil];
        [self addTrackingArea:area];
        [area release];
    }
    return self;
}

- (void)drawRect:(NSRect)rect
{
    [[NSColor redColor] set];
    NSRectFill([self bounds]);
}

- (BOOL)becomeFirstResponder
{
    NSLog(@"becomeFirstResponder");
    return [super becomeFirstResponder];
}

@end

1 Ответ

1 голос
/ 10 августа 2010

Я думаю, что нашел правильный ответ. Это как-то связано с указанием NSWindow принять событие MouseMoved. но к моему удивлению, окно должно принимать события mouseMoved не в плавающем окне, а в текущем окне ключа. Таким образом, решение простое: просто включите ключевое окно, чтобы принимать перемещенные события мыши перед началом отслеживания, и верните переключатель после завершения отслеживания.

...