Chromium Code Reviews| Index: ui/views_content_client/views_content_client_main_parts_mac.mm |
| diff --git a/ui/views_content_client/views_content_client_main_parts_mac.mm b/ui/views_content_client/views_content_client_main_parts_mac.mm |
| index 8d2f12bcf8c00263564fc6dc518f6cb32949dc5c..b0da15ca892e20c8939dea30f0c9eabab94fe3d7 100644 |
| --- a/ui/views_content_client/views_content_client_main_parts_mac.mm |
| +++ b/ui/views_content_client/views_content_client_main_parts_mac.mm |
| @@ -2,13 +2,28 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +#import <Cocoa/Cocoa.h> |
| + |
| #include "base/files/file_path.h" |
| +#include "base/mac/scoped_nsobject.h" |
| #include "base/path_service.h" |
| #include "content/public/common/content_paths.h" |
| #include "content/shell/browser/shell_browser_context.h" |
| #include "ui/views_content_client/views_content_client.h" |
| #include "ui/views_content_client/views_content_client_main_parts.h" |
| +// A simple NSApplicationDelegate that provides a basic mainMenu and can |
| +// activate a task when the application has finished loading. |
| +@interface ContentClientAppController : NSObject<NSApplicationDelegate> { |
|
Robert Sesek
2014/07/21 17:53:54
naming: ViewContentClientAppController, to disting
tapted
2014/07/22 00:06:51
Done.
|
| + @private |
| + base::Closure task_; |
| +} |
| + |
| +// Set the task to run after receiving -applicationDidFinishLaunching:. |
| +- (void)setTask:(const base::Closure&)task; |
| + |
| +@end |
| + |
| namespace ui { |
| namespace { |
| @@ -18,12 +33,14 @@ class ViewsContentClientMainPartsMac : public ViewsContentClientMainParts { |
| ViewsContentClientMainPartsMac( |
| const content::MainFunctionParams& content_params, |
| ViewsContentClient* views_content_client); |
| - virtual ~ViewsContentClientMainPartsMac() {} |
| + virtual ~ViewsContentClientMainPartsMac(); |
| // content::BrowserMainParts: |
| virtual void PreMainMessageLoopRun() OVERRIDE; |
| private: |
| + base::scoped_nsobject<ContentClientAppController> app_controller_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(ViewsContentClientMainPartsMac); |
| }; |
| @@ -34,12 +51,25 @@ ViewsContentClientMainPartsMac::ViewsContentClientMainPartsMac( |
| // Cache the child process path to avoid triggering an AssertIOAllowed. |
| base::FilePath child_process_exe; |
| PathService::Get(content::CHILD_PROCESS_EXE, &child_process_exe); |
| + |
| + app_controller_.reset([[ContentClientAppController alloc] init]); |
| + [[NSApplication sharedApplication] setDelegate:app_controller_]; |
|
Robert Sesek
2014/07/21 17:53:54
This is only for demo applications, right? Otherwi
tapted
2014/07/22 00:06:51
Yep - just demo apps. Currently views_examples_wit
|
| } |
| void ViewsContentClientMainPartsMac::PreMainMessageLoopRun() { |
| ViewsContentClientMainParts::PreMainMessageLoopRun(); |
| - views_content_client()->task().Run(browser_context(), NULL); |
| + // On Mac, the task must be deferred to applicationDidFinishLaunching. If not, |
| + // the widget can activate, but (even if configured) the mainMenu won't be |
| + // ready to switch over in the OSX UI, so it will look strange. |
| + NSWindow* window_context = nil; |
| + [app_controller_ setTask:base::Bind(views_content_client()->task(), |
| + base::Unretained(browser_context()), |
| + base::Unretained(window_context))]; |
| +} |
| + |
| +ViewsContentClientMainPartsMac::~ViewsContentClientMainPartsMac() { |
| + [[NSApplication sharedApplication] setDelegate:nil]; |
| } |
| } // namespace |
| @@ -53,3 +83,36 @@ ViewsContentClientMainParts* ViewsContentClientMainParts::Create( |
| } |
| } // namespace ui |
| + |
| +@implementation ContentClientAppController |
| + |
| +- (void)setTask:(const base::Closure&)task { |
| + task_ = task; |
| +} |
| + |
| +- (void)applicationDidFinishLaunching:(NSNotification*)aNotification { |
| + // To get key events, the application needs to have an activation policy. |
| + // Unbundled apps (i.e. those without an Info.plist) default to |
| + // NSApplicationActivationPolicyProhibited. |
| + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; |
| + |
| + // Create a basic mainMenu object using the executable filename. |
| + base::scoped_nsobject<NSMenu> mainMenu([[NSMenu alloc] initWithTitle:@""]); |
| + NSMenuItem* appMenuItem = |
| + [mainMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; |
| + [NSApp setMainMenu:mainMenu]; |
| + |
| + base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); |
| + NSString* appName = [[NSProcessInfo processInfo] processName]; |
| + // TODO(tapted): Localize "Quit" if this is ever used for a released binary. |
|
Robert Sesek
2014/07/21 17:53:54
I wonder if you can use the AppKit string for this
tapted
2014/07/22 00:06:51
Found a way to do this using info gathered here: h
Robert Sesek
2014/07/22 00:39:12
Hm yeah, definitely not as pretty. I think unlocal
tapted
2014/07/22 01:23:49
Done - (rolled it back to unlocalized).
|
| + // At the time of writing, ui_strings.grd has "Close" but not "Quit". |
| + NSString* quitTitle = [@"Quit " stringByAppendingString:appName]; |
| + [appMenu addItemWithTitle:quitTitle |
| + action:@selector(terminate:) |
| + keyEquivalent:@"q"]; |
| + [appMenuItem setSubmenu:appMenu]; |
| + |
| + task_.Run(); |
| +} |
| + |
| +@end |