Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 30, 2011, 04:12 PM   #1
Saphrosit
macrumors newbie
 
Join Date: Oct 2010
Assertion failure in NSEvent when runModalForWindow

Hi everybody,

I'm experiencing a strange problem: in my application I wait for keyDown events, using this code

Code:
machPort =  CGEventTapCreate(kCGSessionEventTap,
					 kCGTailAppendEventTap,
					 kCGEventTapOptionDefault,
					 CGEventMaskBit(kCGEventKeyDown),
					 (CGEventTapCallBack) eventTapFunction,
					 self );
		
CFRunLoopSourceRef mKeyboardEventSrc = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, machPort, 0);
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFRunLoopAddSource(runLoop,  mKeyboardEventSrc, kCFRunLoopDefaultMode);
I need to show a window after the pressure of some keys. I need also the program to stop while the user makes a choice in that window, so I call

Code:
[[NSApplication sharedApplication] runModalForWindow:myWindow];
To stop runModal I linked a button in the window to a method that runs:
Code:
[myWindow orderOut:self];
[[NSApplication sharedApplication] stopModal];
The problem is that I receive a
Code:
Assertion failure in -[NSEvent _initWithCGSEvent:eventRef:], /SourceCache/AppKit/AppKit-1038.35/AppKit.subproj/NSEvent.m:1260
Invalid parameter not satisfying: cgsEvent.type > 0 && cgsEvent.type <= kCGSLastEventType
error when trying to `stopModal`. Can someone explain me why and how to solve it?
Thanks in advance
Saphrosit is offline   0 Reply With Quote
Old Apr 30, 2011, 09:26 PM   #2
jiminaus
macrumors 65816
 
Join Date: Dec 2010
Location: Sydney
Don't use the CoreFoundation run loop functions with NSApplication. Use NSRunLoop instead.

Code:
@interface MYAppDelegate : NSObject <NSApplicationDelegate> {
@private
    CFMachPortRef machPort;
    NSMachPort *machPortWrapper;
}
@end

@implementation MYAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    machPort = CGEventTapCreate(kCGSessionEventTap,
                                kCGTailAppendEventTap,
                                kCGEventTapOptionDefault,
                                CGEventMaskBit(kCGEventKeyDown),
                                eventTapFunction,
                                self);
    if (!machPort) {
        NSException *e =
            [NSException exceptionWithName:@"FailedToCreateKeyDownEventTap"
                                    reason:@"Failed to create an event tap for key down events"
                                  userInfo:[NSDictionary dictionary]];
        @throw e;
    }
    
    /* 
       Wrap the Mach port behind machPort into an NSMachPort object.
       Note the NSMachPortDeallocateNone option is critical.  We don't
       want NSMachPort to invalidate or destroy the mach port.   That
       responsibility lies with machPort.
    */
    machPortWrapper = 
        [[NSMachPort alloc] 
                initWithMachPort:CFMachPortGetPort(machPort) 
                         options:NSMachPortDeallocateNone];
    
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop addPort:machPortWrapper forMode:NSDefaultRunLoopMode];
}

- (void)applicationWillTerminate:(NSNotification *)aNotification
{
    if (machPortWrapper) {
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop removePort:machPortWrapper forMode:NSDefaultRunLoopMode];
        [machPortWrapper release];
        machPortWrapper = NULL;
    }
    if (machPort) {
        CFRelease(machPort);
        machPort = NULL;
    }
}

@end
jiminaus is offline   0 Reply With Quote
Old May 1, 2011, 06:25 AM   #3
Saphrosit
Thread Starter
macrumors newbie
 
Join Date: Oct 2010
Nothing changed...

I think the problem is due to an illegal CGEventType passed to eventTapFunction:

Code:
CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
	
	NSEvent* sysEvent = [NSEvent eventWithCGEvent:event];
	Controller *app = (Controller*) refcon;
#if DEBUG_EVENT	
	NSLog(@"event received: %@, type = %lu",sysEvent,[sysEvent type]);
#endif
	if (type == NX_KEYDOWN && [sysEvent type] == NSKeyDown) {	
              [app myFunction];
	}
	return event;
}
I found that, when app crashes, type is -2. I tried to add
Code:
	if (type != NX_KEYDOWN)
		return event;
so I do not receive the assertion failure but the application stops to handle events. Not sure this is the right way to solve the problem...
Saphrosit is offline   0 Reply With Quote
Old May 1, 2011, 06:52 AM   #4
jiminaus
macrumors 65816
 
Join Date: Dec 2010
Location: Sydney
I don't know why you're getting that. I don't get that in my test project which shows a modal dialog whenever the user hits Ctrl+Cmd+A.

Note that you should have only been getting key down events in your eventTapFunction so testing for it shouldn't have been necessary.

Just returning the event is fine. The event will continue to be processed as though your tap wasn't in place at all. But are you saying that when you do this, your app stops receiving further events?

Me being me, I'd want to know what this spurious event is, in case it's a symptom of another problem.

EDIT: Actually an event type CGEventType is defined in CGEventType.h as unsigned 32-bit integer. So your -2 is actually 0xFFFFFFFE. In CGEventType.h that's defined as kCGEventTapDisabledByTimeout. There's a comment just about this that says:
Quote:
/* Out of band event types. These are delivered to the event tap callback
to notify it of unusual conditions that disable the event tap. */
So it looks like your event tap is timing out. That's why your not getting anymore events after this.


EDIT 2: Just to confirm, you using an event tap because you need this functionality to trigger even if your application is not in the foreground right? Otherwise, I think you'd better off overriding sendEvent: in NSApplication.

Last edited by jiminaus; May 1, 2011 at 08:27 AM.
jiminaus is offline   0 Reply With Quote
Old May 1, 2011, 07:46 PM   #5
Saphrosit
Thread Starter
macrumors newbie
 
Join Date: Oct 2010
Quote:
Originally Posted by jiminaus View Post
Actually an event type CGEventType is defined in CGEventType.h as unsigned 32-bit integer. So your -2 is actually 0xFFFFFFFE. In CGEventType.h that's defined as kCGEventTapDisabledByTimeout. There's a comment just about this that says:

So it looks like your event tap is timing out. That's why your not getting anymore events after this.
Wonder why I get this event... I thought of a workaround, may this be a solution?
Code:
	if (type == -2) {
		[app reHandleEvent];
		return event;
	}
Code:
-(void)reHandleEvent {
	
	machPort =  CGEventTapCreate(kCGSessionEventTap,
				 kCGTailAppendEventTap,
				 kCGEventTapOptionDefault,
				 CGEventMaskBit(kCGEventKeyDown),
				 (CGEventTapCallBack) eventTapFunction,
				 self );
	
	NSMachPort *machPortWrapper = [[NSMachPort alloc] 
initWithMachPort:CFMachPortGetPort(machPort) 
options:NSMachPortDeallocateNone];
	
	[[NSRunLoop currentRunLoop] addPort:machPortWrapper forMode:NSDefaultRunLoopMode];	
	
	[machPortWrapper release];

}
Not sure if, when event tap get disabled, it gets also dismissed correctly or if it leaks somewhere...

Quote:
Originally Posted by jiminaus View Post
EDIT 2: Just to confirm, you using an event tap because you need this functionality to trigger even if your application is not in the foreground right? Otherwise, I think you'd better off overriding sendEvent: in NSApplication.
Application runs in background

Last edited by Saphrosit; May 2, 2011 at 05:28 AM.
Saphrosit is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Seagate SSHD failure + SATA cable failure? Blondie :) MacBook Pro 0 Apr 10, 2014 09:52 PM
HD Failure? dawgfan MacBook 11 Jan 18, 2013 04:41 PM
runModalForWindow - set screen position? fbs419 Mac Programming 0 Oct 5, 2012 02:03 PM
Resolved: How to prevent number of rows assertion failure? ArtOfWarfare iPhone/iPad Programming 4 Sep 15, 2012 12:58 AM
SimCard Failure :( sk8ters iPhone Tips, Help and Troubleshooting 0 Sep 12, 2012 05:42 PM

Forum Jump

All times are GMT -5. The time now is 09:26 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC