diff options
author | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-07 00:33:33 +0000 |
---|---|---|
committer | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-07 00:33:33 +0000 |
commit | 0548c535089c52b722990abf03f3df375499034d (patch) | |
tree | 7b87e1b8e0dc8d1f705727f5e30599680cfe894f /chrome | |
parent | e7a2d749e769e50d1b9aa8114620cc839715c7e2 (diff) | |
download | chromium_src-0548c535089c52b722990abf03f3df375499034d.zip chromium_src-0548c535089c52b722990abf03f3df375499034d.tar.gz chromium_src-0548c535089c52b722990abf03f3df375499034d.tar.bz2 |
Make panel adjust bounds per preferred size change notification on Windows.
BUG=none
TEST=new browser test
Review URL: http://codereview.chromium.org/7537030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99880 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
32 files changed, 436 insertions, 45 deletions
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 703daed..a0e100b 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -150,6 +150,7 @@ class ExtensionHost : public RenderViewHostDelegate, virtual void HandleMouseActivate() OVERRIDE; virtual void RunFileChooser(RenderViewHost* render_view_host, const ViewHostMsg_RunFileChooser_Params& params); + virtual void UpdatePreferredSize(const gfx::Size& new_size); // RenderViewHostDelegate::View virtual void CreateNewWindow( @@ -179,7 +180,6 @@ class ExtensionHost : public RenderViewHostDelegate, virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE; virtual void GotFocus() OVERRIDE; virtual void TakeFocus(bool reverse) OVERRIDE; - virtual void UpdatePreferredSize(const gfx::Size& new_size) OVERRIDE; // NotificationObserver virtual void Observe(int type, diff --git a/chrome/browser/notifications/balloon_host.h b/chrome/browser/notifications/balloon_host.h index bc55201..921fbb0 100644 --- a/chrome/browser/notifications/balloon_host.h +++ b/chrome/browser/notifications/balloon_host.h @@ -63,6 +63,7 @@ class BalloonHost : public RenderViewHostDelegate, virtual void HandleMouseDown() OVERRIDE; virtual RendererPreferences GetRendererPrefs( content::BrowserContext* browser_context) const OVERRIDE; + virtual void UpdatePreferredSize(const gfx::Size& pref_size) OVERRIDE; // RenderViewHostDelegate::View methods. Only the ones for opening new // windows are currently implemented. @@ -93,7 +94,6 @@ class BalloonHost : public RenderViewHostDelegate, virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE {} virtual void GotFocus() OVERRIDE {} virtual void TakeFocus(bool reverse) OVERRIDE {} - virtual void UpdatePreferredSize(const gfx::Size& pref_size) OVERRIDE; // Enable Web UI. This has to be called before renderer is created. void EnableWebUI(); diff --git a/chrome/browser/tab_contents/background_contents.h b/chrome/browser/tab_contents/background_contents.h index 950baae..afad19f 100644 --- a/chrome/browser/tab_contents/background_contents.h +++ b/chrome/browser/tab_contents/background_contents.h @@ -108,7 +108,6 @@ class BackgroundContents : public RenderViewHostDelegate, virtual void UpdateDragCursor(WebKit::WebDragOperation operation) {} virtual void GotFocus() {} virtual void TakeFocus(bool reverse) {} - virtual void UpdatePreferredSize(const gfx::Size& new_size) {} // NotificationObserver virtual void Observe(int type, diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index 92c737c..0ae84e5 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -247,9 +247,6 @@ void TabContentsViewGtk::RestoreFocus() { SetInitialFocus(); } -void TabContentsViewGtk::UpdatePreferredSize(const gfx::Size& pref_size) { -} - bool TabContentsViewGtk::IsDoingDrag() const { return false; } diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h index 5e5bd0a..b21171f 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.h +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h @@ -62,7 +62,6 @@ class TabContentsViewGtk : public TabContentsView, virtual void SetInitialFocus() OVERRIDE; virtual void StoreFocus() OVERRIDE; virtual void RestoreFocus() OVERRIDE; - virtual void UpdatePreferredSize(const gfx::Size& pref_size) OVERRIDE; virtual bool IsDoingDrag() const OVERRIDE; virtual void CancelDragAndCloseTab() OVERRIDE; virtual bool IsEventTracking() const OVERRIDE; diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.h b/chrome/browser/tab_contents/tab_contents_view_mac.h index 0ece02e..809bf23 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.h +++ b/chrome/browser/tab_contents/tab_contents_view_mac.h @@ -73,7 +73,6 @@ class TabContentsViewMac : public TabContentsView, virtual void SetInitialFocus() OVERRIDE; virtual void StoreFocus() OVERRIDE; virtual void RestoreFocus() OVERRIDE; - virtual void UpdatePreferredSize(const gfx::Size& pref_size) OVERRIDE; virtual bool IsDoingDrag() const OVERRIDE; virtual void CancelDragAndCloseTab() OVERRIDE; virtual bool IsEventTracking() const OVERRIDE; diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 1c315b0..b6bafea 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -234,10 +234,6 @@ void TabContentsViewMac::RestoreFocus() { focus_tracker_.reset(nil); } -void TabContentsViewMac::UpdatePreferredSize(const gfx::Size& pref_size) { - preferred_width_ = pref_size.width(); -} - bool TabContentsViewMac::IsDoingDrag() const { return false; } diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index d96ca0c..e92d6c7 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -3438,11 +3438,6 @@ void Browser::AddNewContents(TabContents* source, params.window_action = browser::NavigateParams::SHOW_WINDOW; params.user_gesture = user_gesture; browser::Navigate(¶ms); - - NotificationService::current()->Notify( - content::NOTIFICATION_TAB_ADDED, - Source<TabContentsDelegate>(this), - Details<TabContents>(new_contents)); } void Browser::ActivateContents(TabContents* contents) { @@ -3881,6 +3876,11 @@ void Browser::ExitTabbedFullscreenModeIfNecessary() { NotifyTabOfFullscreenExitIfNecessary(); } +void Browser::UpdatePreferredSize(TabContents* source, + const gfx::Size& pref_size) { + window_->UpdatePreferredSize(source, pref_size); +} + /////////////////////////////////////////////////////////////////////////////// // Browser, TabContentsWrapperDelegate implementation: diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index fdd1083..00f6440 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -981,6 +981,8 @@ class Browser : public TabHandlerDelegate, const string16& type, const string16& data, int intent_id) OVERRIDE; + virtual void UpdatePreferredSize(TabContents* source, + const gfx::Size& pref_size) OVERRIDE; virtual void FindReply(TabContents* tab, int request_id, diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index f597016..a62496b 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc @@ -533,6 +533,13 @@ void Navigate(NavigateParams* params) { if (params->source_contents != params->target_contents) params->browser->ActivateTabAt(singleton_index, user_initiated); } + + if (params->disposition != CURRENT_TAB) { + NotificationService::current()->Notify( + content::NOTIFICATION_TAB_ADDED, + Source<TabContentsDelegate>(params->browser), + Details<TabContents>(params->target_contents->tab_contents())); + } } // Returns the index of an existing singleton tab in |params->browser| matching diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 51e96f9..8da015c 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -33,6 +33,7 @@ struct NativeWebKeyboardEvent; namespace gfx { class Rect; +class Size; } class Extension; @@ -344,6 +345,13 @@ class BrowserWindow { virtual void ShowKeyboardOverlay(gfx::NativeWindow owning_window) = 0; #endif + // Invoked when the preferred size of the contents in current tab has been + // changed. We might choose to update the window size to accomodate this + // change. + // Note that this won't be fired if we change tabs. + virtual void UpdatePreferredSize(TabContents* tab_contents, + const gfx::Size& pref_size) {} + // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(Browser* browser); diff --git a/chrome/browser/ui/panels/base_panel_browser_test.cc b/chrome/browser/ui/panels/base_panel_browser_test.cc index b0a4c05..4015c52 100644 --- a/chrome/browser/ui/panels/base_panel_browser_test.cc +++ b/chrome/browser/ui/panels/base_panel_browser_test.cc @@ -13,7 +13,9 @@ #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_switches.h" +#include "chrome/test/base/ui_test_utils.h" #include "content/browser/tab_contents/test_tab_contents.h" +#include "content/common/url_constants.h" #if defined(OS_MACOSX) #include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h" @@ -158,6 +160,7 @@ BasePanelBrowserTest::~BasePanelBrowserTest() { } void BasePanelBrowserTest::SetUpCommandLine(CommandLine* command_line) { + EnableDOMAutomation(); command_line->AppendSwitch(switches::kEnablePanels); } @@ -171,6 +174,7 @@ void BasePanelBrowserTest::SetUpOnMainThread() { panel_manager); panel_manager->set_auto_hiding_desktop_bar(mock_auto_hiding_desktop_bar_); panel_manager->SetWorkAreaForTesting(testing_work_area_); + panel_manager->enable_auto_sizing(false); } Panel* BasePanelBrowserTest::CreatePanelWithParams( @@ -189,9 +193,16 @@ Panel* BasePanelBrowserTest::CreatePanelWithParams( browser()->profile()); EXPECT_TRUE(panel_browser->is_type_panel()); - TabContentsWrapper* tab_contents = - new TabContentsWrapper(new TestTabContents(browser()->profile(), NULL)); - panel_browser->AddTab(tab_contents, PageTransition::LINK); + if (params.url.is_empty()) { + TabContentsWrapper* tab_contents = + new TabContentsWrapper(new TestTabContents(browser()->profile(), NULL)); + panel_browser->AddTab(tab_contents, PageTransition::LINK); + } else { + panel_browser->AddSelectedTabWithURL(params.url, + PageTransition::START_PAGE); + ui_test_utils::WaitForNavigation( + &panel_browser->GetSelectedTabContents()->controller()); + } Panel* panel = static_cast<Panel*>(panel_browser->window()); if (params.show_flag == SHOW_AS_ACTIVE) diff --git a/chrome/browser/ui/panels/base_panel_browser_test.h b/chrome/browser/ui/panels/base_panel_browser_test.h index 2f08401..685acc1 100644 --- a/chrome/browser/ui/panels/base_panel_browser_test.h +++ b/chrome/browser/ui/panels/base_panel_browser_test.h @@ -42,6 +42,7 @@ class BasePanelBrowserTest : public InProcessBrowserTest { std::string name; gfx::Rect bounds; ShowFlag show_flag; + GURL url; CreatePanelParams(const std::string& name, const gfx::Rect& bounds, diff --git a/chrome/browser/ui/panels/native_panel.h b/chrome/browser/ui/panels/native_panel.h index 2a4fdb1..8aa419d 100644 --- a/chrome/browser/ui/panels/native_panel.h +++ b/chrome/browser/ui/panels/native_panel.h @@ -67,6 +67,15 @@ class NativePanel { virtual Browser* GetPanelBrowser() const = 0; virtual void DestroyPanelBrowser() = 0; + + // Returns the extent of the non-client area, that is, the window size minus + // the size of the client area. + virtual gfx::Size GetNonClientAreaExtent() const = 0; + + // Gets or sets the restored height, which is the full height of the panel + // when it is expanded. + virtual int GetRestoredHeight() const = 0; + virtual void SetRestoredHeight(int height) = 0; }; // A NativePanel utility interface used for accessing elements of the diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index b598ab9..7195e30 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -8,12 +8,16 @@ #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" +#include "content/browser/renderer_host/render_view_host.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/panels/native_panel.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/window_sizer.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/extension.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "content/common/content_notification_types.h" +#include "content/common/view_messages.h" #include "ui/gfx/rect.h" // static @@ -27,9 +31,15 @@ const Extension* Panel::GetExtension(Browser* browser) { } Panel::Panel(Browser* browser, const gfx::Rect& bounds) - : native_panel_(NULL), + : min_size_(bounds.size()), + max_size_(bounds.size()), + native_panel_(NULL), expansion_state_(EXPANDED) { native_panel_ = CreateNativePanel(browser, this, bounds); + + registrar_.Add(this, + content::NOTIFICATION_TAB_ADDED, + Source<TabContentsDelegate>(browser)); } Panel::~Panel() { @@ -44,6 +54,18 @@ void Panel::SetPanelBounds(const gfx::Rect& bounds) { native_panel_->SetPanelBounds(bounds); } +void Panel::SetMaxSize(const gfx::Size& max_size) { + if (max_size_ == max_size) + return; + max_size_ = max_size; + + // Note: |render_view_host| might be NULL if the tab has not been created. + // If so, we will do it when NOTIFICATION_TAB_ADDED is received. + RenderViewHost* render_view_host = GetRenderViewHost(); + if (render_view_host) + RequestRenderViewHostToDisableScrollbars(render_view_host); +} + void Panel::SetExpansionState(ExpansionState new_expansion_state) { if (expansion_state_ == new_expansion_state) return; @@ -75,6 +97,14 @@ bool Panel::IsDrawingAttention() const { return native_panel_->IsDrawingAttention(); } +int Panel::GetRestoredHeight() const { + return native_panel_->GetRestoredHeight(); +} + +void Panel::SetRestoredHeight(int height) { + native_panel_->SetRestoredHeight(height); +} + void Panel::Show() { native_panel_->ShowPanel(); } @@ -445,6 +475,52 @@ void Panel::ShowKeyboardOverlay(gfx::NativeWindow owning_window) { } #endif +void Panel::UpdatePreferredSize(TabContents* tab_contents, + const gfx::Size& pref_size) { + gfx::Size non_client_size = native_panel_->GetNonClientAreaExtent(); + return manager()->OnPreferredWindowSizeChanged(this, + gfx::Size(pref_size.width() + non_client_size.width(), + pref_size.height() + non_client_size.height())); +} + +void Panel::Observe(int type, + const NotificationSource& source, + const NotificationDetails& details) { + switch (type) { + case content::NOTIFICATION_TAB_ADDED: + case content::NOTIFICATION_TAB_CONTENTS_SWAPPED: { + RenderViewHost* render_view_host = GetRenderViewHost(); + DCHECK(render_view_host); + render_view_host->Send(new ViewMsg_EnablePreferredSizeChangedMode( + render_view_host->routing_id(), + kPreferredSizeWidth | kPreferredSizeHeightThisIsSlow)); + RequestRenderViewHostToDisableScrollbars(render_view_host); + break; + } + default: + NOTREACHED() << "Got a notification we didn't register for!"; + break; + } +} + +RenderViewHost* Panel::GetRenderViewHost() const { + TabContents* tab_contents = browser()->GetSelectedTabContents(); + if (!tab_contents) + return NULL; + return tab_contents->render_view_host(); +} + +void Panel::RequestRenderViewHostToDisableScrollbars( + RenderViewHost* render_view_host) { + DCHECK(render_view_host); + + gfx::Size non_client_size = native_panel_->GetNonClientAreaExtent(); + render_view_host->Send(new ViewMsg_DisableScrollbarsForSmallWindows( + render_view_host->routing_id(), + gfx::Size(max_size_.width() - non_client_size.width(), + max_size_.height() - non_client_size.height()))); +} + Browser* Panel::browser() const { return native_panel_->GetPanelBrowser(); } diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h index 81b5548f2..bdf3c2d 100644 --- a/chrome/browser/ui/panels/panel.h +++ b/chrome/browser/ui/panels/panel.h @@ -9,10 +9,13 @@ #include "chrome/browser/ui/browser_window.h" #include "base/memory/scoped_ptr.h" +#include "content/common/notification_observer.h" +#include "content/common/notification_registrar.h" #include "ui/gfx/rect.h" class NativePanel; class PanelManager; +class RenderViewHost; // A platform independent implementation of BrowserWindow for Panels. This // class would get the first crack at all the BrowserWindow calls for Panels and @@ -24,7 +27,7 @@ class PanelManager; // Panel size is restricted to certain limits. // - Invoke an appropriate PanelManager function to do stuff that might affect // other Panels. For example deleting a panel would rearrange other panels. -class Panel : public BrowserWindow { +class Panel : public BrowserWindow, public NotificationObserver { public: enum ExpansionState { // The panel is fully expanded with both title-bar and the client-area. @@ -46,6 +49,11 @@ class Panel : public BrowserWindow { bool IsDrawingAttention() const; + // Gets or sets the restored height, which is the full height of the panel + // when it is expanded. + int GetRestoredHeight() const; + void SetRestoredHeight(int height); + // BrowserWindow overrides. virtual void Show() OVERRIDE; virtual void ShowInactive() OVERRIDE; @@ -146,6 +154,13 @@ class Panel : public BrowserWindow { #if defined(OS_CHROMEOS) virtual void ShowKeyboardOverlay(gfx::NativeWindow owning_window) OVERRIDE; #endif + virtual void UpdatePreferredSize(TabContents* tab_contents, + const gfx::Size& pref_size) OVERRIDE; + + // NotificationObserver overrides. + virtual void Observe(int type, + const NotificationSource& source, + const NotificationDetails& details) OVERRIDE; // Construct a native panel BrowserWindow implementation for the specified // |browser|. @@ -157,12 +172,11 @@ class Panel : public BrowserWindow { // Returns NULL if it cannot be found. static const Extension* GetExtension(Browser* browser); -#ifdef UNIT_TEST NativePanel* native_panel() { return native_panel_; } -#endif - Browser* browser() const; ExpansionState expansion_state() const { return expansion_state_; } + const gfx::Size& min_size() const { return min_size_; } + const gfx::Size& max_size() const { return max_size_; } protected: virtual void DestroyBrowser() OVERRIDE; @@ -179,12 +193,32 @@ class Panel : public BrowserWindow { // not allowed for Panel. void SetPanelBounds(const gfx::Rect& bounds); + // Updates the maximum size. + void SetMaxSize(const gfx::Size& max_size); + + // NULL might be returned if the tab has not been added. + RenderViewHost* GetRenderViewHost() const; + + // Requests RenderViewHost not to show the scrollbars till |max_size_| since + // the panel can grow to |max_size_|. + void RequestRenderViewHostToDisableScrollbars( + RenderViewHost* render_view_host); + + // This is the minimum size that the panel can shrink to. + gfx::Size min_size_; + + // This is the size beyond which the panel is not going to grow to accomodate + // the growing content and WebKit would add the scrollbars in such case. + gfx::Size max_size_; + // Platform specifc implementation for panels. It'd be one of // PanelBrowserWindowGtk/PanelBrowserView/PanelBrowserWindowCocoa. NativePanel* native_panel_; // Weak, owns us. ExpansionState expansion_state_; + NotificationRegistrar registrar_; + DISALLOW_COPY_AND_ASSIGN(Panel); }; diff --git a/chrome/browser/ui/panels/panel_browser_frame_view.cc b/chrome/browser/ui/panels/panel_browser_frame_view.cc index ef907fd..3acb5f6 100644 --- a/chrome/browser/ui/panels/panel_browser_frame_view.cc +++ b/chrome/browser/ui/panels/panel_browser_frame_view.cc @@ -560,6 +560,11 @@ int PanelBrowserFrameView::MinimizedPanelHeight() { return kMinimizedPanelHeight; } +gfx::Size PanelBrowserFrameView::NonClientAreaSize() const { + return gfx::Size(NonClientBorderThickness() * 2, + NonClientTopBorderHeight() + NonClientBorderThickness()); +} + SkColor PanelBrowserFrameView::GetTitleColor(PaintState paint_state) const { switch (paint_state) { case PAINT_AS_INACTIVE: diff --git a/chrome/browser/ui/panels/panel_browser_frame_view.h b/chrome/browser/ui/panels/panel_browser_frame_view.h index fa98d54..c454a8b 100644 --- a/chrome/browser/ui/panels/panel_browser_frame_view.h +++ b/chrome/browser/ui/panels/panel_browser_frame_view.h @@ -47,6 +47,10 @@ class PanelBrowserFrameView : public BrowserNonClientFrameView, // Returns the height of the panel in minimized state. static int MinimizedPanelHeight(); + // Returns the size of the non-client area, that is, the window size minus + // the size of the client area. + gfx::Size NonClientAreaSize() const; + protected: // Overridden from BrowserNonClientFrameView: virtual gfx::Rect GetBoundsForTabStrip(views::View* tabstrip) const OVERRIDE; diff --git a/chrome/browser/ui/panels/panel_browser_view.cc b/chrome/browser/ui/panels/panel_browser_view.cc index 470e8fb..f7cada5 100644 --- a/chrome/browser/ui/panels/panel_browser_view.cc +++ b/chrome/browser/ui/panels/panel_browser_view.cc @@ -37,7 +37,7 @@ PanelBrowserView::PanelBrowserView(Browser* browser, Panel* panel, : BrowserView(browser), panel_(panel), bounds_(bounds), - original_height_(bounds.height()), + restored_height_(bounds.height()), closed_(false), focused_(false), mouse_pressed_(false), @@ -82,8 +82,13 @@ bool PanelBrowserView::CanMaximize() const { } void PanelBrowserView::SetBounds(const gfx::Rect& bounds) { + if (bounds_ == bounds) + return; bounds_ = bounds; + if (panel_->expansion_state() == Panel::EXPANDED) + restored_height_ = bounds.height(); + // No animation if the panel is being dragged. if (mouse_dragging_) { ::BrowserView::SetBounds(bounds); @@ -194,7 +199,7 @@ void PanelBrowserView::OnPanelExpansionStateChanged( int height; switch (expansion_state) { case Panel::EXPANDED: - height = original_height_; + height = restored_height_; break; case Panel::TITLE_ONLY: height = GetFrameView()->NonClientTopBorderHeight(); @@ -210,7 +215,7 @@ void PanelBrowserView::OnPanelExpansionStateChanged( break; default: NOTREACHED(); - height = original_height_; + height = restored_height_; break; } @@ -318,6 +323,18 @@ void PanelBrowserView::HandlePanelKeyboardEvent( HandleKeyboardEvent(event); } +gfx::Size PanelBrowserView::GetNonClientAreaExtent() const { + return GetFrameView()->NonClientAreaSize(); +} + +int PanelBrowserView::GetRestoredHeight() const { + return restored_height_; +} + +void PanelBrowserView::SetRestoredHeight(int height) { + restored_height_ = height; +} + Browser* PanelBrowserView::GetPanelBrowser() const { return browser(); } diff --git a/chrome/browser/ui/panels/panel_browser_view.h b/chrome/browser/ui/panels/panel_browser_view.h index c855fd0..d42299c 100644 --- a/chrome/browser/ui/panels/panel_browser_view.h +++ b/chrome/browser/ui/panels/panel_browser_view.h @@ -96,6 +96,9 @@ class PanelBrowserView : public BrowserView, bool* is_keyboard_shortcut) OVERRIDE; virtual void HandlePanelKeyboardEvent( const NativeWebKeyboardEvent& event) OVERRIDE; + virtual gfx::Size GetNonClientAreaExtent() const OVERRIDE; + virtual int GetRestoredHeight() const OVERRIDE; + virtual void SetRestoredHeight(int height) OVERRIDE; virtual Browser* GetPanelBrowser() const OVERRIDE; virtual void DestroyPanelBrowser() OVERRIDE; @@ -109,9 +112,9 @@ class PanelBrowserView : public BrowserView, scoped_ptr<Panel> panel_; gfx::Rect bounds_; - // Stores the original height of the panel so we can restore it after it's + // Stores the full height of the panel so we can restore it after it's // been minimized. - int original_height_; + int restored_height_; // Is the panel being closed? Do not use it when it is closed. bool closed_; diff --git a/chrome/browser/ui/panels/panel_browser_view_browsertest.cc b/chrome/browser/ui/panels/panel_browser_view_browsertest.cc index 834398e..d48f107 100644 --- a/chrome/browser/ui/panels/panel_browser_view_browsertest.cc +++ b/chrome/browser/ui/panels/panel_browser_view_browsertest.cc @@ -13,10 +13,13 @@ #include "chrome/browser/ui/panels/panel_browser_view.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_mouse_watcher_win.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" +#include "chrome/test/base/ui_test_utils.h" #include "grit/generated_resources.h" +#include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/animation/slide_animation.h" @@ -27,6 +30,9 @@ #include "views/controls/link.h" #include "views/controls/textfield/textfield.h" +const FilePath::CharType* kUpdateSizeTestFile = + FILE_PATH_LITERAL("update-preferred-size.html"); + class PanelBrowserViewTest : public BasePanelBrowserTest { public: PanelBrowserViewTest() : BasePanelBrowserTest() { } @@ -386,6 +392,57 @@ class PanelBrowserViewTest : public BasePanelBrowserTest { panel->Close(); } + + void TestUpdatePreferredSize() { + PanelManager::GetInstance()->enable_auto_sizing(true); + + // Create a test panel with tab contents loaded. + CreatePanelParams params("PanelTest1", gfx::Rect(0, 0, 100, 100), + SHOW_AS_ACTIVE); + params.url = GURL(chrome::kAboutBlankURL); + Panel* panel = CreatePanelWithParams(params); + + // Load the test page. + ui_test_utils::NavigateToURL(panel->browser(), + ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory), + FilePath(kUpdateSizeTestFile))); + gfx::Rect initial_bounds = panel->GetBounds(); + EXPECT_EQ(100, initial_bounds.width()); + EXPECT_EQ(100, initial_bounds.height()); + + // Expand the test page. + EXPECT_TRUE(ui_test_utils::ExecuteJavaScript( + panel->browser()->GetSelectedTabContents()->render_view_host(), + std::wstring(), + L"changeSize(50);")); + + // Wait till the bounds get changed. + gfx::Rect bounds_on_grow; + while ((bounds_on_grow = panel->GetBounds()) == initial_bounds) { + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); + MessageLoop::current()->RunAllPending(); + } + EXPECT_GT(bounds_on_grow.width(), initial_bounds.width()); + EXPECT_EQ(bounds_on_grow.height(), initial_bounds.height()); + + // Shrink the test page. + EXPECT_TRUE(ui_test_utils::ExecuteJavaScript( + panel->browser()->GetSelectedTabContents()->render_view_host(), + std::wstring(), + L"changeSize(-30);")); + + // Wait till the bounds get changed. + gfx::Rect bounds_on_shrink; + while ((bounds_on_shrink = panel->GetBounds()) == bounds_on_grow) { + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); + MessageLoop::current()->RunAllPending(); + } + EXPECT_LT(bounds_on_shrink.width(), bounds_on_grow.width()); + EXPECT_GT(bounds_on_shrink.width(), initial_bounds.width()); + EXPECT_EQ(bounds_on_shrink.height(), initial_bounds.height()); + + panel->Close(); + } }; // Panel is not supported for Linux view yet. @@ -535,4 +592,8 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserViewTest, DISABLED_DrawAttention) { IN_PROC_BROWSER_TEST_F(PanelBrowserViewTest, ChangeAutoHideTaskBarThickness) { TestChangeAutoHideTaskBarThickness(); } + +IN_PROC_BROWSER_TEST_F(PanelBrowserViewTest, UpdatePreferredSize) { + TestUpdatePreferredSize(); +} #endif diff --git a/chrome/browser/ui/panels/panel_browser_window_cocoa.h b/chrome/browser/ui/panels/panel_browser_window_cocoa.h index 73620e0d..6c33f92 100644 --- a/chrome/browser/ui/panels/panel_browser_window_cocoa.h +++ b/chrome/browser/ui/panels/panel_browser_window_cocoa.h @@ -52,6 +52,9 @@ class PanelBrowserWindowCocoa : public NativePanel { const NativeWebKeyboardEvent& event) OVERRIDE; virtual Browser* GetPanelBrowser() const OVERRIDE; virtual void DestroyPanelBrowser() OVERRIDE; + virtual gfx::Size GetNonClientAreaExtent() const OVERRIDE; + virtual int GetRestoredHeight() const OVERRIDE; + virtual void SetRestoredHeight(int height) OVERRIDE; Panel* panel() { return panel_.get(); } Browser* browser() const { return browser_.get(); } diff --git a/chrome/browser/ui/panels/panel_browser_window_cocoa.mm b/chrome/browser/ui/panels/panel_browser_window_cocoa.mm index facaf2d..0e97848 100644 --- a/chrome/browser/ui/panels/panel_browser_window_cocoa.mm +++ b/chrome/browser/ui/panels/panel_browser_window_cocoa.mm @@ -197,6 +197,20 @@ void PanelBrowserWindowCocoa::didCloseNativeWindow() { panel_->manager()->Remove(panel_.get()); controller_ = NULL; } +gfx::Size PanelBrowserWindowCocoa::GetNonClientAreaExtent() const { + NOTIMPLEMENTED(); + return gfx::Size(); +} + +int PanelBrowserWindowCocoa::GetRestoredHeight() const { + NOTIMPLEMENTED(); + return 0; +} + +void PanelBrowserWindowCocoa::SetRestoredHeight(int height) { + NOTIMPLEMENTED(); +} + // NativePanelTesting implementation. // static diff --git a/chrome/browser/ui/panels/panel_browser_window_gtk.cc b/chrome/browser/ui/panels/panel_browser_window_gtk.cc index 4f6eb97..f80ff30 100644 --- a/chrome/browser/ui/panels/panel_browser_window_gtk.cc +++ b/chrome/browser/ui/panels/panel_browser_window_gtk.cc @@ -192,6 +192,20 @@ void PanelBrowserWindowGtk::DestroyPanelBrowser() { DestroyBrowser(); } +gfx::Size PanelBrowserWindowGtk::GetNonClientAreaExtent() const { + NOTIMPLEMENTED(); + return gfx::Size(); +} + +int PanelBrowserWindowGtk::GetRestoredHeight() const { + NOTIMPLEMENTED(); + return 0; +} + +void PanelBrowserWindowGtk::SetRestoredHeight(int height) { + NOTIMPLEMENTED(); +} + void PanelBrowserWindowGtk::SetBoundsImpl() { gtk_window_move(window_, bounds_.x(), bounds_.y()); gtk_window_resize(window(), bounds_.width(), bounds_.height()); diff --git a/chrome/browser/ui/panels/panel_browser_window_gtk.h b/chrome/browser/ui/panels/panel_browser_window_gtk.h index c13e2d7..53c90fb 100644 --- a/chrome/browser/ui/panels/panel_browser_window_gtk.h +++ b/chrome/browser/ui/panels/panel_browser_window_gtk.h @@ -64,6 +64,9 @@ class PanelBrowserWindowGtk : public BrowserWindowGtk, const NativeWebKeyboardEvent& event) OVERRIDE; virtual Browser* GetPanelBrowser() const OVERRIDE; virtual void DestroyPanelBrowser() OVERRIDE; + virtual gfx::Size GetNonClientAreaExtent() const OVERRIDE; + virtual int GetRestoredHeight() const OVERRIDE; + virtual void SetRestoredHeight(int height) OVERRIDE; private: void SetBoundsImpl(); diff --git a/chrome/browser/ui/panels/panel_manager.cc b/chrome/browser/ui/panels/panel_manager.cc index 20c0198..ee0d5f9 100644 --- a/chrome/browser/ui/panels/panel_manager.cc +++ b/chrome/browser/ui/panels/panel_manager.cc @@ -17,8 +17,10 @@ namespace { const size_t kInvalidPanelIndex = static_cast<size_t>(-1); // Minimum width and height of a panel. -const int kPanelMinWidthPixels = 64; -const int kPanelMinHeightPixels = 24; +// Note: The minimum size of a widget (see widget.cc) is fixed to 100x100. +// TODO(jianli): Need to fix this to support smaller panel. +const int kPanelMinWidthPixels = 100; +const int kPanelMinHeightPixels = 100; // Default width and height of a panel. const int kPanelDefaultWidthPixels = 240; @@ -50,7 +52,8 @@ PanelManager::PanelManager() : dragging_panel_index_(kInvalidPanelIndex), dragging_panel_original_x_(0), delayed_titlebar_action_(NO_ACTION), - ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { + ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), + auto_sizing_enabled_(true) { auto_hiding_desktop_bar_ = AutoHidingDesktopBar::Create(this); OnDisplayChanged(); } @@ -107,10 +110,8 @@ Panel* PanelManager::CreatePanel(Browser* browser) { height = kPanelDefaultHeightPixels; } - int max_panel_width = - static_cast<int>(adjusted_work_area_.width() * kPanelMaxWidthFactor); - int max_panel_height = - static_cast<int>(adjusted_work_area_.height() * kPanelMaxHeightFactor); + int max_panel_width = GetMaxPanelWidth(); + int max_panel_height = GetMaxPanelHeight(); if (width < kPanelMinWidthPixels) width = kPanelMinWidthPixels; @@ -139,9 +140,19 @@ Panel* PanelManager::CreatePanel(Browser* browser) { Panel* panel = new Panel(browser, gfx::Rect(x, y, width, height)); panels_.push_back(panel); + UpdateMaxSizeForAllPanels(); + return panel; } +int PanelManager::GetMaxPanelWidth() const { + return static_cast<int>(adjusted_work_area_.width() * kPanelMaxWidthFactor); +} + +int PanelManager::GetMaxPanelHeight() const { + return static_cast<int>(adjusted_work_area_.height() * kPanelMaxHeightFactor); +} + int PanelManager::GetRightMostAvaialblePosition() const { return panels_.empty() ? adjusted_work_area_.right() : (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); @@ -303,6 +314,74 @@ void PanelManager::EndDragging(bool cancelled) { DelayedRemove(); } +void PanelManager::OnPreferredWindowSizeChanged( + Panel* panel, const gfx::Size& preferred_window_size) { + if (!auto_sizing_enabled_) + return; + + gfx::Rect bounds = panel->GetBounds(); + int restored_height = panel->GetRestoredHeight(); + + // The panel width: + // * cannot grow or shrink to go beyond [min_width, max_width] + // * cannot grow to take more than the available space and go beyond the left + // of the work area. + int new_width = preferred_window_size.width(); + if (new_width > panel->max_size().width()) + new_width = panel->max_size().width(); + if (new_width < panel->min_size().width()) + new_width = panel->min_size().width(); + + int right_most_available_position = GetRightMostAvaialblePosition(); + if (new_width - bounds.width() > right_most_available_position) + new_width = bounds.width() + right_most_available_position; + + if (new_width != bounds.width()) { + int delta = bounds.width() - new_width; + bounds.set_x(bounds.x() + delta); + bounds.set_width(new_width); + + // Reposition all the panels on the left. + int panel_index = -1; + for (int i = 0; i < static_cast<int>(panels_.size()); ++i) { + if (panels_[i] == panel) { + panel_index = i; + break; + } + } + DCHECK(panel_index >= 0); + for (int i = static_cast<int>(panels_.size()) -1; i > panel_index; + --i) { + gfx::Rect this_bounds = panels_[i]->GetBounds(); + this_bounds.set_x(this_bounds.x() + delta); + panels_[i]->SetPanelBounds(this_bounds); + } + } + + // The panel height: + // * cannot grow or shrink to go beyond [min_height, max_height] + int new_height = preferred_window_size.height(); + if (new_height > panel->max_size().height()) + new_height = panel->max_size().height(); + if (new_height < panel->min_size().height()) + new_height = panel->min_size().height(); + + if (new_height != restored_height) { + // If the panel is not expanded, we only need to save the new restored + // height. + if (panel->expansion_state() == Panel::EXPANDED) { + bounds.set_y(bounds.y() - new_height + bounds.height()); + bounds.set_height(new_height); + } else { + panel->SetRestoredHeight(new_height); + } + } + + panel->SetPanelBounds(bounds); + + UpdateMaxSizeForAllPanels(); +} + bool PanelManager::ShouldBringUpTitlebars(int mouse_x, int mouse_y) const { // We should always bring up the titlebar if the mouse is over the // visible auto-hiding bottom bar. @@ -410,6 +489,7 @@ int PanelManager::GetBottomPositionForExpansionState( bottom += auto_hiding_desktop_bar_->GetThickness( AutoHidingDesktopBar::ALIGN_BOTTOM); } + return bottom; } @@ -450,6 +530,8 @@ void PanelManager::Rearrange(Panels::iterator iter_to_start, rightmost_position = new_bounds.x() - kPanelsHorizontalSpacing; } + + UpdateMaxSizeForAllPanels(); } void PanelManager::RemoveAll() { @@ -468,3 +550,20 @@ void PanelManager::RemoveAll() { bool PanelManager::is_dragging_panel() const { return dragging_panel_index_ != kInvalidPanelIndex; } + +void PanelManager::UpdateMaxSizeForAllPanels() { + if (!auto_sizing_enabled_) + return; + + for (Panels::const_iterator iter = panels_.begin(); + iter != panels_.end(); ++iter) { + Panel* panel = *iter; + // A panel can at most grow to take over all the avaialble space that is + // returned by GetRightMostAvaialblePosition. + int width_can_grow_to = + panel->GetBounds().width() + GetRightMostAvaialblePosition(); + panel->SetMaxSize(gfx::Size( + std::min(width_can_grow_to, GetMaxPanelWidth()), + GetMaxPanelHeight())); + } +} diff --git a/chrome/browser/ui/panels/panel_manager.h b/chrome/browser/ui/panels/panel_manager.h index 998f91f..27d0f5f 100644 --- a/chrome/browser/ui/panels/panel_manager.h +++ b/chrome/browser/ui/panels/panel_manager.h @@ -45,6 +45,11 @@ class PanelManager : public AutoHidingDesktopBar::Observer, void Drag(int delta_x); void EndDragging(bool cancelled); + // Invoked when the preferred window size of the given panel might need to + // get changed. + void OnPreferredWindowSizeChanged( + Panel* panel, const gfx::Size& preferred_window_size); + // Returns true if we should bring up the titlebars, given the current mouse // point. bool ShouldBringUpTitlebars(int mouse_x, int mouse_y) const; @@ -74,6 +79,10 @@ class PanelManager : public AutoHidingDesktopBar::Observer, auto_hiding_desktop_bar_ = auto_hiding_desktop_bar; } + void enable_auto_sizing(bool enabled) { + auto_sizing_enabled_ = enabled; + } + void SetWorkAreaForTesting(const gfx::Rect& work_area) { SetWorkArea(work_area); } @@ -128,8 +137,14 @@ class PanelManager : public AutoHidingDesktopBar::Observer, // Does the real job of bringing up or down the titlebars. void DoBringUpOrDownTitlebars(bool bring_up); + int GetMaxPanelWidth() const; + int GetMaxPanelHeight() const; int GetRightMostAvaialblePosition() const; + // Updates the maximum size of each panel as the result of adding, removing, + // or sizing panels. + void UpdateMaxSizeForAllPanels(); + Panels panels_; // Stores the panels that are pending to remove. We want to delay the removal @@ -164,6 +179,11 @@ class PanelManager : public AutoHidingDesktopBar::Observer, ScopedRunnableMethodFactory<PanelManager> method_factory_; + // Whether or not bounds will be updated when the preferred content size is + // changed. The testing code could set this flag to false so that other tests + // will not be affected. + bool auto_sizing_enabled_; + static const int kPanelsHorizontalSpacing = 4; DISALLOW_COPY_AND_ASSIGN(PanelManager); diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.cc index 492650b..1e13c51 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.cc @@ -222,9 +222,6 @@ void TabContentsViewTouch::RestoreFocus() { } } -void TabContentsViewTouch::UpdatePreferredSize(const gfx::Size& pref_size) { -} - bool TabContentsViewTouch::IsDoingDrag() const { return false; } diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h b/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h index 65ac649..6397668 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h @@ -65,7 +65,6 @@ class TabContentsViewTouch : public TabContentsView, public views::View { virtual void SetInitialFocus() OVERRIDE; virtual void StoreFocus() OVERRIDE; virtual void RestoreFocus() OVERRIDE; - virtual void UpdatePreferredSize(const gfx::Size& pref_size) OVERRIDE; virtual bool IsDoingDrag() const OVERRIDE; virtual void CancelDragAndCloseTab() OVERRIDE; virtual bool IsEventTracking() const OVERRIDE; diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc index ab91362..0eab11bb 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.cc @@ -220,9 +220,6 @@ void TabContentsViewViews::RestoreFocus() { } } -void TabContentsViewViews::UpdatePreferredSize(const gfx::Size& pref_size) { -} - bool TabContentsViewViews::IsDoingDrag() const { return native_tab_contents_view_->IsDoingDrag(); } diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h index 8c6b09e..b41f796 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h +++ b/chrome/browser/ui/views/tab_contents/tab_contents_view_views.h @@ -64,7 +64,6 @@ class TabContentsViewViews : public views::Widget, virtual void SetInitialFocus() OVERRIDE; virtual void StoreFocus() OVERRIDE; virtual void RestoreFocus() OVERRIDE; - virtual void UpdatePreferredSize(const gfx::Size& pref_size) OVERRIDE; virtual bool IsDoingDrag() const OVERRIDE; virtual void CancelDragAndCloseTab() OVERRIDE; virtual bool IsEventTracking() const; diff --git a/chrome/test/data/update-preferred-size.html b/chrome/test/data/update-preferred-size.html new file mode 100644 index 0000000..76e3f3f --- /dev/null +++ b/chrome/test/data/update-preferred-size.html @@ -0,0 +1,18 @@ +<html> + +<head> +<script> +function changeSize(delta) { + var elem = document.getElementById("textInput"); + elem.size = elem.size + delta; +} +</script> +</head> + +<body> + +Hello<br/> +<input id="textInput" type="text" size="5"><br/> + +</body> +</html>
\ No newline at end of file |