OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/bind.h" | |
6 #include "base/macros.h" | |
7 #include "mojo/application/application_runner_chromium.h" | |
8 #include "mojo/converters/geometry/geometry_type_converters.h" | |
9 #include "mojo/converters/input_events/input_events_type_converters.h" | |
10 #include "mojo/examples/keyboard/keyboard.mojom.h" | |
11 #include "mojo/examples/window_manager/debug_panel.h" | |
12 #include "mojo/examples/window_manager/window_manager.mojom.h" | |
13 #include "mojo/public/c/system/main.h" | |
14 #include "mojo/public/cpp/application/application_connection.h" | |
15 #include "mojo/public/cpp/application/application_delegate.h" | |
16 #include "mojo/public/cpp/application/application_impl.h" | |
17 #include "mojo/public/cpp/application/interface_factory_impl.h" | |
18 #include "mojo/public/cpp/application/service_provider_impl.h" | |
19 #include "mojo/services/public/cpp/view_manager/view.h" | |
20 #include "mojo/services/public/cpp/view_manager/view_manager.h" | |
21 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" | |
22 #include "mojo/services/public/cpp/view_manager/view_observer.h" | |
23 #include "mojo/services/public/interfaces/input_events/input_events.mojom.h" | |
24 #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" | |
25 #include "mojo/services/window_manager/window_manager_app.h" | |
26 #include "mojo/services/window_manager/window_manager_delegate.h" | |
27 #include "mojo/views/views_init.h" | |
28 #include "ui/aura/window.h" | |
29 #include "ui/events/event.h" | |
30 #include "ui/events/event_constants.h" | |
31 #include "ui/gfx/geometry/size_conversions.h" | |
32 #include "ui/wm/core/focus_rules.h" | |
33 | |
34 #if defined CreateWindow | |
35 #undef CreateWindow | |
36 #endif | |
37 | |
38 namespace mojo { | |
39 namespace examples { | |
40 | |
41 class WindowManager; | |
42 | |
43 namespace { | |
44 | |
45 const int kBorderInset = 25; | |
46 const int kControlPanelWidth = 200; | |
47 const int kTextfieldHeight = 25; | |
48 | |
49 class WMFocusRules : public wm::FocusRules { | |
50 public: | |
51 WMFocusRules(mojo::WindowManagerApp* window_manager_app, | |
52 mojo::View* window_container) | |
53 : window_container_(window_container), | |
54 window_manager_app_(window_manager_app) {} | |
55 virtual ~WMFocusRules() {} | |
56 | |
57 private: | |
58 // Overridden from wm::FocusRules: | |
59 virtual bool IsToplevelWindow(aura::Window* window) const override { | |
60 return mojo::WindowManagerApp::GetViewForWindow(window)->parent() == | |
61 window_container_; | |
62 } | |
63 virtual bool CanActivateWindow(aura::Window* window) const override { | |
64 return mojo::WindowManagerApp::GetViewForWindow(window)->parent() == | |
65 window_container_; | |
66 } | |
67 virtual bool CanFocusWindow(aura::Window* window) const override { | |
68 return true; | |
69 } | |
70 virtual aura::Window* GetToplevelWindow(aura::Window* window) const override { | |
71 mojo::View* view = mojo::WindowManagerApp::GetViewForWindow(window); | |
72 while (view->parent() != window_container_) { | |
73 view = view->parent(); | |
74 // Unparented hierarchy, there is no "top level" window. | |
75 if (!view) | |
76 return NULL; | |
77 } | |
78 | |
79 return window_manager_app_->GetWindowForViewId(view->id()); | |
80 } | |
81 virtual aura::Window* GetActivatableWindow( | |
82 aura::Window* window) const override { | |
83 return GetToplevelWindow(window); | |
84 } | |
85 virtual aura::Window* GetFocusableWindow( | |
86 aura::Window* window) const override { | |
87 return window; | |
88 } | |
89 virtual aura::Window* GetNextActivatableWindow( | |
90 aura::Window* ignore) const override { | |
91 aura::Window* activatable = GetActivatableWindow(ignore); | |
92 const aura::Window::Windows& children = activatable->parent()->children(); | |
93 for (aura::Window::Windows::const_reverse_iterator it = children.rbegin(); | |
94 it != children.rend(); ++it) { | |
95 if (*it != ignore) | |
96 return *it; | |
97 } | |
98 return NULL; | |
99 } | |
100 | |
101 mojo::View* window_container_; | |
102 mojo::WindowManagerApp* window_manager_app_; | |
103 | |
104 DISALLOW_COPY_AND_ASSIGN(WMFocusRules); | |
105 }; | |
106 | |
107 } // namespace | |
108 | |
109 class WindowManagerConnection : public InterfaceImpl<IWindowManager> { | |
110 public: | |
111 explicit WindowManagerConnection(WindowManager* window_manager) | |
112 : window_manager_(window_manager) {} | |
113 virtual ~WindowManagerConnection() {} | |
114 | |
115 private: | |
116 // Overridden from IWindowManager: | |
117 virtual void CloseWindow(Id view_id) override; | |
118 virtual void ShowKeyboard(Id view_id, RectPtr bounds) override; | |
119 virtual void HideKeyboard(Id view_id) override; | |
120 | |
121 WindowManager* window_manager_; | |
122 | |
123 DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); | |
124 }; | |
125 | |
126 class NavigatorHostImpl : public InterfaceImpl<NavigatorHost> { | |
127 public: | |
128 explicit NavigatorHostImpl(WindowManager* window_manager, Id view_id) | |
129 : window_manager_(window_manager), view_id_(view_id) {} | |
130 virtual ~NavigatorHostImpl() { | |
131 } | |
132 | |
133 private: | |
134 virtual void DidNavigateLocally(const mojo::String& url) override; | |
135 virtual void RequestNavigate(Target target, URLRequestPtr request) override; | |
136 | |
137 WindowManager* window_manager_; | |
138 Id view_id_; | |
139 | |
140 DISALLOW_COPY_AND_ASSIGN(NavigatorHostImpl); | |
141 }; | |
142 | |
143 class KeyboardManager : public KeyboardClient, | |
144 public ViewObserver { | |
145 public: | |
146 KeyboardManager() : view_manager_(NULL), view_(NULL) { | |
147 } | |
148 virtual ~KeyboardManager() { | |
149 if (view_) | |
150 view_->parent()->RemoveObserver(this); | |
151 } | |
152 | |
153 View* view() { return view_; } | |
154 | |
155 void Init(ApplicationImpl* application, | |
156 ViewManager* view_manager, | |
157 View* parent, | |
158 const Rect& bounds) { | |
159 view_manager_ = view_manager; | |
160 view_ = View::Create(view_manager); | |
161 view_->SetBounds(bounds); | |
162 parent->AddChild(view_); | |
163 view_->Embed("mojo:keyboard"); | |
164 application->ConnectToService("mojo:keyboard", &keyboard_service_); | |
165 keyboard_service_.set_client(this); | |
166 parent->AddObserver(this); | |
167 } | |
168 | |
169 void Show(Id view_id, const Rect& bounds) { | |
170 keyboard_service_->SetTarget(view_id); | |
171 view_->SetVisible(true); | |
172 } | |
173 | |
174 void Hide(Id view_id) { | |
175 keyboard_service_->SetTarget(0); | |
176 view_->SetVisible(false); | |
177 } | |
178 | |
179 private: | |
180 // KeyboardClient: | |
181 virtual void OnKeyboardEvent(Id view_id, | |
182 int32_t code, | |
183 int32_t flags) override { | |
184 // TODO(sky): figure this out. Code use to dispatch events, but that's a | |
185 // hack. Instead strings should be passed through, or maybe a richer text | |
186 // input interface. | |
187 } | |
188 | |
189 // Overridden from ViewObserver: | |
190 virtual void OnViewBoundsChanged(View* parent, | |
191 const Rect& old_bounds, | |
192 const Rect& new_bounds) override { | |
193 Rect keyboard_bounds(view_->bounds()); | |
194 keyboard_bounds.y = | |
195 new_bounds.y + new_bounds.height - keyboard_bounds.height; | |
196 keyboard_bounds.width = | |
197 keyboard_bounds.width + new_bounds.width - old_bounds.width; | |
198 view_->SetBounds(keyboard_bounds); | |
199 } | |
200 virtual void OnViewDestroyed(View* parent) override { | |
201 DCHECK_EQ(parent, view_->parent()); | |
202 parent->RemoveObserver(this); | |
203 view_ = NULL; | |
204 } | |
205 | |
206 KeyboardServicePtr keyboard_service_; | |
207 ViewManager* view_manager_; | |
208 | |
209 // View the keyboard is attached to. | |
210 View* view_; | |
211 | |
212 DISALLOW_COPY_AND_ASSIGN(KeyboardManager); | |
213 }; | |
214 | |
215 class RootLayoutManager : public ViewObserver { | |
216 public: | |
217 RootLayoutManager(ViewManager* view_manager, | |
218 View* root, | |
219 Id content_view_id, | |
220 Id launcher_ui_view_id, | |
221 Id control_panel_view_id) | |
222 : root_(root), | |
223 view_manager_(view_manager), | |
224 content_view_id_(content_view_id), | |
225 launcher_ui_view_id_(launcher_ui_view_id), | |
226 control_panel_view_id_(control_panel_view_id) {} | |
227 virtual ~RootLayoutManager() { | |
228 if (root_) | |
229 root_->RemoveObserver(this); | |
230 } | |
231 | |
232 private: | |
233 // Overridden from ViewObserver: | |
234 virtual void OnViewBoundsChanged(View* view, | |
235 const Rect& old_bounds, | |
236 const Rect& new_bounds) override { | |
237 DCHECK_EQ(view, root_); | |
238 | |
239 View* content_view = view_manager_->GetViewById(content_view_id_); | |
240 content_view->SetBounds(new_bounds); | |
241 | |
242 int delta_width = new_bounds.width - old_bounds.width; | |
243 int delta_height = new_bounds.height - old_bounds.height; | |
244 | |
245 View* launcher_ui_view = | |
246 view_manager_->GetViewById(launcher_ui_view_id_); | |
247 Rect launcher_ui_bounds(launcher_ui_view->bounds()); | |
248 launcher_ui_bounds.width += delta_width; | |
249 launcher_ui_view->SetBounds(launcher_ui_bounds); | |
250 | |
251 View* control_panel_view = | |
252 view_manager_->GetViewById(control_panel_view_id_); | |
253 Rect control_panel_bounds(control_panel_view->bounds()); | |
254 control_panel_bounds.x += delta_width; | |
255 control_panel_view->SetBounds(control_panel_bounds); | |
256 | |
257 const View::Children& content_views = content_view->children(); | |
258 View::Children::const_iterator iter = content_views.begin(); | |
259 for(; iter != content_views.end(); ++iter) { | |
260 View* view = *iter; | |
261 if (view->id() == control_panel_view->id() || | |
262 view->id() == launcher_ui_view->id()) | |
263 continue; | |
264 Rect view_bounds(view->bounds()); | |
265 view_bounds.width += delta_width; | |
266 view_bounds.height += delta_height; | |
267 view->SetBounds(view_bounds); | |
268 } | |
269 } | |
270 virtual void OnViewDestroyed(View* view) override { | |
271 DCHECK_EQ(view, root_); | |
272 root_->RemoveObserver(this); | |
273 root_ = NULL; | |
274 } | |
275 | |
276 View* root_; | |
277 ViewManager* view_manager_; | |
278 const Id content_view_id_; | |
279 const Id launcher_ui_view_id_; | |
280 const Id control_panel_view_id_; | |
281 | |
282 DISALLOW_COPY_AND_ASSIGN(RootLayoutManager); | |
283 }; | |
284 | |
285 class Window : public InterfaceFactory<NavigatorHost> { | |
286 public: | |
287 Window(WindowManager* window_manager, View* view) | |
288 : window_manager_(window_manager), view_(view) {} | |
289 | |
290 virtual ~Window() {} | |
291 | |
292 View* view() const { return view_; } | |
293 | |
294 void Embed(const std::string& url) { | |
295 scoped_ptr<ServiceProviderImpl> service_provider_impl( | |
296 new ServiceProviderImpl()); | |
297 service_provider_impl->AddService<NavigatorHost>(this); | |
298 view_->Embed(url, service_provider_impl.Pass()); | |
299 } | |
300 | |
301 private: | |
302 // InterfaceFactory<NavigatorHost> | |
303 virtual void Create(ApplicationConnection* connection, | |
304 InterfaceRequest<NavigatorHost> request) override { | |
305 BindToRequest(new NavigatorHostImpl(window_manager_, view_->id()), | |
306 &request); | |
307 } | |
308 | |
309 WindowManager* window_manager_; | |
310 View* view_; | |
311 }; | |
312 | |
313 class WindowManager | |
314 : public ApplicationDelegate, | |
315 public DebugPanel::Delegate, | |
316 public ViewManagerDelegate, | |
317 public WindowManagerDelegate, | |
318 public ui::EventHandler { | |
319 public: | |
320 WindowManager() | |
321 : shell_(nullptr), | |
322 window_manager_factory_(this), | |
323 launcher_ui_(NULL), | |
324 view_manager_(NULL), | |
325 window_manager_app_(new WindowManagerApp(this, this)), | |
326 app_(NULL) {} | |
327 | |
328 virtual ~WindowManager() { | |
329 // host() may be destroyed by the time we get here. | |
330 // TODO: figure out a way to always cleanly remove handler. | |
331 if (window_manager_app_->host()) | |
332 window_manager_app_->host()->window()->RemovePreTargetHandler(this); | |
333 } | |
334 | |
335 void CloseWindow(Id view_id) { | |
336 WindowVector::iterator iter = GetWindowByViewId(view_id); | |
337 DCHECK(iter != windows_.end()); | |
338 Window* window = *iter; | |
339 windows_.erase(iter); | |
340 window->view()->Destroy(); | |
341 } | |
342 | |
343 void ShowKeyboard(Id view_id, const Rect& bounds) { | |
344 // TODO: this needs to validate |view_id|. That is, it shouldn't assume | |
345 // |view_id| is valid and it also needs to make sure the client that sent | |
346 // this really owns |view_id|. | |
347 // TODO: honor |bounds|. | |
348 if (!keyboard_manager_) { | |
349 keyboard_manager_.reset(new KeyboardManager); | |
350 View* parent = view_manager_->GetRoots().back(); | |
351 int ideal_height = 200; | |
352 // TODO(sky): 10 is a bit of a hack here. There is a bug that causes | |
353 // white strips to appear when 0 is used. Figure this out! | |
354 Rect keyboard_bounds; | |
355 keyboard_bounds.x = 10; | |
356 keyboard_bounds.y = parent->bounds().height - ideal_height; | |
357 keyboard_bounds.width = parent->bounds().width - 20; | |
358 keyboard_bounds.height = ideal_height; | |
359 keyboard_manager_->Init(app_, view_manager_, parent, keyboard_bounds); | |
360 } | |
361 keyboard_manager_->Show(view_id, bounds); | |
362 } | |
363 | |
364 void HideKeyboard(Id view_id) { | |
365 // See comment in ShowKeyboard() about validating args. | |
366 if (keyboard_manager_) | |
367 keyboard_manager_->Hide(view_id); | |
368 } | |
369 | |
370 void DidNavigateLocally(uint32 source_view_id, const mojo::String& url) { | |
371 LOG(ERROR) << "DidNavigateLocally: source_view_id: " << source_view_id | |
372 << " url: " << url.To<std::string>(); | |
373 } | |
374 | |
375 // Overridden from DebugPanel::Delegate: | |
376 virtual void CloseTopWindow() override { | |
377 if (!windows_.empty()) | |
378 CloseWindow(windows_.back()->view()->id()); | |
379 } | |
380 | |
381 virtual void RequestNavigate(uint32 source_view_id, | |
382 Target target, | |
383 URLRequestPtr request) override { | |
384 OnLaunch(source_view_id, target, request->url); | |
385 } | |
386 | |
387 private: | |
388 typedef std::vector<Window*> WindowVector; | |
389 | |
390 // Overridden from ApplicationDelegate: | |
391 virtual void Initialize(ApplicationImpl* app) override { | |
392 shell_ = app->shell(); | |
393 app_ = app; | |
394 views_init_.reset(new ViewsInit); | |
395 window_manager_app_->Initialize(app); | |
396 } | |
397 | |
398 virtual bool ConfigureIncomingConnection( | |
399 ApplicationConnection* connection) override { | |
400 connection->AddService(&window_manager_factory_); | |
401 window_manager_app_->ConfigureIncomingConnection(connection); | |
402 return true; | |
403 } | |
404 | |
405 // Overridden from ViewManagerDelegate: | |
406 virtual void OnEmbed(ViewManager* view_manager, | |
407 View* root, | |
408 ServiceProviderImpl* exported_services, | |
409 scoped_ptr<ServiceProvider> imported_services) override { | |
410 DCHECK(!view_manager_); | |
411 view_manager_ = view_manager; | |
412 | |
413 View* view = View::Create(view_manager_); | |
414 root->AddChild(view); | |
415 Rect rect; | |
416 rect.width = root->bounds().width; | |
417 rect.height = root->bounds().height; | |
418 view->SetBounds(rect); | |
419 content_view_id_ = view->id(); | |
420 | |
421 Id launcher_ui_id = CreateLauncherUI(); | |
422 Id control_panel_id = CreateControlPanel(view); | |
423 | |
424 root_layout_manager_.reset( | |
425 new RootLayoutManager(view_manager, root, | |
426 content_view_id_, | |
427 launcher_ui_id, | |
428 control_panel_id)); | |
429 root->AddObserver(root_layout_manager_.get()); | |
430 | |
431 window_manager_app_->host()->window()->AddPreTargetHandler(this); | |
432 | |
433 window_manager_app_->InitFocus(new WMFocusRules(window_manager_app_.get(), | |
434 view)); | |
435 } | |
436 virtual void OnViewManagerDisconnected(ViewManager* view_manager) override { | |
437 DCHECK_EQ(view_manager_, view_manager); | |
438 view_manager_ = NULL; | |
439 base::MessageLoop::current()->Quit(); | |
440 } | |
441 | |
442 // Overridden from WindowManagerDelegate: | |
443 virtual void Embed( | |
444 const String& url, | |
445 InterfaceRequest<ServiceProvider> service_provider) override { | |
446 const Id kInvalidSourceViewId = 0; | |
447 OnLaunch(kInvalidSourceViewId, TARGET_DEFAULT, url); | |
448 } | |
449 | |
450 // Overridden from ui::EventHandler: | |
451 virtual void OnEvent(ui::Event* event) override { | |
452 View* view = WindowManagerApp::GetViewForWindow( | |
453 static_cast<aura::Window*>(event->target())); | |
454 if (event->type() == ui::ET_MOUSE_PRESSED && | |
455 !IsDescendantOfKeyboard(view)) { | |
456 view->SetFocus(); | |
457 } | |
458 } | |
459 | |
460 void OnLaunch(uint32 source_view_id, | |
461 Target requested_target, | |
462 const mojo::String& url) { | |
463 Target target = debug_panel_->navigation_target(); | |
464 if (target == TARGET_DEFAULT) { | |
465 if (requested_target != TARGET_DEFAULT) { | |
466 target = requested_target; | |
467 } else { | |
468 // TODO(aa): Should be TARGET_NEW_NODE if source origin and dest origin | |
469 // are different? | |
470 target = TARGET_SOURCE_NODE; | |
471 } | |
472 } | |
473 | |
474 Window* dest_view = NULL; | |
475 if (target == TARGET_SOURCE_NODE) { | |
476 WindowVector::iterator source_view = GetWindowByViewId(source_view_id); | |
477 bool app_initiated = source_view != windows_.end(); | |
478 if (app_initiated) | |
479 dest_view = *source_view; | |
480 else if (!windows_.empty()) | |
481 dest_view = windows_.back(); | |
482 } | |
483 | |
484 if (!dest_view) { | |
485 dest_view = CreateWindow(); | |
486 windows_.push_back(dest_view); | |
487 } | |
488 | |
489 dest_view->Embed(url); | |
490 } | |
491 | |
492 // TODO(beng): proper layout manager!! | |
493 Id CreateLauncherUI() { | |
494 View* view = view_manager_->GetViewById(content_view_id_); | |
495 Rect bounds = view->bounds(); | |
496 bounds.x += kBorderInset; | |
497 bounds.y += kBorderInset; | |
498 bounds.width -= 2 * kBorderInset; | |
499 bounds.height = kTextfieldHeight; | |
500 launcher_ui_ = CreateWindow(bounds); | |
501 launcher_ui_->Embed("mojo:browser"); | |
502 return launcher_ui_->view()->id(); | |
503 } | |
504 | |
505 Window* CreateWindow() { | |
506 View* view = view_manager_->GetViewById(content_view_id_); | |
507 Rect bounds; | |
508 bounds.x = kBorderInset; | |
509 bounds.y = 2 * kBorderInset + kTextfieldHeight; | |
510 bounds.width = view->bounds().width - 3 * kBorderInset - kControlPanelWidth; | |
511 bounds.height = | |
512 view->bounds().height - (3 * kBorderInset + kTextfieldHeight); | |
513 if (!windows_.empty()) { | |
514 bounds.x = windows_.back()->view()->bounds().x + 35; | |
515 bounds.y = windows_.back()->view()->bounds().y + 35; | |
516 } | |
517 return CreateWindow(bounds); | |
518 } | |
519 | |
520 Window* CreateWindow(const Rect& bounds) { | |
521 View* content = view_manager_->GetViewById(content_view_id_); | |
522 View* view = View::Create(view_manager_); | |
523 content->AddChild(view); | |
524 view->SetBounds(bounds); | |
525 view->SetFocus(); | |
526 return new Window(this, view); | |
527 } | |
528 | |
529 bool IsDescendantOfKeyboard(View* target) { | |
530 return keyboard_manager_.get() && | |
531 keyboard_manager_->view()->Contains(target); | |
532 } | |
533 | |
534 Id CreateControlPanel(View* root) { | |
535 View* view = View::Create(view_manager_); | |
536 root->AddChild(view); | |
537 | |
538 Rect bounds; | |
539 bounds.x = root->bounds().width - kControlPanelWidth - kBorderInset; | |
540 bounds.y = kBorderInset * 2 + kTextfieldHeight; | |
541 bounds.width = kControlPanelWidth; | |
542 bounds.height = | |
543 root->bounds().height - kBorderInset * 3 - kTextfieldHeight; | |
544 view->SetBounds(bounds); | |
545 | |
546 debug_panel_ = new DebugPanel(this, shell_, view); | |
547 return view->id(); | |
548 } | |
549 | |
550 WindowVector::iterator GetWindowByViewId(Id view_id) { | |
551 for (std::vector<Window*>::iterator iter = windows_.begin(); | |
552 iter != windows_.end(); | |
553 ++iter) { | |
554 if ((*iter)->view()->id() == view_id) { | |
555 return iter; | |
556 } | |
557 } | |
558 return windows_.end(); | |
559 } | |
560 | |
561 Shell* shell_; | |
562 | |
563 InterfaceFactoryImplWithContext<WindowManagerConnection, WindowManager> | |
564 window_manager_factory_; | |
565 | |
566 scoped_ptr<ViewsInit> views_init_; | |
567 DebugPanel* debug_panel_; | |
568 Window* launcher_ui_; | |
569 WindowVector windows_; | |
570 ViewManager* view_manager_; | |
571 scoped_ptr<RootLayoutManager> root_layout_manager_; | |
572 | |
573 scoped_ptr<WindowManagerApp> window_manager_app_; | |
574 | |
575 // Id of the view most content is added to. The keyboard is NOT added here. | |
576 Id content_view_id_; | |
577 | |
578 scoped_ptr<KeyboardManager> keyboard_manager_; | |
579 ApplicationImpl* app_; | |
580 | |
581 DISALLOW_COPY_AND_ASSIGN(WindowManager); | |
582 }; | |
583 | |
584 void WindowManagerConnection::CloseWindow(Id view_id) { | |
585 window_manager_->CloseWindow(view_id); | |
586 } | |
587 | |
588 void WindowManagerConnection::ShowKeyboard(Id view_id, RectPtr bounds) { | |
589 window_manager_->ShowKeyboard(view_id, *bounds); | |
590 } | |
591 | |
592 void WindowManagerConnection::HideKeyboard(Id view_id) { | |
593 window_manager_->HideKeyboard(view_id); | |
594 } | |
595 | |
596 void NavigatorHostImpl::DidNavigateLocally(const mojo::String& url) { | |
597 window_manager_->DidNavigateLocally(view_id_, url); | |
598 } | |
599 | |
600 void NavigatorHostImpl::RequestNavigate(Target target, URLRequestPtr request) { | |
601 window_manager_->RequestNavigate(view_id_, target, request.Pass()); | |
602 } | |
603 | |
604 } // namespace examples | |
605 } // namespace mojo | |
606 | |
607 MojoResult MojoMain(MojoHandle shell_handle) { | |
608 mojo::ApplicationRunnerChromium runner(new mojo::examples::WindowManager); | |
609 return runner.Run(shell_handle); | |
610 } | |
OLD | NEW |