diff options
author | jcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-05 19:58:07 +0000 |
---|---|---|
committer | jcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-05 19:58:07 +0000 |
commit | 705243f33047d66a6e0c674041af5dc59073871d (patch) | |
tree | c7d01e2a6b6281455643895369fe3c93032e6cf4 /chrome | |
parent | 377ddd48b5aff4fb231d78fa197f07c933424110 (diff) | |
download | chromium_src-705243f33047d66a6e0c674041af5dc59073871d.zip chromium_src-705243f33047d66a6e0c674041af5dc59073871d.tar.gz chromium_src-705243f33047d66a6e0c674041af5dc59073871d.tar.bz2 |
Make the app launcher bubble fit its contents.
It remains at least as wide as the browser location bar (that way it can always point at the + button).
InfoBubble was modified so it can be resized.
BUG=42260
TEST=Open the app launcher multiple-times. The app launcher
should fit its contents nicely.
Review URL: http://codereview.chromium.org/1739020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46482 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 6 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 3 | ||||
-rw-r--r-- | chrome/browser/notifications/balloon_host.cc | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 4 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_delegate.h | 4 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view.cc | 12 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view.h | 8 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_mac.h | 3 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_mac.mm | 5 | ||||
-rw-r--r-- | chrome/browser/views/app_launcher.cc | 79 | ||||
-rw-r--r-- | chrome/browser/views/app_launcher.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/info_bubble.cc | 108 | ||||
-rw-r--r-- | chrome/browser/views/info_bubble.h | 46 | ||||
-rw-r--r-- | chrome/browser/views/pinned_contents_info_bubble.cc | 32 | ||||
-rw-r--r-- | chrome/browser/views/pinned_contents_info_bubble.h | 14 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 32 |
17 files changed, 235 insertions, 130 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index afe2124..bd78486 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -49,7 +49,7 @@ #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/sync_ui_util_mac.h" #include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_view.h" +#include "chrome/browser/tab_contents/tab_contents_view_mac.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" @@ -566,8 +566,10 @@ if (contents) { // If the intrinsic width is bigger, then make it the zoomed width. const int kScrollbarWidth = 16; // TODO(viettrungluu): ugh. + TabContentsViewMac* tab_contents_view = + static_cast<TabContentsViewMac*>(contents->view()); CGFloat intrinsicWidth = static_cast<CGFloat>( - contents->view()->preferred_width() + kScrollbarWidth); + tab_contents_view->preferred_width() + kScrollbarWidth); zoomedWidth = std::max(zoomedWidth, std::min(intrinsicWidth, frame.size.width)); } diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 71c19613..e62f6bb 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -706,8 +706,7 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) { extension_host_type_ == ViewType::EXTENSION_MOLE || extension_host_type_ == ViewType::EXTENSION_POPUP || extension_host_type_ == ViewType::EXTENSION_INFOBAR) { - render_view_host->Send(new ViewMsg_EnablePreferredSizeChangedMode( - render_view_host->routing_id())); + render_view_host->EnablePreferredSizeChangedMode(); } } diff --git a/chrome/browser/notifications/balloon_host.cc b/chrome/browser/notifications/balloon_host.cc index 9499f4f..da819b0 100644 --- a/chrome/browser/notifications/balloon_host.cc +++ b/chrome/browser/notifications/balloon_host.cc @@ -15,7 +15,6 @@ #include "chrome/common/bindings_policy.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" -#include "chrome/common/render_messages.h" #include "chrome/common/renderer_preferences.h" #include "chrome/common/url_constants.h" @@ -58,8 +57,7 @@ void BalloonHost::Close(RenderViewHost* render_view_host) { } void BalloonHost::RenderViewCreated(RenderViewHost* render_view_host) { - render_view_host->Send(new ViewMsg_EnablePreferredSizeChangedMode( - render_view_host->routing_id())); + render_view_host->EnablePreferredSizeChangedMode(); } void BalloonHost::RenderViewReady(RenderViewHost* render_view_host) { diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 88729ea..c592b81 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1813,6 +1813,10 @@ void RenderViewHost::SendContentSettings(const GURL& url, Send(new ViewMsg_SetContentSettingsForCurrentURL(url, settings)); } +void RenderViewHost::EnablePreferredSizeChangedMode() { + Send(new ViewMsg_EnablePreferredSizeChangedMode(routing_id())); +} + void RenderViewHost::OnExtensionPostMessage( int port_id, const std::string& message) { if (process()->profile()->GetExtensionMessageService()) { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index b384d6d..84dec34 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -460,6 +460,10 @@ class RenderViewHost : public RenderWidgetHost { void SendContentSettings(const GURL& url, const ContentSettings& settings); + // Tells the renderer to notify us when the page contents preferred size + // changed. + void EnablePreferredSizeChangedMode(); + protected: // RenderWidgetHost protected overrides. virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index eb26827..2c153d2 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -286,6 +286,10 @@ class TabContentsDelegate : public AutomationResourceRoutingDelegate { // Returns whether infobars are enabled. Overrideable by child classes. virtual bool infobars_enabled() { return true; } + // Notification that the preferred size of the contents has changed. + // Only called if RenderViewHost::EnablePreferredSizeChangedMode() was called. + virtual void UpdatePreferredSize(const gfx::Size& pref_size) {} + protected: ~TabContentsDelegate() {} }; diff --git a/chrome/browser/tab_contents/tab_contents_view.cc b/chrome/browser/tab_contents/tab_contents_view.cc index b6d45a0..935b96d 100644 --- a/chrome/browser/tab_contents/tab_contents_view.cc +++ b/chrome/browser/tab_contents/tab_contents_view.cc @@ -12,8 +12,7 @@ #include "chrome/browser/tab_contents/tab_contents_delegate.h" TabContentsView::TabContentsView(TabContents* tab_contents) - : tab_contents_(tab_contents), - preferred_width_(0) { + : tab_contents_(tab_contents) { } void TabContentsView::RenderWidgetHostDestroyed(RenderWidgetHost* host) { @@ -26,10 +25,6 @@ void TabContentsView::RenderViewCreated(RenderViewHost* host) { // Default implementation does nothing. Platforms may override. } -void TabContentsView::UpdatePreferredSize(const gfx::Size& pref_size) { - preferred_width_ = pref_size.width(); -} - void TabContentsView::CreateNewWindow( int route_id, WindowContainerType window_container_type) { @@ -72,6 +67,11 @@ bool TabContentsView::PreHandleKeyboardEvent( event, is_keyboard_shortcut); } +void TabContentsView::UpdatePreferredSize(const gfx::Size& pref_size) { + if (tab_contents_->delegate()) + tab_contents_->delegate()->UpdatePreferredSize(pref_size); +} + void TabContentsView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { if (tab_contents_->delegate()) tab_contents_->delegate()->HandleKeyboardEvent(event); diff --git a/chrome/browser/tab_contents/tab_contents_view.h b/chrome/browser/tab_contents/tab_contents_view.h index e9e26b3..e54e19d 100644 --- a/chrome/browser/tab_contents/tab_contents_view.h +++ b/chrome/browser/tab_contents/tab_contents_view.h @@ -130,11 +130,8 @@ class TabContentsView : public RenderViewHostDelegate::View { virtual void HandleMouseEvent() {} virtual void HandleMouseLeave() {} - // Set and return the content's intrinsic width. + // Notification that the preferred size of the contents has changed. virtual void UpdatePreferredSize(const gfx::Size& pref_size); - int preferred_width() const { - return preferred_width_; - } // If we try to close the tab while a drag is in progress, we crash. These // methods allow the tab contents to determine if a drag is in progress and @@ -202,9 +199,6 @@ class TabContentsView : public RenderViewHostDelegate::View { typedef std::map<int, RenderWidgetHostView*> PendingWidgetViews; PendingWidgetViews pending_widget_views_; - // The page content's intrinsic width. - int preferred_width_; - DISALLOW_COPY_AND_ASSIGN(TabContentsView); }; diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.h b/chrome/browser/tab_contents/tab_contents_view_mac.h index 38853ac..91ef23d 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.h +++ b/chrome/browser/tab_contents/tab_contents_view_mac.h @@ -67,6 +67,7 @@ class TabContentsViewMac : public TabContentsView, virtual void SetInitialFocus(); virtual void StoreFocus(); virtual void RestoreFocus(); + virtual void UpdatePreferredSize(const gfx::Size& pref_size); virtual RenderWidgetHostView* CreateNewWidgetInternal( int route_id, WebKit::WebPopupType popup_type); @@ -95,6 +96,8 @@ class TabContentsViewMac : public TabContentsView, // CloseTabAfterEventTracking() implementation. void CloseTab(); + int preferred_width() const { return preferred_width_; } + private: // The Cocoa NSView that lives in the view hierarchy. scoped_nsobject<TabContentsViewCocoa> cocoa_view_; diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 495ac24..9e8b70d 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -219,6 +219,11 @@ void TabContentsViewMac::RestoreFocus() { focus_tracker_.reset(nil); } +void TabContentsViewMac::UpdatePreferredSize(const gfx::Size& pref_size) { + preferred_width_ = pref_size.width(); + TabContentsView::UpdatePreferredSize(pref_size); +} + void TabContentsViewMac::UpdateDragCursor(WebDragOperation operation) { [cocoa_view_ setCurrentDragOperation: operation]; } diff --git a/chrome/browser/views/app_launcher.cc b/chrome/browser/views/app_launcher.cc index 20379f5..4970f15 100644 --- a/chrome/browser/views/app_launcher.cc +++ b/chrome/browser/views/app_launcher.cc @@ -16,6 +16,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/dom_view.h" @@ -31,20 +32,13 @@ namespace { -// Padding & margins for the navigation entry. -const int kNavigationEntryPadding = 2; -const int kNavigationEntryXMargin = 3; -const int kNavigationEntryYMargin = 1; - // Padding between the navigation bar and the render view contents. const int kNavigationBarBottomPadding = 3; // NavigationBar constants. -const int kNavigationBarHeight = 23; const int kNavigationBarBorderThickness = 1; -// The delta applied to the default font size for the Omnibox. -const int kAutocompleteEditFontDelta = 3; +const SkColor kBorderColor = SkColorSetRGB(205, 201, 201); // Command line switch for specifying url of the page. // TODO: nuke when we convert to the real app page. Also nuke code in @@ -60,6 +54,14 @@ static GURL GetMenuURL() { return GURL(chrome::kChromeUIAppLauncherURL); } +// Returns the location bar view of |browser|. +static views::View* GetBrowserLocationBar(Browser* browser) { + BrowserView* browser_view = static_cast<BrowserView*>(browser->window()); + views::RootView* root_view = views::Widget::GetWidgetFromNativeWindow( + browser_view->GetNativeHandle())->GetRootView(); + return root_view->GetViewByID(VIEW_ID_LOCATION_BAR); +} + } // namespace // InfoBubbleContentsView @@ -74,6 +76,10 @@ class InfoBubbleContentsView : public views::View, explicit InfoBubbleContentsView(AppLauncher* app_launcher); ~InfoBubbleContentsView(); + // Computes and sets the preferred size for the InfoBubbleContentsView based + // on the preferred size of the DOMUI contents specified. + void ComputePreferredSize(const gfx::Size& dom_view_preferred_size); + // Sets the initial focus. // Should be called when the bubble that contains us is shown. void BubbleShown(); @@ -102,9 +108,15 @@ class InfoBubbleContentsView : public views::View, // The view containing the renderer view. DOMView* dom_view_; + // The preferred size for this view (at which it fits its contents). + gfx::Size preferred_size_; + // CommandUpdater the location bar sends commands to. CommandUpdater command_updater_; + // The width of the browser's location bar. + int browser_location_bar_width_; + DISALLOW_COPY_AND_ASSIGN(InfoBubbleContentsView); }; @@ -116,11 +128,27 @@ InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher) // Allow the location bar to open URLs. command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, true); DCHECK(app_launcher); + + browser_location_bar_width_ = + GetBrowserLocationBar(app_launcher->browser())->width(); } InfoBubbleContentsView::~InfoBubbleContentsView() { } +void InfoBubbleContentsView::ComputePreferredSize( + const gfx::Size& dom_view_preferred_size) { + preferred_size_ = dom_view_preferred_size; + + // Add the padding and location bar height. + preferred_size_.Enlarge( + 0, location_bar_->height() + kNavigationBarBottomPadding); + + // Make sure the width is at least the browser location bar width. + if (preferred_size_.width() < browser_location_bar_width_) + preferred_size_.set_width(browser_location_bar_width_); +} + void InfoBubbleContentsView::BubbleShown() { location_bar_->RequestFocus(); } @@ -138,7 +166,8 @@ void InfoBubbleContentsView::ViewHierarchyChanged( // We make the AppLauncher the TabContents delegate so we get notifications // from the page to open links. dom_view_->tab_contents()->set_delegate(app_launcher_); - + dom_view_->tab_contents()->render_view_host()-> + EnablePreferredSizeChangedMode(); GURL url = GetMenuURL(); std::string ref = url.ref(); if (!app_launcher_->hash_params().empty()) { @@ -160,9 +189,15 @@ void InfoBubbleContentsView::ViewHierarchyChanged( LocationBarView::APP_LAUNCHER); location_bar_->set_border( - views::Border::CreateSolidBorder(1, SkColorSetRGB(205, 201, 201))); + views::Border::CreateSolidBorder(kNavigationBarBorderThickness, + kBorderColor)); AddChildView(location_bar_); location_bar_->Init(); + // Size the location to its preferred size so ComputePreferredSize() computes + // the right size. + location_bar_->SizeToPreferredSize(); + ComputePreferredSize(gfx::Size(browser_location_bar_width_, 0)); + Layout(); } TabContents* InfoBubbleContentsView::GetTabContents() { @@ -170,8 +205,7 @@ TabContents* InfoBubbleContentsView::GetTabContents() { } gfx::Size InfoBubbleContentsView::GetPreferredSize() { - gfx::Rect bounds = app_launcher_->browser()->window()->GetRestoredBounds(); - return gfx::Size(bounds.width() * 6 / 7, bounds.height() * 9 / 10); + return preferred_size_; } void InfoBubbleContentsView::Layout() { @@ -179,14 +213,12 @@ void InfoBubbleContentsView::Layout() { return; gfx::Rect bounds = GetLocalBounds(false); - location_bar_->SetBounds(bounds.x(), bounds.y(), bounds.width(), location_bar_->GetPreferredSize().height()); int render_y = location_bar_->bounds().bottom() + kNavigationBarBottomPadding; - gfx::Size dom_view_size = - gfx::Size(width(), std::max(0, bounds.height() - render_y + bounds.y())); - dom_view_->SetBounds(bounds.x(), render_y, - dom_view_size.width(), dom_view_size.height()); + dom_view_->SetBounds(0, render_y, + width(), + std::max(0, bounds.height() - render_y + bounds.y())); } void InfoBubbleContentsView::ExecuteCommand(int id) { @@ -240,9 +272,7 @@ AppLauncher* AppLauncher::ShowForNewTab(Browser* browser, // Figure out where the location bar is, so we can pin the bubble to // make our url bar appear exactly over it. - views::RootView* root_view = views::Widget::GetWidgetFromNativeWindow( - browser_view->GetNativeHandle())->GetRootView(); - views::View* location_bar = root_view->GetViewByID(VIEW_ID_LOCATION_BAR); + views::View* location_bar = GetBrowserLocationBar(browser); gfx::Point location_bar_origin = location_bar->bounds().origin(); views::RootView::ConvertPointToScreen(location_bar->GetParent(), &location_bar_origin); @@ -281,6 +311,15 @@ void AppLauncher::AddNewContents(TabContents* source, #endif } +void AppLauncher::UpdatePreferredSize(const gfx::Size& pref_size) { + if (pref_size.width() == 0 || pref_size.height() == 0) + return; + + gfx::Size size(pref_size); + info_bubble_content_->ComputePreferredSize(size); + info_bubble_->SizeToContents(); +} + void AppLauncher::InfoBubbleClosing(InfoBubble* info_bubble, bool closed_by_escape) { // Delay deleting to be safe (we, and our tabcontents may be on the stack). diff --git a/chrome/browser/views/app_launcher.h b/chrome/browser/views/app_launcher.h index 2b5f429..9104b98 100644 --- a/chrome/browser/views/app_launcher.h +++ b/chrome/browser/views/app_launcher.h @@ -97,6 +97,7 @@ class AppLauncher : public InfoBubbleDelegate, virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {} virtual void URLStarredChanged(TabContents* source, bool starred) {} virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} + virtual void UpdatePreferredSize(const gfx::Size& pref_size); private: friend class DeleteTask<AppLauncher>; diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc index be5174c..3a69a1b 100644 --- a/chrome/browser/views/info_bubble.cc +++ b/chrome/browser/views/info_bubble.cc @@ -30,25 +30,25 @@ const SkColor InfoBubble::kBackgroundColor = const SkColor InfoBubble::kBackgroundColor = SK_ColorWHITE; #endif -void BorderContents::InitAndGetBounds( +void BorderContents::Init() { + DCHECK(!bubble_border_); + bubble_border_ = new BubbleBorder(); + set_border(bubble_border_); + bubble_border_->set_background_color(InfoBubble::kBackgroundColor); +} + +void BorderContents::SizeAndGetBounds( const gfx::Rect& position_relative_to, const gfx::Size& contents_size, bool prefer_arrow_on_right, gfx::Rect* contents_bounds, gfx::Rect* window_bounds) { - // Set the border. - if (!bubble_border_) - bubble_border_ = new BubbleBorder; - set_border(bubble_border_); - bubble_border_->set_background_color(InfoBubble::kBackgroundColor); - // Give the contents a margin. gfx::Size local_contents_size(contents_size); local_contents_size.Enlarge(kLeftMargin + kRightMargin, kTopMargin + kBottomMargin); - // Try putting the arrow in its initial location, and calculating the - // bounds. + // Try putting the arrow in its initial location, and calculating the bounds. BubbleBorder::ArrowLocation arrow_location(prefer_arrow_on_right ? BubbleBorder::TOP_RIGHT : BubbleBorder::TOP_LEFT); bubble_border_->set_arrow_location(arrow_location); @@ -121,25 +121,28 @@ BorderWidget::BorderWidget() : border_contents_(NULL) { set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED); } -gfx::Rect BorderWidget::InitAndGetBounds( - HWND owner, + +void BorderWidget::Init(HWND owner) { + DCHECK(!border_contents_); + border_contents_ = CreateBorderContents(); + border_contents_->Init(); + WidgetWin::Init(GetAncestor(owner, GA_ROOT), gfx::Rect()); + SetContentsView(border_contents_); + SetWindowPos(owner, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW); +} + +gfx::Rect BorderWidget::SizeAndGetBounds( const gfx::Rect& position_relative_to, const gfx::Size& contents_size, bool prefer_arrow_on_right) { - // Set up the border view and ask it to calculate our bounds (and our - // contents'). - if (!border_contents_) - border_contents_ = new BorderContents; - gfx::Rect contents_bounds, window_bounds; - border_contents_->InitAndGetBounds(position_relative_to, contents_size, + // Ask the border view to calculate our bounds (and our contents'). + gfx::Rect contents_bounds; + gfx::Rect window_bounds; + border_contents_->SizeAndGetBounds(position_relative_to, contents_size, prefer_arrow_on_right, &contents_bounds, &window_bounds); - - // Initialize ourselves. - WidgetWin::Init(GetAncestor(owner, GA_ROOT), window_bounds); - SetContentsView(border_contents_); - SetWindowPos(owner, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW); + SetBounds(window_bounds); // Chop a hole out of our region to show the contents through. // CreateRectRgn() expects (left, top, right, bottom) in window coordinates. @@ -156,6 +159,10 @@ gfx::Rect BorderWidget::InitAndGetBounds( return contents_bounds; } +BorderContents* BorderWidget::CreateBorderContents() { + return new BorderContents(); +} + LRESULT BorderWidget::OnMouseActivate(HWND window, UINT hit_test, UINT mouse_message) { @@ -184,6 +191,7 @@ InfoBubble::InfoBubble() : #if defined(OS_LINUX) WidgetGtk(TYPE_WINDOW), + border_contents_(NULL), #endif delegate_(NULL), parent_(NULL), @@ -196,6 +204,8 @@ void InfoBubble::Init(views::Window* parent, InfoBubbleDelegate* delegate) { parent_ = parent; delegate_ = delegate; + position_relative_to_ = position_relative_to; + contents_ = contents; // Create the main window. #if defined(OS_WIN) @@ -234,12 +244,14 @@ void InfoBubble::Init(views::Window* parent, (contents->UILayoutIsRightToLeft() == delegate->PreferOriginSideAnchor()); #if defined(OS_WIN) - if (!border_.get()) - border_.reset(new BorderWidget); + DCHECK(!border_.get()); + border_.reset(CreateBorderWidget()); + border_->Init(GetNativeView()); + // Initialize and position the border window. - window_bounds = border_->InitAndGetBounds(GetNativeView(), - position_relative_to, contents->GetPreferredSize(), - prefer_arrow_on_right); + window_bounds = border_->SizeAndGetBounds(position_relative_to, + contents->GetPreferredSize(), + prefer_arrow_on_right); // Make |contents| take up the entire contents view. contents_view->SetLayoutManager(new views::FillLayout); @@ -249,17 +261,18 @@ void InfoBubble::Init(views::Window* parent, views::Background::CreateSolidBackground(kBackgroundColor)); #else // Create a view to paint the border and background. - BorderContents* border_contents = new BorderContents; + border_contents_ = new BorderContents; + border_contents_->Init(); gfx::Rect contents_bounds; - border_contents->InitAndGetBounds(position_relative_to, + border_contents_->SizeAndGetBounds(position_relative_to, contents->GetPreferredSize(), prefer_arrow_on_right, &contents_bounds, &window_bounds); // This new view must be added before |contents| so it will paint under it. - contents_view->AddChildView(0, border_contents); + contents_view->AddChildView(0, border_contents_); // |contents_view| has no layout manager, so we have to explicitly position // its children. - border_contents->SetBounds(gfx::Rect(gfx::Point(), window_bounds.size())); + border_contents_->SetBounds(gfx::Rect(gfx::Point(), window_bounds.size())); contents->SetBounds(contents_bounds); #endif SetBounds(window_bounds); @@ -283,6 +296,37 @@ void InfoBubble::Init(views::Window* parent, } #if defined(OS_WIN) +BorderWidget* InfoBubble::CreateBorderWidget() { + return new BorderWidget; +} +#endif + +void InfoBubble::SizeToContents() { + gfx::Rect window_bounds; + + bool prefer_arrow_on_right = delegate_ && + (contents_->UILayoutIsRightToLeft() == + delegate_->PreferOriginSideAnchor()); + +#if defined(OS_WIN) + // Initialize and position the border window. + window_bounds = border_->SizeAndGetBounds(position_relative_to_, + contents_->GetPreferredSize(), + prefer_arrow_on_right); +#else + gfx::Rect contents_bounds; + border_contents_->SizeAndGetBounds(position_relative_to_, + contents_->GetPreferredSize(), prefer_arrow_on_right, + &contents_bounds, &window_bounds); + // |contents_view| has no layout manager, so we have to explicitly position + // its children. + border_contents_->SetBounds(gfx::Rect(gfx::Point(), window_bounds.size())); + contents_->SetBounds(contents_bounds); +#endif + SetBounds(window_bounds); +} + +#if defined(OS_WIN) void InfoBubble::OnActivate(UINT action, BOOL minimized, HWND window) { // The popup should close when it is deactivated. if (action == WA_INACTIVE && !closed_) { diff --git a/chrome/browser/views/info_bubble.h b/chrome/browser/views/info_bubble.h index ea80b0f..4b76507 100644 --- a/chrome/browser/views/info_bubble.h +++ b/chrome/browser/views/info_bubble.h @@ -23,7 +23,9 @@ // InfoBubble insets the contents for you, so the contents typically shouldn't // have any additional margins. +#if defined(OS_WIN) class BorderWidget; +#endif class BubbleBorder; class InfoBubble; @@ -41,16 +43,18 @@ class BorderContents : public views::View { public: BorderContents() : bubble_border_(NULL) { } - // Given the size of the contents and the rect to point at, initializes the - // bubble and returns the bounds of both the border - // and the contents inside the bubble. + // Must be called before this object can be used. + void Init(); + + // Given the size of the contents and the rect to point at, returns the bounds + // of both the border and the contents inside the bubble. // |prefer_arrow_on_right| specifies the preferred location for the arrow // anchor. If the bubble does not fit on the monitor, the arrow location may // changed so it can. // // TODO(pkasting): Maybe this should use mirroring transformations instead, // which would hopefully simplify this code. - virtual void InitAndGetBounds( + virtual void SizeAndGetBounds( const gfx::Rect& position_relative_to, // In screen coordinates const gfx::Size& contents_size, bool prefer_arrow_on_right, @@ -86,17 +90,23 @@ class BorderWidget : public views::WidgetWin { BorderWidget(); virtual ~BorderWidget() { } - // Given the owning (parent) window, the size of the contained contents - // (without margins), and the rect (in screen coordinates) to point to, - // initializes the window and returns the bounds (in screen coordinates) the + // Initializes the BrowserWidget making |owner| its owning window. + void Init(HWND owner); + + // Given the size of the contained contents (without margins), and the rect + // (in screen coordinates) to point to, sets the border window positions and + // sizes the border window and returns the bounds (in screen coordinates) the // contents should use. |is_rtl| is supplied to // BorderContents::InitAndGetBounds(), see its declaration for details. - virtual gfx::Rect InitAndGetBounds(HWND owner, - const gfx::Rect& position_relative_to, + virtual gfx::Rect SizeAndGetBounds(const gfx::Rect& position_relative_to, const gfx::Size& contents_size, bool is_rtl); protected: + // Instanciates and returns the BorderContents this BorderWidget should use. + // Subclasses can return their own BorderContents implementation. + virtual BorderContents* CreateBorderContents(); + BorderContents* border_contents_; private: @@ -155,6 +165,10 @@ class InfoBubble views::View* contents, InfoBubbleDelegate* delegate); + // Resizes and potentially moves the InfoBubble to best accomodate the + // contents preferred size. + void SizeToContents(); + // Overridden from WidgetWin: virtual void Close(); @@ -171,6 +185,12 @@ class InfoBubble InfoBubbleDelegate* delegate); #if defined(OS_WIN) + // Instanciates and returns the BorderWidget this InfoBubble should use. + // Subclasses can return their own BorderWidget specialization. + virtual BorderWidget* CreateBorderWidget(); +#endif + +#if defined(OS_WIN) // Overridden from WidgetWin: virtual void OnActivate(UINT action, BOOL minimized, HWND window); #elif defined(OS_LINUX) @@ -181,6 +201,9 @@ class InfoBubble #if defined(OS_WIN) // The window used to render the padding, border and arrow. scoped_ptr<BorderWidget> border_; +#elif defined(OS_LINUX) + // The view displaying the border. + BorderContents* border_contents_; #endif private: @@ -200,6 +223,11 @@ class InfoBubble // Have we been closed? bool closed_; + gfx::Rect position_relative_to_; + + views::View* contents_; + + DISALLOW_COPY_AND_ASSIGN(InfoBubble); }; diff --git a/chrome/browser/views/pinned_contents_info_bubble.cc b/chrome/browser/views/pinned_contents_info_bubble.cc index 8331db1..a4edcf1 100644 --- a/chrome/browser/views/pinned_contents_info_bubble.cc +++ b/chrome/browser/views/pinned_contents_info_bubble.cc @@ -5,18 +5,17 @@ #include "chrome/browser/views/pinned_contents_info_bubble.h" #include "chrome/browser/views/bubble_border.h" +#include "views/window/window.h" #if defined(OS_WIN) // BorderWidget --------------------------------------------------------------- -void PinnedContentsBorderContents::InitAndGetBounds( +void PinnedContentsBorderContents::SizeAndGetBounds( const gfx::Rect& position_relative_to, const gfx::Size& contents_size, bool prefer_arrow_on_right, gfx::Rect* contents_bounds, gfx::Rect* window_bounds) { - bubble_border_ = new BubbleBorder; - // Arrow offset is calculated from the middle of the |position_relative_to|. int offset = position_relative_to.x() + (position_relative_to.width() / 2); offset -= bubble_anchor_.x(); @@ -26,7 +25,7 @@ void PinnedContentsBorderContents::InitAndGetBounds( offset += kLeftMargin + insets.left() + 1; bubble_border_->set_arrow_offset(offset); - BorderContents::InitAndGetBounds( + BorderContents::SizeAndGetBounds( position_relative_to, contents_size, prefer_arrow_on_right, contents_bounds, window_bounds); @@ -34,15 +33,8 @@ void PinnedContentsBorderContents::InitAndGetBounds( window_bounds->Offset(0, -(kTopMargin + 1)); } -gfx::Rect PinnedContentsBorderWidget::InitAndGetBounds( - HWND owner, - const gfx::Rect& position_relative_to, - const gfx::Size& contents_size, - bool prefer_arrow_on_right) { - border_contents_ = new PinnedContentsBorderContents(bubble_anchor_); - return BorderWidget::InitAndGetBounds( - owner, position_relative_to, contents_size, - prefer_arrow_on_right); +BorderContents* PinnedContentsBorderWidget::CreateBorderContents() { + return new PinnedContentsBorderContents(bubble_anchor_); } #endif @@ -61,14 +53,10 @@ PinnedContentsInfoBubble* PinnedContentsInfoBubble::Show( return window; } -void PinnedContentsInfoBubble::Init(views::Window* parent, - const gfx::Rect& position_relative_to, - views::View* contents, - InfoBubbleDelegate* delegate) { -// TODO(finnur): This needs to be implemented for other platforms once we -// decide this is the way to go. +// TODO(finnur): This needs to be implemented for other platforms once we decide +// this is the way to go. #if defined(OS_WIN) - border_.reset(new PinnedContentsBorderWidget(bubble_anchor_)); -#endif - InfoBubble::Init(parent, position_relative_to, contents, delegate); +BorderWidget* PinnedContentsInfoBubble::CreateBorderWidget() { + return new PinnedContentsBorderWidget(bubble_anchor_); } +#endif diff --git a/chrome/browser/views/pinned_contents_info_bubble.h b/chrome/browser/views/pinned_contents_info_bubble.h index 92477c0..7ceb89b 100644 --- a/chrome/browser/views/pinned_contents_info_bubble.h +++ b/chrome/browser/views/pinned_contents_info_bubble.h @@ -16,7 +16,7 @@ class PinnedContentsBorderContents : public BorderContents { : bubble_anchor_(bubble_anchor) {} // BorderContents overrides: - virtual void InitAndGetBounds( + virtual void SizeAndGetBounds( const gfx::Rect& position_relative_to, // In screen coordinates const gfx::Size& contents_size, bool prefer_arrow_on_right, @@ -39,10 +39,7 @@ class PinnedContentsBorderWidget : public BorderWidget { virtual ~PinnedContentsBorderWidget() {} // BorderWidget overrides: - virtual gfx::Rect InitAndGetBounds(HWND owner, - const gfx::Rect& position_relative_to, - const gfx::Size& contents_size, - bool is_rtl); + virtual BorderContents* CreateBorderContents(); private: // The location of the pinned contents (in screen coordinates). @@ -75,10 +72,9 @@ class PinnedContentsInfoBubble : public InfoBubble { virtual ~PinnedContentsInfoBubble() {} // InfoBubble overrides: - virtual void Init(views::Window* parent, - const gfx::Rect& position_relative_to, - views::View* contents, - InfoBubbleDelegate* delegate); +#if defined(OS_WIN) + virtual BorderWidget* CreateBorderWidget(); +#endif // The location of the pinned contents (in screen coordinates). const gfx::Point bubble_anchor_; diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 4ef4983..33238d6 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2975,25 +2975,20 @@ void RenderView::CheckPreferredSize() { // We don't always want to send the change messages over IPC, only if we've // be put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode| // message. - if (send_preferred_size_changes_) { - if (!webview()) - return; - - // WebCore likes to tell us things have changed even when they haven't, so - // cache the width and height and only send the IPC message when we're sure - // they're different. - int width = webview()->mainFrame()->contentsPreferredWidth(); - int height = webview()->mainFrame()->documentElementScrollHeight(); + if (!send_preferred_size_changes_ || !webview()) + return; - if (width != preferred_size_.width() || - height != preferred_size_.height()) { - preferred_size_.set_width(width); - preferred_size_.set_height(height); + // WebCore likes to tell us things have changed even when they haven't, so + // cache the width and height and only send the IPC message when we're sure + // they're different. + gfx::Size size(webview()->mainFrame()->contentsPreferredWidth(), + webview()->mainFrame()->documentElementScrollHeight()); + if (size == preferred_size_) + return; - Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_, - preferred_size_)); - } - } + preferred_size_ = size; + Send(new ViewHostMsg_DidContentsPreferredSizeChange(routing_id_, + preferred_size_)); } void RenderView::didChangeScrollOffset(WebFrame* frame) { @@ -3021,7 +3016,7 @@ void RenderView::reportFindInPageMatchCount(int request_id, int count, request_id, count, gfx::Rect(), - -1, // // Don't update active match ordinal. + -1, // Don't update active match ordinal. final_update)); } } @@ -3825,6 +3820,7 @@ void RenderView::OnEnableViewSourceMode() { } void RenderView::OnEnablePreferredSizeChangedMode() { + DCHECK(!send_preferred_size_changes_); send_preferred_size_changes_ = true; if (ViewType::ShouldAutoResize(view_type_)) |