Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #import "base/message_pump_mac.h" | 5 #import "base/message_pump_mac.h" |
| 6 | 6 |
| 7 #import <AppKit/AppKit.h> | |
| 8 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
| 9 | 8 |
| 10 #include <limits> | 9 #include <limits> |
| 11 | 10 |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/run_loop.h" | |
| 13 #include "base/time.h" | 13 #include "base/time.h" |
| 14 | 14 |
| 15 #if !defined(OS_IOS) | |
| 16 #import <AppKit/AppKit.h> | |
| 17 #endif // !defined(OS_IOS) | |
| 18 | |
| 15 namespace { | 19 namespace { |
| 16 | 20 |
| 17 void NoOp(void* info) { | 21 void NoOp(void* info) { |
| 18 } | 22 } |
| 19 | 23 |
| 20 const CFTimeInterval kCFTimeIntervalMax = | 24 const CFTimeInterval kCFTimeIntervalMax = |
| 21 std::numeric_limits<CFTimeInterval>::max(); | 25 std::numeric_limits<CFTimeInterval>::max(); |
| 22 | 26 |
| 23 // Set to true if MessagePumpMac::Create() is called before NSApp is | 27 // Set to true if MessagePumpMac::Create() is called before NSApp is |
| 24 // initialized. Only accessed from the main thread. | 28 // initialized. Only accessed from the main thread. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 } | 157 } |
| 154 | 158 |
| 155 // Must be called on the run loop thread. | 159 // Must be called on the run loop thread. |
| 156 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) { | 160 void MessagePumpCFRunLoopBase::Run(Delegate* delegate) { |
| 157 // nesting_level_ will be incremented in EnterExitRunLoop, so set | 161 // nesting_level_ will be incremented in EnterExitRunLoop, so set |
| 158 // run_nesting_level_ accordingly. | 162 // run_nesting_level_ accordingly. |
| 159 int last_run_nesting_level = run_nesting_level_; | 163 int last_run_nesting_level = run_nesting_level_; |
| 160 run_nesting_level_ = nesting_level_ + 1; | 164 run_nesting_level_ = nesting_level_ + 1; |
| 161 | 165 |
| 162 Delegate* last_delegate = delegate_; | 166 Delegate* last_delegate = delegate_; |
| 167 SetDelegate(delegate); | |
| 168 | |
| 169 DoRun(delegate); | |
| 170 | |
| 171 // Restore the previous state of the object. | |
| 172 SetDelegate(last_delegate); | |
| 173 run_nesting_level_ = last_run_nesting_level; | |
| 174 } | |
| 175 | |
| 176 void MessagePumpCFRunLoopBase::SetDelegate(Delegate* delegate) { | |
| 163 delegate_ = delegate; | 177 delegate_ = delegate; |
| 164 | 178 |
| 165 if (delegate) { | 179 if (delegate) { |
| 166 // If any work showed up but could not be dispatched for want of a | 180 // If any work showed up but could not be dispatched for want of a |
| 167 // delegate, set it up for dispatch again now that a delegate is | 181 // delegate, set it up for dispatch again now that a delegate is |
| 168 // available. | 182 // available. |
| 169 if (delegateless_work_) { | 183 if (delegateless_work_) { |
| 170 CFRunLoopSourceSignal(work_source_); | 184 CFRunLoopSourceSignal(work_source_); |
| 171 delegateless_work_ = false; | 185 delegateless_work_ = false; |
| 172 } | 186 } |
| 173 if (delegateless_idle_work_) { | 187 if (delegateless_idle_work_) { |
| 174 CFRunLoopSourceSignal(idle_work_source_); | 188 CFRunLoopSourceSignal(idle_work_source_); |
| 175 delegateless_idle_work_ = false; | 189 delegateless_idle_work_ = false; |
| 176 } | 190 } |
| 177 } | 191 } |
| 178 | |
| 179 DoRun(delegate); | |
| 180 | |
| 181 // Restore the previous state of the object. | |
| 182 delegate_ = last_delegate; | |
| 183 run_nesting_level_ = last_run_nesting_level; | |
| 184 } | 192 } |
| 185 | 193 |
| 186 // May be called on any thread. | 194 // May be called on any thread. |
| 187 void MessagePumpCFRunLoopBase::ScheduleWork() { | 195 void MessagePumpCFRunLoopBase::ScheduleWork() { |
| 188 CFRunLoopSourceSignal(work_source_); | 196 CFRunLoopSourceSignal(work_source_); |
| 189 CFRunLoopWakeUp(run_loop_); | 197 CFRunLoopWakeUp(run_loop_); |
| 190 } | 198 } |
| 191 | 199 |
| 192 // Must be called on the run loop thread. | 200 // Must be called on the run loop thread. |
| 193 void MessagePumpCFRunLoopBase::ScheduleDelayedWork( | 201 void MessagePumpCFRunLoopBase::ScheduleDelayedWork( |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 | 520 |
| 513 keep_running_ = true; | 521 keep_running_ = true; |
| 514 } | 522 } |
| 515 | 523 |
| 516 void MessagePumpNSRunLoop::Quit() { | 524 void MessagePumpNSRunLoop::Quit() { |
| 517 keep_running_ = false; | 525 keep_running_ = false; |
| 518 CFRunLoopSourceSignal(quit_source_); | 526 CFRunLoopSourceSignal(quit_source_); |
| 519 CFRunLoopWakeUp(run_loop()); | 527 CFRunLoopWakeUp(run_loop()); |
| 520 } | 528 } |
| 521 | 529 |
| 530 #if defined(OS_IOS) | |
| 531 void MessagePumpUIApplication::DoRun(Delegate* delegate) { | |
| 532 NOTREACHED(); | |
| 533 } | |
| 534 | |
| 535 void MessagePumpUIApplication::Quit() { | |
| 536 NOTREACHED(); | |
| 537 } | |
| 538 | |
| 539 void MessagePumpUIApplication::Attach(Delegate* delegate) { | |
|
Mark Mentovai
2012/07/12 01:08:19
DCHECK(!run_loop_); ? That’d require you to initia
rohitrao (ping after 24h)
2012/07/12 14:20:03
Done. Attach() should never be called multiple ti
| |
| 540 run_loop_ = new base::RunLoop(); | |
| 541 CHECK(run_loop_->BeforeRun()); | |
| 542 SetDelegate(delegate); | |
| 543 } | |
| 544 | |
| 545 MessagePumpUIApplication::~MessagePumpUIApplication() {} | |
|
Mark Mentovai
2012/07/12 01:08:19
Try to keep things ordered sort of consistently, p
rohitrao (ping after 24h)
2012/07/12 14:20:03
Ooh, I know what I'm watching tonight.
| |
| 546 | |
| 547 #else | |
| 548 | |
| 522 MessagePumpNSApplication::MessagePumpNSApplication() | 549 MessagePumpNSApplication::MessagePumpNSApplication() |
| 523 : keep_running_(true), | 550 : keep_running_(true), |
| 524 running_own_loop_(false) { | 551 running_own_loop_(false) { |
| 525 } | 552 } |
| 526 | 553 |
| 527 MessagePumpNSApplication::~MessagePumpNSApplication() {} | 554 MessagePumpNSApplication::~MessagePumpNSApplication() {} |
| 528 | 555 |
| 529 void MessagePumpNSApplication::DoRun(Delegate* delegate) { | 556 void MessagePumpNSApplication::DoRun(Delegate* delegate) { |
| 530 bool last_running_own_loop_ = running_own_loop_; | 557 bool last_running_own_loop_ = running_own_loop_; |
| 531 | 558 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 613 // CrApplication is responsible for setting handlingSendEvent to true just | 640 // CrApplication is responsible for setting handlingSendEvent to true just |
| 614 // before it sends the event through the event handling mechanism, and | 641 // before it sends the event through the event handling mechanism, and |
| 615 // returning it to its previous value once the event has been sent. | 642 // returning it to its previous value once the event has been sent. |
| 616 NSAutoreleasePool* MessagePumpCrApplication::CreateAutoreleasePool() { | 643 NSAutoreleasePool* MessagePumpCrApplication::CreateAutoreleasePool() { |
| 617 if (MessagePumpMac::IsHandlingSendEvent()) | 644 if (MessagePumpMac::IsHandlingSendEvent()) |
| 618 return nil; | 645 return nil; |
| 619 return MessagePumpNSApplication::CreateAutoreleasePool(); | 646 return MessagePumpNSApplication::CreateAutoreleasePool(); |
| 620 } | 647 } |
| 621 | 648 |
| 622 // static | 649 // static |
| 623 MessagePump* MessagePumpMac::Create() { | |
| 624 if ([NSThread isMainThread]) { | |
| 625 if ([NSApp conformsToProtocol:@protocol(CrAppProtocol)]) | |
| 626 return new MessagePumpCrApplication; | |
| 627 | |
| 628 // The main-thread MessagePump implementations REQUIRE an NSApp. | |
| 629 // Executables which have specific requirements for their | |
| 630 // NSApplication subclass should initialize appropriately before | |
| 631 // creating an event loop. | |
| 632 [NSApplication sharedApplication]; | |
| 633 not_using_crapp = true; | |
| 634 return new MessagePumpNSApplication; | |
| 635 } | |
| 636 | |
| 637 return new MessagePumpNSRunLoop; | |
| 638 } | |
| 639 | |
| 640 // static | |
| 641 bool MessagePumpMac::UsingCrApp() { | 650 bool MessagePumpMac::UsingCrApp() { |
| 642 DCHECK([NSThread isMainThread]); | 651 DCHECK([NSThread isMainThread]); |
| 643 | 652 |
| 644 // If NSApp is still not initialized, then the subclass used cannot | 653 // If NSApp is still not initialized, then the subclass used cannot |
| 645 // be determined. | 654 // be determined. |
| 646 DCHECK(NSApp); | 655 DCHECK(NSApp); |
| 647 | 656 |
| 648 // The pump was created using MessagePumpNSApplication. | 657 // The pump was created using MessagePumpNSApplication. |
| 649 if (not_using_crapp) | 658 if (not_using_crapp) |
| 650 return false; | 659 return false; |
| 651 | 660 |
| 652 return [NSApp conformsToProtocol:@protocol(CrAppProtocol)]; | 661 return [NSApp conformsToProtocol:@protocol(CrAppProtocol)]; |
| 653 } | 662 } |
| 654 | 663 |
| 655 // static | 664 // static |
| 656 bool MessagePumpMac::IsHandlingSendEvent() { | 665 bool MessagePumpMac::IsHandlingSendEvent() { |
| 657 DCHECK([NSApp conformsToProtocol:@protocol(CrAppProtocol)]); | 666 DCHECK([NSApp conformsToProtocol:@protocol(CrAppProtocol)]); |
| 658 NSObject<CrAppProtocol>* app = static_cast<NSObject<CrAppProtocol>*>(NSApp); | 667 NSObject<CrAppProtocol>* app = static_cast<NSObject<CrAppProtocol>*>(NSApp); |
| 659 return [app isHandlingSendEvent]; | 668 return [app isHandlingSendEvent]; |
| 660 } | 669 } |
| 670 #endif // !defined(OS_IOS) | |
| 671 | |
| 672 // static | |
| 673 MessagePump* MessagePumpMac::Create() { | |
| 674 if ([NSThread isMainThread]) { | |
| 675 #if defined(OS_IOS) | |
| 676 return new MessagePumpUIApplication; | |
| 677 #else | |
| 678 if ([NSApp conformsToProtocol:@protocol(CrAppProtocol)]) | |
| 679 return new MessagePumpCrApplication; | |
| 680 | |
| 681 // The main-thread MessagePump implementations REQUIRE an NSApp. | |
| 682 // Executables which have specific requirements for their | |
| 683 // NSApplication subclass should initialize appropriately before | |
| 684 // creating an event loop. | |
| 685 [NSApplication sharedApplication]; | |
| 686 not_using_crapp = true; | |
| 687 return new MessagePumpNSApplication; | |
| 688 #endif | |
| 689 } | |
| 690 | |
| 691 return new MessagePumpNSRunLoop; | |
| 692 } | |
| 661 | 693 |
| 662 } // namespace base | 694 } // namespace base |
| OLD | NEW |