OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <Cocoa/Cocoa.h> | |
6 | |
5 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/mac/scoped_nsobject.h" | |
6 #include "base/path_service.h" | 9 #include "base/path_service.h" |
7 #include "content/public/common/content_paths.h" | 10 #include "content/public/common/content_paths.h" |
8 #include "content/shell/browser/shell_browser_context.h" | 11 #include "content/shell/browser/shell_browser_context.h" |
9 #include "ui/views_content_client/views_content_client.h" | 12 #include "ui/views_content_client/views_content_client.h" |
10 #include "ui/views_content_client/views_content_client_main_parts.h" | 13 #include "ui/views_content_client/views_content_client_main_parts.h" |
11 | 14 |
15 // A simple NSApplicationDelegate that provides a basic mainMenu and can | |
16 // activate a task when the application has finished loading. | |
17 @interface ContentClientAppController : NSObject<NSApplicationDelegate> { | |
Robert Sesek
2014/07/21 17:53:54
naming: ViewContentClientAppController, to disting
tapted
2014/07/22 00:06:51
Done.
| |
18 @private | |
19 base::Closure task_; | |
20 } | |
21 | |
22 // Set the task to run after receiving -applicationDidFinishLaunching:. | |
23 - (void)setTask:(const base::Closure&)task; | |
24 | |
25 @end | |
26 | |
12 namespace ui { | 27 namespace ui { |
13 | 28 |
14 namespace { | 29 namespace { |
15 | 30 |
16 class ViewsContentClientMainPartsMac : public ViewsContentClientMainParts { | 31 class ViewsContentClientMainPartsMac : public ViewsContentClientMainParts { |
17 public: | 32 public: |
18 ViewsContentClientMainPartsMac( | 33 ViewsContentClientMainPartsMac( |
19 const content::MainFunctionParams& content_params, | 34 const content::MainFunctionParams& content_params, |
20 ViewsContentClient* views_content_client); | 35 ViewsContentClient* views_content_client); |
21 virtual ~ViewsContentClientMainPartsMac() {} | 36 virtual ~ViewsContentClientMainPartsMac(); |
22 | 37 |
23 // content::BrowserMainParts: | 38 // content::BrowserMainParts: |
24 virtual void PreMainMessageLoopRun() OVERRIDE; | 39 virtual void PreMainMessageLoopRun() OVERRIDE; |
25 | 40 |
26 private: | 41 private: |
42 base::scoped_nsobject<ContentClientAppController> app_controller_; | |
43 | |
27 DISALLOW_COPY_AND_ASSIGN(ViewsContentClientMainPartsMac); | 44 DISALLOW_COPY_AND_ASSIGN(ViewsContentClientMainPartsMac); |
28 }; | 45 }; |
29 | 46 |
30 ViewsContentClientMainPartsMac::ViewsContentClientMainPartsMac( | 47 ViewsContentClientMainPartsMac::ViewsContentClientMainPartsMac( |
31 const content::MainFunctionParams& content_params, | 48 const content::MainFunctionParams& content_params, |
32 ViewsContentClient* views_content_client) | 49 ViewsContentClient* views_content_client) |
33 : ViewsContentClientMainParts(content_params, views_content_client) { | 50 : ViewsContentClientMainParts(content_params, views_content_client) { |
34 // Cache the child process path to avoid triggering an AssertIOAllowed. | 51 // Cache the child process path to avoid triggering an AssertIOAllowed. |
35 base::FilePath child_process_exe; | 52 base::FilePath child_process_exe; |
36 PathService::Get(content::CHILD_PROCESS_EXE, &child_process_exe); | 53 PathService::Get(content::CHILD_PROCESS_EXE, &child_process_exe); |
54 | |
55 app_controller_.reset([[ContentClientAppController alloc] init]); | |
56 [[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
| |
37 } | 57 } |
38 | 58 |
39 void ViewsContentClientMainPartsMac::PreMainMessageLoopRun() { | 59 void ViewsContentClientMainPartsMac::PreMainMessageLoopRun() { |
40 ViewsContentClientMainParts::PreMainMessageLoopRun(); | 60 ViewsContentClientMainParts::PreMainMessageLoopRun(); |
41 | 61 |
42 views_content_client()->task().Run(browser_context(), NULL); | 62 // On Mac, the task must be deferred to applicationDidFinishLaunching. If not, |
63 // the widget can activate, but (even if configured) the mainMenu won't be | |
64 // ready to switch over in the OSX UI, so it will look strange. | |
65 NSWindow* window_context = nil; | |
66 [app_controller_ setTask:base::Bind(views_content_client()->task(), | |
67 base::Unretained(browser_context()), | |
68 base::Unretained(window_context))]; | |
69 } | |
70 | |
71 ViewsContentClientMainPartsMac::~ViewsContentClientMainPartsMac() { | |
72 [[NSApplication sharedApplication] setDelegate:nil]; | |
43 } | 73 } |
44 | 74 |
45 } // namespace | 75 } // namespace |
46 | 76 |
47 // static | 77 // static |
48 ViewsContentClientMainParts* ViewsContentClientMainParts::Create( | 78 ViewsContentClientMainParts* ViewsContentClientMainParts::Create( |
49 const content::MainFunctionParams& content_params, | 79 const content::MainFunctionParams& content_params, |
50 ViewsContentClient* views_content_client) { | 80 ViewsContentClient* views_content_client) { |
51 return | 81 return |
52 new ViewsContentClientMainPartsMac(content_params, views_content_client); | 82 new ViewsContentClientMainPartsMac(content_params, views_content_client); |
53 } | 83 } |
54 | 84 |
55 } // namespace ui | 85 } // namespace ui |
86 | |
87 @implementation ContentClientAppController | |
88 | |
89 - (void)setTask:(const base::Closure&)task { | |
90 task_ = task; | |
91 } | |
92 | |
93 - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { | |
94 // To get key events, the application needs to have an activation policy. | |
95 // Unbundled apps (i.e. those without an Info.plist) default to | |
96 // NSApplicationActivationPolicyProhibited. | |
97 [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; | |
98 | |
99 // Create a basic mainMenu object using the executable filename. | |
100 base::scoped_nsobject<NSMenu> mainMenu([[NSMenu alloc] initWithTitle:@""]); | |
101 NSMenuItem* appMenuItem = | |
102 [mainMenu addItemWithTitle:@"" action:NULL keyEquivalent:@""]; | |
103 [NSApp setMainMenu:mainMenu]; | |
104 | |
105 base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]); | |
106 NSString* appName = [[NSProcessInfo processInfo] processName]; | |
107 // 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).
| |
108 // At the time of writing, ui_strings.grd has "Close" but not "Quit". | |
109 NSString* quitTitle = [@"Quit " stringByAppendingString:appName]; | |
110 [appMenu addItemWithTitle:quitTitle | |
111 action:@selector(terminate:) | |
112 keyEquivalent:@"q"]; | |
113 [appMenuItem setSubmenu:appMenu]; | |
114 | |
115 task_.Run(); | |
116 } | |
117 | |
118 @end | |
OLD | NEW |