diff options
author | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-12 20:27:10 +0000 |
---|---|---|
committer | twiz@chromium.org <twiz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-12 20:27:10 +0000 |
commit | c7bf140b32a1a6504e48716b90c6a13fd5c421d3 (patch) | |
tree | 876ada1f8ca6320060aab4db3790522989829d31 | |
parent | 1be7eadb032256687abda35ae4b2ba4770757c70 (diff) | |
download | chromium_src-c7bf140b32a1a6504e48716b90c6a13fd5c421d3.zip chromium_src-c7bf140b32a1a6504e48716b90c6a13fd5c421d3.tar.gz chromium_src-c7bf140b32a1a6504e48716b90c6a13fd5c421d3.tar.bz2 |
Clone of issue 577015.
See http://codereview.chromium.org/577015 for the review status of this CL.
BUG=None
TEST=ExtensionApiTest.Popup
Review URL: http://codereview.chromium.org/600101
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38927 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/win/window_impl.h | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_popup_api.cc | 19 | ||||
-rw-r--r-- | chrome/browser/views/browser_actions_container.cc | 16 | ||||
-rw-r--r-- | chrome/browser/views/browser_bubble.cc | 5 | ||||
-rw-r--r-- | chrome/browser/views/browser_bubble.h | 8 | ||||
-rw-r--r-- | chrome/browser/views/browser_bubble_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/browser_bubble_win.cc | 5 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_popup.cc | 157 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_popup.h | 31 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_shelf.cc | 3 | ||||
-rw-r--r-- | chrome/browser/views/location_bar_view.cc | 16 | ||||
-rwxr-xr-x | chrome/common/extensions/api/extension_api.json | 6 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 8 | ||||
-rw-r--r-- | chrome/test/data/extensions/api_test/popup/toolband.html | 14 | ||||
-rw-r--r-- | views/controls/native/native_view_host.cc | 11 |
15 files changed, 231 insertions, 74 deletions
diff --git a/app/win/window_impl.h b/app/win/window_impl.h index fb5d512..2f6a2ab 100644 --- a/app/win/window_impl.h +++ b/app/win/window_impl.h @@ -68,7 +68,7 @@ class WindowImpl : public MessageMapInterface { DCHECK_EQ((class_style & CS_GLOBALCLASS), 0); class_style_ = class_style; } - UINT initial_class_style() { return class_style_; } + UINT initial_class_style() const { return class_style_; } protected: // Handles the WndProc callback for this object. diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc index f68553c..48e414c 100644 --- a/chrome/browser/extensions/extension_popup_api.cc +++ b/chrome/browser/extensions/extension_popup_api.cc @@ -44,6 +44,10 @@ const wchar_t kTopKey[] = L"top"; const wchar_t kLeftKey[] = L"left"; const wchar_t kGiveFocusKey[] = L"giveFocus"; const wchar_t kDomAnchorKey[] = L"domAnchor"; +const wchar_t kBorderStyleKey[] = L"borderStyle"; + +// chrome enumeration values +const char kRectangleChrome[] = "rectangle"; }; // namespace @@ -111,6 +115,18 @@ bool PopupShowFunction::RunImpl() { &give_focus)); } +#if defined(TOOLKIT_VIEWS) + // The default behaviour is to provide the bubble-chrome to the popup. + ExtensionPopup::PopupChrome chrome = ExtensionPopup::BUBBLE_CHROME; + if (show_details->HasKey(kBorderStyleKey)) { + std::string chrome_string; + EXTENSION_FUNCTION_VALIDATE(show_details->GetString(kBorderStyleKey, + &chrome_string)); + if (chrome_string == kRectangleChrome) + chrome = ExtensionPopup::RECTANGLE_CHROME; + } +#endif + GURL url = dispatcher()->url().Resolve(url_string); if (!url.is_valid()) { error_ = kInvalidURLError; @@ -144,7 +160,8 @@ bool PopupShowFunction::RunImpl() { dispatcher()->GetFrameNativeWindow(), rect, arrow_location, - give_focus); + give_focus, + chrome); ExtensionPopupHost* popup_host = dispatcher()->GetPopupHost(); DCHECK(popup_host); diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc index 5a1ae90..be8cf1b 100644 --- a/chrome/browser/views/browser_actions_container.cc +++ b/chrome/browser/views/browser_actions_container.cc @@ -534,13 +534,15 @@ void BrowserActionsContainer::OnBrowserActionExecuted( BubbleBorder::ArrowLocation arrow_location = UILayoutIsRightToLeft() ? BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT; - popup_ = ExtensionPopup::Show(button->GetPopupUrl(), - browser_, - browser_->profile(), - frame_window, - rect, - arrow_location, - true); // Activate the popup window. + popup_ = ExtensionPopup::Show( + button->GetPopupUrl(), + browser_, + browser_->profile(), + frame_window, + rect, + arrow_location, + true, // Activate the popup window. + ExtensionPopup::BUBBLE_CHROME); popup_->set_delegate(this); popup_button_ = button; popup_button_->SetButtonPushed(); diff --git a/chrome/browser/views/browser_bubble.cc b/chrome/browser/views/browser_bubble.cc index 26dff82..1b690db 100644 --- a/chrome/browser/views/browser_bubble.cc +++ b/chrome/browser/views/browser_bubble.cc @@ -25,12 +25,13 @@ BrowserView* GetBrowserViewFromFrame(views::Widget* frame) { } // namespace BrowserBubble::BrowserBubble(views::View* view, views::Widget* frame, - const gfx::Point& origin) + const gfx::Point& origin, bool drop_shadow) : frame_(frame), view_(view), visible_(false), delegate_(NULL), - attached_(false) { + attached_(false), + drop_shadow_enabled_(drop_shadow) { gfx::Size size = view->GetPreferredSize(); bounds_.SetRect(origin.x(), origin.y(), size.width(), size.height()); InitPopup(); diff --git a/chrome/browser/views/browser_bubble.h b/chrome/browser/views/browser_bubble.h index 25b91e9..012c552 100644 --- a/chrome/browser/views/browser_bubble.h +++ b/chrome/browser/views/browser_bubble.h @@ -38,9 +38,10 @@ class BrowserBubble { // Note that the bubble will size itself to the preferred size of |view|. // |view| is the embedded view, |frame| is widget that the bubble is being // positioned relative to, |origin| is the location that the bubble will - // be positioned relative to |frame|. + // be positioned relative to |frame|. Pass true through |drop_shadow| to + // surround the bubble widget with a drop-shadow. BrowserBubble(views::View* view, views::Widget* frame, - const gfx::Point& origin); + const gfx::Point& origin, bool drop_shadow); virtual ~BrowserBubble(); // Call manually if you need to detach the bubble from tracking the browser's @@ -116,6 +117,9 @@ class BrowserBubble { // Is the bubble attached to a Browser window. bool attached_; + // Does the bubble have a drop-shadow. + bool drop_shadow_enabled_; + DISALLOW_COPY_AND_ASSIGN(BrowserBubble); }; diff --git a/chrome/browser/views/browser_bubble_gtk.cc b/chrome/browser/views/browser_bubble_gtk.cc index ebc343a..66b07c1 100644 --- a/chrome/browser/views/browser_bubble_gtk.cc +++ b/chrome/browser/views/browser_bubble_gtk.cc @@ -76,6 +76,10 @@ class BubbleWidget : public views::WidgetGtk { } // namespace void BrowserBubble::InitPopup() { + // TODO(port) + DCHECK(!drop_shadow_enabled_) << + "Drop shadows not supported on GTK browser bubbles."; + views::WidgetGtk* pop = new BubbleWidget(this); pop->SetOpacity(0xFF); pop->make_transient_to_parent(); diff --git a/chrome/browser/views/browser_bubble_win.cc b/chrome/browser/views/browser_bubble_win.cc index 2a2a4c2..a74b84a 100644 --- a/chrome/browser/views/browser_bubble_win.cc +++ b/chrome/browser/views/browser_bubble_win.cc @@ -79,6 +79,11 @@ void BrowserBubble::InitPopup() { // popup_ is a Widget, but we need to do some WidgetWin stuff first, then // we'll assign it into popup_. views::WidgetWin* pop = new BubbleWidget(this); + + // Enable the drop-shadow through the native windows drop-shadow support. + if (drop_shadow_enabled_) + pop->set_initial_class_style(CS_DROPSHADOW | pop->initial_class_style()); + pop->Init(frame_->GetNativeView(), bounds_); pop->SetContentsView(view_); diff --git a/chrome/browser/views/extensions/extension_popup.cc b/chrome/browser/views/extensions/extension_popup.cc index 9fc5ae7..70c9222 100644 --- a/chrome/browser/views/extensions/extension_popup.cc +++ b/chrome/browser/views/extensions/extension_popup.cc @@ -14,6 +14,7 @@ #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" #include "chrome/common/notification_type.h" +#include "third_party/skia/include/core/SkColor.h" #include "views/widget/root_view.h" #include "views/window/window.h" @@ -32,17 +33,32 @@ const int ExtensionPopup::kMinHeight = 25; const int ExtensionPopup::kMaxWidth = 800; const int ExtensionPopup::kMaxHeight = 600; +// The width, in pixels, of the black-border on a popup. +const int kPopupBorderWidth = 1; + +const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2; + ExtensionPopup::ExtensionPopup(ExtensionHost* host, views::Widget* frame, const gfx::Rect& relative_to, BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show) + bool activate_on_show, + PopupChrome chrome) : BrowserBubble(host->view(), frame, - gfx::Point()), + gfx::Point(), + RECTANGLE_CHROME == chrome), // If no bubble chrome is to + // be displayed, then enable a + // drop-shadow on the bubble + // widget. relative_to_(relative_to), extension_host_(host), - activate_on_show_(activate_on_show) { + activate_on_show_(activate_on_show), + border_widget_(NULL), + border_(NULL), + border_view_(NULL), + popup_chrome_(chrome), + anchor_position_(arrow_location) { host->view()->SetContainer(this); registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING, @@ -51,45 +67,56 @@ ExtensionPopup::ExtensionPopup(ExtensionHost* host, // TODO(erikkay) Some of this border code is derived from InfoBubble. // We should see if we can unify these classes. - gfx::NativeView native_window = frame->GetNativeView(); + // The bubble chrome requires a separate window, so construct it here. + if (BUBBLE_CHROME == popup_chrome_) { + gfx::NativeView native_window = frame->GetNativeView(); #if defined(OS_LINUX) - border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); - static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent(); - static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent(); + border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW); + static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent(); + static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent(); #else - border_widget_ = Widget::CreatePopupWidget(Widget::Transparent, - Widget::NotAcceptEvents, - Widget::DeleteOnDestroy); + border_widget_ = Widget::CreatePopupWidget(Widget::Transparent, + Widget::NotAcceptEvents, + Widget::DeleteOnDestroy); #endif - border_widget_->Init(native_window, bounds()); + border_widget_->Init(native_window, bounds()); #if defined(OS_LINUX) - TabOverviewTypes::instance()->SetWindowType( - border_widget_->GetNativeView(), - TabOverviewTypes::WINDOW_TYPE_CHROME_INFO_BUBBLE, - NULL); + TabOverviewTypes::instance()->SetWindowType( + border_widget_->GetNativeView(), + TabOverviewTypes::WINDOW_TYPE_CHROME_INFO_BUBBLE, + NULL); #endif - border_ = new BubbleBorder; - border_->set_arrow_location(arrow_location); + border_ = new BubbleBorder; + border_->set_arrow_location(arrow_location); - border_view_ = new views::View; - border_view_->set_background(new BubbleBackground(border_)); - border_view_->set_border(border_); - border_widget_->SetContentsView(border_view_); + border_view_ = new views::View; + border_view_->set_background(new BubbleBackground(border_)); - // Ensure that the popup contents are always displayed ontop of the border - // widget. - border_widget_->MoveAbove(popup_); + border_view_->set_border(border_); + border_widget_->SetContentsView(border_view_); + // Ensure that the popup contents are always displayed ontop of the border + // widget. + border_widget_->MoveAbove(popup_); + } else { + // Otherwise simply set a black-border on the view containing the popup + // extension view. + views::Border* border = views::Border::CreateSolidBorder(kPopupBorderWidth, + SK_ColorBLACK); + view()->set_border(border); + } } ExtensionPopup::~ExtensionPopup() { // The widget is set to delete on destroy, so no leak here. - border_widget_->Close(); + if (border_widget_) + border_widget_->Close(); } void ExtensionPopup::Hide() { BrowserBubble::Hide(); - border_widget_->Hide(); + if (border_widget_) + border_widget_->Hide(); } void ExtensionPopup::Show(bool activate) { @@ -104,7 +131,8 @@ void ExtensionPopup::Show(bool activate) { ResizeToView(); // Show the border first, then the popup overlaid on top. - border_widget_->Show(); + if (border_widget_) + border_widget_->Show(); BrowserBubble::Show(activate); } @@ -113,27 +141,27 @@ void ExtensionPopup::ResizeToView() { // know our position to do it. gfx::Size new_size = view()->size(); - // The rounded corners cut off more of the view than the border insets claim. - // Since we can't clip the ExtensionView's corners, we need to increase the - // inset by half the corner radius as well as lying about the size of the - // contents size to compensate. - int corner_inset = BubbleBorder::GetCornerRadius() / 2; - gfx::Size adjusted_size = new_size; - adjusted_size.Enlarge(2 * corner_inset, 2 * corner_inset); - gfx::Rect rect = border_->GetBounds(relative_to_, adjusted_size); - border_widget_->SetBounds(rect); - - // Now calculate the inner bounds. This is a bit more convoluted than - // it should be because BrowserBubble coordinates are in Browser coordinates - // while |rect| is in screen coordinates. - gfx::Insets border_insets; - border_->GetInsets(&border_insets); + gfx::Rect rect = GetOuterBounds(relative_to_, new_size); gfx::Point origin = rect.origin(); views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); - origin.set_x(origin.x() + border_insets.left() + corner_inset); - origin.set_y(origin.y() + border_insets.top() + corner_inset); + if (border_widget_) { + // Set the bubble-chrome widget according to the outer bounds of the entire + // popup. + border_widget_->SetBounds(rect); - SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height()); + // Now calculate the inner bounds. This is a bit more convoluted than + // it should be because BrowserBubble coordinates are in Browser coordinates + // while |rect| is in screen coordinates. + gfx::Insets border_insets; + border_->GetInsets(&border_insets); + + origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius); + origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius); + + SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height()); + } else { + SetBounds(origin.x(), origin.y(), rect.width(), rect.height()); + } } void ExtensionPopup::Observe(NotificationType type, @@ -159,6 +187,39 @@ void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) { ResizeToView(); } +gfx::Rect ExtensionPopup::GetOuterBounds(const gfx::Rect& position_relative_to, + const gfx::Size& contents_size) const { + gfx::Size adjusted_size = contents_size; + // If the popup has a bubble-chrome, then let the BubbleBorder compute + // the bounds. + if (BUBBLE_CHROME == popup_chrome_) { + // The rounded corners cut off more of the view than the border insets + // claim. Since we can't clip the ExtensionView's corners, we need to + // increase the inset by half the corner radius as well as lying about the + // size of the contents size to compensate. + adjusted_size.Enlarge(2 * kPopupBubbleCornerRadius, + 2 * kPopupBubbleCornerRadius); + return border_->GetBounds(position_relative_to, adjusted_size); + } + + // Otherwise, enlarge the bounds by the size of the local border. + gfx::Insets border_insets; + view()->border()->GetInsets(&border_insets); + adjusted_size.Enlarge(border_insets.width(), border_insets.height()); + + // Position the bounds according to the location of the |anchor_position_|. + int y; + if ((anchor_position_ == BubbleBorder::TOP_LEFT) || + (anchor_position_ == BubbleBorder::TOP_RIGHT)) { + y = position_relative_to.bottom(); + } else { + y = position_relative_to.y() - adjusted_size.height(); + } + + return gfx::Rect(position_relative_to.x(), y, adjusted_size.width(), + adjusted_size.height()); +} + // static ExtensionPopup* ExtensionPopup::Show( const GURL& url, @@ -167,7 +228,8 @@ ExtensionPopup* ExtensionPopup::Show( gfx::NativeWindow frame_window, const gfx::Rect& relative_to, BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show) { + bool activate_on_show, + PopupChrome chrome) { DCHECK(profile); DCHECK(frame_window); ExtensionProcessManager* manager = profile->GetExtensionProcessManager(); @@ -187,7 +249,8 @@ ExtensionPopup* ExtensionPopup::Show( ExtensionHost* host = manager->CreatePopup(url, browser); ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to, - arrow_location, activate_on_show); + arrow_location, activate_on_show, + chrome); // If the host had somehow finished loading, then we'd miss the notification // and not show. This seems to happen in single-process mode. diff --git a/chrome/browser/views/extensions/extension_popup.h b/chrome/browser/views/extensions/extension_popup.h index 92eab93..72df7b2 100644 --- a/chrome/browser/views/extensions/extension_popup.h +++ b/chrome/browser/views/extensions/extension_popup.h @@ -26,6 +26,11 @@ class ExtensionPopup : public BrowserBubble, public NotificationObserver, public ExtensionView::Container { public: + enum PopupChrome { + BUBBLE_CHROME, + RECTANGLE_CHROME + }; + virtual ~ExtensionPopup(); // Create and show a popup with |url| positioned adjacent to |relative_to| in @@ -42,6 +47,12 @@ class ExtensionPopup : public BrowserBubble, // If |arrow_location| is BOTTOM_*, then the popup 'pops up', otherwise // the popup 'drops down'. // Pass |activate_on_show| as true to activate the popup window. + // The |chrome| argument controls the chrome that surrounds the pop-up. + // Passing BUBBLE_CHROME will give the pop-up a bubble-like appearance, + // including the arrow mentioned above. Passing RECTANGLE_CHROME will give + // the popup a rectangular, black border with a drop-shadow with no arrow. + // The positioning of the popup is still governed by the arrow-location + // parameter. // // The actual display of the popup is delayed until the page contents // finish loading in order to minimize UI flashing and resizing. @@ -50,7 +61,8 @@ class ExtensionPopup : public BrowserBubble, gfx::NativeWindow frame_window, const gfx::Rect& relative_to, BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show); + bool activate_on_show, + PopupChrome chrome); ExtensionHost* host() const { return extension_host_.get(); } @@ -80,7 +92,14 @@ class ExtensionPopup : public BrowserBubble, views::Widget* frame, const gfx::Rect& relative_to, BubbleBorder::ArrowLocation arrow_location, - bool activate_on_show); + bool activate_on_show, + PopupChrome chrome); + + // Gives the desired bounds (in screen coordinates) given the rect to point + // to and the size of the contained contents. Includes all of the + // border-chrome surrounding the pop-up as well. + gfx::Rect GetOuterBounds(const gfx::Rect& position_relative_to, + const gfx::Size& contents_size) const; // The area on the screen that the popup should be positioned relative to. gfx::Rect relative_to_; @@ -101,6 +120,14 @@ class ExtensionPopup : public BrowserBubble, BubbleBorder* border_; views::View* border_view_; + // The type of chrome associated with the popup window. + PopupChrome popup_chrome_; + + // A cached copy of the arrow-position for the bubble chrome. + // If a black-border was requested, we still need this value to determine + // the position of the pop-up in relation to |relative_to_|. + BubbleBorder::ArrowLocation anchor_position_; + DISALLOW_COPY_AND_ASSIGN(ExtensionPopup); }; diff --git a/chrome/browser/views/extensions/extension_shelf.cc b/chrome/browser/views/extensions/extension_shelf.cc index 69b6dc1..640dfed 100644 --- a/chrome/browser/views/extensions/extension_shelf.cc +++ b/chrome/browser/views/extensions/extension_shelf.cc @@ -428,7 +428,8 @@ void ExtensionShelf::Toolstrip::LayoutWindow() { if (!window_.get()) { window_.reset(new BrowserBubble(this, shelf_->GetWidget(), - gfx::Point(0, 0))); + gfx::Point(0, 0), + false)); // Do not add a drop-shadow. window_->set_delegate(this); } diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc index fef451d..18d0f1a 100644 --- a/chrome/browser/views/location_bar_view.cc +++ b/chrome/browser/views/location_bar_view.cc @@ -1501,13 +1501,15 @@ void LocationBarView::PageActionImageView::ExecuteAction(int button) { rect.set_x(origin.x()); rect.set_y(origin.y()); - popup_ = ExtensionPopup::Show(page_action_->GetPopupUrl(current_tab_id_), - browser, - browser->profile(), - browser->window()->GetNativeHandle(), - rect, - BubbleBorder::TOP_RIGHT, - true); // Activate the popup window. + popup_ = ExtensionPopup::Show( + page_action_->GetPopupUrl(current_tab_id_), + browser, + browser->profile(), + browser->window()->GetNativeHandle(), + rect, + BubbleBorder::TOP_RIGHT, + true, // Activate the popup window. + ExtensionPopup::BUBBLE_CHROME); popup_->set_delegate(this); } else { ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted( diff --git a/chrome/common/extensions/api/extension_api.json b/chrome/common/extensions/api/extension_api.json index 69805df..562ada0 100755 --- a/chrome/common/extensions/api/extension_api.json +++ b/chrome/common/extensions/api/extension_api.json @@ -1912,6 +1912,12 @@ "type": "boolean", "description": "Pass true to give the focus to the popup window. The default behaviour is true.", "optional": true + }, + "borderStyle": { + "type": "string", + "description": "Pass 'bubble' to give the pop-up window a bubble-chrome border, including an arrow pointing at the relative-to point. Pass 'rectangle' to give the pop-up a rectangular black border with drop-shadow. Default behaviour is to pass 'bubble'.", + "optional": true, + "enum": ["bubble", "rectangle"] } } }, diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index 4b50d36..f543366 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -447,6 +447,11 @@ var chrome = chrome || {}; giveFocus: { type: "boolean", optional: true + }, + borderStyle: { + type: "string", + optional: true, + enum: ["bubble", "rectangle"] } } }, @@ -456,7 +461,8 @@ var chrome = chrome || {}; [url, { domAnchor: getAbsoluteRect(showDetails.relativeTo), - giveFocus: showDetails.giveFocus + giveFocus: showDetails.giveFocus, + borderStyle: showDetails.borderStyle }, callback], internalSchema); diff --git a/chrome/test/data/extensions/api_test/popup/toolband.html b/chrome/test/data/extensions/api_test/popup/toolband.html index 77467ee..f0dd50b2 100644 --- a/chrome/test/data/extensions/api_test/popup/toolband.html +++ b/chrome/test/data/extensions/api_test/popup/toolband.html @@ -92,6 +92,20 @@ window.onload = function() { // chrome.experimental.extension.getPopupView() == undefined); }); chrome.experimental.extension.getPopupView().close(); + }, + function popupBlackBorder() { + // Validate that displaying a pop-up with a black border still invokes + // the callback successfully. Note that this test does not validate + // the actual style of the border displayed. + var showDetails = { + "relativeTo": document.getElementById("anchorHere"), + "borderStyle": "rectangle" + }; + chrome.experimental.popup.show("toolband_popup.html", + showDetails, + chrome.test.callbackPass(function() { + chrome.experimental.extension.getPopupView().close(); + })); } ]); } diff --git a/views/controls/native/native_view_host.cc b/views/controls/native/native_view_host.cc index 79abc1d..463f149 100644 --- a/views/controls/native/native_view_host.cc +++ b/views/controls/native/native_view_host.cc @@ -98,10 +98,15 @@ void NativeViewHost::Layout() { // Since widgets know nothing about the View hierarchy (they are direct // children of the Widget that hosts our View hierarchy) they need to be // positioned in the coordinate system of the Widget, not the current - // view. - gfx::Point top_left; + // view. Also, they should be positioned respecting the border insets + // of the native view. + gfx::Insets insets = GetInsets(); + gfx::Point top_left(insets.left(), insets.top()); ConvertPointToWidget(this, &top_left); - native_wrapper_->ShowWidget(top_left.x(), top_left.y(), width(), height()); + gfx::Rect local_bounds = GetLocalBounds(false); + native_wrapper_->ShowWidget(top_left.x(), top_left.y(), + local_bounds.width(), + local_bounds.height()); } else { native_wrapper_->HideWidget(); } |