panel_view.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
116c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek// Copyright (c) 2012 The Chromium Authors. All rights reserved. 216c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek// Use of this source code is governed by a BSD-style license that can be 316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek// found in the LICENSE file. 416c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek 516c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "chrome/browser/ui/views/panels/panel_view.h" 616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek 716c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include <map> 816c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "base/logging.h" 916c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "base/message_loop/message_loop.h" 102e331b938b38057e333fab0ba841130ea8467794Douglas Gregor#include "base/strings/utf_string_conversions.h" 112e331b938b38057e333fab0ba841130ea8467794Douglas Gregor#include "chrome/app/chrome_command_ids.h" 122e331b938b38057e333fab0ba841130ea8467794Douglas Gregor#include "chrome/browser/profiles/profile.h" 1316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "chrome/browser/ui/host_desktop.h" 1416c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "chrome/browser/ui/panels/panel.h" 1516c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "chrome/browser/ui/panels/panel_bounds_animation.h" 160a90d32523bfe5fa63e11b648686c9699f786d15Ted Kremenek#include "chrome/browser/ui/panels/panel_manager.h" 1716c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "chrome/browser/ui/panels/stacked_panel_collection.h" 18ed122735639d83c10f18c28c7fd117bfcd0f62cbTed Kremenek#include "chrome/browser/ui/views/auto_keep_alive.h" 19f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "chrome/browser/ui/views/panels/panel_frame_view.h" 20f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "content/public/browser/render_view_host.h" 2116c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "content/public/browser/render_widget_host_view.h" 226931900f43cea558c6974075256c07728dbfecc6Douglas Gregor#include "content/public/browser/web_contents.h" 23283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor#include "ui/aura/window.h" 24aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#include "ui/aura/window_tree_host.h" 25283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor#include "ui/gfx/image/image.h" 261f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor#include "ui/gfx/path.h" 27aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#include "ui/gfx/screen.h" 28f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "ui/views/controls/button/image_button.h" 29edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek#include "ui/views/controls/webview/webview.h" 3016c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "ui/views/widget/widget.h" 3116c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek 321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor#if defined(OS_WIN) 3316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "base/win/windows_version.h" 34bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek#include "chrome/browser/shell_integration.h" 355bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor#include "chrome/browser/ui/views/panels/taskbar_window_thumbnailer_win.h" 36bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek#include "ui/base/win/shell.h" 375bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor#include "ui/gfx/icon_util.h" 3816c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "ui/views/win/hwnd_util.h" 3916c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#endif 40e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek 41e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek#if defined(USE_X11) && !defined(OS_CHROMEOS) 42e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek#include "chrome/browser/ui/views/panels/x11_panel_resizer.h" 43e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" 44387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt#endif 45387475d0c18aaeb022108de9d33b6c9fb7998843Sean Hunt 46387475d0c18aaeb022108de9d33b6c9fb7998843Sean Huntnamespace { 476639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis 486639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis#if defined(OS_WIN) 495f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen// If the height of a stacked panel shrinks below this threshold during the 5084b796492de8a708150dd3f86ae191041d42eef9Argyrios Kyrtzidis// user resizing, it will be treated as minimized. 51e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenekconst int kStackedPanelHeightShrinkThresholdToBecomeMinimized = 52e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek panel::kTitlebarHeight + 20; 53e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek#endif 54e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek 55e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek// Supported accelerators. 5605756dc8d11cd2054e0cb94f0302e4eb39acc68eDmitri Gribenko// Note: We can't use the acclerator table defined in chrome/browser/ui/views 57a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek// due to checkdeps violation. 58e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenekstruct AcceleratorMapping { 593315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko ui::KeyboardCode keycode; 60e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek int modifiers; 61e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek int command_id; 62e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek}; 6367812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenkoconst AcceleratorMapping kPanelAcceleratorMap[] = { 64aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 65007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 6654d67caeee4fdce81f07163832f1163d5f2af5d2Daniel Dunbar { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW }, 67aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_R, ui::EF_CONTROL_DOWN, IDC_RELOAD }, 68aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_F5, ui::EF_NONE, IDC_RELOAD }, 69aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_R, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, 70aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis IDC_RELOAD_IGNORING_CACHE }, 71aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_F5, ui::EF_CONTROL_DOWN, IDC_RELOAD_IGNORING_CACHE }, 72aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_F5, ui::EF_SHIFT_DOWN, IDC_RELOAD_IGNORING_CACHE }, 73aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_ESCAPE, ui::EF_NONE, IDC_STOP }, 74aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 75aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 76aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 77aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 78aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 79aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 80aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_DEV_TOOLS }, 81aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis { ui::VKEY_J, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, 82aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis IDC_DEV_TOOLS_CONSOLE }, 83aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis}; 84aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 85aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisconst std::map<ui::Accelerator, int>& GetAcceleratorTable() { 86aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis static std::map<ui::Accelerator, int>* accelerators = NULL; 87aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!accelerators) { 88aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis accelerators = new std::map<ui::Accelerator, int>(); 895bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor for (size_t i = 0; i < arraysize(kPanelAcceleratorMap); ++i) { 90edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek ui::Accelerator accelerator(kPanelAcceleratorMap[i].keycode, 91edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek kPanelAcceleratorMap[i].modifiers); 9205756dc8d11cd2054e0cb94f0302e4eb39acc68eDmitri Gribenko (*accelerators)[accelerator] = kPanelAcceleratorMap[i].command_id; 9367812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko } 94aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 9554d67caeee4fdce81f07163832f1163d5f2af5d2Daniel Dunbar return *accelerators; 9697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 9797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 9897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor// NativePanelTesting implementation. 9997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorclass NativePanelTestingWin : public NativePanelTesting { 10097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor public: 10142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor explicit NativePanelTestingWin(PanelView* panel_view); 10297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 10342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor private: 10442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual void PressLeftMouseButtonTitlebar( 10542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor const gfx::Point& mouse_location, panel::ClickModifier modifier) OVERRIDE; 10697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor virtual void ReleaseMouseButtonTitlebar( 10742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel::ClickModifier modifier) OVERRIDE; 10842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual void DragTitlebar(const gfx::Point& mouse_location) OVERRIDE; 10942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual void CancelDragTitlebar() OVERRIDE; 11042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual void FinishDragTitlebar() OVERRIDE; 11142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool VerifyDrawingAttention() const OVERRIDE; 11242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool VerifyActiveState(bool is_active) OVERRIDE; 11342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool VerifyAppIcon() const OVERRIDE; 11442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool VerifySystemMinimizeState() const OVERRIDE; 11542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool IsWindowVisible() const OVERRIDE; 11642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool IsWindowSizeKnown() const OVERRIDE; 11742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool IsAnimatingBounds() const OVERRIDE; 11842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool IsButtonVisible( 11942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel::TitlebarButtonType button_type) const OVERRIDE; 12042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual panel::CornerStyle GetWindowCornerStyle() const OVERRIDE; 12142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor virtual bool EnsureApplicationRunOnForeground() OVERRIDE; 12242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 12342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor PanelView* panel_view_; 12442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor}; 12542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 12642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas GregorNativePanelTestingWin::NativePanelTestingWin(PanelView* panel_view) 12742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor : panel_view_(panel_view) { 12842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 12942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 13042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid NativePanelTestingWin::PressLeftMouseButtonTitlebar( 13142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor const gfx::Point& mouse_location, panel::ClickModifier modifier) { 13242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_view_->OnTitlebarMousePressed(mouse_location); 13342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 13497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 13542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid NativePanelTestingWin::ReleaseMouseButtonTitlebar( 13642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel::ClickModifier modifier) { 13742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_view_->OnTitlebarMouseReleased(modifier); 13842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 13942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 14042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid NativePanelTestingWin::DragTitlebar(const gfx::Point& mouse_location) { 14142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_view_->OnTitlebarMouseDragged(mouse_location); 14242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 14342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 14442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid NativePanelTestingWin::CancelDragTitlebar() { 14542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_view_->OnTitlebarMouseCaptureLost(); 14642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 14742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 14842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid NativePanelTestingWin::FinishDragTitlebar() { 14942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_view_->OnTitlebarMouseReleased(panel::NO_MODIFIER); 150df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier} 151df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier 15242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::VerifyDrawingAttention() const { 1538cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier base::MessageLoop::current()->RunUntilIdle(); 1548cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier return panel_view_->GetFrameView()->GetPaintState() == 1558cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier PanelFrameView::PAINT_FOR_ATTENTION; 1568cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier} 15742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 15842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::VerifyActiveState(bool is_active) { 15942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return panel_view_->GetFrameView()->GetPaintState() == 16042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor (is_active ? PanelFrameView::PAINT_AS_ACTIVE 16142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor : PanelFrameView::PAINT_AS_INACTIVE); 16242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 16342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 16442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::VerifyAppIcon() const { 16542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#if defined(OS_WIN) 16642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // We only care about Windows 7 and later. 16742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (base::win::GetVersion() < base::win::VERSION_WIN7) 16842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return true; 16942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 17042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor HWND native_window = views::HWNDForWidget(panel_view_->window()); 17142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor HICON app_icon = reinterpret_cast<HICON>( 17242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor ::SendMessage(native_window, WM_GETICON, ICON_BIG, 0L)); 17342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (!app_icon) 17442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return false; 17542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor scoped_ptr<SkBitmap> bitmap(IconUtil::CreateSkBitmapFromHICON(app_icon)); 17642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return bitmap.get() && 17742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor bitmap->width() == panel::kPanelAppIconSize && 17842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor bitmap->height() == panel::kPanelAppIconSize; 17942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#else 18042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return true; 18142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 18297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 18342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 18442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::VerifySystemMinimizeState() const { 18542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#if defined(OS_WIN) 18697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor HWND native_window = views::HWNDForWidget(panel_view_->window()); 18742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor WINDOWPLACEMENT placement; 18842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (!::GetWindowPlacement(native_window, &placement)) 18942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return false; 19042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (placement.showCmd == SW_MINIMIZE || placement.showCmd == SW_SHOWMINIMIZED) 19142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return true; 19242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 19342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // If the panel window has owner window, as in stacked mode, check its owner 19442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // window. Note that owner window, instead of parent window, is returned 19542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // though GWL_HWNDPARENT contains 'parent'. 19642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor HWND owner_window = 19742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor reinterpret_cast<HWND>(::GetWindowLongPtr(native_window, 19828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley GWLP_HWNDPARENT)); 19942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (!owner_window || !::GetWindowPlacement(owner_window, &placement)) 20042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return false; 20142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return placement.showCmd == SW_MINIMIZE || 20228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley placement.showCmd == SW_SHOWMINIMIZED; 20342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#else 20442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return true; 20542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 20628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley} 20742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 20842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::IsWindowVisible() const { 20942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#if defined(OS_WIN) 21042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor HWND native_window = views::HWNDForWidget(panel_view_->window()); 21142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return ::IsWindowVisible(native_window) == TRUE; 212276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman#else 21342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return panel_view_->visible(); 21442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 2154ca8ac2e61c37ddadf37024af86f3e1019af8532Douglas Gregor} 21642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 21742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::IsWindowSizeKnown() const { 218c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith return true; 21942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 22042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 22142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::IsAnimatingBounds() const { 22242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return panel_view_->IsAnimatingBounds(); 22342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 22442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 22542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool NativePanelTestingWin::IsButtonVisible( 22642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel::TitlebarButtonType button_type) const { 22742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor PanelFrameView* frame_view = panel_view_->GetFrameView(); 22803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor 22942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor switch (button_type) { 23042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor case panel::CLOSE_BUTTON: 23142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return frame_view->close_button()->visible(); 23242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor case panel::MINIMIZE_BUTTON: 23342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return frame_view->minimize_button()->visible(); 23442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor case panel::RESTORE_BUTTON: 23542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return frame_view->restore_button()->visible(); 23642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor default: 237b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek NOTREACHED(); 238b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek } 239eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard return false; 240b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek} 24142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 24242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorpanel::CornerStyle NativePanelTestingWin::GetWindowCornerStyle() const { 24342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return panel_view_->GetFrameView()->corner_style(); 2444b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 2454b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2464b9c2d235fb9449e249d74f48ecfec601650de93John McCallbool NativePanelTestingWin::EnsureApplicationRunOnForeground() { 2474b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Not needed on views. 2484b9c2d235fb9449e249d74f48ecfec601650de93John McCall return true; 2494b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 2504b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2514b9c2d235fb9449e249d74f48ecfec601650de93John McCall} // namespace 2524b9c2d235fb9449e249d74f48ecfec601650de93John McCall 2534b9c2d235fb9449e249d74f48ecfec601650de93John McCall// static 25442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas GregorNativePanel* Panel::CreateNativePanel(Panel* panel, 25542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor const gfx::Rect& bounds, 25697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor bool always_on_top) { 257534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith return new PanelView(panel, bounds, always_on_top); 25842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 25942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 26036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor// The panel window has to be created as always-on-top. We cannot create it 261534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith// as non-always-on-top and then change it to always-on-top because Windows 26242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor// system might deny making a window always-on-top if the application is not 26342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor// a foreground application. 26442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas GregorPanelView::PanelView(Panel* panel, const gfx::Rect& bounds, bool always_on_top) 265534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith : panel_(panel), 266534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith bounds_(bounds), 267534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith window_(NULL), 268534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith window_closed_(false), 269534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith web_view_(NULL), 27042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor always_on_top_(always_on_top), 27142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor focused_(false), 27242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor user_resizing_(false), 273534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith#if defined(OS_WIN) 274051303ce09291dfbed537fa33b0d8a4d92c82b75Tareq A. Siraj user_resizing_interior_stacked_panel_edge_(false), 275051303ce09291dfbed537fa33b0d8a4d92c82b75Tareq A. Siraj#endif 276051303ce09291dfbed537fa33b0d8a4d92c82b75Tareq A. Siraj mouse_pressed_(false), 277051303ce09291dfbed537fa33b0d8a4d92c82b75Tareq A. Siraj mouse_dragging_state_(NO_DRAGGING), 27842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor is_drawing_attention_(false), 27942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor force_to_paint_as_inactive_(false), 28042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor old_focused_view_(NULL) { 28142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_ = new views::Widget; 28242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); 28342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor params.delegate = this; 28442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor params.remove_standard_frame = true; 28542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor params.keep_on_top = always_on_top; 28642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor params.visible_on_all_workspaces = always_on_top; 28742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor params.bounds = bounds; 28842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_->Init(params); 28942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM); 29042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_->set_focus_on_creation(false); 29142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_->AddObserver(this); 29242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 29342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // Prevent the browser process from shutting down while this window is open. 29442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor keep_alive_.reset(new AutoKeepAlive(GetNativePanelWindow())); 29542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 29642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor web_view_ = new views::WebView(NULL); 29742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor AddChildView(web_view_); 29842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 29942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // Register accelarators supported by panels. 30042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor views::FocusManager* focus_manager = GetFocusManager(); 30142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor const std::map<ui::Accelerator, int>& accelerator_table = 3028ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor GetAcceleratorTable(); 30342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor for (std::map<ui::Accelerator, int>::const_iterator iter = 30442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor accelerator_table.begin(); 305534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith iter != accelerator_table.end(); ++iter) { 30642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor focus_manager->RegisterAccelerator( 30742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor iter->first, ui::AcceleratorManager::kNormalPriority, this); 30842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor } 30942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 31042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#if defined(OS_WIN) 31142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor ui::win::SetAppIdForWindow( 31242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor ShellIntegration::GetAppModelIdForProfile( 31342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor base::UTF8ToWide(panel->app_name()), panel->profile()->GetPath()), 31442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor views::HWNDForWidget(window_)); 31542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor ui::win::PreventWindowFromPinning(views::HWNDForWidget(window_)); 31642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 31742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 31897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor#if defined(USE_X11) && !defined(OS_CHROMEOS) 31942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // Swap the default non client event handler with one which handles resizes 32042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // for panels entirely within Chrome. This is needed because it is not 32142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // possible to tell when a resize performed by the window manager ends. 32242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor views::DesktopWindowTreeHostX11* host = 32342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor views::DesktopWindowTreeHostX11::GetHostForXID( 32442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_->GetNativeView()->GetHost()->GetAcceleratedWidget()); 32542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor scoped_ptr<ui::EventHandler> resizer( 32697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor new X11PanelResizer(panel_.get(), window_->GetNativeWindow())); 32742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor host->SwapNonClientEventHandler(resizer.Pass()); 32842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 32942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 33042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 33142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas GregorPanelView::~PanelView() { 33242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 33342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 33442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::ShowPanel() { 33542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor ShowPanelInactive(); 33642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor ActivatePanel(); 33742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 33842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 33942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::ShowPanelInactive() { 34042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (window_->IsVisible()) 34142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return; 34242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor window_->ShowInactive(); 34342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // No animation is used for initial creation of a panel on Win. 34442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // Signal immediately that pending actions can be performed. 34542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_->manager()->OnPanelAnimationEnded(panel_.get()); 346f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne} 34742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 34842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorgfx::Rect PanelView::GetPanelBounds() const { 34942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return bounds_; 35042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 35142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 35242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::SetPanelBounds(const gfx::Rect& bounds) { 35342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor SetBoundsInternal(bounds, true); 35442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 35542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 35642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::SetPanelBoundsInstantly(const gfx::Rect& bounds) { 35742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor SetBoundsInternal(bounds, false); 35842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 35942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 36042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::SetBoundsInternal(const gfx::Rect& new_bounds, bool animate) { 36142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (bounds_ == new_bounds) 36242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return; 36342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 36442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor bounds_ = new_bounds; 36542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 36642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (!animate) { 36742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // If no animation is in progress, apply bounds change instantly. Otherwise, 36842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // continue the animation with new target bounds. 36942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (!IsAnimatingBounds()) 37097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor SetWidgetBounds(bounds_); 37142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return; 37242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor } 37342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 37442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor animation_start_bounds_ = window_->GetWindowBoundsInScreen(); 37542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 37642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor bounds_animator_.reset(new PanelBoundsAnimation( 37742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor this, panel_.get(), animation_start_bounds_, new_bounds)); 37842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor bounds_animator_->Start(); 37942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 38042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 38142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#if defined(OS_WIN) 38242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorbool PanelView::FilterMessage(HWND hwnd, 38342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor UINT message, 38442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor WPARAM w_param, 38542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor LPARAM l_param, 38642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor LRESULT* l_result) { 38742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor switch (message) { 38842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor case WM_SIZING: 38942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor if (w_param == WMSZ_BOTTOM) 39042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor user_resizing_interior_stacked_panel_edge_ = true; 39142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor break; 39242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor } 39342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor return false; 39442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 39542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 39642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 39742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::AnimationEnded(const gfx::Animation* animation) { 39842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor panel_->manager()->OnPanelAnimationEnded(panel_.get()); 39942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 40042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 40142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::AnimationProgressed(const gfx::Animation* animation) { 40242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor gfx::Rect new_bounds = bounds_animator_->CurrentValueBetween( 40342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor animation_start_bounds_, bounds_); 40442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor SetWidgetBounds(new_bounds); 40542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 40642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 40742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregorvoid PanelView::SetWidgetBounds(const gfx::Rect& new_bounds) { 40842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#if defined(OS_WIN) 40942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // An overlapped window is a top-level window that has a titlebar, border, 41042b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // and client area. The Windows system will automatically put the shadow 41142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // around the whole window. Also the system will enforce the minimum height 41242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // (38 pixels based on observation) for the overlapped window such that it 41342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // will always has the space for the titlebar. 41442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // 41542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // On contrast, a popup window is a bare minimum window without border and 41642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // titlebar by default. It is often used for the popup menu and the window 417b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek // with short life. The Windows system does not add the shadow around the 418b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek // whole window though CS_DROPSHADOW class style could be passed to add the 419b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek // drop shadow which is only around the right and bottom edges. 420b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek // 421b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek // The height of the title-only or minimized panel is smaller than the minimum 422f85e193739c953358c865005855253af4f68a497John McCall // overlapped window height. If the panel still uses the overlapped window 42342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // style, Windows system will automatically increase the window height. To 42442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // work around this limitation, we temporarily change the window style to 42542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // popup when the height to set is smaller than the minimum overlapped window 42642b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // height and then restore the window style to overlapped when the height 42742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // grows. 42842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor static const int kMinimumOverlappedWindowHeight = 38; 42942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor gfx::Rect old_bounds = GetWidget()->GetRestoredBounds(); 430be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor if (old_bounds.height() > kMinimumOverlappedWindowHeight && 43142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor new_bounds.height() <= kMinimumOverlappedWindowHeight) { 43242b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // When the panel height shrinks below the minimum overlapped window height, 43342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // change the window style to popup such that we can show the title-only 434ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor // and minimized panel without additional height being added by the system. 43542b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor UpdateWindowAttribute(GWL_STYLE, 43697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor WS_POPUP, 43742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU, 43842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor true); 43942b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor } else if (old_bounds.height() <= kMinimumOverlappedWindowHeight && 44091a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall new_bounds.height() > kMinimumOverlappedWindowHeight) { 441c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor // Change the window style back to overlappped when the panel height grow 4429a4db032ecd991626d236a502e770126db32bd31Richard Smith // taller than the minimum overlapped window height. 44342b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor UpdateWindowAttribute(GWL_STYLE, 44497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU, 44597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor WS_POPUP, 44697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor true); 44742b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor } 44842b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor#endif 44997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 45076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall GetWidget()->SetBounds(new_bounds); 45142b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor} 45297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 45397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorvoid PanelView::ClosePanel() { 45442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor // We're already closing. Do nothing. 45597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (window_closed_) 45697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return; 45797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 45897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (!panel_->ShouldCloseWindow()) 45997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return; 46097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 461e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne // Cancel any currently running animation since we're closing down. 46297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (bounds_animator_.get()) 46397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor bounds_animator_.reset(); 46442b2984771a7fd1b17c78bbb2c59fed3db2f1960Douglas Gregor 4659fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith if (panel_->GetWebContents()) { 46697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor // Still have web contents. Allow renderer to shut down. 46797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor // When web contents are destroyed, we will be called back again. 46897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor panel_->OnWindowClosing(); 469011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor return; 470011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor } 471011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor 472011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor panel_->OnNativePanelClosed(); 473ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor if (window_) 47497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor window_->Close(); 475aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis window_closed_ = true; 476aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 477aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 478aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid PanelView::ActivatePanel() { 479aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis window_->Activate(); 480aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 481aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 482aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid PanelView::DeactivatePanel() { 483aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!focused_) 484aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 485aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 486aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#if defined(OS_WIN) 487aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // Need custom behavior for always-on-top panels to avoid 48897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor // the OS activating a minimized panel when this one is 489ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor // deactivated. 490ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor if (always_on_top_) { 491ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor ::SetForegroundWindow(::GetDesktopWindow()); 492ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor return; 493ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor } 49497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor#endif 495aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 49697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor window_->Deactivate(); 49797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 49897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 4992e331b938b38057e333fab0ba841130ea8467794Douglas Gregorbool PanelView::IsPanelActive() const { 500b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return focused_; 501a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 50254d67caeee4fdce81f07163832f1163d5f2af5d2Daniel Dunbar 503cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenkovoid PanelView::PreventActivationByOS(bool prevent_activation) { 504aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#if defined(OS_WIN) 5052e331b938b38057e333fab0ba841130ea8467794Douglas Gregor // Set the flags "NoActivate" to make sure the minimized panels do not get 5062e331b938b38057e333fab0ba841130ea8467794Douglas Gregor // activated by the OS. In addition, set "AppWindow" to make sure the 5072e331b938b38057e333fab0ba841130ea8467794Douglas Gregor // minimized panels do appear in the taskbar and Alt-Tab menu if it is not 50867812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko // in a stack. 5092e331b938b38057e333fab0ba841130ea8467794Douglas Gregor int value_to_change = WS_EX_NOACTIVATE; 5102e331b938b38057e333fab0ba841130ea8467794Douglas Gregor if (!panel_->stack()) 51167812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko value_to_change |= WS_EX_APPWINDOW; 51262d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko if (prevent_activation) 5132e331b938b38057e333fab0ba841130ea8467794Douglas Gregor UpdateWindowAttribute(GWL_EXSTYLE, value_to_change, 0, false); 5142e331b938b38057e333fab0ba841130ea8467794Douglas Gregor else 5154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis UpdateWindowAttribute(GWL_EXSTYLE, 0, value_to_change, false); 516b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor#endif 517a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 5184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 519cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenkogfx::NativeWindow PanelView::GetNativePanelWindow() { 5203315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko return window_->GetNativeWindow(); 52178db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor} 52278db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor 52378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregorvoid PanelView::UpdatePanelTitleBar() { 52467812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko UpdateWindowTitle(); 52578db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor UpdateWindowIcon(); 52678db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor} 52767812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko 52862d0f569360a664018316e4a21a4e960560b271dDmitri Gribenkovoid PanelView::UpdatePanelLoadingAnimations(bool should_animate) { 52978db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor GetFrameView()->UpdateThrobber(); 53078db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor} 5314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 532b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregorvoid PanelView::PanelWebContentsFocused(content::WebContents* contents) { 533a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek web_view_->OnWebContentsFocused(contents); 534ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek} 535ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek 536ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenekvoid PanelView::PanelCut() { 537ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek // Nothing to do since we do not have panel-specific system menu. 538cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko NOTREACHED(); 5393315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko} 5401adb082a709f7b588f03672999294e061234b2cfDouglas Gregor 5411adb082a709f7b588f03672999294e061234b2cfDouglas Gregorvoid PanelView::PanelCopy() { 5421adb082a709f7b588f03672999294e061234b2cfDouglas Gregor // Nothing to do since we do not have panel-specific system menu. 54367812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko NOTREACHED(); 5441adb082a709f7b588f03672999294e061234b2cfDouglas Gregor} 5451adb082a709f7b588f03672999294e061234b2cfDouglas Gregor 54667812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenkovoid PanelView::PanelPaste() { 54762d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko // Nothing to do since we do not have panel-specific system menu. 5481adb082a709f7b588f03672999294e061234b2cfDouglas Gregor NOTREACHED(); 5491adb082a709f7b588f03672999294e061234b2cfDouglas Gregor} 5504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis 551a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekvoid PanelView::DrawAttention(bool draw_attention) { 55254d67caeee4fdce81f07163832f1163d5f2af5d2Daniel Dunbar DCHECK((panel_->attention_mode() & Panel::USE_PANEL_ATTENTION) != 0); 553cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko 5543315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko if (is_drawing_attention_ == draw_attention) 5557d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return; 5567d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor is_drawing_attention_ = draw_attention; 5577d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor GetFrameView()->SchedulePaint(); 55867812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko 5597d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if ((panel_->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) { 5607d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor#if defined(OS_WIN) 56167812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko // The default implementation of Widget::FlashFrame only flashes 5 times. 56262d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko // We need more than that. 5637d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor FLASHWINFO fwi; 5647d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor fwi.cbSize = sizeof(fwi); 565b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis fwi.hwnd = views::HWNDForWidget(window_); 566a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (draw_attention) { 567a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek fwi.dwFlags = FLASHW_ALL; 5680b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor fwi.uCount = panel::kNumberOfTimesToFlashPanelForAttention; 569cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko fwi.dwTimeout = 0; 5703315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko } else { 5710b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // TODO(jianli): calling FlashWindowEx with FLASHW_STOP flag for the 5720b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // panel window has the same problem as the stack window. However, 5730b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // we cannot take the similar fix since there is no background window 57467812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko // to replace for the regular panel window. More investigation is needed. 5750b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor fwi.dwFlags = FLASHW_STOP; 5760b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 57767812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko ::FlashWindowEx(&fwi); 57862d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko#else 5790b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor window_->FlashFrame(draw_attention); 5800b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor#endif 581b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis } 582b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis} 583a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 5846931900f43cea558c6974075256c07728dbfecc6Douglas Gregorbool PanelView::IsDrawingAttention() const { 5856931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return is_drawing_attention_; 5866931900f43cea558c6974075256c07728dbfecc6Douglas Gregor} 587cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko 5883315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenkovoid PanelView::HandlePanelKeyboardEvent( 5896931900f43cea558c6974075256c07728dbfecc6Douglas Gregor const content::NativeWebKeyboardEvent& event) { 5906931900f43cea558c6974075256c07728dbfecc6Douglas Gregor views::FocusManager* focus_manager = GetFocusManager(); 5916931900f43cea558c6974075256c07728dbfecc6Douglas Gregor if (focus_manager->shortcut_handling_suspended()) 59267812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko return; 5936931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 5946931900f43cea558c6974075256c07728dbfecc6Douglas Gregor ui::Accelerator accelerator( 59567812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko static_cast<ui::KeyboardCode>(event.windowsKeyCode), 59662d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko content::GetModifiersFromNativeWebKeyboardEvent(event)); 5976931900f43cea558c6974075256c07728dbfecc6Douglas Gregor if (event.type == blink::WebInputEvent::KeyUp) 5986931900f43cea558c6974075256c07728dbfecc6Douglas Gregor accelerator.set_type(ui::ET_KEY_RELEASED); 599011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor focus_manager->ProcessAccelerator(accelerator); 600011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor} 601011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor 602011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregorvoid PanelView::FullScreenModeChanged(bool is_full_screen) { 603cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko if (is_full_screen) { 6043315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko if (window_->IsVisible() && always_on_top_) 605011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor window_->Hide(); 606011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor } else { 607011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor if (!window_->IsVisible()) { 60867812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko ShowPanelInactive(); 609011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor 610011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor#if defined(OS_WIN) 61167812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko // When hiding and showing again a top-most window that belongs to a 61262d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko // background application (i.e. the application is not a foreground one), 613011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor // the window may loose top-most placement even though its WS_EX_TOPMOST 614011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor // bit is still set. Re-issuing SetWindowsPos() returns the window to its 615b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis // top-most placement. 616a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (always_on_top_) 617a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor window_->SetAlwaysOnTop(true); 618a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor#endif 619cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko } 6203315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko } 621a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor} 622a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 623a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregorbool PanelView::IsPanelAlwaysOnTop() const { 62467812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko return always_on_top_; 625a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor} 626a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 62767812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenkovoid PanelView::SetPanelAlwaysOnTop(bool on_top) { 62862d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko if (always_on_top_ == on_top) 629a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return; 630a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor always_on_top_ = on_top; 6312957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis 632a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek window_->SetAlwaysOnTop(on_top); 6333315618561d19c99a7a52c72a31fb182111da716Dmitri Gribenko window_->SetVisibleOnAllWorkspaces(on_top); 6343064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek window_->non_client_view()->Layout(); 6353064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek window_->client_view()->Layout(); 6363064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek} 63767812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko 6383064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenekvoid PanelView::UpdatePanelMinimizeRestoreButtonVisibility() { 63967812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko GetFrameView()->UpdateTitlebarMinimizeRestoreButtonVisibility(); 6403064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek} 6413064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 6429f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregorvoid PanelView::SetWindowCornerStyle(panel::CornerStyle corner_style) { 643a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek GetFrameView()->SetWindowCornerStyle(corner_style); 644aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 645cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko 646cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenkovoid PanelView::PanelExpansionStateChanging(Panel::ExpansionState old_state, 6479f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Panel::ExpansionState new_state) { 6489f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor#if defined(OS_WIN) 6499f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // Live preview is only available since Windows 7. 6509f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (base::win::GetVersion() < base::win::VERSION_WIN7) 6519f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return; 6529f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor 6539f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (panel_->collection()->type() != PanelCollection::DOCKED) 65462d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko return; 65562d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko 656ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis bool is_minimized = old_state != Panel::EXPANDED; 657ee0f84fc84ed7de7975e102668d8e53a778f7a8cArgyrios Kyrtzidis bool will_be_minimized = new_state != Panel::EXPANDED; 6584807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor if (is_minimized == will_be_minimized) 6594807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor return; 66067812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko 661a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek HWND native_window = views::HWNDForWidget(window_); 662aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 663572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (!thumbnailer_.get()) { 664572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor DCHECK(native_window); 665572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor thumbnailer_.reset(new TaskbarWindowThumbnailerWin(native_window, NULL)); 66667812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko } 667572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 66867812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko // Cache the image at this point. 669572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (will_be_minimized) { 670572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor // If the panel is still active (we will deactivate the minimizd panel at 6719e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth // later time), we need to paint it immediately as inactive so that we can 6729e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth // take a snapshot of inactive panel. 673aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (focused_) { 6744807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor force_to_paint_as_inactive_ = true; 6754807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor ::RedrawWindow(native_window, NULL, NULL, 6764807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW); 677664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis } 678664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis 679664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis // Start the thumbnailer and capture the snapshot now. 680664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis thumbnailer_->Start(); 681664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis thumbnailer_->CaptureSnapshot(); 682664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis } else { 683664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis force_to_paint_as_inactive_ = false; 684664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis thumbnailer_->Stop(); 685664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis } 686664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis 687664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis#endif 688664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis} 689664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis 69067812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenkogfx::Size PanelView::WindowSizeFromContentSize( 691664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis const gfx::Size& content_size) const { 692664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis gfx::Size frame = GetFrameView()->NonClientAreaSize(); 693664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis return gfx::Size(content_size.width() + frame.width(), 694664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis content_size.height() + frame.height()); 695664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis} 696664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis 697664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidisgfx::Size PanelView::ContentSizeFromWindowSize( 698664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis const gfx::Size& window_size) const { 6999f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor gfx::Size frame = GetFrameView()->NonClientAreaSize(); 7009f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return gfx::Size(window_size.width() - frame.width(), 701ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor window_size.height() - frame.height()); 702a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 703aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 704ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregorint PanelView::TitleOnlyHeight() const { 705ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return panel::kTitlebarHeight; 706ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor} 70767812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko 708ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregorvoid PanelView::MinimizePanelBySystem() { 70967812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko window_->Minimize(); 710ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor} 711ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 71236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregorbool PanelView::IsPanelMinimizedBySystem() const { 713a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return window_->IsMinimized(); 71436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor} 71536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 716cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenkobool PanelView::IsPanelShownOnActiveDesktop() const { 717aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#if defined(OS_WIN) 71836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // Virtual desktop is not supported by the native Windows system. 71936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return true; 72036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor#else 72167812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko NOTIMPLEMENTED(); 72236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return true; 72336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor#endif 72467812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko} 72562d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko 72636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregorvoid PanelView::ShowShadow(bool show) { 72736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor#if defined(OS_WIN) 728e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko // The overlapped window has the shadow while the popup window does not have 729a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek // the shadow. 7301f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor int overlap_style = WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU; 7311f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor int popup_style = WS_POPUP; 732cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko UpdateWindowAttribute(GWL_STYLE, 7331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor show ? overlap_style : popup_style, 734aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis show ? popup_style : overlap_style, 7351f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor true); 7361f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor#endif 7371f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 7391f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorvoid PanelView::AttachWebContents(content::WebContents* contents) { 740e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko web_view_->SetWebContents(contents); 7411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 742a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 7431f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorvoid PanelView::DetachWebContents(content::WebContents* contents) { 744cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko web_view_->SetWebContents(NULL); 7451f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7461f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 747aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios KyrtzidisNativePanelTesting* PanelView::CreateNativePanelTesting() { 7481f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return new NativePanelTestingWin(this); 7491f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7501f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 7511f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorvoid PanelView::OnDisplayChanged() { 7521f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged(); 7531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 755a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekvoid PanelView::OnWorkAreaChanged() { 7561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor panel_->manager()->display_settings_provider()->OnDisplaySettingsChanged(); 757cb6bcf1c6392398ce9fccb4a0881dd4149568dcfDmitri Gribenko} 7581f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 7591f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorbool PanelView::WillProcessWorkAreaChange() const { 760aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return true; 7611f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7621f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 7631f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorviews::View* PanelView::GetContentsView() { 7641f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return this; 7651f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 7671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorviews::NonClientFrameView* PanelView::CreateNonClientFrameView( 7681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor views::Widget* widget) { 76967812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko PanelFrameView* frame_view = new PanelFrameView(this); 77067812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko frame_view->Init(); 77162d0f569360a664018316e4a21a4e960560b271dDmitri Gribenko return frame_view; 7721f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 7731f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 774e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenkobool PanelView::CanResize() const { 775e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko return true; 776283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor} 777283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor 778ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenkobool PanelView::CanMaximize() const { 779283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor return false; 780283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor} 781283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor 782ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenkobase::string16 PanelView::GetWindowTitle() const { 78378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor return panel_->GetWindowTitle(); 7841adb082a709f7b588f03672999294e061234b2cfDouglas Gregor} 7851adb082a709f7b588f03672999294e061234b2cfDouglas Gregor 7862e331b938b38057e333fab0ba841130ea8467794Douglas Gregorgfx::ImageSkia PanelView::GetWindowAppIcon() { 7872e331b938b38057e333fab0ba841130ea8467794Douglas Gregor gfx::Image app_icon = panel_->app_icon(); 788ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenko if (app_icon.IsEmpty()) 789283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor return GetWindowIcon(); 790283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor else 7917d91438047450869d7b881e1c63868c4b52a3cc2Dmitri Gribenko return *app_icon.ToImageSkia(); 7927d91438047450869d7b881e1c63868c4b52a3cc2Dmitri Gribenko} 79395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 79495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenekgfx::ImageSkia PanelView::GetWindowIcon() { 795404628caa53a3f898047d73b38647d6fbb827e00Dmitri Gribenko gfx::Image icon = panel_->GetCurrentPageIcon(); 796404628caa53a3f898047d73b38647d6fbb827e00Dmitri Gribenko return icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia(); 7978ccac3de1335f1cfd7cea56ba1cefcf0b724ce3fArgyrios Kyrtzidis} 7988ccac3de1335f1cfd7cea56ba1cefcf0b724ce3fArgyrios Kyrtzidis 799f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregorvoid PanelView::WindowClosing() { 800b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor // When closing a panel via window.close, API or the close button, 801b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor // ClosePanel() is called first, destroying the native |window_| 80297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor // which results in this method being called. ClosePanel() sets 803b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor // |window_closed_| to NULL. 80446f92523918fd4ac4df5489265c7f85c1b28baeaDmitri Gribenko // If we still have a |window_closed_| here, the close was triggered by the 8054451746d8f658b51eaf15dd24664a488457063a9Argyrios Kyrtzidis // OS, (e.g. clicking on taskbar menu), which destroys the native |window_| 8064451746d8f658b51eaf15dd24664a488457063a9Argyrios Kyrtzidis // without invoking ClosePanel() beforehand. 8075694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko if (!window_closed_) { 808a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek panel_->OnWindowClosing(); 809a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ClosePanel(); 810a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek DCHECK(window_closed_); 81167812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko } 812283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor} 813283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor 814e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisvoid PanelView::DeleteDelegate() { 815e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis delete this; 816e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis} 81721c3607282550779c9ae5fe784928597807fd110Argyrios Kyrtzidis 818e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidisvoid PanelView::OnWindowBeginUserBoundsChange() { 819e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis user_resizing_ = true; 820e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis panel_->OnPanelStartUserResizing(); 821e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis 82221c3607282550779c9ae5fe784928597807fd110Argyrios Kyrtzidis#if defined(OS_WIN) 82321c3607282550779c9ae5fe784928597807fd110Argyrios Kyrtzidis StackedPanelCollection* stack = panel_->stack(); 824e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (stack) { 82521c3607282550779c9ae5fe784928597807fd110Argyrios Kyrtzidis // Listen to WM_SIZING message in order to find out whether the interior 82621c3607282550779c9ae5fe784928597807fd110Argyrios Kyrtzidis // edge is being resized such that the specific maximum size could be 82705756dc8d11cd2054e0cb94f0302e4eb39acc68eDmitri Gribenko // passed to the system. 828e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis if (panel_->stack()->GetPanelBelow(panel_.get())) { 829e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis ui::HWNDSubclass::AddFilterToTarget(views::HWNDForWidget(window_), this); 830e15db6f0d226a3bc88d244512d1004c7c1c07391Argyrios Kyrtzidis user_resizing_interior_stacked_panel_edge_ = false; 831aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 832aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 833aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // Keep track of the original full size of the resizing panel such that it 834aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // can be restored to this size once it is shrunk to minimized state. 835aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis original_full_size_of_resizing_panel_ = panel_->full_size(); 836aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 837aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // Keep track of the original full size of the panel below the resizing 838aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // panel such that it can be restored to this size once it is shrunk to 839aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // minimized state. 840aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Panel* below_panel = stack->GetPanelBelow(panel_.get()); 841aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (below_panel && !below_panel->IsMinimized()) { 842aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis original_full_size_of_panel_below_resizing_panel_ = 843aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis below_panel->full_size(); 844aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 845aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 846aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#endif 847aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 848aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 849aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid PanelView::OnWindowEndUserBoundsChange() { 850aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis user_resizing_ = false; 851aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis panel_->OnPanelEndUserResizing(); 852aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 853aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // No need to proceed with post-resizing update when there is no size change. 854aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis gfx::Rect new_bounds = window_->GetWindowBoundsInScreen(); 855aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (bounds_ == new_bounds) 856aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 857aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis bounds_ = new_bounds; 858aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 859aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis panel_->IncreaseMaxSize(bounds_.size()); 860aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis panel_->set_full_size(bounds_.size()); 861aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 862aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#if defined(OS_WIN) 863aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis StackedPanelCollection* stack = panel_->stack(); 864aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (stack) { 865aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // No need to listen to WM_SIZING message any more. 866aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis ui::HWNDSubclass::RemoveFilterFromAllTargets(this); 867aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 868aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // If the height of resizing panel shrinks close to the titlebar height, 869aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // treate it as minimized. This could occur when the user is dragging 870aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // 1) the top edge of the top panel downward to shrink it; or 871aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // 2) the bottom edge of any panel upward to shrink it. 872aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (panel_->GetBounds().height() < 873aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis kStackedPanelHeightShrinkThresholdToBecomeMinimized) { 874aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis stack->MinimizePanel(panel_.get()); 875aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis panel_->set_full_size(original_full_size_of_resizing_panel_); 876aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 877aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 878aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // If the height of panel below the resizing panel shrinks close to the 879ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenko // titlebar height, treat it as minimized. This could occur when the user 880aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // is dragging the bottom edge of non-bottom panel downward to expand it 881ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenko // and also shrink the panel below. 882aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Panel* below_panel = stack->GetPanelBelow(panel_.get()); 883aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (below_panel && !below_panel->IsMinimized() && 884ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenko below_panel->GetBounds().height() < 885ff74f9683943c0db9cb075423596b00ea3b38c5dDmitri Gribenko kStackedPanelHeightShrinkThresholdToBecomeMinimized) { 886aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis stack->MinimizePanel(below_panel); 887aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis below_panel->set_full_size( 888aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis original_full_size_of_panel_below_resizing_panel_); 889aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 890aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 891aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#endif 892aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 893aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis panel_->collection()->RefreshLayout(); 894aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 895aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 896aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisviews::Widget* PanelView::GetWidget() { 897aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return window_; 898aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 89939e6ab4be93d9c5e729a578ddd9d415cd2d49872David Blaikie 900aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisconst views::Widget* PanelView::GetWidget() const { 901aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return window_; 902aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 903aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 904aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid PanelView::UpdateLoadingAnimations(bool should_animate) { 905aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis GetFrameView()->UpdateThrobber(); 906aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 907aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 908aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid PanelView::UpdateWindowTitle() { 909aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis window_->UpdateWindowTitle(); 910aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis GetFrameView()->UpdateTitle(); 911aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 912aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 913283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregorvoid PanelView::UpdateWindowIcon() { 914283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor window_->UpdateWindowIcon(); 915283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor GetFrameView()->UpdateIcon(); 9162e331b938b38057e333fab0ba841130ea8467794Douglas Gregor} 917007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek 918007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenekvoid PanelView::Layout() { 919007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // |web_view_| might not be created yet when the window is first created. 920007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (web_view_) 921007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek web_view_->SetBounds(0, 0, width(), height()); 922007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek} 923007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek 924007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenekgfx::Size PanelView::GetMinimumSize() const { 925eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // If the panel is minimized, it can be rendered to very small size, like 926b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis // 4-pixel lines when it is docked. Otherwise, its size should not be less 927b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis // than its minimum size. 928b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis return panel_->IsMinimized() ? gfx::Size() : 929fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis gfx::Size(panel::kPanelMinWidth, panel::kPanelMinHeight); 930fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis} 931fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis 932fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidisgfx::Size PanelView::GetMaximumSize() const { 933fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis // If the user is resizing a stacked panel by its bottom edge, make sure its 934fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis // height cannot grow more than what the panel below it could offer. This is 935b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis // because growing a stacked panel by y amount will shrink the panel below it 936b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis // by same amount and we do not want the panel below it being shrunk to be 937b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis // smaller than the titlebar. 938b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis#if defined(OS_WIN) 939d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis if (panel_->stack() && user_resizing_interior_stacked_panel_edge_) { 940d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis Panel* below_panel = panel_->stack()->GetPanelBelow(panel_.get()); 941e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko if (below_panel && !below_panel->IsMinimized()) { 942d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis return gfx::Size(0, below_panel->GetBounds().bottom() - 943d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis panel_->GetBounds().y() - panel::kTitlebarHeight); 944d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis } 945d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis } 946d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis#endif 947d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis return gfx::Size(); 948e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis} 949e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis 950e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidisbool PanelView::AcceleratorPressed(const ui::Accelerator& accelerator) { 951e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis if (mouse_pressed_ && accelerator.key_code() == ui::VKEY_ESCAPE) { 952e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis OnTitlebarMouseCaptureLost(); 953e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis return true; 954e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis } 955d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis 956d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis // No other accelerator is allowed when the drag begins. 957d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis if (mouse_dragging_state_ == DRAGGING_STARTED) 958d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis return true; 959d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis 960e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko const std::map<ui::Accelerator, int>& accelerator_table = 961e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko GetAcceleratorTable(); 962d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis std::map<ui::Accelerator, int>::const_iterator iter = 963d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis accelerator_table.find(accelerator); 964d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis DCHECK(iter != accelerator_table.end()); 965e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko return panel_->ExecuteCommandIfEnabled(iter->second); 966d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis} 967d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis 968d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidisvoid PanelView::OnWidgetDestroying(views::Widget* widget) { 969d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis window_ = NULL; 970d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis} 971d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis 972e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidisvoid PanelView::OnWidgetActivationChanged(views::Widget* widget, bool active) { 973e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis#if defined(OS_WIN) 974e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis // WM_NCACTIVATED could be sent when an active window is being destroyed on 975e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis // Windows. We need to guard against this. 976e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis if (window_closed_) 977e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis return; 978e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis 979e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis bool focused = active; 980e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_NATIVE) { 981e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis // The panel window is in focus (actually accepting keystrokes) if it is 982e9ebd852ec1effa393bcc4aad73d9c657a5279c1Argyrios Kyrtzidis // active and belongs to a foreground application. 983d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis focused = active && 984d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis views::HWNDForWidget(widget) == ::GetForegroundWindow(); 985d98ef9ae48ab4090d4d5d703ce65cfac62807fdaArgyrios Kyrtzidis } 986fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis#else 987fa865df489fe68668c554dece36c68b4ce03920fArgyrios Kyrtzidis NOTIMPLEMENTED(); 988b0d6eaa6b646c18c49923aefc76973801f561701Argyrios Kyrtzidis bool focused = active; 989eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek#endif 990eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 991eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (focused_ == focused) 992eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek return; 993eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek focused_ = focused; 994eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 995eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // Expand the panel if the minimized panel is activated by means other than 996eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // clicking on its titlebar. This is the workaround to support restoring the 997eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // minimized panel by other means, like alt-tabbing, win-tabbing, or clicking 998eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // the taskbar icon. Note that this workaround does not work for one edge 999eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // case: the mouse happens to be at the minimized panel when the user tries to 1000eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // bring up the panel with the above alternatives. 1001da6fb69873079a0193ed8c9fa1d1b859d4f87b95Ted Kremenek // When the user clicks on the minimized panel, the panel expansion will be 1002eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // done when we process the mouse button pressed message. 1003eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek#if defined(OS_WIN) 1004eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (focused_ && panel_->IsMinimized() && 1005eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek panel_->collection()->type() == PanelCollection::DOCKED && 1006eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek gfx::Screen::GetScreenFor(widget->GetNativeWindow())-> 1007eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek GetWindowUnderCursor() != widget->GetNativeWindow()) { 1008eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek panel_->Restore(); 1009eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek } 101067812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko#endif 1011eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1012eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek panel()->OnActiveStateChanged(focused); 1013eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1014eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // Give web contents view a chance to set focus to the appropriate element. 1015eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (focused_) { 1016eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek content::WebContents* web_contents = panel_->GetWebContents(); 1017eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (web_contents) 1018eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek web_contents->RestoreFocus(); 1019eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek } 1020eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek} 1021eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1022eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenekvoid PanelView::OnWidgetBoundsChanged(views::Widget* widget, 1023eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek const gfx::Rect& new_bounds) { 1024eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (user_resizing_) 1025eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek panel()->collection()->OnPanelResizedByMouse(panel(), new_bounds); 1026eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek} 1027eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1028eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenekbool PanelView::OnTitlebarMousePressed(const gfx::Point& mouse_location) { 1029eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek mouse_pressed_ = true; 1030eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek mouse_dragging_state_ = NO_DRAGGING; 1031eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek last_mouse_location_ = mouse_location; 1032eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek return true; 1033eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek} 1034eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1035eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenekbool PanelView::OnTitlebarMouseDragged(const gfx::Point& mouse_location) { 1036eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (!mouse_pressed_) 1037e8b3de090b9de3c27c5d381e767217ddb849d5d8Anders Carlsson return false; 1038eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1039eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (mouse_dragging_state_ == NO_DRAGGING && 1040eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek ExceededDragThreshold(mouse_location - last_mouse_location_)) { 1041eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // When a drag begins, we do not want to the client area to still receive 1042eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek // the focus. We do not need to do this for the unfocused minimized panel. 1043eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek if (!panel_->IsMinimized()) { 1044eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek old_focused_view_ = GetFocusManager()->GetFocusedView(); 1045eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek GetFocusManager()->SetFocusedView(GetFrameView()); 1046eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek } 1047eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek 1048eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek panel_->manager()->StartDragging(panel_.get(), last_mouse_location_); 1049eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek mouse_dragging_state_ = DRAGGING_STARTED; 1050eca099bdb0178d408d4f717c2e9627e0d0e673c6Ted Kremenek } 10518fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor if (mouse_dragging_state_ == DRAGGING_STARTED) { 10528fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor panel_->manager()->Drag(mouse_location); 10538fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor 10548fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // Once in drag, update |last_mouse_location_| on each drag fragment, since 1055e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko // we already dragged the panel up to the current mouse location. 1056e22339c44bb28d71a2cc97c840d3da0c4bdb4909Dmitri Gribenko last_mouse_location_ = mouse_location; 10578fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor } 1058d1f09b482b3874be07dfe9dd24bfad98915989c3Douglas Gregor return true; 10595e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis} 10605e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis 10615e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidisbool PanelView::OnTitlebarMouseReleased(panel::ClickModifier modifier) { 106228a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis if (mouse_dragging_state_ != NO_DRAGGING) { 1063d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko // Ensure dragging a minimized panel does not leave it activated. 1064d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko // Windows activates a panel on mouse-down, regardless of our attempts 10655e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis // to prevent activation of a minimized panel. Now that we know mouse-down 10668fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // resulted in a mouse-drag, we need to ensure the minimized panel is 10678fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // deactivated. 10688fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor if (panel_->IsMinimized() && focused_) 106967812b2f94f4b5e7d2596db1705ffa1149ddc45aDmitri Gribenko panel_->Deactivate(); 10708fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor 10718fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor if (mouse_dragging_state_ == DRAGGING_STARTED) { 1072b3958476b21702a15f64f09d2862506d03dffe7bDmitri Gribenko // When a drag ends, restore the focus. 10735e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis if (old_focused_view_) { 10745e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis GetFocusManager()->SetFocusedView(old_focused_view_); 10755e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis old_focused_view_ = NULL; 107628a83f57003469fb615ad27dd34bcf5b0a10da8cArgyrios Kyrtzidis } 1077d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko return EndDragging(false); 1078d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko } 10795e192a7d60e776fa65e633cd9c2a0d59df132f23Argyrios Kyrtzidis 10808fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // The panel drag was cancelled before the mouse is released. Do not 10818fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor // treat this as a click. 10828fa0a80b4482ad94e82c4a19e23de17fd69140b5Douglas Gregor return true; 10838eece46c544e79190d5b3e7c28f68c1463fbf2f9Ted Kremenek } 1084bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1085bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek panel_->OnTitlebarClicked(modifier); 1086bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return true; 1087cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko} 1088bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1089bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenekbool PanelView::OnTitlebarMouseCaptureLost() { 1090bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (mouse_dragging_state_ == DRAGGING_STARTED) 1091bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return EndDragging(true); 1092bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return true; 1093bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek} 1094bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1095bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenekbool PanelView::EndDragging(bool cancelled) { 1096bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek // Only handle clicks that started in our window. 1097bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (!mouse_pressed_) 1098bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return false; 1099bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek mouse_pressed_ = false; 1100bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1101bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek mouse_dragging_state_ = DRAGGING_ENDED; 1102bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek panel_->manager()->EndDragging(cancelled); 1103bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return true; 1104bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek} 1105bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1106bbf66ca1dad17773cc682d69b8482c4e179aeaebTed KremenekPanelFrameView* PanelView::GetFrameView() const { 11078eece46c544e79190d5b3e7c28f68c1463fbf2f9Ted Kremenek return static_cast<PanelFrameView*>(window_->non_client_view()->frame_view()); 11088eece46c544e79190d5b3e7c28f68c1463fbf2f9Ted Kremenek} 1109bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1110bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenekbool PanelView::IsAnimatingBounds() const { 1111bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (bounds_animator_.get() && bounds_animator_->is_animating()) 1112bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return true; 1113bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek StackedPanelCollection* stack = panel_->stack(); 1114bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (!stack) 1115bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return false; 1116bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return stack->IsAnimatingPanelBounds(panel_.get()); 1117bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek} 1118bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1119bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenekbool PanelView::IsWithinResizingArea(const gfx::Point& mouse_location) const { 1120bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek gfx::Rect bounds = window_->GetWindowBoundsInScreen(); 1121bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek DCHECK(bounds.Contains(mouse_location)); 1122bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek return mouse_location.x() < bounds.x() + kResizeInsideBoundsSize || 1123bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek mouse_location.x() >= bounds.right() - kResizeInsideBoundsSize || 1124bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek mouse_location.y() < bounds.y() + kResizeInsideBoundsSize || 1125bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek mouse_location.y() >= bounds.bottom() - kResizeInsideBoundsSize; 1126bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek} 1127bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1128bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek#if defined(OS_WIN) 1129bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenekvoid PanelView::UpdateWindowAttribute(int attribute_index, 1130bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek int attribute_value_to_set, 1131bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek int attribute_value_to_reset, 1132bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek bool update_frame) { 1133bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek HWND native_window = views::HWNDForWidget(window_); 1134bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek int value = ::GetWindowLong(native_window, attribute_index); 1135bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek int expected_value = value; 1136bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (attribute_value_to_set) 1137bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek expected_value |= attribute_value_to_set; 1138bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (attribute_value_to_reset) 1139bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek expected_value &= ~attribute_value_to_reset; 1140bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (value != expected_value) 1141bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek ::SetWindowLong(native_window, attribute_index, expected_value); 1142bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek 1143bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek // Per MSDN, if any of the frame styles is changed, SetWindowPos with the 1144bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek // SWP_FRAMECHANGED flag must be called in order for the cached window data 1145bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek // to be updated properly. 1146bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591(v=vs.85).aspx 1147bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek if (update_frame) { 1148bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek ::SetWindowPos(native_window, NULL, 0, 0, 0, 0, 1149bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | 1150bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek SWP_NOZORDER | SWP_NOACTIVATE); 1151bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek } 1152bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek} 1153bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek#endif 1154bbf66ca1dad17773cc682d69b8482c4e179aeaebTed Kremenek