Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: chrome/browser/ui/views/extensions/native_app_window_views.cc

Issue 21344002: Move native_app_window code to apps areas (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to after mac app shim fix Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/extensions/native_app_window_views.h"
6
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/path_service.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/extensions/extension_host.h"
13 #include "chrome/browser/favicon/favicon_tab_helper.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views .h"
16 #include "chrome/browser/ui/views/extensions/shell_window_frame_view.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/extensions/extension.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/browser/render_widget_host_view.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_view.h"
24 #include "extensions/common/draggable_region.h"
25 #include "ui/views/controls/webview/webview.h"
26 #include "ui/views/widget/widget.h"
27 #include "ui/views/window/non_client_view.h"
28
29 #if defined(OS_WIN)
30 #include "base/strings/utf_string_conversions.h"
31 #include "chrome/browser/ui/web_applications/web_app_ui.h"
32 #include "chrome/browser/web_applications/web_app.h"
33 #include "chrome/browser/web_applications/web_app_win.h"
34 #include "ui/base/win/shell.h"
35 #include "ui/views/win/hwnd_util.h"
36 #endif
37
38 #if defined(USE_ASH)
39 #include "ash/screen_ash.h"
40 #include "ash/shell.h"
41 #include "ash/wm/custom_frame_view_ash.h"
42 #include "ash/wm/panels/panel_frame_view.h"
43 #include "ash/wm/window_properties.h"
44 #include "chrome/browser/ui/ash/ash_util.h"
45 #include "ui/aura/client/aura_constants.h"
46 #include "ui/aura/root_window.h"
47 #include "ui/aura/window.h"
48 #endif
49
50 using apps::ShellWindow;
51
52 namespace {
53
54 const int kMinPanelWidth = 100;
55 const int kMinPanelHeight = 100;
56 const int kDefaultPanelWidth = 200;
57 const int kDefaultPanelHeight = 300;
58 const int kResizeInsideBoundsSize = 5;
59
60 struct AcceleratorMapping {
61 ui::KeyboardCode keycode;
62 int modifiers;
63 int command_id;
64 };
65 const AcceleratorMapping kAppWindowAcceleratorMap[] = {
66 { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
67 { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
68 { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW },
69 };
70
71 const std::map<ui::Accelerator, int>& GetAcceleratorTable() {
72 typedef std::map<ui::Accelerator, int> AcceleratorMap;
73 CR_DEFINE_STATIC_LOCAL(AcceleratorMap, accelerators, ());
74 if (accelerators.empty()) {
75 for (size_t i = 0; i < arraysize(kAppWindowAcceleratorMap); ++i) {
76 ui::Accelerator accelerator(kAppWindowAcceleratorMap[i].keycode,
77 kAppWindowAcceleratorMap[i].modifiers);
78 accelerators[accelerator] = kAppWindowAcceleratorMap[i].command_id;
79 }
80 }
81 return accelerators;
82 }
83
84 #if defined(OS_WIN)
85 void CreateIconAndSetRelaunchDetails(
86 const base::FilePath web_app_path,
87 const base::FilePath icon_file,
88 const ShellIntegration::ShortcutInfo& shortcut_info,
89 const HWND hwnd) {
90 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
91
92 // Set the relaunch data so "Pin this program to taskbar" has the app's
93 // information.
94 CommandLine command_line = ShellIntegration::CommandLineArgsForLauncher(
95 shortcut_info.url,
96 shortcut_info.extension_id,
97 shortcut_info.profile_path);
98
99 // TODO(benwells): Change this to use app_host.exe.
100 base::FilePath chrome_exe;
101 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
102 NOTREACHED();
103 return;
104 }
105 command_line.SetProgram(chrome_exe);
106 ui::win::SetRelaunchDetailsForWindow(command_line.GetCommandLineString(),
107 shortcut_info.title, hwnd);
108
109 if (!base::PathExists(web_app_path) &&
110 !file_util::CreateDirectory(web_app_path)) {
111 return;
112 }
113 ui::win::SetAppIconForWindow(icon_file.value(), hwnd);
114 web_app::internals::CheckAndSaveIcon(icon_file, shortcut_info.favicon);
115 }
116 #endif
117
118 } // namespace
119
120 NativeAppWindowViews::NativeAppWindowViews(
121 ShellWindow* shell_window,
122 const ShellWindow::CreateParams& create_params)
123 : shell_window_(shell_window),
124 web_view_(NULL),
125 window_(NULL),
126 is_fullscreen_(false),
127 frameless_(create_params.frame == ShellWindow::FRAME_NONE),
128 transparent_background_(create_params.transparent_background),
129 minimum_size_(create_params.minimum_size),
130 maximum_size_(create_params.maximum_size),
131 resizable_(create_params.resizable),
132 weak_ptr_factory_(this) {
133 Observe(web_contents());
134
135 window_ = new views::Widget;
136 if (create_params.window_type == ShellWindow::WINDOW_TYPE_PANEL ||
137 create_params.window_type == ShellWindow::WINDOW_TYPE_V1_PANEL) {
138 InitializePanelWindow(create_params);
139 } else {
140 InitializeDefaultWindow(create_params);
141 }
142 extension_keybinding_registry_.reset(
143 new ExtensionKeybindingRegistryViews(
144 profile(),
145 window_->GetFocusManager(),
146 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY,
147 shell_window_));
148
149 OnViewWasResized();
150 window_->AddObserver(this);
151 }
152
153 NativeAppWindowViews::~NativeAppWindowViews() {
154 web_view_->SetWebContents(NULL);
155 }
156
157 void NativeAppWindowViews::InitializeDefaultWindow(
158 const ShellWindow::CreateParams& create_params) {
159 views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW);
160 init_params.delegate = this;
161 init_params.remove_standard_frame = ShouldUseChromeStyleFrame();
162 init_params.use_system_default_icon = true;
163 // TODO(erg): Conceptually, these are toplevel windows, but we theoretically
164 // could plumb context through to here in some cases.
165 init_params.top_level = true;
166 gfx::Rect window_bounds = create_params.bounds;
167 bool position_specified =
168 window_bounds.x() != INT_MIN && window_bounds.y() != INT_MIN;
169 if (position_specified && !window_bounds.IsEmpty())
170 init_params.bounds = window_bounds;
171 window_->Init(init_params);
172
173 gfx::Rect adjusted_bounds = window_bounds;
174 adjusted_bounds.Inset(-GetFrameInsets());
175 // Center window if no position was specified.
176 if (!position_specified)
177 window_->CenterWindow(adjusted_bounds.size());
178 else if (!adjusted_bounds.IsEmpty() && adjusted_bounds != window_bounds)
179 window_->SetBounds(adjusted_bounds);
180
181 // Register accelarators supported by app windows.
182 // TODO(jeremya/stevenjb): should these be registered for panels too?
183 views::FocusManager* focus_manager = GetFocusManager();
184 const std::map<ui::Accelerator, int>& accelerator_table =
185 GetAcceleratorTable();
186 for (std::map<ui::Accelerator, int>::const_iterator iter =
187 accelerator_table.begin();
188 iter != accelerator_table.end(); ++iter) {
189 focus_manager->RegisterAccelerator(
190 iter->first, ui::AcceleratorManager::kNormalPriority, this);
191 }
192
193 #if defined(OS_WIN)
194 string16 app_name = UTF8ToWide(
195 web_app::GenerateApplicationNameFromExtensionId(extension()->id()));
196 HWND hwnd = GetNativeAppWindowHWND();
197 ui::win::SetAppIdForWindow(ShellIntegration::GetAppModelIdForProfile(
198 app_name, profile()->GetPath()), hwnd);
199
200 web_app::UpdateShortcutInfoAndIconForApp(
201 *extension(), profile(),
202 base::Bind(&NativeAppWindowViews::OnShortcutInfoLoaded,
203 weak_ptr_factory_.GetWeakPtr()));
204 #endif
205 }
206
207 #if defined(OS_WIN)
208 void NativeAppWindowViews::OnShortcutInfoLoaded(
209 const ShellIntegration::ShortcutInfo& shortcut_info) {
210 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
211
212 HWND hwnd = GetNativeAppWindowHWND();
213
214 // Set window's icon to the one we're about to create/update in the web app
215 // path. The icon cache will refresh on icon creation.
216 base::FilePath web_app_path = web_app::GetWebAppDataDirectory(
217 shortcut_info.profile_path, shortcut_info.extension_id,
218 shortcut_info.url);
219 base::FilePath icon_file = web_app_path
220 .Append(web_app::internals::GetSanitizedFileName(shortcut_info.title))
221 .ReplaceExtension(FILE_PATH_LITERAL(".ico"));
222
223 content::BrowserThread::PostBlockingPoolTask(
224 FROM_HERE,
225 base::Bind(&CreateIconAndSetRelaunchDetails,
226 web_app_path, icon_file, shortcut_info, hwnd));
227 }
228
229 HWND NativeAppWindowViews::GetNativeAppWindowHWND() const {
230 return views::HWNDForWidget(GetWidget()->GetTopLevelWidget());
231 }
232 #endif
233
234 void NativeAppWindowViews::InitializePanelWindow(
235 const ShellWindow::CreateParams& create_params) {
236 views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL);
237 params.delegate = this;
238
239 preferred_size_ = gfx::Size(create_params.bounds.width(),
240 create_params.bounds.height());
241 if (preferred_size_.width() == 0)
242 preferred_size_.set_width(kDefaultPanelWidth);
243 else if (preferred_size_.width() < kMinPanelWidth)
244 preferred_size_.set_width(kMinPanelWidth);
245
246 if (preferred_size_.height() == 0)
247 preferred_size_.set_height(kDefaultPanelHeight);
248 else if (preferred_size_.height() < kMinPanelHeight)
249 preferred_size_.set_height(kMinPanelHeight);
250 #if defined(USE_ASH)
251 if (ash::Shell::HasInstance()) {
252 // Open a new panel on the active root window where
253 // a current active/focused window is on.
254 aura::RootWindow* active = ash::Shell::GetActiveRootWindow();
255 params.bounds = ash::ScreenAsh::ConvertRectToScreen(
256 active, gfx::Rect(preferred_size_));
257 } else {
258 params.bounds = gfx::Rect(preferred_size_);
259 }
260 #else
261 params.bounds = gfx::Rect(preferred_size_);
262 #endif
263 // TODO(erg): Conceptually, these are toplevel windows, but we theoretically
264 // could plumb context through to here in some cases.
265 params.top_level = true;
266 window_->Init(params);
267 window_->set_focus_on_creation(create_params.focused);
268
269 #if defined(USE_ASH)
270 if (create_params.state == ui::SHOW_STATE_DETACHED) {
271 gfx::Rect window_bounds(create_params.bounds.x(),
272 create_params.bounds.y(),
273 preferred_size_.width(),
274 preferred_size_.height());
275 aura::Window* native_window = GetNativeWindow();
276 native_window->SetProperty(ash::internal::kPanelAttachedKey, false);
277 native_window->SetDefaultParentByRootWindow(
278 native_window->GetRootWindow(), native_window->GetBoundsInScreen());
279 window_->SetBounds(window_bounds);
280 }
281 #else
282 // TODO(stevenjb): NativeAppWindow panels need to be implemented for other
283 // platforms.
284 #endif
285 }
286
287 // ui::BaseWindow implementation.
288
289 bool NativeAppWindowViews::IsActive() const {
290 return window_->IsActive();
291 }
292
293 bool NativeAppWindowViews::IsMaximized() const {
294 return window_->IsMaximized();
295 }
296
297 bool NativeAppWindowViews::IsMinimized() const {
298 return window_->IsMinimized();
299 }
300
301 bool NativeAppWindowViews::IsFullscreen() const {
302 return window_->IsFullscreen();
303 }
304
305 gfx::NativeWindow NativeAppWindowViews::GetNativeWindow() {
306 return window_->GetNativeWindow();
307 }
308
309 gfx::Rect NativeAppWindowViews::GetRestoredBounds() const {
310 return window_->GetRestoredBounds();
311 }
312
313 ui::WindowShowState NativeAppWindowViews::GetRestoredState() const {
314 if (IsMaximized())
315 return ui::SHOW_STATE_MAXIMIZED;
316 #if defined(USE_ASH)
317 // On Ash, restore fullscreen.
318 if (IsFullscreen())
319 return ui::SHOW_STATE_FULLSCREEN;
320 // Use kRestoreShowStateKey in case a window is minimized/hidden.
321 ui::WindowShowState restore_state =
322 window_->GetNativeWindow()->GetProperty(
323 aura::client::kRestoreShowStateKey);
324 if (restore_state != ui::SHOW_STATE_MINIMIZED)
325 return restore_state;
326 #endif
327 return ui::SHOW_STATE_NORMAL;
328 }
329
330 gfx::Rect NativeAppWindowViews::GetBounds() const {
331 return window_->GetWindowBoundsInScreen();
332 }
333
334 void NativeAppWindowViews::Show() {
335 if (window_->IsVisible()) {
336 window_->Activate();
337 return;
338 }
339
340 window_->Show();
341 }
342
343 void NativeAppWindowViews::ShowInactive() {
344 if (window_->IsVisible())
345 return;
346 window_->ShowInactive();
347 }
348
349 void NativeAppWindowViews::Hide() {
350 window_->Hide();
351 }
352
353 void NativeAppWindowViews::Close() {
354 window_->Close();
355 }
356
357 void NativeAppWindowViews::Activate() {
358 window_->Activate();
359 }
360
361 void NativeAppWindowViews::Deactivate() {
362 window_->Deactivate();
363 }
364
365 void NativeAppWindowViews::Maximize() {
366 window_->Maximize();
367 }
368
369 void NativeAppWindowViews::Minimize() {
370 window_->Minimize();
371 }
372
373 void NativeAppWindowViews::Restore() {
374 window_->Restore();
375 }
376
377 void NativeAppWindowViews::SetBounds(const gfx::Rect& bounds) {
378 GetWidget()->SetBounds(bounds);
379 }
380
381 void NativeAppWindowViews::FlashFrame(bool flash) {
382 window_->FlashFrame(flash);
383 }
384
385 bool NativeAppWindowViews::IsAlwaysOnTop() const {
386 if (!shell_window_->window_type_is_panel())
387 return false;
388 #if defined(USE_ASH)
389 return window_->GetNativeWindow()->GetProperty(
390 ash::internal::kPanelAttachedKey);
391 #else
392 return true;
393 #endif
394 }
395
396 gfx::Insets NativeAppWindowViews::GetFrameInsets() const {
397 if (frameless())
398 return gfx::Insets();
399
400 // The pretend client_bounds passed in need to be large enough to ensure that
401 // GetWindowBoundsForClientBounds() doesn't decide that it needs more than
402 // the specified amount of space to fit the window controls in, and return a
403 // number larger than the real frame insets. Most window controls are smaller
404 // than 1000x1000px, so this should be big enough.
405 gfx::Rect client_bounds = gfx::Rect(1000, 1000);
406 gfx::Rect window_bounds =
407 window_->non_client_view()->GetWindowBoundsForClientBounds(
408 client_bounds);
409 return window_bounds.InsetsFrom(client_bounds);
410 }
411
412 gfx::NativeView NativeAppWindowViews::GetHostView() const {
413 return window_->GetNativeView();
414 }
415
416 gfx::Point NativeAppWindowViews::GetDialogPosition(const gfx::Size& size) {
417 gfx::Size shell_window_size = window_->GetWindowBoundsInScreen().size();
418 return gfx::Point(shell_window_size.width() / 2 - size.width() / 2,
419 shell_window_size.height() / 2 - size.height() / 2);
420 }
421
422 void NativeAppWindowViews::AddObserver(
423 web_modal::WebContentsModalDialogHostObserver* observer) {
424 observer_list_.AddObserver(observer);
425 }
426 void NativeAppWindowViews::RemoveObserver(
427 web_modal::WebContentsModalDialogHostObserver* observer) {
428 observer_list_.RemoveObserver(observer);
429 }
430
431 // Private method. TODO(stevenjb): Move this below InitializePanelWindow()
432 // to match declaration order.
433 void NativeAppWindowViews::OnViewWasResized() {
434 // TODO(jeremya): this doesn't seem like a terribly elegant way to keep the
435 // window shape in sync.
436 #if defined(OS_WIN) && !defined(USE_AURA)
437 DCHECK(window_);
438 DCHECK(web_view_);
439 gfx::Size sz = web_view_->size();
440 int height = sz.height(), width = sz.width();
441 if (ShouldUseChromeStyleFrame()) {
442 // Set the window shape of the RWHV.
443 const int kCornerRadius = 1;
444 gfx::Path path;
445 if (window_->IsMaximized() || window_->IsFullscreen()) {
446 // Don't round the corners when the window is maximized or fullscreen.
447 path.addRect(0, 0, width, height);
448 } else {
449 if (frameless_) {
450 path.moveTo(0, kCornerRadius);
451 path.lineTo(kCornerRadius, 0);
452 path.lineTo(width - kCornerRadius, 0);
453 path.lineTo(width, kCornerRadius);
454 } else {
455 // Don't round the top corners in chrome-style frame mode.
456 path.moveTo(0, 0);
457 path.lineTo(width, 0);
458 }
459 path.lineTo(width, height - kCornerRadius - 1);
460 path.lineTo(width - kCornerRadius - 1, height);
461 path.lineTo(kCornerRadius + 1, height);
462 path.lineTo(0, height - kCornerRadius - 1);
463 path.close();
464 }
465 SetWindowRgn(web_contents()->GetView()->GetNativeView(),
466 path.CreateNativeRegion(), 1);
467 }
468
469 SkRegion* rgn = new SkRegion;
470 if (!window_->IsFullscreen()) {
471 if (draggable_region())
472 rgn->op(*draggable_region(), SkRegion::kUnion_Op);
473 if (!window_->IsMaximized()) {
474 if (frameless_)
475 rgn->op(0, 0, width, kResizeInsideBoundsSize, SkRegion::kUnion_Op);
476 rgn->op(0, 0, kResizeInsideBoundsSize, height, SkRegion::kUnion_Op);
477 rgn->op(width - kResizeInsideBoundsSize, 0, width, height,
478 SkRegion::kUnion_Op);
479 rgn->op(0, height - kResizeInsideBoundsSize, width, height,
480 SkRegion::kUnion_Op);
481 }
482 }
483 if (web_contents()->GetRenderViewHost()->GetView())
484 web_contents()->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn);
485 #endif
486
487 FOR_EACH_OBSERVER(web_modal::WebContentsModalDialogHostObserver,
488 observer_list_,
489 OnPositionRequiresUpdate());
490 }
491
492 bool NativeAppWindowViews::ShouldUseChromeStyleFrame() const {
493 return !CommandLine::ForCurrentProcess()->HasSwitch(
494 switches::kAppsUseNativeFrame) || frameless_;
495 }
496
497 // WidgetDelegate implementation.
498
499 void NativeAppWindowViews::OnWidgetMove() {
500 shell_window_->OnNativeWindowChanged();
501 }
502
503 views::View* NativeAppWindowViews::GetInitiallyFocusedView() {
504 return web_view_;
505 }
506
507 bool NativeAppWindowViews::CanResize() const {
508 return resizable_ &&
509 (maximum_size_.IsEmpty() || minimum_size_ != maximum_size_);
510 }
511
512 bool NativeAppWindowViews::CanMaximize() const {
513 return resizable_ && maximum_size_.IsEmpty();
514 }
515
516 string16 NativeAppWindowViews::GetWindowTitle() const {
517 return shell_window_->GetTitle();
518 }
519
520 bool NativeAppWindowViews::ShouldShowWindowTitle() const {
521 return shell_window_->window_type() == ShellWindow::WINDOW_TYPE_V1_PANEL;
522 }
523
524 gfx::ImageSkia NativeAppWindowViews::GetWindowAppIcon() {
525 gfx::Image app_icon = shell_window_->app_icon();
526 if (app_icon.IsEmpty())
527 return GetWindowIcon();
528 else
529 return *app_icon.ToImageSkia();
530 }
531
532 gfx::ImageSkia NativeAppWindowViews::GetWindowIcon() {
533 content::WebContents* web_contents = shell_window_->web_contents();
534 if (web_contents) {
535 FaviconTabHelper* favicon_tab_helper =
536 FaviconTabHelper::FromWebContents(web_contents);
537 gfx::Image app_icon = favicon_tab_helper->GetFavicon();
538 if (!app_icon.IsEmpty())
539 return *app_icon.ToImageSkia();
540 }
541 return gfx::ImageSkia();
542 }
543
544 bool NativeAppWindowViews::ShouldShowWindowIcon() const {
545 return shell_window_->window_type() == ShellWindow::WINDOW_TYPE_V1_PANEL;
546 }
547
548 void NativeAppWindowViews::SaveWindowPlacement(const gfx::Rect& bounds,
549 ui::WindowShowState show_state) {
550 views::WidgetDelegate::SaveWindowPlacement(bounds, show_state);
551 shell_window_->OnNativeWindowChanged();
552 }
553
554 void NativeAppWindowViews::DeleteDelegate() {
555 window_->RemoveObserver(this);
556 shell_window_->OnNativeClose();
557 }
558
559 views::Widget* NativeAppWindowViews::GetWidget() {
560 return window_;
561 }
562
563 const views::Widget* NativeAppWindowViews::GetWidget() const {
564 return window_;
565 }
566
567 views::NonClientFrameView* NativeAppWindowViews::CreateNonClientFrameView(
568 views::Widget* widget) {
569 #if defined(USE_ASH)
570 if (chrome::IsNativeViewInAsh(widget->GetNativeView())) {
571 if (shell_window_->window_type_is_panel()) {
572 ash::PanelFrameView::FrameType frame_type = frameless_ ?
573 ash::PanelFrameView::FRAME_NONE : ash::PanelFrameView::FRAME_ASH;
574 return new ash::PanelFrameView(widget, frame_type);
575 }
576 if (!frameless_) {
577 ash::CustomFrameViewAsh* frame = new ash::CustomFrameViewAsh();
578 frame->Init(widget);
579 return frame;
580 }
581 }
582 #endif
583 if (ShouldUseChromeStyleFrame()) {
584 ShellWindowFrameView* frame_view = new ShellWindowFrameView(this);
585 frame_view->Init(window_);
586 return frame_view;
587 }
588 return views::WidgetDelegateView::CreateNonClientFrameView(widget);
589 }
590
591 bool NativeAppWindowViews::ShouldDescendIntoChildForEventHandling(
592 gfx::NativeView child,
593 const gfx::Point& location) {
594 #if defined(USE_AURA)
595 if (child == web_view_->web_contents()->GetView()->GetNativeView()) {
596 // Shell window should claim mouse events that fall within the draggable
597 // region.
598 return !draggable_region_.get() ||
599 !draggable_region_->contains(location.x(), location.y());
600 }
601 #endif
602
603 return true;
604 }
605
606 // WidgetObserver implementation.
607
608 void NativeAppWindowViews::OnWidgetVisibilityChanged(views::Widget* widget,
609 bool visible) {
610 shell_window_->OnNativeWindowChanged();
611 }
612
613 void NativeAppWindowViews::OnWidgetActivationChanged(views::Widget* widget,
614 bool active) {
615 shell_window_->OnNativeWindowChanged();
616 if (active)
617 shell_window_->OnNativeWindowActivated();
618 }
619
620 // WebContentsObserver implementation.
621
622 void NativeAppWindowViews::RenderViewCreated(
623 content::RenderViewHost* render_view_host) {
624 if (transparent_background_) {
625 // Use a background with transparency to trigger transparency in Webkit.
626 SkBitmap background;
627 background.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
628 background.allocPixels();
629 background.eraseARGB(0x00, 0x00, 0x00, 0x00);
630
631 content::RenderWidgetHostView* view = render_view_host->GetView();
632 DCHECK(view);
633 view->SetBackground(background);
634 }
635 }
636
637 // views::View implementation.
638
639 void NativeAppWindowViews::Layout() {
640 DCHECK(web_view_);
641 web_view_->SetBounds(0, 0, width(), height());
642 OnViewWasResized();
643 }
644
645 void NativeAppWindowViews::ViewHierarchyChanged(
646 const ViewHierarchyChangedDetails& details) {
647 if (details.is_add && details.child == this) {
648 web_view_ = new views::WebView(NULL);
649 AddChildView(web_view_);
650 web_view_->SetWebContents(web_contents());
651 }
652 }
653
654 gfx::Size NativeAppWindowViews::GetPreferredSize() {
655 if (!preferred_size_.IsEmpty())
656 return preferred_size_;
657 return views::View::GetPreferredSize();
658 }
659
660 gfx::Size NativeAppWindowViews::GetMinimumSize() {
661 return minimum_size_;
662 }
663
664 gfx::Size NativeAppWindowViews::GetMaximumSize() {
665 return maximum_size_;
666 }
667
668 void NativeAppWindowViews::OnFocus() {
669 web_view_->RequestFocus();
670 }
671
672 bool NativeAppWindowViews::AcceleratorPressed(
673 const ui::Accelerator& accelerator) {
674 const std::map<ui::Accelerator, int>& accelerator_table =
675 GetAcceleratorTable();
676 std::map<ui::Accelerator, int>::const_iterator iter =
677 accelerator_table.find(accelerator);
678 DCHECK(iter != accelerator_table.end());
679 int command_id = iter->second;
680 switch (command_id) {
681 case IDC_CLOSE_WINDOW:
682 Close();
683 return true;
684 default:
685 NOTREACHED() << "Unknown accelerator sent to app window.";
686 }
687 return false;
688 }
689
690 // NativeAppWindow implementation.
691
692 void NativeAppWindowViews::SetFullscreen(bool fullscreen) {
693 // Fullscreen not supported by panels.
694 if (shell_window_->window_type_is_panel())
695 return;
696 is_fullscreen_ = fullscreen;
697 window_->SetFullscreen(fullscreen);
698 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we
699 // ever drop the window out of fullscreen in response to something that
700 // wasn't the app calling webkitCancelFullScreen().
701 }
702
703 bool NativeAppWindowViews::IsFullscreenOrPending() const {
704 return is_fullscreen_;
705 }
706
707 bool NativeAppWindowViews::IsDetached() const {
708 if (!shell_window_->window_type_is_panel())
709 return false;
710 #if defined(USE_ASH)
711 return !window_->GetNativeWindow()->GetProperty(
712 ash::internal::kPanelAttachedKey);
713 #else
714 return false;
715 #endif
716 }
717
718 views::View* NativeAppWindowViews::GetContentsView() {
719 return this;
720 }
721
722 void NativeAppWindowViews::UpdateWindowIcon() {
723 window_->UpdateWindowIcon();
724 }
725
726 void NativeAppWindowViews::UpdateWindowTitle() {
727 window_->UpdateWindowTitle();
728 }
729
730 void NativeAppWindowViews::UpdateDraggableRegions(
731 const std::vector<extensions::DraggableRegion>& regions) {
732 // Draggable region is not supported for non-frameless window.
733 if (!frameless_)
734 return;
735
736 draggable_region_.reset(ShellWindow::RawDraggableRegionsToSkRegion(regions));
737 OnViewWasResized();
738 }
739
740 void NativeAppWindowViews::HandleKeyboardEvent(
741 const content::NativeWebKeyboardEvent& event) {
742 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event,
743 GetFocusManager());
744 }
745
746 void NativeAppWindowViews::RenderViewHostChanged() {
747 OnViewWasResized();
748 }
749
750 //------------------------------------------------------------------------------
751 // NativeAppWindow::Create
752
753 // static
754 NativeAppWindow* NativeAppWindow::Create(
755 ShellWindow* shell_window, const ShellWindow::CreateParams& params) {
756 return new NativeAppWindowViews(shell_window, params);
757 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698