summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-05 19:58:07 +0000
committerjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-05 19:58:07 +0000
commit705243f33047d66a6e0c674041af5dc59073871d (patch)
treec7d01e2a6b6281455643895369fe3c93032e6cf4 /chrome
parent377ddd48b5aff4fb231d78fa197f07c933424110 (diff)
downloadchromium_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.mm6
-rw-r--r--chrome/browser/extensions/extension_host.cc3
-rw-r--r--chrome/browser/notifications/balloon_host.cc4
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc4
-rw-r--r--chrome/browser/renderer_host/render_view_host.h4
-rw-r--r--chrome/browser/tab_contents/tab_contents_delegate.h4
-rw-r--r--chrome/browser/tab_contents/tab_contents_view.cc12
-rw-r--r--chrome/browser/tab_contents/tab_contents_view.h8
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.h3
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_mac.mm5
-rw-r--r--chrome/browser/views/app_launcher.cc79
-rw-r--r--chrome/browser/views/app_launcher.h1
-rw-r--r--chrome/browser/views/info_bubble.cc108
-rw-r--r--chrome/browser/views/info_bubble.h46
-rw-r--r--chrome/browser/views/pinned_contents_info_bubble.cc32
-rw-r--r--chrome/browser/views/pinned_contents_info_bubble.h14
-rw-r--r--chrome/renderer/render_view.cc32
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_))