| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/message_pump_mac.h" | 5 #import "base/message_pump_mac.h" |
| 6 | 6 |
| 7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
| 8 #import <Foundation/Foundation.h> | 8 #import <Foundation/Foundation.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/time.h" | 13 #include "base/time.h" |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 void NoOp(void* info) { | 17 void NoOp(void* info) { |
| 18 } | 18 } |
| 19 | 19 |
| 20 const CFTimeInterval kCFTimeIntervalMax = | 20 const CFTimeInterval kCFTimeIntervalMax = |
| 21 std::numeric_limits<CFTimeInterval>::max(); | 21 std::numeric_limits<CFTimeInterval>::max(); |
| 22 | 22 |
| 23 // Set to true if MessagePumpMac::Create() is called before NSApp is |
| 24 // initialized. Only accessed from the main thread. |
| 25 bool not_using_crapp = false; |
| 26 |
| 23 } // namespace | 27 } // namespace |
| 24 | 28 |
| 25 namespace base { | 29 namespace base { |
| 26 | 30 |
| 27 // A scoper for autorelease pools created from message pump run loops. | 31 // A scoper for autorelease pools created from message pump run loops. |
| 28 // Avoids dirtying up the ScopedNSAutoreleasePool interface for the rare | 32 // Avoids dirtying up the ScopedNSAutoreleasePool interface for the rare |
| 29 // case where an autorelease pool needs to be passed in. | 33 // case where an autorelease pool needs to be passed in. |
| 30 class MessagePumpScopedAutoreleasePool { | 34 class MessagePumpScopedAutoreleasePool { |
| 31 public: | 35 public: |
| 32 explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) : | 36 explicit MessagePumpScopedAutoreleasePool(MessagePumpCFRunLoopBase* pump) : |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 modifierFlags:0 | 588 modifierFlags:0 |
| 585 timestamp:0 | 589 timestamp:0 |
| 586 windowNumber:0 | 590 windowNumber:0 |
| 587 context:NULL | 591 context:NULL |
| 588 subtype:0 | 592 subtype:0 |
| 589 data1:0 | 593 data1:0 |
| 590 data2:0] | 594 data2:0] |
| 591 atStart:NO]; | 595 atStart:NO]; |
| 592 } | 596 } |
| 593 | 597 |
| 598 MessagePumpCrApplication::MessagePumpCrApplication() { |
| 599 } |
| 600 |
| 594 // Prevents an autorelease pool from being created if the app is in the midst of | 601 // Prevents an autorelease pool from being created if the app is in the midst of |
| 595 // handling a UI event because various parts of AppKit depend on objects that | 602 // handling a UI event because various parts of AppKit depend on objects that |
| 596 // are created while handling a UI event to be autoreleased in the event loop. | 603 // are created while handling a UI event to be autoreleased in the event loop. |
| 597 // An example of this is NSWindowController. When a window with a window | 604 // An example of this is NSWindowController. When a window with a window |
| 598 // controller is closed it goes through a stack like this: | 605 // controller is closed it goes through a stack like this: |
| 599 // (Several stack frames elided for clarity) | 606 // (Several stack frames elided for clarity) |
| 600 // | 607 // |
| 601 // #0 [NSWindowController autorelease] | 608 // #0 [NSWindowController autorelease] |
| 602 // #1 DoAClose | 609 // #1 DoAClose |
| 603 // #2 MessagePumpCFRunLoopBase::DoWork() | 610 // #2 MessagePumpCFRunLoopBase::DoWork() |
| (...skipping 11 matching lines...) Expand all Loading... |
| 615 // window in frame #5. When the stack is unwound to frame #5, the window would | 622 // window in frame #5. When the stack is unwound to frame #5, the window would |
| 616 // no longer exists and crashes may occur. Apple gets around this by never | 623 // no longer exists and crashes may occur. Apple gets around this by never |
| 617 // releasing the pool it creates in frame #4, and letting frame #7 clean it up | 624 // releasing the pool it creates in frame #4, and letting frame #7 clean it up |
| 618 // when it cleans up the pool that wraps frame #7. When an autorelease pool is | 625 // when it cleans up the pool that wraps frame #7. When an autorelease pool is |
| 619 // released it releases all other pools that were created after it on the | 626 // released it releases all other pools that were created after it on the |
| 620 // autorelease pool stack. | 627 // autorelease pool stack. |
| 621 // | 628 // |
| 622 // CrApplication is responsible for setting handlingSendEvent to true just | 629 // CrApplication is responsible for setting handlingSendEvent to true just |
| 623 // before it sends the event through the event handling mechanism, and | 630 // before it sends the event through the event handling mechanism, and |
| 624 // returning it to its previous value once the event has been sent. | 631 // returning it to its previous value once the event has been sent. |
| 625 NSAutoreleasePool* MessagePumpNSApplication::CreateAutoreleasePool() { | 632 NSAutoreleasePool* MessagePumpCrApplication::CreateAutoreleasePool() { |
| 626 NSAutoreleasePool* pool = nil; | 633 if (MessagePumpMac::IsHandlingSendEvent()) |
| 627 DCHECK([NSApp conformsToProtocol:@protocol(CrAppProtocol)]); | 634 return nil; |
| 628 if (![NSApp isHandlingSendEvent]) { | 635 return MessagePumpNSApplication::CreateAutoreleasePool(); |
| 629 pool = MessagePumpCFRunLoopBase::CreateAutoreleasePool(); | |
| 630 } | |
| 631 return pool; | |
| 632 } | 636 } |
| 633 | 637 |
| 634 // static | 638 // static |
| 635 MessagePump* MessagePumpMac::Create() { | 639 MessagePump* MessagePumpMac::Create() { |
| 636 if ([NSThread isMainThread]) { | 640 if ([NSThread isMainThread]) { |
| 641 if ([NSApp conformsToProtocol:@protocol(CrAppProtocol)]) |
| 642 return new MessagePumpCrApplication; |
| 643 [NSApplication sharedApplication]; |
| 644 not_using_crapp = true; |
| 637 return new MessagePumpNSApplication; | 645 return new MessagePumpNSApplication; |
| 638 } | 646 } |
| 639 | 647 |
| 640 return new MessagePumpNSRunLoop; | 648 return new MessagePumpNSRunLoop; |
| 641 } | 649 } |
| 642 | 650 |
| 651 // static |
| 652 bool MessagePumpMac::UsingCrApp() { |
| 653 DCHECK([NSThread isMainThread]); |
| 654 |
| 655 // If NSApp is still not initialized, then the subclass used cannot |
| 656 // be determined. |
| 657 DCHECK(NSApp); |
| 658 |
| 659 // The pump was created using MessagePumpNSApplication. |
| 660 if (not_using_crapp) |
| 661 return false; |
| 662 |
| 663 return [NSApp conformsToProtocol:@protocol(CrAppProtocol)]; |
| 664 } |
| 665 |
| 666 // static |
| 667 bool MessagePumpMac::IsHandlingSendEvent() { |
| 668 DCHECK([NSApp conformsToProtocol:@protocol(CrAppProtocol)]); |
| 669 NSObject<CrAppProtocol>* app = static_cast<NSObject<CrAppProtocol>*>(NSApp); |
| 670 return [app isHandlingSendEvent]; |
| 671 } |
| 672 |
| 643 } // namespace base | 673 } // namespace base |
| OLD | NEW |