Cocoa nextEventMatchingMask not receiving NSMouseMoved event

Posted by Jonny on Stack Overflow See other posts from Stack Overflow or by Jonny
Published on 2010-04-02T06:05:42Z Indexed on 2010/04/02 6:13 UTC
Read the original article Hit count: 500

Filed under:
|
|
|

Hello,

I created a local event loop and showed up a borderless window (derived from NSPanel), I found in the event loop there's no NSMouseMoved event received, although I can receive Mouse button down/up events.

What should I do to get the NSMouseMoved events? I found making the float window as key window can receive the NSMouseMoved events, but I don't want to change key window. And it appears this is possible, because I found after clicking the test App Icon in System Dock Bar, I can receive the mousemoved events, and the key window/mainwindow are unchanged.

Here's the my test code: (Create a Cocoa App project names FloatWindowTest, and put a button to link it with the onClick: IBAction). Thanks in advance!

-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

© Stack Overflow or respective owner

Related posts about cocoa

Related posts about custom-controls