OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/shell/browser/shell.h" | 5 #include "content/shell/browser/shell.h" |
6 | 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/strings/utf_string_conversions.h" |
7 #include "content/public/browser/web_contents.h" | 9 #include "content/public/browser/web_contents.h" |
8 #include "content/public/browser/web_contents_view.h" | 10 #include "content/public/browser/web_contents_view.h" |
9 #include "content/shell/browser/shell_aura.h" | |
10 #include "ui/aura/client/aura_constants.h" | |
11 #include "ui/aura/client/default_activation_client.h" | |
12 #include "ui/aura/client/default_capture_client.h" | |
13 #include "ui/aura/env.h" | 11 #include "ui/aura/env.h" |
14 #include "ui/aura/focus_manager.h" | |
15 #include "ui/aura/layout_manager.h" | |
16 #include "ui/aura/root_window.h" | 12 #include "ui/aura/root_window.h" |
| 13 #include "ui/aura/window.h" |
| 14 #include "ui/base/accessibility/accessibility_types.h" |
| 15 #include "ui/base/clipboard/clipboard.h" |
| 16 #include "ui/base/resource/resource_bundle.h" |
| 17 #include "ui/events/event.h" |
| 18 #include "ui/gfx/screen.h" |
| 19 #include "ui/views/controls/button/label_button.h" |
| 20 #include "ui/views/controls/textfield/textfield.h" |
| 21 #include "ui/views/controls/textfield/textfield_controller.h" |
| 22 #include "ui/views/controls/webview/webview.h" |
| 23 #include "ui/views/layout/fill_layout.h" |
| 24 #include "ui/views/layout/grid_layout.h" |
| 25 #include "ui/views/test/desktop_test_views_delegate.h" |
| 26 #include "ui/views/view.h" |
| 27 #include "ui/views/widget/desktop_aura/desktop_screen.h" |
| 28 #include "ui/views/widget/widget.h" |
| 29 #include "ui/views/widget/widget_delegate.h" |
| 30 |
| 31 #if defined(OS_CHROMEOS) |
| 32 #include "chromeos/dbus/dbus_thread_manager.h" |
17 #include "ui/aura/test/test_screen.h" | 33 #include "ui/aura/test/test_screen.h" |
18 #include "ui/aura/window.h" | 34 #include "ui/shell/minimal_shell.h" |
19 #include "ui/base/ime/input_method.h" | 35 #endif |
20 #include "ui/base/ime/input_method_delegate.h" | 36 |
21 #include "ui/base/ime/input_method_factory.h" | 37 #if defined(OS_WIN) |
22 #include "ui/gfx/screen.h" | 38 #include <fcntl.h> |
| 39 #include <io.h> |
| 40 #endif |
23 | 41 |
24 namespace content { | 42 namespace content { |
25 | 43 |
26 namespace { | 44 namespace { |
27 | 45 // ViewDelegate implementation for aura content shell |
28 class FillLayout : public aura::LayoutManager { | 46 class ShellViewsDelegateAura : public views::DesktopTestViewsDelegate { |
29 public: | 47 public: |
30 explicit FillLayout(aura::RootWindow* root) | 48 ShellViewsDelegateAura() : use_transparent_windows_(false) { |
31 : root_(root) { | 49 } |
32 } | 50 |
33 | 51 virtual ~ShellViewsDelegateAura() { |
34 virtual ~FillLayout() {} | 52 } |
| 53 |
| 54 void SetUseTransparentWindows(bool transparent) { |
| 55 use_transparent_windows_ = transparent; |
| 56 } |
| 57 |
| 58 // Overridden from views::TestViewsDelegate: |
| 59 virtual bool UseTransparentWindows() const OVERRIDE { |
| 60 return use_transparent_windows_; |
| 61 } |
35 | 62 |
36 private: | 63 private: |
37 // aura::LayoutManager: | 64 bool use_transparent_windows_; |
38 virtual void OnWindowResized() OVERRIDE { | 65 |
39 } | 66 DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegateAura); |
40 | |
41 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE { | |
42 child->SetBounds(gfx::Rect(root_->GetHostSize())); | |
43 } | |
44 | |
45 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE { | |
46 } | |
47 | |
48 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE { | |
49 } | |
50 | |
51 virtual void OnChildWindowVisibilityChanged(aura::Window* child, | |
52 bool visible) OVERRIDE { | |
53 } | |
54 | |
55 virtual void SetChildBounds(aura::Window* child, | |
56 const gfx::Rect& requested_bounds) OVERRIDE { | |
57 SetChildBoundsDirect(child, requested_bounds); | |
58 } | |
59 | |
60 aura::RootWindow* root_; | |
61 | |
62 DISALLOW_COPY_AND_ASSIGN(FillLayout); | |
63 }; | 67 }; |
64 | 68 |
65 class MinimalInputEventFilter : public ui::internal::InputMethodDelegate, | 69 // Maintain the UI controls and web view for content shell |
66 public ui::EventHandler { | 70 class ShellWindowDelegateView : public views::WidgetDelegateView, |
| 71 public views::TextfieldController, |
| 72 public views::ButtonListener { |
67 public: | 73 public: |
68 explicit MinimalInputEventFilter(aura::RootWindow* root) | 74 enum UIControl { |
69 : root_(root), | 75 BACK_BUTTON, |
70 input_method_(ui::CreateInputMethod(this, NULL)) { | 76 FORWARD_BUTTON, |
71 input_method_->Init(true); | 77 STOP_BUTTON |
72 root_->AddPreTargetHandler(this); | 78 }; |
73 root_->SetProperty(aura::client::kRootWindowInputMethodKey, | 79 |
74 input_method_.get()); | 80 ShellWindowDelegateView(Shell* shell) |
75 } | 81 : shell_(shell), |
76 | 82 toolbar_view_(new View), |
77 virtual ~MinimalInputEventFilter() { | 83 contents_view_(new View) { |
78 root_->RemovePreTargetHandler(this); | 84 } |
79 root_->SetProperty(aura::client::kRootWindowInputMethodKey, | 85 virtual ~ShellWindowDelegateView() {} |
80 static_cast<ui::InputMethod*>(NULL)); | 86 |
| 87 // Update the state of UI controls |
| 88 void SetAddressBarURL(const GURL& url) { |
| 89 url_entry_->SetText(ASCIIToUTF16(url.spec())); |
| 90 } |
| 91 void SetWebContents(WebContents* web_contents) { |
| 92 contents_view_->SetLayoutManager(new views::FillLayout()); |
| 93 web_view_ = new views::WebView(web_contents->GetBrowserContext()); |
| 94 web_view_->SetWebContents(web_contents); |
| 95 web_contents->GetView()->Focus(); |
| 96 contents_view_->AddChildView(web_view_); |
| 97 Layout(); |
| 98 } |
| 99 void SetWindowTitle(const string16& title) { title_ = title; } |
| 100 void EnableUIControl(UIControl control, bool is_enabled) { |
| 101 if (control == BACK_BUTTON) { |
| 102 back_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL |
| 103 : views::CustomButton::STATE_DISABLED); |
| 104 } else if (control == FORWARD_BUTTON) { |
| 105 forward_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL |
| 106 : views::CustomButton::STATE_DISABLED); |
| 107 } else if (control == STOP_BUTTON) { |
| 108 stop_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL |
| 109 : views::CustomButton::STATE_DISABLED); |
| 110 } |
81 } | 111 } |
82 | 112 |
83 private: | 113 private: |
84 // ui::EventHandler: | 114 // Initialize the UI control contained in shell window |
85 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE { | 115 void InitShellWindow() { |
86 const ui::EventType type = event->type(); | 116 set_background(views::Background::CreateStandardPanelBackground()); |
87 if (type == ui::ET_TRANSLATED_KEY_PRESS || | 117 |
88 type == ui::ET_TRANSLATED_KEY_RELEASE) { | 118 views::GridLayout* layout = new views::GridLayout(this); |
89 // The |event| is already handled by this object, change the type of the | 119 SetLayoutManager(layout); |
90 // event to ui::ET_KEY_* and pass it to the next filter. | 120 |
91 static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent(); | 121 views::ColumnSet* column_set = layout->AddColumnSet(0); |
92 } else { | 122 column_set->AddPaddingColumn(0, 2); |
93 bool handled = false; | 123 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, |
94 if (event->HasNativeEvent()) | 124 views::GridLayout::USE_PREF, 0, 0); |
95 handled = input_method_->DispatchKeyEvent(event->native_event()); | 125 column_set->AddPaddingColumn(0, 2); |
96 else | 126 |
97 handled = input_method_->DispatchFabricatedKeyEvent(*event); | 127 layout->AddPaddingRow(0, 2); |
98 if (handled) | 128 |
99 event->StopPropagation(); | 129 // Add toolbar buttons and URL text field |
100 } | 130 { |
101 } | 131 layout->StartRow(0, 0); |
102 | 132 views::GridLayout* toolbar_layout = new views::GridLayout(toolbar_view_); |
103 // ui::InputMethodDelegate: | 133 toolbar_view_->SetLayoutManager(toolbar_layout); |
104 virtual bool DispatchKeyEventPostIME( | 134 |
105 const base::NativeEvent& event) OVERRIDE { | 135 views::ColumnSet* toolbar_column_set = |
106 ui::TranslatedKeyEvent aura_event(event, false /* is_char */); | 136 toolbar_layout->AddColumnSet(0); |
107 return root_->AsRootWindowHostDelegate()->OnHostKeyEvent( | 137 // Back button |
108 &aura_event); | 138 back_button_ = new views::LabelButton(this, ASCIIToUTF16("Back")); |
109 } | 139 back_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
110 | 140 gfx::Size back_button_size = back_button_->GetPreferredSize(); |
111 virtual bool DispatchFabricatedKeyEventPostIME(ui::EventType type, | 141 toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
112 ui::KeyboardCode key_code, | 142 views::GridLayout::CENTER, 0, |
113 int flags) OVERRIDE { | 143 views::GridLayout::FIXED, |
114 ui::TranslatedKeyEvent aura_event(type == ui::ET_KEY_PRESSED, key_code, | 144 back_button_size.width(), |
115 flags); | 145 back_button_size.width() / 2); |
116 return root_->AsRootWindowHostDelegate()->OnHostKeyEvent( | 146 // Forward button |
117 &aura_event); | 147 forward_button_ = new views::LabelButton(this, ASCIIToUTF16("Forward")); |
118 } | 148 forward_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
119 | 149 gfx::Size forward_button_size = forward_button_->GetPreferredSize(); |
120 aura::RootWindow* root_; | 150 toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
121 scoped_ptr<ui::InputMethod> input_method_; | 151 views::GridLayout::CENTER, 0, |
122 | 152 views::GridLayout::FIXED, |
123 DISALLOW_COPY_AND_ASSIGN(MinimalInputEventFilter); | 153 forward_button_size.width(), |
| 154 forward_button_size.width() / 2); |
| 155 // Refresh button |
| 156 refresh_button_ = new views::LabelButton(this, ASCIIToUTF16("Refresh")); |
| 157 refresh_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| 158 gfx::Size refresh_button_size = refresh_button_->GetPreferredSize(); |
| 159 toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
| 160 views::GridLayout::CENTER, 0, |
| 161 views::GridLayout::FIXED, |
| 162 refresh_button_size.width(), |
| 163 refresh_button_size.width() / 2); |
| 164 // Stop button |
| 165 stop_button_ = new views::LabelButton(this, ASCIIToUTF16("Stop")); |
| 166 stop_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| 167 gfx::Size stop_button_size = stop_button_->GetPreferredSize(); |
| 168 toolbar_column_set->AddColumn(views::GridLayout::CENTER, |
| 169 views::GridLayout::CENTER, 0, |
| 170 views::GridLayout::FIXED, |
| 171 stop_button_size.width(), |
| 172 stop_button_size.width() / 2); |
| 173 toolbar_column_set->AddPaddingColumn(0, 2); |
| 174 // URL entry |
| 175 url_entry_ = new views::Textfield(); |
| 176 url_entry_->SetController(this); |
| 177 toolbar_column_set->AddColumn(views::GridLayout::FILL, |
| 178 views::GridLayout::FILL, 1, |
| 179 views::GridLayout::USE_PREF, 0, 0); |
| 180 |
| 181 // Fill up the first row |
| 182 toolbar_layout->StartRow(0, 0); |
| 183 toolbar_layout->AddView(back_button_); |
| 184 toolbar_layout->AddView(forward_button_); |
| 185 toolbar_layout->AddView(refresh_button_); |
| 186 toolbar_layout->AddView(stop_button_); |
| 187 toolbar_layout->AddView(url_entry_); |
| 188 |
| 189 layout->AddView(toolbar_view_); |
| 190 } |
| 191 |
| 192 layout->AddPaddingRow(0, 5); |
| 193 |
| 194 // Add web contents view as the second row |
| 195 { |
| 196 layout->StartRow(1, 0); |
| 197 layout->AddView(contents_view_); |
| 198 } |
| 199 |
| 200 layout->AddPaddingRow(0, 5); |
| 201 } |
| 202 // Overridden from TextfieldController |
| 203 virtual void ContentsChanged(views::Textfield* sender, |
| 204 const string16& new_contents) OVERRIDE { |
| 205 } |
| 206 virtual bool HandleKeyEvent(views::Textfield* sender, |
| 207 const ui::KeyEvent& key_event) OVERRIDE { |
| 208 if (sender == url_entry_ && key_event.key_code() == ui::VKEY_RETURN) { |
| 209 std::string text = UTF16ToUTF8(url_entry_->text()); |
| 210 GURL url(text); |
| 211 if (!url.has_scheme()) { |
| 212 url = GURL(std::string("http://") + std::string(text)); |
| 213 url_entry_->SetText(ASCIIToUTF16(url.spec())); |
| 214 } |
| 215 shell_->LoadURL(url); |
| 216 return true; |
| 217 } |
| 218 return false; |
| 219 } |
| 220 |
| 221 // Overridden from ButtonListener |
| 222 virtual void ButtonPressed(views::Button* sender, |
| 223 const ui::Event& event) OVERRIDE { |
| 224 if (sender == back_button_) |
| 225 shell_->GoBackOrForward(-1); |
| 226 else if (sender == forward_button_) |
| 227 shell_->GoBackOrForward(1); |
| 228 else if (sender == refresh_button_) |
| 229 shell_->Reload(); |
| 230 else if (sender == stop_button_) |
| 231 shell_->Stop(); |
| 232 } |
| 233 |
| 234 // Overridden from WidgetDelegateView |
| 235 virtual bool CanResize() const OVERRIDE { return true; } |
| 236 virtual bool CanMaximize() const OVERRIDE { return true; } |
| 237 virtual string16 GetWindowTitle() const OVERRIDE { |
| 238 return title_; |
| 239 } |
| 240 virtual void WindowClosing() OVERRIDE { |
| 241 if (shell_) { |
| 242 delete shell_; |
| 243 shell_ = NULL; |
| 244 } |
| 245 } |
| 246 virtual View* GetContentsView() OVERRIDE { return this; } |
| 247 |
| 248 // Overridden from View |
| 249 virtual void ViewHierarchyChanged( |
| 250 const ViewHierarchyChangedDetails& details) OVERRIDE { |
| 251 if (details.is_add && details.child == this) { |
| 252 InitShellWindow(); |
| 253 } |
| 254 } |
| 255 |
| 256 private: |
| 257 // Hold a reference of Shell for deleting it when the window is closing |
| 258 Shell* shell_; |
| 259 |
| 260 // Window title |
| 261 string16 title_; |
| 262 |
| 263 // Toolbar view contains forward/backward/reload button and URL entry |
| 264 View* toolbar_view_; |
| 265 views::LabelButton* back_button_; |
| 266 views::LabelButton* forward_button_; |
| 267 views::LabelButton* refresh_button_; |
| 268 views::LabelButton* stop_button_; |
| 269 views::Textfield* url_entry_; |
| 270 |
| 271 // Contents view contains the web contents view |
| 272 View* contents_view_; |
| 273 views::WebView* web_view_; |
| 274 |
| 275 DISALLOW_COPY_AND_ASSIGN(ShellWindowDelegateView); |
124 }; | 276 }; |
125 | 277 |
126 } | 278 } // namespace |
127 | 279 |
128 ShellAuraPlatformData::ShellAuraPlatformData() { | 280 #if defined(OS_CHROMEOS) |
129 } | 281 shell::MinimalShell* Shell::minimal_shell_ = NULL; |
130 | 282 #endif |
131 ShellAuraPlatformData::~ShellAuraPlatformData() { | 283 views::ViewsDelegate* Shell::views_delegate_ = NULL; |
132 } | |
133 | |
134 void ShellAuraPlatformData::CreateWindow(int width, int height) { | |
135 aura::TestScreen* screen = aura::TestScreen::Create(); | |
136 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen); | |
137 root_window_.reset(screen->CreateRootWindowForPrimaryDisplay()); | |
138 root_window_->SetHostSize(gfx::Size(width, height)); | |
139 root_window_->ShowRootWindow(); | |
140 root_window_->SetLayoutManager(new FillLayout(root_window_.get())); | |
141 | |
142 focus_client_.reset(new aura::FocusManager()); | |
143 aura::client::SetFocusClient(root_window_.get(), focus_client_.get()); | |
144 | |
145 activation_client_.reset( | |
146 new aura::client::DefaultActivationClient(root_window_.get())); | |
147 capture_client_.reset( | |
148 new aura::client::DefaultCaptureClient(root_window_.get())); | |
149 ime_filter_.reset(new MinimalInputEventFilter(root_window_.get())); | |
150 } | |
151 | 284 |
152 // static | 285 // static |
153 void Shell::PlatformInitialize(const gfx::Size& default_window_size) { | 286 void Shell::PlatformInitialize(const gfx::Size& default_window_size) { |
154 aura::Env::CreateInstance(); | 287 #if defined(OS_WIN) |
| 288 _setmode(_fileno(stdout), _O_BINARY); |
| 289 _setmode(_fileno(stderr), _O_BINARY); |
| 290 #endif |
| 291 #if defined(OS_CHROMEOS) |
| 292 chromeos::DBusThreadManager::Initialize(); |
| 293 gfx::Screen::SetScreenInstance( |
| 294 gfx::SCREEN_TYPE_NATIVE, aura::TestScreen::Create()); |
| 295 minimal_shell_ = new shell::MinimalShell(default_window_size); |
| 296 #else |
| 297 gfx::Screen::SetScreenInstance( |
| 298 gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen()); |
| 299 #endif |
| 300 views_delegate_ = new ShellViewsDelegateAura(); |
155 } | 301 } |
156 | 302 |
157 void Shell::PlatformExit() { | 303 void Shell::PlatformExit() { |
| 304 std::vector<Shell*> windows = windows_; |
| 305 for (std::vector<Shell*>::iterator it = windows.begin(); |
| 306 it != windows.end(); ++it) { |
| 307 (*it)->window_widget_->Close(); |
| 308 } |
| 309 #if defined(OS_CHROMEOS) |
| 310 if (minimal_shell_) |
| 311 delete minimal_shell_; |
| 312 #endif |
| 313 if (views_delegate_) |
| 314 delete views_delegate_; |
| 315 #if defined(OS_CHROMEOS) |
| 316 chromeos::DBusThreadManager::Shutdown(); |
| 317 #endif |
158 aura::Env::DeleteInstance(); | 318 aura::Env::DeleteInstance(); |
159 } | 319 } |
160 | 320 |
161 void Shell::PlatformCleanUp() { | 321 void Shell::PlatformCleanUp() { |
162 } | 322 } |
163 | 323 |
164 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { | 324 void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { |
| 325 ShellWindowDelegateView* delegate_view = |
| 326 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 327 if (control == BACK_BUTTON) { |
| 328 delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON, |
| 329 is_enabled); |
| 330 } else if (control == FORWARD_BUTTON) { |
| 331 delegate_view->EnableUIControl(ShellWindowDelegateView::FORWARD_BUTTON, |
| 332 is_enabled); |
| 333 } else if (control == STOP_BUTTON) { |
| 334 delegate_view->EnableUIControl(ShellWindowDelegateView::STOP_BUTTON, |
| 335 is_enabled); |
| 336 } |
165 } | 337 } |
166 | 338 |
167 void Shell::PlatformSetAddressBarURL(const GURL& url) { | 339 void Shell::PlatformSetAddressBarURL(const GURL& url) { |
| 340 ShellWindowDelegateView* delegate_view = |
| 341 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 342 delegate_view->SetAddressBarURL(url); |
168 } | 343 } |
169 | 344 |
170 void Shell::PlatformSetIsLoading(bool loading) { | 345 void Shell::PlatformSetIsLoading(bool loading) { |
171 } | 346 } |
172 | 347 |
173 void Shell::PlatformCreateWindow(int width, int height) { | 348 void Shell::PlatformCreateWindow(int width, int height) { |
174 platform_.reset(new ShellAuraPlatformData()); | 349 #if defined(OS_CHROMEOS) |
175 platform_->CreateWindow(width, height); | 350 window_widget_ = |
| 351 views::Widget::CreateWindowWithContextAndBounds( |
| 352 new ShellWindowDelegateView(this), |
| 353 minimal_shell_->GetDefaultParent(NULL, NULL, gfx::Rect()), |
| 354 gfx::Rect(0, 0, width, height)); |
| 355 #else |
| 356 window_widget_ = |
| 357 views::Widget::CreateWindowWithBounds(new ShellWindowDelegateView(this), |
| 358 gfx::Rect(0, 0, width, height)); |
| 359 #endif |
| 360 |
| 361 window_ = window_widget_->GetNativeWindow(); |
| 362 // Call ShowRootWindow on RootWindow created by MinimalShell without |
| 363 // which XWindow owned by RootWindow doesn't get mapped. |
| 364 window_->GetRootWindow()->ShowRootWindow(); |
| 365 window_widget_->Show(); |
176 } | 366 } |
177 | 367 |
178 void Shell::PlatformSetContents() { | 368 void Shell::PlatformSetContents() { |
179 platform_->window()->AddChild(web_contents_->GetView()->GetNativeView()); | 369 ShellWindowDelegateView* delegate_view = |
180 web_contents_->GetView()->GetNativeView()->Show(); | 370 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 371 delegate_view->SetWebContents(web_contents_.get()); |
181 } | 372 } |
182 | 373 |
183 void Shell::PlatformResizeSubViews() { | 374 void Shell::PlatformResizeSubViews() { |
184 } | 375 } |
185 | 376 |
186 void Shell::Close() { | 377 void Shell::Close() { |
| 378 window_widget_->CloseNow(); |
187 } | 379 } |
188 | 380 |
189 void Shell::PlatformSetTitle(const string16& title) { | 381 void Shell::PlatformSetTitle(const string16& title) { |
| 382 ShellWindowDelegateView* delegate_view = |
| 383 static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate()); |
| 384 delegate_view->SetWindowTitle(title); |
| 385 window_widget_->UpdateWindowTitle(); |
190 } | 386 } |
191 | 387 |
192 } // namespace content | 388 } // namespace content |
OLD | NEW |