335 // NSTimeInterval has microseconds precision |
335 // NSTimeInterval has microseconds precision |
336 #define TS_EQUAL(ts1, ts2) (fabs((ts1) - (ts2)) < 1e-6) |
336 #define TS_EQUAL(ts1, ts2) (fabs((ts1) - (ts2)) < 1e-6) |
337 |
337 |
338 - (void)sendEvent:(NSEvent *)event |
338 - (void)sendEvent:(NSEvent *)event |
339 { |
339 { |
340 if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp)) { |
340 if ([event type] == NSApplicationDefined && TS_EQUAL([event timestamp], dummyEventTimestamp) && [event subtype] == 0) { |
341 [seenDummyEventLock lockWhenCondition:NO]; |
341 [seenDummyEventLock lockWhenCondition:NO]; |
342 [seenDummyEventLock unlockWithCondition:YES]; |
342 [seenDummyEventLock unlockWithCondition:YES]; |
|
343 } else if ([event type] == NSApplicationDefined && [event subtype] == 777) { |
|
344 void (^block)() = (void (^)()) [event data1]; |
|
345 block(); |
|
346 [block release]; |
343 } else if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) { |
347 } else if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) { |
344 // Cocoa won't send us key up event when releasing a key while Cmd is down, |
348 // Cocoa won't send us key up event when releasing a key while Cmd is down, |
345 // so we have to do it ourselves. |
349 // so we have to do it ourselves. |
346 [[self keyWindow] sendEvent:event]; |
350 [[self keyWindow] sendEvent:event]; |
347 } else { |
351 } else { |
348 [super sendEvent:event]; |
352 [super sendEvent:event]; |
349 } |
353 } |
350 } |
354 } |
|
355 |
|
356 /* |
|
357 * Posts the block to the AppKit event queue which will be executed |
|
358 * on the main AppKit loop. |
|
359 * While running nested loops this event will be ignored. |
|
360 */ |
|
361 - (void)postRunnableEvent:(void (^)())block |
|
362 { |
|
363 void (^copy)() = [block copy]; |
|
364 NSInteger encode = (NSInteger) copy; |
|
365 [copy retain]; |
|
366 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
|
367 NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined |
|
368 location: NSMakePoint(0,0) |
|
369 modifierFlags: 0 |
|
370 timestamp: 0 |
|
371 windowNumber: 0 |
|
372 context: nil |
|
373 subtype: 777 |
|
374 data1: encode |
|
375 data2: 0]; |
|
376 |
|
377 [NSApp postEvent: event atStart: NO]; |
|
378 [pool drain]; |
|
379 } |
|
380 |
|
381 |
351 |
382 |
352 - (void)postDummyEvent { |
383 - (void)postDummyEvent { |
353 seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO]; |
384 seenDummyEventLock = [[NSConditionLock alloc] initWithCondition:NO]; |
354 dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime; |
385 dummyEventTimestamp = [NSProcessInfo processInfo].systemUptime; |
355 |
386 |