panel_view.cc revision 116680a4aac90f2aa7413d9095a592090648e557
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/panels/panel_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_bounds_animation.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/panels/stacked_panel_collection.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/views/auto_keep_alive.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/panels/panel_frame_view.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/aura/window.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/aura/window_tree_host.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/path.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/webview/webview.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/shell_integration.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/win/shell.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/icon_util.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/win/hwnd_util.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(USE_X11) && !defined(OS_CHROMEOS)
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/browser/shell_integration_linux.h"
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/ui/views/panels/x11_panel_resizer.h"
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_WIN)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// If the height of a stacked panel shrinks below this threshold during the
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// user resizing, it will be treated as minimized.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kStackedPanelHeightShrinkThresholdToBecomeMinimized =
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    panel::kTitlebarHeight + 20;
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Supported accelerators.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: We can't use the acclerator table defined in chrome/browser/ui/views
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// due to checkdeps violation.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AcceleratorMapping {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::KeyboardCode keycode;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int modifiers;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int command_id;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const AcceleratorMapping kPanelAcceleratorMap[] = {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW },
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW },
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_R, ui::EF_CONTROL_DOWN, IDC_RELOAD },
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F5, ui::EF_NONE, IDC_RELOAD },
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_R, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDC_RELOAD_IGNORING_CACHE },
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F5, ui::EF_CONTROL_DOWN, IDC_RELOAD_IGNORING_CACHE },
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_F5, ui::EF_SHIFT_DOWN, IDC_RELOAD_IGNORING_CACHE },
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_ESCAPE, ui::EF_NONE, IDC_STOP },
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS },
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS },
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL },
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL },
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS },
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_DEV_TOOLS },
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { ui::VKEY_J, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IDC_DEV_TOOLS_CONSOLE },
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::map<ui::Accelerator, int>& GetAcceleratorTable() {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::map<ui::Accelerator, int>* accelerators = NULL;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!accelerators) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accelerators = new std::map<ui::Accelerator, int>();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kPanelAcceleratorMap); ++i) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::Accelerator accelerator(kPanelAcceleratorMap[i].keycode,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kPanelAcceleratorMap[i].modifiers);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*accelerators)[accelerator] = kPanelAcceleratorMap[i].command_id;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *accelerators;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativePanelTesting implementation.
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass NativePanelTestingViews : public NativePanelTesting {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  explicit NativePanelTestingViews(PanelView* panel_view);
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~NativePanelTestingViews();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PressLeftMouseButtonTitlebar(
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Point& mouse_location, panel::ClickModifier modifier) OVERRIDE;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseMouseButtonTitlebar(
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel::ClickModifier modifier) OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DragTitlebar(const gfx::Point& mouse_location) OVERRIDE;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelDragTitlebar() OVERRIDE;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FinishDragTitlebar() OVERRIDE;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool VerifyDrawingAttention() const OVERRIDE;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool VerifyActiveState(bool is_active) OVERRIDE;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool VerifyAppIcon() const OVERRIDE;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool VerifySystemMinimizeState() const OVERRIDE;
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual bool IsWindowVisible() const OVERRIDE;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsWindowSizeKnown() const OVERRIDE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsAnimatingBounds() const OVERRIDE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsButtonVisible(
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel::TitlebarButtonType button_type) const OVERRIDE;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual panel::CornerStyle GetWindowCornerStyle() const OVERRIDE;
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual bool EnsureApplicationRunOnForeground() OVERRIDE;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelView* panel_view_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
129116680a4aac90f2aa7413d9095a592090648e557Ben MurdochNativePanelTestingViews::NativePanelTestingViews(PanelView* panel_view)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : panel_view_(panel_view) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
133116680a4aac90f2aa7413d9095a592090648e557Ben MurdochNativePanelTestingViews::~NativePanelTestingViews() {
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NativePanelTestingViews::PressLeftMouseButtonTitlebar(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Point& mouse_location, panel::ClickModifier modifier) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMousePressed(mouse_location);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NativePanelTestingViews::ReleaseMouseButtonTitlebar(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel::ClickModifier modifier) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseReleased(modifier);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NativePanelTestingViews::DragTitlebar(const gfx::Point& mouse_location) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseDragged(mouse_location);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NativePanelTestingViews::CancelDragTitlebar() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseCaptureLost();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid NativePanelTestingViews::FinishDragTitlebar() {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_view_->OnTitlebarMouseReleased(panel::NO_MODIFIER);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::VerifyDrawingAttention() const {
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return panel_view_->GetFrameView()->GetPaintState() ==
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         PanelFrameView::PAINT_FOR_ATTENTION;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::VerifyActiveState(bool is_active) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return panel_view_->GetFrameView()->GetPaintState() ==
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (is_active ? PanelFrameView::PAINT_AS_ACTIVE
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    : PanelFrameView::PAINT_AS_INACTIVE);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::VerifyAppIcon() const {
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We only care about Windows 7 and later.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_WIN7)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND native_window = views::HWNDForWidget(panel_view_->window());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON app_icon = reinterpret_cast<HICON>(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::SendMessage(native_window, WM_GETICON, ICON_BIG, 0L));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!app_icon)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(app_icon));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bitmap.get() &&
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bitmap->width() == panel::kPanelAppIconSize &&
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         bitmap->height() == panel::kPanelAppIconSize;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::VerifySystemMinimizeState() const {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND native_window = views::HWNDForWidget(panel_view_->window());
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WINDOWPLACEMENT placement;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!::GetWindowPlacement(native_window, &placement))
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_SHOWMINIMIZED)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the panel window has owner window, as in stacked mode, check its owner
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // window. Note that owner window, instead of parent window, is returned
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // though GWL_HWNDPARENT contains 'parent'.
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND owner_window =
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      reinterpret_cast<HWND>(::GetWindowLongPtr(native_window,
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                GWLP_HWNDPARENT));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!owner_window || !::GetWindowPlacement(owner_window, &placement))
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return placement.showCmd == SW_MINIMIZE ||
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         placement.showCmd == SW_SHOWMINIMIZED;
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::IsWindowVisible() const {
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return panel_view_->window()->IsVisible();
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::IsWindowSizeKnown() const {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::IsAnimatingBounds() const {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_view_->IsAnimatingBounds();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::IsButtonVisible(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel::TitlebarButtonType button_type) const {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelFrameView* frame_view = panel_view_->GetFrameView();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (button_type) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::CLOSE_BUTTON:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return frame_view->close_button()->visible();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::MINIMIZE_BUTTON:
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return frame_view->minimize_button()->visible();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case panel::RESTORE_BUTTON:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return frame_view->restore_button()->visible();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdochpanel::CornerStyle NativePanelTestingViews::GetWindowCornerStyle() const {
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return panel_view_->GetFrameView()->corner_style();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool NativePanelTestingViews::EnsureApplicationRunOnForeground() {
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Not needed on views.
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return true;
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NativePanel* Panel::CreateNativePanel(Panel* panel,
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                      const gfx::Rect& bounds,
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                      bool always_on_top) {
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return new PanelView(panel, bounds, always_on_top);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The panel window has to be created as always-on-top. We cannot create it
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as non-always-on-top and then change it to always-on-top because Windows
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// system might deny making a window always-on-top if the application is not
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// a foreground application.
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PanelView::PanelView(Panel* panel, const gfx::Rect& bounds, bool always_on_top)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : panel_(panel),
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_(bounds),
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_(NULL),
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      window_closed_(false),
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_view_(NULL),
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      always_on_top_(always_on_top),
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      focused_(false),
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_resizing_(false),
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_resizing_interior_stacked_panel_edge_(false),
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_(false),
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_dragging_state_(NO_DRAGGING),
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_drawing_attention_(false),
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_to_paint_as_inactive_(false),
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_focused_view_(NULL) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = new views::Widget;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.delegate = this;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.remove_standard_frame = true;
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.keep_on_top = always_on_top;
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  params.visible_on_all_workspaces = always_on_top;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds = bounds;
2896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(USE_X11) && !defined(OS_CHROMEOS)
2916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  params.wm_class_name = web_app::GetWMClassFromAppName(panel->app_name());
2926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  params.wm_class_class = shell_integration_linux::GetProgramClassName();
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif
2946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Init(params);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->set_focus_on_creation(false);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->AddObserver(this);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Prevent the browser process from shutting down while this window is open.
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  keep_alive_.reset(new AutoKeepAlive(GetNativePanelWindow()));
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_ = new views::WebView(NULL);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(web_view_);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register accelarators supported by panels.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::FocusManager* focus_manager = GetFocusManager();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::map<ui::Accelerator, int>& accelerator_table =
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAcceleratorTable();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::map<ui::Accelerator, int>::const_iterator iter =
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           accelerator_table.begin();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != accelerator_table.end(); ++iter) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    focus_manager->RegisterAccelerator(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        iter->first, ui::AcceleratorManager::kNormalPriority, this);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::win::SetAppIdForWindow(
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShellIntegration::GetAppModelIdForProfile(
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::UTF8ToWide(panel->app_name()), panel->profile()->GetPath()),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      views::HWNDForWidget(window_));
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ui::win::PreventWindowFromPinning(views::HWNDForWidget(window_));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(USE_X11) && !defined(OS_CHROMEOS)
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Swap the default non client event handler with one which handles resizes
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // for panels entirely within Chrome. This is needed because it is not
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // possible to tell when a resize performed by the window manager ends.
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  views::DesktopWindowTreeHostX11* host =
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      views::DesktopWindowTreeHostX11::GetHostForXID(
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          window_->GetNativeView()->GetHost()->GetAcceleratedWidget());
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::EventHandler> resizer(
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new X11PanelResizer(panel_.get(), window_->GetNativeWindow()));
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  host->SwapNonClientEventHandler(resizer.Pass());
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelView::~PanelView() {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ShowPanel() {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShowPanelInactive();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ActivatePanel();
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ShowPanelInactive() {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_->IsVisible())
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->ShowInactive();
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No animation is used for initial creation of a panel on Win.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Signal immediately that pending actions can be performed.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->OnPanelAnimationEnded(panel_.get());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect PanelView::GetPanelBounds() const {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bounds_;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetPanelBounds(const gfx::Rect& bounds) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetBoundsInternal(bounds, true);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetPanelBoundsInstantly(const gfx::Rect& bounds) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetBoundsInternal(bounds, false);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetBoundsInternal(const gfx::Rect& new_bounds, bool animate) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_ == new_bounds)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_ = new_bounds;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!animate) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If no animation is in progress, apply bounds change instantly. Otherwise,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // continue the animation with new target bounds.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IsAnimatingBounds())
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetWidgetBounds(bounds_);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_start_bounds_ = window_->GetWindowBoundsInScreen();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_animator_.reset(new PanelBoundsAnimation(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this, panel_.get(), animation_start_bounds_, new_bounds));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_animator_->Start();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PanelView::FilterMessage(HWND hwnd,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              UINT message,
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              WPARAM w_param,
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              LPARAM l_param,
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              LRESULT* l_result) {
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (message) {
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case WM_SIZING:
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (w_param == WMSZ_BOTTOM)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        user_resizing_interior_stacked_panel_edge_ = true;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PanelView::AnimationEnded(const gfx::Animation* animation) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->OnPanelAnimationEnded(panel_.get());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
408d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void PanelView::AnimationProgressed(const gfx::Animation* animation) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect new_bounds = bounds_animator_->CurrentValueBetween(
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      animation_start_bounds_, bounds_);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetWidgetBounds(new_bounds);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetWidgetBounds(const gfx::Rect& new_bounds) {
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An overlapped window is a top-level window that has a titlebar, border,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and client area. The Windows system will automatically put the shadow
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // around the whole window. Also the system will enforce the minimum height
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (38 pixels based on observation) for the overlapped window such that it
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will always has the space for the titlebar.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On contrast, a popup window is a bare minimum window without border and
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // titlebar by default. It is often used for the popup menu and the window
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with short life. The Windows system does not add the shadow around the
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whole window though CS_DROPSHADOW class style could be passed to add the
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // drop shadow which is only around the right and bottom edges.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The height of the title-only or minimized panel is smaller than the minimum
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // overlapped window height. If the panel still uses the overlapped window
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // style, Windows system will automatically increase the window height. To
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // work around this limitation, we temporarily change the window style to
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // popup when the height to set is smaller than the minimum overlapped window
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // height and then restore the window style to overlapped when the height
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // grows.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMinimumOverlappedWindowHeight = 38;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect old_bounds = GetWidget()->GetRestoredBounds();
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (old_bounds.height() > kMinimumOverlappedWindowHeight &&
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_bounds.height() <= kMinimumOverlappedWindowHeight) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the panel height shrinks below the minimum overlapped window height,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // change the window style to popup such that we can show the title-only
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and minimized panel without additional height being added by the system.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_STYLE,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_POPUP,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          true);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (old_bounds.height() <= kMinimumOverlappedWindowHeight &&
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             new_bounds.height() > kMinimumOverlappedWindowHeight) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Change the window style back to overlappped when the panel height grow
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // taller than the minimum overlapped window height.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_STYLE,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          WS_POPUP,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          true);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->SetBounds(new_bounds);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ClosePanel() {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're already closing. Do nothing.
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (window_closed_)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!panel_->ShouldCloseWindow())
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel any currently running animation since we're closing down.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_animator_.get())
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds_animator_.reset();
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (panel_->GetWebContents()) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Still have web contents. Allow renderer to shut down.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When web contents are destroyed, we will be called back again.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->OnWindowClosing();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnNativePanelClosed();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (window_)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window_->Close();
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_closed_ = true;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::ActivatePanel() {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Activate();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DeactivatePanel() {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!focused_)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need custom behavior for always-on-top panels to avoid
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the OS activating a minimized panel when this one is
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deactivated.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (always_on_top_) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetForegroundWindow(::GetDesktopWindow());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->Deactivate();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsPanelActive() const {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return focused_;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PreventActivationByOS(bool prevent_activation) {
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the flags "NoActivate" to make sure the minimized panels do not get
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // activated by the OS. In addition, set "AppWindow" to make sure the
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // minimized panels do appear in the taskbar and Alt-Tab menu if it is not
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in a stack.
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int value_to_change = WS_EX_NOACTIVATE;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!panel_->stack())
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    value_to_change |= WS_EX_APPWINDOW;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (prevent_activation)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_EXSTYLE, value_to_change, 0, false);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateWindowAttribute(GWL_EXSTYLE, 0, value_to_change, false);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::NativeWindow PanelView::GetNativePanelWindow() {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_->GetNativeWindow();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdatePanelTitleBar() {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateWindowTitle();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateWindowIcon();
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdatePanelLoadingAnimations(bool should_animate) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateThrobber();
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelWebContentsFocused(content::WebContents* contents) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_->OnWebContentsFocused(contents);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelCut() {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we do not have panel-specific system menu.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelCopy() {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we do not have panel-specific system menu.
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelPaste() {
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing to do since we do not have panel-specific system menu.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DrawAttention(bool draw_attention) {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK((panel_->attention_mode() & Panel::USE_PANEL_ATTENTION) != 0);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_drawing_attention_ == draw_attention)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_drawing_attention_ = draw_attention;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->SchedulePaint();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if ((panel_->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) {
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The default implementation of Widget::FlashFrame only flashes 5 times.
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We need more than that.
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    FLASHWINFO fwi;
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fwi.cbSize = sizeof(fwi);
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fwi.hwnd = views::HWNDForWidget(window_);
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (draw_attention) {
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fwi.dwFlags = FLASHW_ALL;
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fwi.uCount = panel::kNumberOfTimesToFlashPanelForAttention;
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fwi.dwTimeout = 0;
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // TODO(jianli): calling FlashWindowEx with FLASHW_STOP flag for the
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // panel window has the same problem as the stack window. However,
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // we cannot take the similar fix since there is no background window
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // to replace for the regular panel window. More investigation is needed.
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fwi.dwFlags = FLASHW_STOP;
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ::FlashWindowEx(&fwi);
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->FlashFrame(draw_attention);
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsDrawingAttention() const {
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_drawing_attention_;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::HandlePanelKeyboardEvent(
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NativeWebKeyboardEvent& event) {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::FocusManager* focus_manager = GetFocusManager();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focus_manager->shortcut_handling_suspended())
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Accelerator accelerator(
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<ui::KeyboardCode>(event.windowsKeyCode),
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::GetModifiersFromNativeWebKeyboardEvent(event));
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (event.type == blink::WebInputEvent::KeyUp)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accelerator.set_type(ui::ET_KEY_RELEASED);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_manager->ProcessAccelerator(accelerator);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::FullScreenModeChanged(bool is_full_screen) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_full_screen) {
61168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (window_->IsVisible() && always_on_top_)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_->Hide();
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
61468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!window_->IsVisible()) {
61568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ShowPanelInactive();
616eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
617eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
61868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // When hiding and showing again a top-most window that belongs to a
61968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // background application (i.e. the application is not a foreground one),
62068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // the window may loose top-most placement even though its WS_EX_TOPMOST
62168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // bit is still set. Re-issuing SetWindowsPos() returns the window to its
62268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // top-most placement.
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (always_on_top_)
62468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        window_->SetAlwaysOnTop(true);
625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsPanelAlwaysOnTop() const {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return always_on_top_;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::SetPanelAlwaysOnTop(bool on_top) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (always_on_top_ == on_top)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  always_on_top_ = on_top;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetAlwaysOnTop(on_top);
640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window_->SetVisibleOnAllWorkspaces(on_top);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->non_client_view()->Layout();
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->client_view()->Layout();
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdatePanelMinimizeRestoreButtonVisibility() {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateTitlebarMinimizeRestoreButtonVisibility();
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelView::SetWindowCornerStyle(panel::CornerStyle corner_style) {
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetFrameView()->SetWindowCornerStyle(corner_style);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::PanelExpansionStateChanging(Panel::ExpansionState old_state,
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            Panel::ExpansionState new_state) {
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Live preview is only available since Windows 7.
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_WIN7)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (panel_->collection()->type() != PanelCollection::DOCKED)
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_minimized = old_state != Panel::EXPANDED;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool will_be_minimized = new_state != Panel::EXPANDED;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_minimized == will_be_minimized)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND native_window = views::HWNDForWidget(window_);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thumbnailer_.get()) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(native_window);
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    thumbnailer_.reset(new TaskbarWindowThumbnailerWin(native_window, NULL));
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache the image at this point.
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (will_be_minimized) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the panel is still active (we will deactivate the minimizd panel at
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // later time), we need to paint it immediately as inactive so that we can
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // take a snapshot of inactive panel.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (focused_) {
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      force_to_paint_as_inactive_ = true;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::RedrawWindow(native_window, NULL, NULL,
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Start the thumbnailer and capture the snapshot now.
687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    thumbnailer_->Start();
688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    thumbnailer_->CaptureSnapshot();
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    force_to_paint_as_inactive_ = false;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    thumbnailer_->Stop();
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PanelView::WindowSizeFromContentSize(
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& content_size) const {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size frame = GetFrameView()->NonClientAreaSize();
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(content_size.width() + frame.width(),
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   content_size.height() + frame.height());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size PanelView::ContentSizeFromWindowSize(
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& window_size) const {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size frame = GetFrameView()->NonClientAreaSize();
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(window_size.width() - frame.width(),
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   window_size.height() - frame.height());
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int PanelView::TitleOnlyHeight() const {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel::kTitlebarHeight;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelView::MinimizePanelBySystem() {
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->Minimize();
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PanelView::IsPanelMinimizedBySystem() const {
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return window_->IsMinimized();
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool PanelView::IsPanelShownOnActiveDesktop() const {
7242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if defined(OS_WIN)
7252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Virtual desktop is not supported by the native Windows system.
7262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return true;
7272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#else
7282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  NOTIMPLEMENTED();
7292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return true;
7302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif
7312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
7322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PanelView::ShowShadow(bool show) {
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The overlapped window has the shadow while the popup window does not have
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the shadow.
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int overlap_style = WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU;
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int popup_style = WS_POPUP;
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateWindowAttribute(GWL_STYLE,
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        show ? overlap_style : popup_style,
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        show ? popup_style : overlap_style,
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        true);
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::AttachWebContents(content::WebContents* contents) {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_->SetWebContents(contents);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DetachWebContents(content::WebContents* contents) {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_view_->SetWebContents(NULL);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativePanelTesting* PanelView::CreateNativePanelTesting() {
755116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return new NativePanelTestingViews(this);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnDisplayChanged() {
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged();
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWorkAreaChanged() {
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged();
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::WillProcessWorkAreaChange() const {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* PanelView::GetContentsView() {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::NonClientFrameView* PanelView::CreateNonClientFrameView(
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    views::Widget* widget) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PanelFrameView* frame_view = new PanelFrameView(this);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  frame_view->Init();
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frame_view;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::CanResize() const {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::CanMaximize() const {
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 PanelView::GetWindowTitle() const {
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_->GetWindowTitle();
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia PanelView::GetWindowAppIcon() {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image app_icon = panel_->app_icon();
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (app_icon.IsEmpty())
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetWindowIcon();
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *app_icon.ToImageSkia();
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia PanelView::GetWindowIcon() {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image icon = panel_->GetCurrentPageIcon();
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::WindowClosing() {
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When closing a panel via window.close, API or the close button,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClosePanel() is called first, destroying the native |window_|
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which results in this method being called. ClosePanel() sets
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |window_closed_| to NULL.
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we still have a |window_closed_| here, the close was triggered by the
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // OS, (e.g. clicking on taskbar menu), which destroys the native |window_|
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // without invoking ClosePanel() beforehand.
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!window_closed_) {
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->OnWindowClosing();
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClosePanel();
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(window_closed_);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::DeleteDelegate() {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWindowBeginUserBoundsChange() {
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_resizing_ = true;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnPanelStartUserResizing();
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StackedPanelCollection* stack = panel_->stack();
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stack) {
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Listen to WM_SIZING message in order to find out whether the interior
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // edge is being resized such that the specific maximum size could be
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // passed to the system.
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (panel_->stack()->GetPanelBelow(panel_.get())) {
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::HWNDSubclass::AddFilterToTarget(views::HWNDForWidget(window_), this);
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      user_resizing_interior_stacked_panel_edge_ = false;
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Keep track of the original full size of the resizing panel such that it
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // can be restored to this size once it is shrunk to minimized state.
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    original_full_size_of_resizing_panel_ = panel_->full_size();
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Keep track of the original full size of the panel below the resizing
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // panel such that it can be restored to this size once it is shrunk to
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // minimized state.
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Panel* below_panel = stack->GetPanelBelow(panel_.get());
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (below_panel && !below_panel->IsMinimized()) {
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      original_full_size_of_panel_below_resizing_panel_ =
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          below_panel->full_size();
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWindowEndUserBoundsChange() {
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  user_resizing_ = false;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnPanelEndUserResizing();
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No need to proceed with post-resizing update when there is no size change.
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect new_bounds = window_->GetWindowBoundsInScreen();
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_ == new_bounds)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds_ = new_bounds;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->IncreaseMaxSize(bounds_.size());
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->set_full_size(bounds_.size());
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StackedPanelCollection* stack = panel_->stack();
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (stack) {
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No need to listen to WM_SIZING message any more.
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::HWNDSubclass::RemoveFilterFromAllTargets(this);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the height of resizing panel shrinks close to the titlebar height,
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // treate it as minimized. This could occur when the user is dragging
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // 1) the top edge of the top panel downward to shrink it; or
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // 2) the bottom edge of any panel upward to shrink it.
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (panel_->GetBounds().height() <
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            kStackedPanelHeightShrinkThresholdToBecomeMinimized) {
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stack->MinimizePanel(panel_.get());
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_->set_full_size(original_full_size_of_resizing_panel_);
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If the height of panel below the resizing panel shrinks close to the
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // titlebar height, treat it as minimized. This could occur when the user
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // is dragging the bottom edge of non-bottom panel downward to expand it
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // and also shrink the panel below.
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Panel* below_panel = stack->GetPanelBelow(panel_.get());
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (below_panel && !below_panel->IsMinimized() &&
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        below_panel->GetBounds().height() <
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            kStackedPanelHeightShrinkThresholdToBecomeMinimized) {
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stack->MinimizePanel(below_panel);
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      below_panel->set_full_size(
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          original_full_size_of_panel_below_resizing_panel_);
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  panel_->collection()->RefreshLayout();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Widget* PanelView::GetWidget() {
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const views::Widget* PanelView::GetWidget() const {
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateLoadingAnimations(bool should_animate) {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateThrobber();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateWindowTitle() {
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->UpdateWindowTitle();
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateTitle();
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateWindowIcon() {
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->UpdateWindowIcon();
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetFrameView()->UpdateIcon();
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::Layout() {
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |web_view_| might not be created yet when the window is first created.
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_view_)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_view_->SetBounds(0, 0, width(), height());
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size PanelView::GetMinimumSize() const {
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the panel is minimized, it can be rendered to very small size, like
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // 4-pixel lines when it is docked. Otherwise, its size should not be less
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // than its minimum size.
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return panel_->IsMinimized() ? gfx::Size() :
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Size(panel::kPanelMinWidth, panel::kPanelMinHeight);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size PanelView::GetMaximumSize() const {
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the user is resizing a stacked panel by its bottom edge, make sure its
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // height cannot grow more than what the panel below it could offer. This is
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // because growing a stacked panel by y amount will shrink the panel below it
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by same amount and we do not want the panel below it being shrunk to be
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // smaller than the titlebar.
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (panel_->stack() && user_resizing_interior_stacked_panel_edge_) {
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Panel* below_panel = panel_->stack()->GetPanelBelow(panel_.get());
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (below_panel && !below_panel->IsMinimized()) {
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return gfx::Size(0, below_panel->GetBounds().bottom() -
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          panel_->GetBounds().y() - panel::kTitlebarHeight);
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size();
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::AcceleratorPressed(const ui::Accelerator& accelerator) {
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_ && accelerator.key_code() == ui::VKEY_ESCAPE) {
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnTitlebarMouseCaptureLost();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No other accelerator is allowed when the drag begins.
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == DRAGGING_STARTED)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::map<ui::Accelerator, int>& accelerator_table =
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetAcceleratorTable();
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<ui::Accelerator, int>::const_iterator iter =
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accelerator_table.find(accelerator);
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(iter != accelerator_table.end());
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return panel_->ExecuteCommandIfEnabled(iter->second);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelView::OnWidgetDestroying(views::Widget* widget) {
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_ = NULL;
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::OnWidgetActivationChanged(views::Widget* widget, bool active) {
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
981a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // WM_NCACTIVATED could be sent when an active window is being destroyed on
982a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Windows. We need to guard against this.
983a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (window_closed_)
984a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return;
985a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
9863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool focused = active;
9873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_NATIVE) {
9883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // The panel window is in focus (actually accepting keystrokes) if it is
9893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // active and belongs to a foreground application.
9903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    focused = active &&
9913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        views::HWNDForWidget(widget) == ::GetForegroundWindow();
9923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool focused = active;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focused_ == focused)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focused_ = focused;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expand the panel if the minimized panel is activated by means other than
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clicking on its titlebar. This is the workaround to support restoring the
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // minimized panel by other means, like alt-tabbing, win-tabbing, or clicking
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the taskbar icon. Note that this workaround does not work for one edge
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case: the mouse happens to be at the minimized panel when the user tries to
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bring up the panel with the above alternatives.
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the user clicks on the minimized panel, the panel expansion will be
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // done when we process the mouse button pressed message.
10097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (focused_ && panel_->IsMinimized() &&
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_->collection()->type() == PanelCollection::DOCKED &&
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Screen::GetScreenFor(widget->GetNativeWindow())->
1013424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          GetWindowUnderCursor() != widget->GetNativeWindow()) {
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->Restore();
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel()->OnActiveStateChanged(focused);
10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)   // Give web contents view a chance to set focus to the appropriate element.
10213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (focused_) {
10223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    content::WebContents* web_contents = panel_->GetWebContents();
10233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (web_contents)
1024010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      web_contents->RestoreFocus();
10253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelView::OnWidgetBoundsChanged(views::Widget* widget,
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const gfx::Rect& new_bounds) {
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (user_resizing_)
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    panel()->collection()->OnPanelResizedByMouse(panel(), new_bounds);
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMousePressed(const gfx::Point& mouse_location) {
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_ = true;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_dragging_state_ = NO_DRAGGING;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_location_ = mouse_location;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMouseDragged(const gfx::Point& mouse_location) {
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mouse_pressed_)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == NO_DRAGGING &&
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExceededDragThreshold(mouse_location - last_mouse_location_)) {
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When a drag begins, we do not want to the client area to still receive
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the focus. We do not need to do this for the unfocused minimized panel.
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!panel_->IsMinimized()) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      old_focused_view_ = GetFocusManager()->GetFocusedView();
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetFocusManager()->SetFocusedView(GetFrameView());
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->manager()->StartDragging(panel_.get(), last_mouse_location_);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_dragging_state_ = DRAGGING_STARTED;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == DRAGGING_STARTED) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    panel_->manager()->Drag(mouse_location);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once in drag, update |last_mouse_location_| on each drag fragment, since
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we already dragged the panel up to the current mouse location.
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_mouse_location_ = mouse_location;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMouseReleased(panel::ClickModifier modifier) {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ != NO_DRAGGING) {
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure dragging a minimized panel does not leave it activated.
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Windows activates a panel on mouse-down, regardless of our attempts
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to prevent activation of a minimized panel. Now that we know mouse-down
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // resulted in a mouse-drag, we need to ensure the minimized panel is
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // deactivated.
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (panel_->IsMinimized() && focused_)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      panel_->Deactivate();
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_dragging_state_ == DRAGGING_STARTED) {
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // When a drag ends, restore the focus.
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (old_focused_view_) {
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetFocusManager()->SetFocusedView(old_focused_view_);
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        old_focused_view_ = NULL;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return EndDragging(false);
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The panel drag was cancelled before the mouse is released. Do not
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // treat this as a click.
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->OnTitlebarClicked(modifier);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::OnTitlebarMouseCaptureLost() {
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_dragging_state_ == DRAGGING_STARTED)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return EndDragging(true);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::EndDragging(bool cancelled) {
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only handle clicks that started in our window.
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!mouse_pressed_)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_ = false;
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_dragging_state_ = DRAGGING_ENDED;
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  panel_->manager()->EndDragging(cancelled);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PanelFrameView* PanelView::GetFrameView() const {
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<PanelFrameView*>(window_->non_client_view()->frame_view());
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsAnimatingBounds() const {
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (bounds_animator_.get() && bounds_animator_->is_animating())
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StackedPanelCollection* stack = panel_->stack();
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!stack)
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return stack->IsAnimatingPanelBounds(panel_.get());
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PanelView::IsWithinResizingArea(const gfx::Point& mouse_location) const {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds = window_->GetWindowBoundsInScreen();
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bounds.Contains(mouse_location));
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return mouse_location.x() < bounds.x() + kResizeInsideBoundsSize ||
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_location.x() >= bounds.right() - kResizeInsideBoundsSize ||
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_location.y() < bounds.y() + kResizeInsideBoundsSize ||
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         mouse_location.y() >= bounds.bottom() - kResizeInsideBoundsSize;
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PanelView::UpdateWindowAttribute(int attribute_index,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int attribute_value_to_set,
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int attribute_value_to_reset,
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      bool update_frame) {
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND native_window = views::HWNDForWidget(window_);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int value = ::GetWindowLong(native_window, attribute_index);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_value = value;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (attribute_value_to_set)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_value |=  attribute_value_to_set;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (attribute_value_to_reset)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_value &=  ~attribute_value_to_reset;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value != expected_value)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetWindowLong(native_window, attribute_index, expected_value);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Per MSDN, if any of the frame styles is changed, SetWindowPos with the
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SWP_FRAMECHANGED flag must be called in order for the cached window data
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to be updated properly.
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_frame) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::SetWindowPos(native_window, NULL, 0, 0, 0, 0,
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SWP_NOZORDER | SWP_NOACTIVATE);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1160