summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-26 22:00:25 +0000
committerdbeam@chromium.org <dbeam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-26 22:00:25 +0000
commit4b88ddac62bec4c723f3d844cf1b577d0d795453 (patch)
treef0ec7f65e2612a04fa7c986a8b8ec1456096136d
parentd4d245fc2988177f622d043592e349a0c603a950 (diff)
downloadchromium_src-4b88ddac62bec4c723f3d844cf1b577d0d795453.zip
chromium_src-4b88ddac62bec4c723f3d844cf1b577d0d795453.tar.gz
chromium_src-4b88ddac62bec4c723f3d844cf1b577d0d795453.tar.bz2
[zoom bubble] Handle entering/leaving/being in fullscreen on GTK.
This patch should: - hide the zoom bubble when toggling fullscreen - show a bubble without an arrow while in fullscreen This patch also: - changes ArrowLocationGtk to FrameStyle as it's a more appropriate name - renames all of the arrow locations to the equivalent frame styles - adds FIXED_TOP_LEFT, FIXED_TOP_RIGHT to the available frame styles - automatically flips bubbles in RTL to avoid making callers do this - fixes about ~3 callers that weren't flipping BUG=167365 Review URL: https://codereview.chromium.org/11553046 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174636 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc2
-rw-r--r--chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h2
-rw-r--r--chrome/browser/ui/gtk/avatar_menu_button_gtk.cc4
-rw-r--r--chrome/browser/ui/gtk/avatar_menu_button_gtk.h6
-rw-r--r--chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc6
-rw-r--r--chrome/browser/ui/gtk/browser_titlebar.cc8
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.cc2
-rw-r--r--chrome/browser/ui/gtk/bubble/bubble_gtk.cc234
-rw-r--r--chrome/browser/ui/gtk/bubble/bubble_gtk.h88
-rw-r--r--chrome/browser/ui/gtk/bubble/bubble_gtk_browsertest.cc56
-rw-r--r--chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc5
-rw-r--r--chrome/browser/ui/gtk/confirm_bubble_gtk.cc2
-rw-r--r--chrome/browser/ui/gtk/content_setting_bubble_gtk.cc6
-rw-r--r--chrome/browser/ui/gtk/extensions/bundle_installed_bubble_gtk.cc5
-rw-r--r--chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc12
-rw-r--r--chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc6
-rw-r--r--chrome/browser/ui/gtk/first_run_bubble.cc4
-rw-r--r--chrome/browser/ui/gtk/global_error_bubble.cc6
-rw-r--r--chrome/browser/ui/gtk/location_bar_view_gtk.cc24
-rw-r--r--chrome/browser/ui/gtk/location_bar_view_gtk.h10
-rw-r--r--chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc15
-rw-r--r--chrome/browser/ui/gtk/page_info_bubble_gtk.cc5
-rw-r--r--chrome/browser/ui/gtk/password_generation_bubble_gtk.cc2
-rw-r--r--chrome/browser/ui/gtk/script_bubble_gtk.cc6
-rw-r--r--chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc2
-rw-r--r--chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc10
-rw-r--r--chrome/browser/ui/gtk/zoom_bubble_gtk.cc30
-rw-r--r--chrome/browser/ui/gtk/zoom_bubble_gtk.h21
28 files changed, 321 insertions, 258 deletions
diff --git a/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc b/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc
index 1e95a45..72ea14e 100644
--- a/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.cc
@@ -36,7 +36,7 @@ const int kNewProfileLinkLeftPadding = 40;
AvatarMenuBubbleGtk::AvatarMenuBubbleGtk(Browser* browser,
GtkWidget* anchor,
- BubbleGtk::ArrowLocationGtk arrow,
+ BubbleGtk::FrameStyle arrow,
const gfx::Rect* rect)
: contents_(NULL),
theme_service_(GtkThemeService::GetFrom(browser->profile())),
diff --git a/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h b/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h
index 7c3247c..fcb3101 100644
--- a/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h
@@ -29,7 +29,7 @@ class AvatarMenuBubbleGtk : public BubbleDelegateGtk,
public:
AvatarMenuBubbleGtk(Browser* browser,
GtkWidget* anchor,
- BubbleGtk::ArrowLocationGtk arrow,
+ BubbleGtk::FrameStyle arrow,
const gfx::Rect* rect);
virtual ~AvatarMenuBubbleGtk();
diff --git a/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc b/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc
index af58abe..5ff6b1b 100644
--- a/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc
+++ b/chrome/browser/ui/gtk/avatar_menu_button_gtk.cc
@@ -19,7 +19,7 @@
AvatarMenuButtonGtk::AvatarMenuButtonGtk(Browser* browser)
: image_(NULL),
browser_(browser),
- arrow_location_(BubbleGtk::ARROW_LOCATION_TOP_LEFT),
+ frame_style_(BubbleGtk::ANCHOR_TOP_LEFT),
is_gaia_picture_(false),
old_height_(0) {
GtkWidget* event_box = gtk_event_box_new();
@@ -71,7 +71,7 @@ void AvatarMenuButtonGtk::ShowAvatarBubble() {
DCHECK(chrome::IsCommandEnabled(browser_, IDC_SHOW_AVATAR_MENU));
// Only show the avatar bubble if the avatar button is in the title bar.
if (gtk_widget_get_parent_window(widget_.get()))
- new AvatarMenuBubbleGtk(browser_, widget_.get(), arrow_location_, NULL);
+ new AvatarMenuBubbleGtk(browser_, widget_.get(), frame_style_, NULL);
}
void AvatarMenuButtonGtk::UpdateButtonIcon() {
diff --git a/chrome/browser/ui/gtk/avatar_menu_button_gtk.h b/chrome/browser/ui/gtk/avatar_menu_button_gtk.h
index 1f97cbc..24e4d4f 100644
--- a/chrome/browser/ui/gtk/avatar_menu_button_gtk.h
+++ b/chrome/browser/ui/gtk/avatar_menu_button_gtk.h
@@ -31,8 +31,8 @@ class AvatarMenuButtonGtk {
GtkWidget* widget() const { return widget_.get(); }
// Sets the location the arrow should be displayed on the menu bubble.
- void set_menu_arrow_location(BubbleGtk::ArrowLocationGtk arrow_location) {
- arrow_location_ = arrow_location;
+ void set_menu_frame_style(BubbleGtk::FrameStyle frame_style) {
+ frame_style_ = frame_style;
}
// Sets the image to display on the button, typically the profile icon.
@@ -59,7 +59,7 @@ class AvatarMenuButtonGtk {
Browser* browser_;
// Which side of the bubble to display the arrow.
- BubbleGtk::ArrowLocationGtk arrow_location_;
+ BubbleGtk::FrameStyle frame_style_;
scoped_ptr<gfx::Image> icon_;
bool is_gaia_picture_;
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
index 760dc91..f8b5ffa 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bubble_gtk.cc
@@ -154,14 +154,10 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWidget* anchor,
// We want the focus to start on the entry, not on the remove button.
gtk_container_set_focus_child(GTK_CONTAINER(content), table);
- BubbleGtk::ArrowLocationGtk arrow_location =
- base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT :
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
bubble_ = BubbleGtk::Show(anchor_,
NULL,
content,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/browser_titlebar.cc b/chrome/browser/ui/gtk/browser_titlebar.cc
index a3a49a1..186977e 100644
--- a/chrome/browser/ui/gtk/browser_titlebar.cc
+++ b/chrome/browser/ui/gtk/browser_titlebar.cc
@@ -815,12 +815,8 @@ void BrowserTitlebar::UpdateAvatar() {
avatar = cache.GetAvatarIconOfProfileAtIndex(index);
}
avatar_button_->SetIcon(avatar, is_gaia_picture);
-
- BubbleGtk::ArrowLocationGtk arrow_location =
- display_avatar_on_left_ ^ base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT :
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
- avatar_button_->set_menu_arrow_location(arrow_location);
+ avatar_button_->set_menu_frame_style(display_avatar_on_left_ ?
+ BubbleGtk::ANCHOR_TOP_LEFT : BubbleGtk::ANCHOR_TOP_RIGHT);
}
void BrowserTitlebar::MaximizeButtonClicked() {
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index 9805f8d..65be17e 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -1158,7 +1158,7 @@ void BrowserWindowGtk::ShowAvatarBubble(WebContents* web_contents,
const gfx::Rect& rect) {
GtkWidget* widget = web_contents->GetContentNativeView();
new AvatarMenuBubbleGtk(browser_.get(), widget,
- BubbleGtk::ARROW_LOCATION_TOP_LEFT, &rect);
+ BubbleGtk::ANCHOR_TOP_LEFT, &rect);
}
void BrowserWindowGtk::ShowAvatarBubbleFromAvatarButton() {
diff --git a/chrome/browser/ui/gtk/bubble/bubble_gtk.cc b/chrome/browser/ui/gtk/bubble/bubble_gtk.cc
index b955a52..d097b39 100644
--- a/chrome/browser/ui/gtk/bubble/bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/bubble/bubble_gtk.cc
@@ -6,7 +6,7 @@
#include <gdk/gdkkeysyms.h>
-#include "base/logging.h"
+#include "base/i18n/rtl.h"
#include "chrome/browser/ui/gtk/bubble/bubble_accelerators_gtk.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
@@ -35,40 +35,90 @@ const int kArrowToContentPadding = -4;
// We draw flat diagonal corners, each corner is an NxN square.
const int kCornerSize = 3;
+// The amount of padding (in pixels) from the top of |toplevel_window_| to the
+// top of |window_| when fixed positioning is used.
+const int kFixedPositionPaddingEnd = 10;
+const int kFixedPositionPaddingTop = 5;
+
const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xff, 0xff, 0xff);
const GdkColor kFrameColor = GDK_COLOR_RGB(0x63, 0x63, 0x63);
// Helper functions that encapsulate arrow locations.
-bool HasArrow(BubbleGtk::ArrowLocationGtk location) {
- return location != BubbleGtk::ARROW_LOCATION_NONE &&
- location != BubbleGtk::ARROW_LOCATION_FLOAT;
+bool HasArrow(BubbleGtk::FrameStyle frame_style) {
+ return frame_style != BubbleGtk::FLOAT_BELOW_RECT &&
+ frame_style != BubbleGtk::CENTER_OVER_RECT &&
+ frame_style != BubbleGtk::FIXED_TOP_LEFT &&
+ frame_style != BubbleGtk::FIXED_TOP_RIGHT;
+}
+
+bool IsArrowLeft(BubbleGtk::FrameStyle frame_style) {
+ return frame_style == BubbleGtk::ANCHOR_TOP_LEFT ||
+ frame_style == BubbleGtk::ANCHOR_BOTTOM_LEFT;
}
-bool IsArrowLeft(BubbleGtk::ArrowLocationGtk location) {
- return location == BubbleGtk::ARROW_LOCATION_TOP_LEFT ||
- location == BubbleGtk::ARROW_LOCATION_BOTTOM_LEFT;
+bool IsArrowMiddle(BubbleGtk::FrameStyle frame_style) {
+ return frame_style == BubbleGtk::ANCHOR_TOP_MIDDLE ||
+ frame_style == BubbleGtk::ANCHOR_BOTTOM_MIDDLE;
}
-bool IsArrowMiddle(BubbleGtk::ArrowLocationGtk location) {
- return location == BubbleGtk::ARROW_LOCATION_TOP_MIDDLE ||
- location == BubbleGtk::ARROW_LOCATION_BOTTOM_MIDDLE;
+bool IsArrowRight(BubbleGtk::FrameStyle frame_style) {
+ return frame_style == BubbleGtk::ANCHOR_TOP_RIGHT ||
+ frame_style == BubbleGtk::ANCHOR_BOTTOM_RIGHT;
}
-bool IsArrowRight(BubbleGtk::ArrowLocationGtk location) {
- return location == BubbleGtk::ARROW_LOCATION_TOP_RIGHT ||
- location == BubbleGtk::ARROW_LOCATION_BOTTOM_RIGHT;
+bool IsArrowTop(BubbleGtk::FrameStyle frame_style) {
+ return frame_style == BubbleGtk::ANCHOR_TOP_LEFT ||
+ frame_style == BubbleGtk::ANCHOR_TOP_MIDDLE ||
+ frame_style == BubbleGtk::ANCHOR_TOP_RIGHT;
}
-bool IsArrowTop(BubbleGtk::ArrowLocationGtk location) {
- return location == BubbleGtk::ARROW_LOCATION_TOP_LEFT ||
- location == BubbleGtk::ARROW_LOCATION_TOP_MIDDLE ||
- location == BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
+bool IsArrowBottom(BubbleGtk::FrameStyle frame_style) {
+ return frame_style == BubbleGtk::ANCHOR_BOTTOM_LEFT ||
+ frame_style == BubbleGtk::ANCHOR_BOTTOM_MIDDLE ||
+ frame_style == BubbleGtk::ANCHOR_BOTTOM_RIGHT;
}
-bool IsArrowBottom(BubbleGtk::ArrowLocationGtk location) {
- return location == BubbleGtk::ARROW_LOCATION_BOTTOM_LEFT ||
- location == BubbleGtk::ARROW_LOCATION_BOTTOM_MIDDLE ||
- location == BubbleGtk::ARROW_LOCATION_BOTTOM_RIGHT;
+bool IsFixed(BubbleGtk::FrameStyle frame_style) {
+ return frame_style == BubbleGtk::FIXED_TOP_LEFT ||
+ frame_style == BubbleGtk::FIXED_TOP_RIGHT;
+}
+
+BubbleGtk::FrameStyle AdjustFrameStyleForLocale(
+ BubbleGtk::FrameStyle frame_style) {
+ // Only RTL requires more work.
+ if (!base::i18n::IsRTL())
+ return frame_style;
+
+ switch (frame_style) {
+ // These don't flip.
+ case BubbleGtk::ANCHOR_TOP_MIDDLE:
+ case BubbleGtk::ANCHOR_BOTTOM_MIDDLE:
+ case BubbleGtk::FLOAT_BELOW_RECT:
+ case BubbleGtk::CENTER_OVER_RECT:
+ return frame_style;
+
+ // These do flip.
+ case BubbleGtk::ANCHOR_TOP_LEFT:
+ return BubbleGtk::ANCHOR_TOP_RIGHT;
+
+ case BubbleGtk::ANCHOR_TOP_RIGHT:
+ return BubbleGtk::ANCHOR_TOP_LEFT;
+
+ case BubbleGtk::ANCHOR_BOTTOM_LEFT:
+ return BubbleGtk::ANCHOR_BOTTOM_RIGHT;
+
+ case BubbleGtk::ANCHOR_BOTTOM_RIGHT:
+ return BubbleGtk::ANCHOR_BOTTOM_LEFT;
+
+ case BubbleGtk::FIXED_TOP_LEFT:
+ return BubbleGtk::FIXED_TOP_RIGHT;
+
+ case BubbleGtk::FIXED_TOP_RIGHT:
+ return BubbleGtk::FIXED_TOP_LEFT;
+ }
+
+ NOTREACHED();
+ return BubbleGtk::ANCHOR_TOP_LEFT;
}
} // namespace
@@ -77,17 +127,21 @@ bool IsArrowBottom(BubbleGtk::ArrowLocationGtk location) {
BubbleGtk* BubbleGtk::Show(GtkWidget* anchor_widget,
const gfx::Rect* rect,
GtkWidget* content,
- ArrowLocationGtk arrow_location,
+ FrameStyle frame_style,
int attribute_flags,
GtkThemeService* provider,
BubbleDelegateGtk* delegate) {
- BubbleGtk* bubble = new BubbleGtk(provider, attribute_flags);
- bubble->Init(anchor_widget, rect, content, arrow_location, attribute_flags);
+ BubbleGtk* bubble = new BubbleGtk(provider,
+ AdjustFrameStyleForLocale(frame_style),
+ attribute_flags);
+ bubble->Init(anchor_widget, rect, content, attribute_flags);
bubble->set_delegate(delegate);
return bubble;
}
-BubbleGtk::BubbleGtk(GtkThemeService* provider, int attribute_flags)
+BubbleGtk::BubbleGtk(GtkThemeService* provider,
+ FrameStyle frame_style,
+ int attribute_flags)
: delegate_(NULL),
window_(NULL),
theme_service_(provider),
@@ -95,10 +149,10 @@ BubbleGtk::BubbleGtk(GtkThemeService* provider, int attribute_flags)
toplevel_window_(NULL),
anchor_widget_(NULL),
mask_region_(NULL),
- preferred_arrow_location_(ARROW_LOCATION_TOP_LEFT),
- current_arrow_location_(ARROW_LOCATION_TOP_LEFT),
+ requested_frame_style_(frame_style),
+ actual_frame_style_(ANCHOR_TOP_LEFT),
match_system_theme_(attribute_flags & MATCH_SYSTEM_THEME),
- grab_input_(true),
+ grab_input_(attribute_flags & GRAB_INPUT),
closed_by_escape_(false) {
}
@@ -116,7 +170,6 @@ BubbleGtk::~BubbleGtk() {
void BubbleGtk::Init(GtkWidget* anchor_widget,
const gfx::Rect* rect,
GtkWidget* content,
- ArrowLocationGtk arrow_location,
int attribute_flags) {
// If there is a current grab widget (menu, other bubble, etc.), hide it.
GtkWidget* current_grab_widget = gtk_grab_get_current();
@@ -128,9 +181,7 @@ void BubbleGtk::Init(GtkWidget* anchor_widget,
toplevel_window_ = gtk_widget_get_toplevel(anchor_widget_);
DCHECK(gtk_widget_is_toplevel(toplevel_window_));
rect_ = rect ? *rect : gtk_util::WidgetBounds(anchor_widget);
- preferred_arrow_location_ = arrow_location;
- grab_input_ = attribute_flags & GRAB_INPUT;
// Using a TOPLEVEL window may cause placement issues with certain WMs but it
// is necessary to be able to focus the window.
window_ = gtk_window_new(attribute_flags & POPUP_WINDOW ?
@@ -154,8 +205,13 @@ void BubbleGtk::Init(GtkWidget* anchor_widget,
gtk_window_add_accel_group(GTK_WINDOW(window_), accel_group_);
+ // |requested_frame_style_| is used instead of |actual_frame_style_| here
+ // because |actual_frame_style_| is only correct after calling
+ // |UpdateFrameStyle()|. Unfortunately, |UpdateFrameStyle()| requires knowing
+ // the size of |window_| (which happens later on).
+ int arrow_padding = HasArrow(requested_frame_style_) ? kArrowSize : 0;
GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
- gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), kArrowSize, 0, 0, 0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), arrow_padding, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(alignment), content);
gtk_container_add(GTK_CONTAINER(window_), alignment);
@@ -165,7 +221,7 @@ void BubbleGtk::Init(GtkWidget* anchor_widget,
// OnSizeAllocate, so the mask can be applied to the GdkWindow.
gtk_widget_realize(window_);
- UpdateArrowLocation(true); // Force move and reshape.
+ UpdateFrameStyle(true); // Force move and reshape.
StackWindow();
gtk_widget_add_events(window_, GDK_BUTTON_PRESS_MASK);
@@ -218,22 +274,22 @@ void BubbleGtk::Init(GtkWidget* anchor_widget,
// corners. This is a lot more work, but they get anti-aliasing.
// static
std::vector<GdkPoint> BubbleGtk::MakeFramePolygonPoints(
- ArrowLocationGtk arrow_location,
+ FrameStyle frame_style,
int width,
int height,
FrameType type) {
using gtk_util::MakeBidiGdkPoint;
std::vector<GdkPoint> points;
- int top_arrow_size = IsArrowTop(arrow_location) ? kArrowSize : 0;
- int bottom_arrow_size = IsArrowBottom(arrow_location) ? kArrowSize : 0;
- bool on_left = IsArrowLeft(arrow_location);
+ int top_arrow_size = IsArrowTop(frame_style) ? kArrowSize : 0;
+ int bottom_arrow_size = IsArrowBottom(frame_style) ? kArrowSize : 0;
+ bool on_left = IsArrowLeft(frame_style);
// If we're stroking the frame, we need to offset some of our points by 1
// pixel. We do this when we draw horizontal lines that are on the bottom or
// when we draw vertical lines that are closer to the end (where "end" is the
- // right side for ARROW_LOCATION_TOP_LEFT).
- int y_off = (type == FRAME_MASK) ? 0 : -1;
+ // right side for ANCHOR_TOP_LEFT).
+ int y_off = type == FRAME_MASK ? 0 : -1;
// We use this one for arrows located on the left.
int x_off_l = on_left ? y_off : 0;
// We use this one for RTL.
@@ -247,8 +303,7 @@ std::vector<GdkPoint> BubbleGtk::MakeFramePolygonPoints(
// The top arrow.
if (top_arrow_size) {
- int arrow_x = arrow_location == ARROW_LOCATION_TOP_MIDDLE ?
- width / 2 : kArrowX;
+ int arrow_x = frame_style == ANCHOR_TOP_MIDDLE ? width / 2 : kArrowX;
points.push_back(MakeBidiGdkPoint(
arrow_x - top_arrow_size + x_off_r, top_arrow_size, width, on_left));
points.push_back(MakeBidiGdkPoint(
@@ -276,7 +331,7 @@ std::vector<GdkPoint> BubbleGtk::MakeFramePolygonPoints(
// The bottom arrow.
if (bottom_arrow_size) {
- int arrow_x = arrow_location == ARROW_LOCATION_BOTTOM_MIDDLE ?
+ int arrow_x = frame_style == ANCHOR_BOTTOM_MIDDLE ?
width / 2 : kArrowX;
points.push_back(MakeBidiGdkPoint(
arrow_x + bottom_arrow_size + 1 + x_off_l,
@@ -304,43 +359,46 @@ std::vector<GdkPoint> BubbleGtk::MakeFramePolygonPoints(
return points;
}
-BubbleGtk::ArrowLocationGtk BubbleGtk::GetArrowLocation(
- ArrowLocationGtk preferred_location,
+BubbleGtk::FrameStyle BubbleGtk::GetAllowedFrameStyle(
+ FrameStyle preferred_style,
int arrow_x,
int arrow_y,
int width,
int height) {
+ if (IsFixed(preferred_style))
+ return preferred_style;
+
const int screen_width = gdk_screen_get_width(gdk_screen_get_default());
const int screen_height = gdk_screen_get_height(gdk_screen_get_default());
// Choose whether to show the bubble above or below the specified location.
- const bool prefer_top_arrow = IsArrowTop(preferred_location) ||
- preferred_location == ARROW_LOCATION_NONE;
+ const bool prefer_top_arrow = IsArrowTop(preferred_style) ||
+ preferred_style == FLOAT_BELOW_RECT;
// The bleed measures the amount of bubble that would be shown offscreen.
const int top_arrow_bleed =
std::max(height + kArrowSize + arrow_y - screen_height, 0);
const int bottom_arrow_bleed = std::max(height + kArrowSize - arrow_y, 0);
- ArrowLocationGtk arrow_location_none = ARROW_LOCATION_NONE;
- ArrowLocationGtk arrow_location_left = ARROW_LOCATION_TOP_LEFT;
- ArrowLocationGtk arrow_location_middle = ARROW_LOCATION_TOP_MIDDLE;
- ArrowLocationGtk arrow_location_right = ARROW_LOCATION_TOP_RIGHT;
+ FrameStyle frame_style_none = FLOAT_BELOW_RECT;
+ FrameStyle frame_style_left = ANCHOR_TOP_LEFT;
+ FrameStyle frame_style_middle = ANCHOR_TOP_MIDDLE;
+ FrameStyle frame_style_right = ANCHOR_TOP_RIGHT;
if ((prefer_top_arrow && (top_arrow_bleed > bottom_arrow_bleed)) ||
(!prefer_top_arrow && (top_arrow_bleed >= bottom_arrow_bleed))) {
- arrow_location_none = ARROW_LOCATION_FLOAT;
- arrow_location_left = ARROW_LOCATION_BOTTOM_LEFT;
- arrow_location_middle = ARROW_LOCATION_BOTTOM_MIDDLE;
- arrow_location_right =ARROW_LOCATION_BOTTOM_RIGHT;
+ frame_style_none = CENTER_OVER_RECT;
+ frame_style_left = ANCHOR_BOTTOM_LEFT;
+ frame_style_middle = ANCHOR_BOTTOM_MIDDLE;
+ frame_style_right = ANCHOR_BOTTOM_RIGHT;
}
- if (!HasArrow(preferred_location))
- return arrow_location_none;
+ if (!HasArrow(preferred_style))
+ return frame_style_none;
- if (IsArrowMiddle(preferred_location))
- return arrow_location_middle;
+ if (IsArrowMiddle(preferred_style))
+ return frame_style_middle;
// Choose whether to show the bubble left or right of the specified location.
- const bool prefer_left_arrow = IsArrowLeft(preferred_location);
+ const bool prefer_left_arrow = IsArrowLeft(preferred_style);
// The bleed measures the amount of bubble that would be shown offscreen.
const int left_arrow_bleed =
std::max(width + arrow_x - kArrowX - screen_width, 0);
@@ -349,10 +407,10 @@ BubbleGtk::ArrowLocationGtk BubbleGtk::GetArrowLocation(
// Use the preferred location if it doesn't bleed more than the opposite side.
return ((prefer_left_arrow && (left_arrow_bleed <= right_arrow_bleed)) ||
(!prefer_left_arrow && (left_arrow_bleed < right_arrow_bleed))) ?
- arrow_location_left : arrow_location_right;
+ frame_style_left : frame_style_right;
}
-bool BubbleGtk::UpdateArrowLocation(bool force_move_and_reshape) {
+bool BubbleGtk::UpdateFrameStyle(bool force_move_and_reshape) {
if (!toplevel_window_ || !anchor_widget_)
return false;
@@ -363,17 +421,17 @@ bool BubbleGtk::UpdateArrowLocation(bool force_move_and_reshape) {
gtk_widget_translate_coordinates(anchor_widget_, toplevel_window_,
rect_.x(), rect_.y(), &offset_x, &offset_y);
- ArrowLocationGtk old_location = current_arrow_location_;
+ FrameStyle old_frame_style = actual_frame_style_;
GtkAllocation allocation;
gtk_widget_get_allocation(window_, &allocation);
- current_arrow_location_ = GetArrowLocation(
- preferred_arrow_location_,
+ actual_frame_style_ = GetAllowedFrameStyle(
+ requested_frame_style_,
toplevel_x + offset_x + (rect_.width() / 2), // arrow_x
toplevel_y + offset_y,
allocation.width,
allocation.height);
- if (force_move_and_reshape || current_arrow_location_ != old_location) {
+ if (force_move_and_reshape || actual_frame_style_ != old_frame_style) {
UpdateWindowShape();
MoveWindow();
// We need to redraw the entire window to repaint its border.
@@ -391,7 +449,7 @@ void BubbleGtk::UpdateWindowShape() {
GtkAllocation allocation;
gtk_widget_get_allocation(window_, &allocation);
std::vector<GdkPoint> points = MakeFramePolygonPoints(
- current_arrow_location_, allocation.width, allocation.height,
+ actual_frame_style_, allocation.width, allocation.height,
FRAME_MASK);
mask_region_ = gdk_region_polygon(&points[0],
points.size(),
@@ -414,17 +472,28 @@ void BubbleGtk::MoveWindow() {
gtk_widget_translate_coordinates(anchor_widget_, toplevel_window_,
rect_.x(), rect_.y(), &offset_x, &offset_y);
- GtkAllocation allocation;
- gtk_widget_get_allocation(window_, &allocation);
-
gint screen_x = 0;
- if (!HasArrow(current_arrow_location_) ||
- IsArrowMiddle(current_arrow_location_)) {
+ if (IsFixed(actual_frame_style_)) {
+ GtkAllocation toplevel_allocation;
+ gtk_widget_get_allocation(toplevel_window_, &toplevel_allocation);
+
+ GtkAllocation bubble_allocation;
+ gtk_widget_get_allocation(window_, &bubble_allocation);
+
+ int x_offset = actual_frame_style_ == FIXED_TOP_LEFT ?
+ kFixedPositionPaddingEnd :
+ toplevel_allocation.width - bubble_allocation.width -
+ kFixedPositionPaddingEnd;
+ screen_x = toplevel_x + x_offset;
+ } else if (!HasArrow(actual_frame_style_) ||
+ IsArrowMiddle(actual_frame_style_)) {
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(window_, &allocation);
screen_x =
toplevel_x + offset_x + (rect_.width() / 2) - allocation.width / 2;
- } else if (IsArrowLeft(current_arrow_location_)) {
+ } else if (IsArrowLeft(actual_frame_style_)) {
screen_x = toplevel_x + offset_x + (rect_.width() / 2) - kArrowX;
- } else if (IsArrowRight(current_arrow_location_)) {
+ } else if (IsArrowRight(actual_frame_style_)) {
GtkAllocation allocation;
gtk_widget_get_allocation(window_, &allocation);
screen_x = toplevel_x + offset_x + (rect_.width() / 2) -
@@ -434,10 +503,14 @@ void BubbleGtk::MoveWindow() {
}
gint screen_y = toplevel_y + offset_y + rect_.height();
- if (IsArrowTop(current_arrow_location_) ||
- current_arrow_location_ == ARROW_LOCATION_NONE) {
+ if (IsFixed(actual_frame_style_)) {
+ screen_y = toplevel_y + kFixedPositionPaddingTop;
+ } else if (IsArrowTop(actual_frame_style_) ||
+ actual_frame_style_ == FLOAT_BELOW_RECT) {
screen_y += kArrowToContentPadding;
} else {
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(window_, &allocation);
screen_y -= allocation.height + kArrowToContentPadding;
}
@@ -579,7 +652,7 @@ gboolean BubbleGtk::OnExpose(GtkWidget* widget, GdkEventExpose* expose) {
GtkAllocation allocation;
gtk_widget_get_allocation(window_, &allocation);
std::vector<GdkPoint> points = MakeFramePolygonPoints(
- current_arrow_location_, allocation.width, allocation.height,
+ actual_frame_style_, allocation.width, allocation.height,
FRAME_STROKE);
gdk_draw_polygon(drawable, gc, FALSE, &points[0], points.size());
@@ -599,10 +672,9 @@ gboolean BubbleGtk::OnExpose(GtkWidget* widget, GdkEventExpose* expose) {
// and apply our shape mask region.
void BubbleGtk::OnSizeAllocate(GtkWidget* widget,
GtkAllocation* allocation) {
- if (!UpdateArrowLocation(false)) {
+ if (!UpdateFrameStyle(false)) {
UpdateWindowShape();
- if (current_arrow_location_ != ARROW_LOCATION_TOP_LEFT)
- MoveWindow();
+ MoveWindow();
}
}
@@ -671,7 +743,7 @@ void BubbleGtk::OnForeshadowWidgetHide(GtkWidget* widget) {
gboolean BubbleGtk::OnToplevelConfigure(GtkWidget* widget,
GdkEventConfigure* event) {
- if (!UpdateArrowLocation(false))
+ if (!UpdateFrameStyle(false))
MoveWindow();
StackWindow();
return FALSE;
@@ -684,7 +756,7 @@ gboolean BubbleGtk::OnToplevelUnmap(GtkWidget* widget, GdkEvent* event) {
void BubbleGtk::OnAnchorAllocate(GtkWidget* widget,
GtkAllocation* allocation) {
- if (!UpdateArrowLocation(false))
+ if (!UpdateFrameStyle(false))
MoveWindow();
}
diff --git a/chrome/browser/ui/gtk/bubble/bubble_gtk.h b/chrome/browser/ui/gtk/bubble/bubble_gtk.h
index 5005b30..d076556 100644
--- a/chrome/browser/ui/gtk/bubble/bubble_gtk.h
+++ b/chrome/browser/ui/gtk/bubble/bubble_gtk.h
@@ -48,37 +48,40 @@ class BubbleDelegateGtk {
// calling Close().
class BubbleGtk : public content::NotificationObserver {
public:
- // Where should the arrow be placed relative to the bubble?
- enum ArrowLocationGtk {
- ARROW_LOCATION_TOP_LEFT,
- ARROW_LOCATION_TOP_MIDDLE,
- ARROW_LOCATION_TOP_RIGHT,
- ARROW_LOCATION_BOTTOM_LEFT,
- ARROW_LOCATION_BOTTOM_MIDDLE,
- ARROW_LOCATION_BOTTOM_RIGHT,
- ARROW_LOCATION_NONE, // No arrow. Positioned under the supplied rect.
- ARROW_LOCATION_FLOAT, // No arrow. Centered over the supplied rect.
+ // The style of the frame of the bubble (includes positioning and arrow).
+ enum FrameStyle {
+ ANCHOR_TOP_LEFT,
+ ANCHOR_TOP_MIDDLE,
+ ANCHOR_TOP_RIGHT,
+ ANCHOR_BOTTOM_LEFT,
+ ANCHOR_BOTTOM_MIDDLE,
+ ANCHOR_BOTTOM_RIGHT,
+ FLOAT_BELOW_RECT, // No arrow. Positioned under the supplied rect.
+ CENTER_OVER_RECT, // No arrow. Centered over the supplied rect.
+ FIXED_TOP_LEFT, // No arrow. Shown at top left of |toplevel_window_|.
+ FIXED_TOP_RIGHT, // No arrow. Shown at top right of |toplevel_window_|.
};
enum BubbleAttribute {
NONE = 0,
- MATCH_SYSTEM_THEME = 1 << 0, // Matches system colors/themes when possible.
- POPUP_WINDOW = 1 << 1, // Displays as popup instead of top-level window.
- GRAB_INPUT = 1 << 2, // Causes bubble to grab keyboard/pointer input.
+ MATCH_SYSTEM_THEME = 1 << 0, // Matches system colors/themes when possible.
+ POPUP_WINDOW = 1 << 1, // Displays as popup instead of top-level window.
+ GRAB_INPUT = 1 << 2, // Causes bubble to grab keyboard/pointer input.
};
// Show a bubble, pointing at the area |rect| (in coordinates relative to
// |anchor_widget|'s origin). A bubble will try to fit on the screen, so it
// can point to any edge of |rect|. If |rect| is NULL, the widget's entire
// area will be used. The bubble will host the |content| widget. Its arrow
- // will be drawn at |arrow_location| if possible. The |delegate| will be
- // notified when the bubble is closed. The bubble will perform an X grab of
- // the pointer and keyboard, and will close itself if a click is received
- // outside of the bubble.
+ // will be drawn according to |frame_style| if possible, and will be
+ // automatically flipped in RTL locales. The |delegate| will be notified when
+ // the bubble is closed. The bubble will perform an X grab of the pointer and
+ // keyboard, and will close itself if a click is received outside of the
+ // bubble.
static BubbleGtk* Show(GtkWidget* anchor_widget,
const gfx::Rect* rect,
GtkWidget* content,
- ArrowLocationGtk arrow_location,
+ FrameStyle frame_style,
int attribute_flags,
GtkThemeService* provider,
BubbleDelegateGtk* delegate);
@@ -109,40 +112,40 @@ class BubbleGtk : public content::NotificationObserver {
FRAME_STROKE,
};
- BubbleGtk(GtkThemeService* provider, int attribute_flags);
+ BubbleGtk(GtkThemeService* provider,
+ FrameStyle frame_style,
+ int attribute_flags);
virtual ~BubbleGtk();
// Creates the Bubble.
void Init(GtkWidget* anchor_widget,
const gfx::Rect* rect,
GtkWidget* content,
- ArrowLocationGtk arrow_location,
int attribute_flags);
// Make the points for our polygon frame, either for fill (the mask), or for
// when we stroke the border.
static std::vector<GdkPoint> MakeFramePolygonPoints(
- ArrowLocationGtk arrow_location,
+ FrameStyle frame_style,
int width,
int height,
FrameType type);
- // Get the location where the arrow should be placed (which is a function of
- // the preferred location and of the direction that the bubble should be
- // facing to fit onscreen). |arrow_x| (or |arrow_y|) is the X component (or
- // Y component) in screen coordinates of the point at which the bubble's arrow
- // should be aimed, respectively. |width| (or |height|) is the bubble's width
- // (or height).
- static ArrowLocationGtk GetArrowLocation(ArrowLocationGtk preferred_location,
- int arrow_x,
- int arrow_y,
- int width,
- int height);
-
- // Updates |arrow_location_| based on the toplevel window's current position
- // and the bubble's size. If the |force_move_and_reshape| is true or the
- // location changes, moves and reshapes the window and returns true.
- bool UpdateArrowLocation(bool force_move_and_reshape);
+ // Get the allowed frame style (which is a function of the preferred style and
+ // of the direction that the bubble should be facing to fit onscreen).
+ // |arrow_x| (or |arrow_y|) is the X component (or Y component) in screen
+ // coordinates of the point at which the bubble's arrow should be aimed,
+ // respectively. |width| (or |height|) is the bubble's width (or height).
+ static FrameStyle GetAllowedFrameStyle(FrameStyle preferred_location,
+ int arrow_x,
+ int arrow_y,
+ int width,
+ int height);
+
+ // Updates the frame style based on the toplevel window's current position and
+ // the bubble's size. If the |force_move_and_reshape| is true or the location
+ // changes, moves and reshapes the window and returns true.
+ bool UpdateFrameStyle(bool force_move_and_reshape);
// Reshapes the window and updates |mask_region_|.
void UpdateWindowShape();
@@ -209,10 +212,13 @@ class BubbleGtk : public content::NotificationObserver {
// not).
GdkRegion* mask_region_;
- // Where would we prefer for the arrow be drawn relative to the bubble, and
- // where is it currently drawn?
- ArrowLocationGtk preferred_arrow_location_;
- ArrowLocationGtk current_arrow_location_;
+ // The frame style given to |Show()| that will attempt to be used. It will be
+ // flipped in RTL. If there's not enough screen space for the given
+ // FrameStyle, this may be changed and differ from |actual_frame_style_|.
+ FrameStyle requested_frame_style_;
+
+ // The currently used frame style given screen size and directionality.
+ FrameStyle actual_frame_style_;
// Whether the background should match the system theme, when the system theme
// is being used. For example, the bookmark bubble does, but extension popups
diff --git a/chrome/browser/ui/gtk/bubble/bubble_gtk_browsertest.cc b/chrome/browser/ui/gtk/bubble/bubble_gtk_browsertest.cc
index dbf4cb8..b7c54ab 100644
--- a/chrome/browser/ui/gtk/bubble/bubble_gtk_browsertest.cc
+++ b/chrome/browser/ui/gtk/bubble/bubble_gtk_browsertest.cc
@@ -44,31 +44,31 @@ class BubbleGtkTest : public InProcessBrowserTest,
// Tests that we can adjust a bubble arrow so we can show a bubble without being
// clipped. This test verifies the following four issues:
-// 1. Shows a bubble to the top-left corner and see its arrow location always
-// becomes ARROW_LOCATION_TOP_LEFT.
-// 2. Shows a bubble to the top-right corner and see its arrow location always
-// becomes ARROW_LOCATION_TOP_RIGHT.
-// 3. Shows a bubble to the bottom-left corner and see its arrow location always
-// becomes ARROW_LOCATION_BOTTOM_LEFT.
-// 4. Shows a bubble to the top-left corner and see its arrow location always
-// becomes ARROW_LOCATION_BOTTOM_RIGHT.
+// 1. Shows a bubble to the top-left corner and see its frame style always
+// becomes ANCHOR_TOP_LEFT.
+// 2. Shows a bubble to the top-right corner and see its frame style always
+// becomes ANCHOR_TOP_RIGHT.
+// 3. Shows a bubble to the bottom-left corner and see its frame style always
+// becomes ANCHOR_BOTTOM_LEFT.
+// 4. Shows a bubble to the top-left corner and see its frame style always
+// becomes ANCHOR_BOTTOM_RIGHT.
IN_PROC_BROWSER_TEST_F(BubbleGtkTest, ArrowLocation) {
int width = gdk_screen_get_width(gdk_screen_get_default());
int height = gdk_screen_get_height(gdk_screen_get_default());
struct {
int x, y;
- BubbleGtk::ArrowLocationGtk expected;
+ BubbleGtk::FrameStyle expected;
} points[] = {
- {0, 0, BubbleGtk::ARROW_LOCATION_TOP_LEFT},
- {width - 1, 0, BubbleGtk::ARROW_LOCATION_TOP_RIGHT},
- {0, height - 1, BubbleGtk::ARROW_LOCATION_BOTTOM_LEFT},
- {width - 1, height - 1, BubbleGtk::ARROW_LOCATION_BOTTOM_RIGHT},
+ {0, 0, BubbleGtk::ANCHOR_TOP_LEFT},
+ {width - 1, 0, BubbleGtk::ANCHOR_TOP_RIGHT},
+ {0, height - 1, BubbleGtk::ANCHOR_BOTTOM_LEFT},
+ {width - 1, height - 1, BubbleGtk::ANCHOR_BOTTOM_RIGHT},
};
- static const BubbleGtk::ArrowLocationGtk kPreferredLocations[] = {
- BubbleGtk::ARROW_LOCATION_TOP_LEFT,
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT,
- BubbleGtk::ARROW_LOCATION_BOTTOM_LEFT,
- BubbleGtk::ARROW_LOCATION_BOTTOM_RIGHT,
+ static const BubbleGtk::FrameStyle kPreferredLocations[] = {
+ BubbleGtk::ANCHOR_TOP_LEFT,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
+ BubbleGtk::ANCHOR_BOTTOM_LEFT,
+ BubbleGtk::ANCHOR_BOTTOM_RIGHT,
};
GtkWidget* anchor = GetNativeBrowserWindow();
@@ -89,7 +89,7 @@ IN_PROC_BROWSER_TEST_F(BubbleGtkTest, ArrowLocation) {
BubbleGtk::GRAB_INPUT,
theme_service,
this);
- EXPECT_EQ(points[i].expected, bubble->current_arrow_location_);
+ EXPECT_EQ(points[i].expected, bubble->actual_frame_style_);
bubble->Close();
}
}
@@ -100,16 +100,16 @@ IN_PROC_BROWSER_TEST_F(BubbleGtkTest, NoArrow) {
int height = gdk_screen_get_height(gdk_screen_get_default());
struct {
int x, y;
- BubbleGtk::ArrowLocationGtk expected;
+ BubbleGtk::FrameStyle expected;
} points[] = {
- {0, 0, BubbleGtk::ARROW_LOCATION_NONE},
- {width - 1, 0, BubbleGtk::ARROW_LOCATION_NONE},
- {0, height - 1, BubbleGtk::ARROW_LOCATION_FLOAT},
- {width - 1, height - 1, BubbleGtk::ARROW_LOCATION_FLOAT},
+ {0, 0, BubbleGtk::FLOAT_BELOW_RECT},
+ {width - 1, 0, BubbleGtk::FLOAT_BELOW_RECT},
+ {0, height - 1, BubbleGtk::CENTER_OVER_RECT},
+ {width - 1, height - 1, BubbleGtk::CENTER_OVER_RECT},
};
- static const BubbleGtk::ArrowLocationGtk kPreferredLocations[] = {
- BubbleGtk::ARROW_LOCATION_NONE,
- BubbleGtk::ARROW_LOCATION_FLOAT,
+ static const BubbleGtk::FrameStyle kPreferredLocations[] = {
+ BubbleGtk::FLOAT_BELOW_RECT,
+ BubbleGtk::CENTER_OVER_RECT,
};
GtkWidget* anchor = GetNativeBrowserWindow();
@@ -130,7 +130,7 @@ IN_PROC_BROWSER_TEST_F(BubbleGtkTest, NoArrow) {
BubbleGtk::GRAB_INPUT,
theme_service,
this);
- EXPECT_EQ(points[i].expected, bubble->current_arrow_location_);
+ EXPECT_EQ(points[i].expected, bubble->actual_frame_style_);
bubble->Close();
}
}
diff --git a/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc b/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc
index 870bc7f..6e7b5e4 100644
--- a/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/chrome_to_mobile_bubble_gtk.cc
@@ -245,11 +245,10 @@ ChromeToMobileBubbleGtk::ChromeToMobileBubbleGtk(GtkWidget* anchor_widget,
// Initialize focus to the send button.
gtk_container_set_focus_child(GTK_CONTAINER(content), send_);
- BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT : BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
+ BubbleGtk::FrameStyle frame_style = BubbleGtk::ANCHOR_TOP_RIGHT;
const int attribute_flags = BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW | BubbleGtk::GRAB_INPUT;
- bubble_ = BubbleGtk::Show(anchor_widget_, NULL, content, arrow_location,
+ bubble_ = BubbleGtk::Show(anchor_widget_, NULL, content, frame_style,
attribute_flags, theme_service_, this /*delegate*/);
if (!bubble_) {
NOTREACHED();
diff --git a/chrome/browser/ui/gtk/confirm_bubble_gtk.cc b/chrome/browser/ui/gtk/confirm_bubble_gtk.cc
index 28aba96..7822767 100644
--- a/chrome/browser/ui/gtk/confirm_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/confirm_bubble_gtk.cc
@@ -139,7 +139,7 @@ void ConfirmBubbleGtk::Show() {
bubble_ = BubbleGtk::Show(anchor_,
&rect,
content,
- BubbleGtk::ARROW_LOCATION_NONE,
+ BubbleGtk::FLOAT_BELOW_RECT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc b/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc
index 8c60c61..6430802 100644
--- a/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc
@@ -258,14 +258,10 @@ void ContentSettingBubbleGtk::BuildBubble() {
gtk_widget_grab_focus(bottom_box);
gtk_widget_grab_focus(button);
- BubbleGtk::ArrowLocationGtk arrow_location =
- !base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
bubble_ = BubbleGtk::Show(anchor_,
NULL,
bubble_content,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/extensions/bundle_installed_bubble_gtk.cc b/chrome/browser/ui/gtk/extensions/bundle_installed_bubble_gtk.cc
index 0211c5e..792642b 100644
--- a/chrome/browser/ui/gtk/extensions/bundle_installed_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/bundle_installed_bubble_gtk.cc
@@ -91,15 +91,12 @@ void BundleInstalledBubbleGtk::ShowInternal(const BundleInstaller* bundle) {
gtk_box_pack_start(GTK_BOX(close_column), close_button_->widget(),
FALSE, FALSE, 0);
- BubbleGtk::ArrowLocationGtk arrow_location =
- !base::i18n::IsRTL() ? BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
gfx::Rect bounds = gtk_util::WidgetBounds(reference_widget);
bubble_ = BubbleGtk::Show(reference_widget,
&bounds,
bubble_content,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc b/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc
index 08f3f39..724f1a1 100644
--- a/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/extension_installed_bubble_gtk.cc
@@ -327,20 +327,14 @@ void ExtensionInstalledBubbleGtk::ShowInternal() {
gtk_box_pack_start(GTK_BOX(close_column), close_button_->widget(),
FALSE, FALSE, 0);
- BubbleGtk::ArrowLocationGtk arrow_location =
- !base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
+ BubbleGtk::FrameStyle frame_style = BubbleGtk::ANCHOR_TOP_RIGHT;
gfx::Rect bounds = gtk_util::WidgetBounds(reference_widget);
if (type_ == OMNIBOX_KEYWORD) {
// Reverse the arrow for omnibox keywords, since the bubble will be on the
// other side of the window. We also clear the width to avoid centering
// the popup on the URL bar.
- arrow_location =
- !base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT :
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
+ frame_style = BubbleGtk::ANCHOR_TOP_LEFT;
if (base::i18n::IsRTL())
bounds.Offset(bounds.width(), 0);
bounds.set_width(0);
@@ -349,7 +343,7 @@ void ExtensionInstalledBubbleGtk::ShowInternal() {
bubble_ = BubbleGtk::Show(reference_widget,
&bounds,
bubble_content,
- arrow_location,
+ frame_style,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc b/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
index e0b0605..42c95da 100644
--- a/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
+++ b/chrome/browser/ui/gtk/extensions/extension_popup_gtk.cc
@@ -185,14 +185,10 @@ void ExtensionPopupGtk::ShowPopup() {
// We'll be in the upper-right corner of the window for LTR languages, so we
// want to put the arrow at the upper-right corner of the bubble to match the
// page and app menus.
- BubbleGtk::ArrowLocationGtk arrow_location =
- !base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
bubble_ = BubbleGtk::Show(anchor_,
NULL,
border_box,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
being_inspected_ ? 0 :
BubbleGtk::POPUP_WINDOW | BubbleGtk::GRAB_INPUT,
GtkThemeService::GetFrom(browser_->profile()),
diff --git a/chrome/browser/ui/gtk/first_run_bubble.cc b/chrome/browser/ui/gtk/first_run_bubble.cc
index a0776b9..7207758 100644
--- a/chrome/browser/ui/gtk/first_run_bubble.cc
+++ b/chrome/browser/ui/gtk/first_run_bubble.cc
@@ -69,12 +69,10 @@ FirstRunBubble::FirstRunBubble(Browser* browser,
gtk_box_pack_start(GTK_BOX(content), top_line, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(content), subtext, FALSE, FALSE, 0);
- BubbleGtk::ArrowLocationGtk arrow_location = !base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT : BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
bubble_ = BubbleGtk::Show(anchor,
&rect,
content,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_LEFT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/global_error_bubble.cc b/chrome/browser/ui/gtk/global_error_bubble.cc
index ea6c6c1..c28cb49 100644
--- a/chrome/browser/ui/gtk/global_error_bubble.cc
+++ b/chrome/browser/ui/gtk/global_error_bubble.cc
@@ -101,14 +101,10 @@ GlobalErrorBubble::GlobalErrorBubble(Browser* browser,
g_signal_connect(bottom, "realize", G_CALLBACK(OnBottomRealizeThunk), this);
- BubbleGtk::ArrowLocationGtk arrow_location =
- base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT :
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
bubble_ = BubbleGtk::Show(anchor,
NULL,
content,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
index fc11c4b..ac0abc3 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc
@@ -620,6 +620,10 @@ void LocationBarViewGtk::Init(bool popup_window_mode) {
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED,
content::Source<Profile>(browser()->profile()));
+ registrar_.Add(this,
+ chrome::NOTIFICATION_FULLSCREEN_CHANGED,
+ content::Source<FullscreenController>(
+ browser()->fullscreen_controller()));
edit_bookmarks_enabled_.Init(prefs::kEditBookmarksEnabled,
profile->GetPrefs(),
base::Bind(&LocationBarViewGtk::UpdateStarIcon,
@@ -751,7 +755,7 @@ void LocationBarViewGtk::Update(const WebContents* contents) {
} else {
gtk_widget_queue_draw(widget());
}
- ZoomBubbleGtk::Close();
+ ZoomBubbleGtk::CloseBubble();
}
void LocationBarViewGtk::OnAutocompleteAccept(const GURL& url,
@@ -1184,6 +1188,11 @@ void LocationBarViewGtk::Observe(int type,
break;
}
+ case chrome::NOTIFICATION_FULLSCREEN_CHANGED: {
+ ZoomBubbleGtk::CloseBubble();
+ break;
+ }
+
default:
NOTREACHED();
}
@@ -1523,7 +1532,7 @@ gboolean LocationBarViewGtk::OnZoomButtonPress(GtkWidget* widget,
if (event->button == 1 && GetWebContents()) {
// If the zoom icon is clicked, show the zoom bubble and keep it open until
// it loses focus.
- ZoomBubbleGtk::Show(zoom_.get(), GetWebContents(), false);
+ ZoomBubbleGtk::ShowBubble(GetZoomBubbleAnchor(), GetWebContents(), false);
return TRUE;
}
return FALSE;
@@ -1575,7 +1584,14 @@ void LocationBarViewGtk::ShowZoomBubble() {
if (!zoom_.get() || toolbar_model_->GetInputInProgress())
return;
- ZoomBubbleGtk::Show(zoom_.get(), GetWebContents(), true);
+ ZoomBubbleGtk::ShowBubble(GetZoomBubbleAnchor(), GetWebContents(), true);
+}
+
+GtkWidget* LocationBarViewGtk::GetZoomBubbleAnchor() {
+ // |browser_->window()| is null until |browser_->CreateBrowserWindow()| has
+ // been called.
+ return browser_->window() && browser_->window()->IsFullscreen() ?
+ GTK_WIDGET(browser()->window()->GetNativeWindow()) : zoom_.get();
}
void LocationBarViewGtk::ShowStarBubble(const GURL& url,
@@ -1622,7 +1638,7 @@ void LocationBarViewGtk::UpdateZoomIcon() {
if (!zoom_controller || zoom_controller->IsAtDefaultZoom() ||
toolbar_model_->GetInputInProgress()) {
gtk_widget_hide(zoom_.get());
- ZoomBubbleGtk::Close();
+ ZoomBubbleGtk::CloseBubble();
return;
}
diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.h b/chrome/browser/ui/gtk/location_bar_view_gtk.h
index 0a2443d..e734a1f 100644
--- a/chrome/browser/ui/gtk/location_bar_view_gtk.h
+++ b/chrome/browser/ui/gtk/location_bar_view_gtk.h
@@ -102,9 +102,6 @@ class LocationBarViewGtk : public OmniboxEditController,
// Shows the Chrome To Mobile bubble.
void ShowChromeToMobileBubble();
- // Shows the bookmark bubble.
- void ShowZoomBubble();
-
// Happens when the zoom changes for the active tab. |can_show_bubble| will be
// true if it was a user action and a bubble could be shown.
void ZoomChangedForActiveTab(bool can_show_bubble);
@@ -395,6 +392,13 @@ class LocationBarViewGtk : public OmniboxEditController,
void ShowFirstRunBubbleInternal();
+ // Get the correct zoom bubble anchor according to whether the browser window
+ // is fullscreen or not.
+ GtkWidget* GetZoomBubbleAnchor();
+
+ // Shows the zoom bubble.
+ void ShowZoomBubble();
+
// Show or hide |tab_to_search_box_| and |tab_to_search_hint_| according to
// the value of |show_selected_keyword_|, |show_keyword_hint_|, and the
// available horizontal space in the location bar.
diff --git a/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc b/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc
index 5b64086..bbc495a 100644
--- a/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/one_click_signin_bubble_gtk.cc
@@ -78,15 +78,12 @@ OneClickSigninBubbleGtk::OneClickSigninBubbleGtk(
GtkWidget* const app_menu_widget =
browser_window_gtk->GetToolbar()->GetAppMenuButton();
gfx::Rect bounds = gtk_util::WidgetBounds(app_menu_widget);
- BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_LEFT : BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
- bubble_ =
- BubbleGtk::Show(app_menu_widget, &bounds, bubble_content,
- arrow_location,
- BubbleGtk::MATCH_SYSTEM_THEME |
- BubbleGtk::POPUP_WINDOW |
- BubbleGtk::GRAB_INPUT,
- theme_provider, this);
+ bubble_ = BubbleGtk::Show(app_menu_widget, &bounds, bubble_content,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
+ BubbleGtk::MATCH_SYSTEM_THEME |
+ BubbleGtk::POPUP_WINDOW |
+ BubbleGtk::GRAB_INPUT,
+ theme_provider, this);
gtk_widget_grab_focus(ok_button);
}
diff --git a/chrome/browser/ui/gtk/page_info_bubble_gtk.cc b/chrome/browser/ui/gtk/page_info_bubble_gtk.cc
index baed55f..f33adcd 100644
--- a/chrome/browser/ui/gtk/page_info_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/page_info_bubble_gtk.cc
@@ -119,13 +119,10 @@ PageInfoBubbleGtk::PageInfoBubbleGtk(gfx::NativeWindow parent,
InitContents();
- BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
bubble_ = BubbleGtk::Show(anchor_,
NULL, // |rect|
contents_,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_LEFT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc b/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc
index 15edaf3..660d563 100644
--- a/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/password_generation_bubble_gtk.cc
@@ -89,7 +89,7 @@ PasswordGenerationBubbleGtk::PasswordGenerationBubbleGtk(
bubble_ = BubbleGtk::Show(web_contents->GetContentNativeView(),
&anchor_rect,
content,
- BubbleGtk::ARROW_LOCATION_TOP_LEFT,
+ BubbleGtk::ANCHOR_TOP_LEFT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/script_bubble_gtk.cc b/chrome/browser/ui/gtk/script_bubble_gtk.cc
index 181313c..bc8c8e9 100644
--- a/chrome/browser/ui/gtk/script_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/script_bubble_gtk.cc
@@ -130,14 +130,10 @@ void ScriptBubbleGtk::BuildBubble() {
G_CALLBACK(&OnItemLinkClickedThunk), this);
}
- BubbleGtk::ArrowLocationGtk arrow_location =
- !base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
bubble_ = BubbleGtk::Show(anchor_,
NULL,
bubble_content,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_RIGHT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc b/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc
index c712723..a5acd69 100644
--- a/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/speech_recognition_bubble_gtk.cc
@@ -197,7 +197,7 @@ void SpeechRecognitionBubbleGtk::Show() {
bubble_ = BubbleGtk::Show(reference_widget,
&target_rect,
content,
- BubbleGtk::ARROW_LOCATION_TOP_LEFT,
+ BubbleGtk::ANCHOR_TOP_LEFT,
BubbleGtk::POPUP_WINDOW | BubbleGtk::GRAB_INPUT,
theme_provider,
this);
diff --git a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
index a5bda8f..a3202af 100644
--- a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
+++ b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
@@ -166,9 +166,6 @@ InternalPageInfoPopupGtk::InternalPageInfoPopupGtk(
gtk_widget_show_all(contents);
// Create the bubble.
- BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
BrowserWindowGtk* browser_window =
BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent);
GtkWidget* anchor = browser_window->
@@ -176,7 +173,7 @@ InternalPageInfoPopupGtk::InternalPageInfoPopupGtk(
bubble_ = BubbleGtk::Show(anchor,
NULL, // |rect|
contents,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_LEFT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
@@ -239,13 +236,10 @@ WebsiteSettingsPopupGtk::WebsiteSettingsPopupGtk(
InitContents();
- BubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
- BubbleGtk::ARROW_LOCATION_TOP_RIGHT :
- BubbleGtk::ARROW_LOCATION_TOP_LEFT;
bubble_ = BubbleGtk::Show(anchor_,
NULL, // |rect|
contents_,
- arrow_location,
+ BubbleGtk::ANCHOR_TOP_LEFT,
BubbleGtk::MATCH_SYSTEM_THEME |
BubbleGtk::POPUP_WINDOW |
BubbleGtk::GRAB_INPUT,
diff --git a/chrome/browser/ui/gtk/zoom_bubble_gtk.cc b/chrome/browser/ui/gtk/zoom_bubble_gtk.cc
index cb27846..9d82d80a 100644
--- a/chrome/browser/ui/gtk/zoom_bubble_gtk.cc
+++ b/chrome/browser/ui/gtk/zoom_bubble_gtk.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/ui/gtk/zoom_bubble_gtk.h"
+#include "base/i18n/rtl.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
@@ -33,9 +34,9 @@ const int kBubbleAnchorHeight = 25;
} // namespace
// static
-void ZoomBubbleGtk::Show(GtkWidget* anchor,
- content::WebContents* web_contents,
- bool auto_close) {
+void ZoomBubbleGtk::ShowBubble(GtkWidget* anchor,
+ content::WebContents* web_contents,
+ bool auto_close) {
// If the bubble is already showing and its |auto_close_| value is equal to
// |auto_close|, the bubble can be reused and only the label text needs to
// be updated.
@@ -47,7 +48,7 @@ void ZoomBubbleGtk::Show(GtkWidget* anchor,
// If the bubble is already showing but its |auto_close_| value is not equal
// to |auto_close|, the bubble's focus properties must change, so the
// current bubble must be closed and a new one created.
- Close();
+ CloseBubble();
DCHECK(!g_bubble);
g_bubble = new ZoomBubbleGtk(anchor, web_contents, auto_close);
@@ -55,9 +56,14 @@ void ZoomBubbleGtk::Show(GtkWidget* anchor,
}
// static
-void ZoomBubbleGtk::Close() {
+void ZoomBubbleGtk::CloseBubble() {
if (g_bubble)
- g_bubble->CloseBubble();
+ g_bubble->Close();
+}
+
+// static
+bool ZoomBubbleGtk::IsShowing() {
+ return g_bubble != NULL;
}
ZoomBubbleGtk::ZoomBubbleGtk(GtkWidget* anchor,
@@ -104,11 +110,11 @@ ZoomBubbleGtk::ZoomBubbleGtk(GtkWidget* anchor,
gtk_container_set_focus_child(GTK_CONTAINER(container), NULL);
- gfx::Rect rect(kBubbleAnchorWidth, kBubbleAnchorHeight);
- BubbleGtk::ArrowLocationGtk arrow_location =
- BubbleGtk::ARROW_LOCATION_TOP_MIDDLE;
+ gfx::Rect rect = gfx::Rect(kBubbleAnchorWidth, kBubbleAnchorHeight);
+ BubbleGtk::FrameStyle frame_style = gtk_widget_is_toplevel(anchor) ?
+ BubbleGtk::FIXED_TOP_RIGHT : BubbleGtk::ANCHOR_TOP_MIDDLE;
int bubble_options = BubbleGtk::MATCH_SYSTEM_THEME | BubbleGtk::POPUP_WINDOW;
- bubble_ = BubbleGtk::Show(anchor, &rect, event_box_, arrow_location,
+ bubble_ = BubbleGtk::Show(anchor, &rect, event_box_, frame_style,
auto_close ? bubble_options : bubble_options | BubbleGtk::GRAB_INPUT,
theme_service, NULL);
@@ -167,7 +173,7 @@ void ZoomBubbleGtk::StartTimerIfNecessary() {
FROM_HERE,
base::TimeDelta::FromMilliseconds(kBubbleCloseDelay),
this,
- &ZoomBubbleGtk::CloseBubble);
+ &ZoomBubbleGtk::Close);
}
}
@@ -176,7 +182,7 @@ void ZoomBubbleGtk::StopTimerIfNecessary() {
timer_.Stop();
}
-void ZoomBubbleGtk::CloseBubble() {
+void ZoomBubbleGtk::Close() {
DCHECK(bubble_);
bubble_->Close();
}
diff --git a/chrome/browser/ui/gtk/zoom_bubble_gtk.h b/chrome/browser/ui/gtk/zoom_bubble_gtk.h
index c4d8397..fe79917 100644
--- a/chrome/browser/ui/gtk/zoom_bubble_gtk.h
+++ b/chrome/browser/ui/gtk/zoom_bubble_gtk.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_UI_GTK_ZOOM_BUBBLE_GTK_H_
#define CHROME_BROWSER_UI_GTK_ZOOM_BUBBLE_GTK_H_
+#include <gtk/gtk.h>
+
#include "base/basictypes.h"
#include "base/timer.h"
#include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
@@ -18,13 +20,18 @@ class WebContents;
class ZoomBubbleGtk {
public:
- // Shows the zoom bubble, pointing at |anchor_widget|.
- static void Show(GtkWidget* anchor,
- content::WebContents* web_contents,
- bool auto_close);
+ // Shows the zoom bubble below |anchor_widget| with an arrow pointing at
+ // |anchor_widget|. If |anchor_widget| is a toplevel window, the bubble will
+ // fixed positioned in the top right of corner of the widget with no arrow.
+ static void ShowBubble(GtkWidget* anchor,
+ content::WebContents* web_contents,
+ bool auto_close);
- // Closes the zoom bubble.
- static void Close();
+ // Whether the zoom bubble is currently showing.
+ static bool IsShowing();
+
+ // Closes the zoom bubble (if there is one).
+ static void CloseBubble();
private:
ZoomBubbleGtk(GtkWidget* anchor,
@@ -44,7 +51,7 @@ class ZoomBubbleGtk {
void Refresh();
// Closes the zoom bubble.
- void CloseBubble();
+ void Close();
// Notified when the bubble is destroyed so this instance can be deleted.
CHROMEGTK_CALLBACK_0(ZoomBubbleGtk, void, OnDestroy);