Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1475)

Unified Diff: chrome/browser/gtk/info_bubble_gtk.cc

Issue 332022: GTK: Fix browser action bubble arrow positions. (Closed)
Patch Set: update comment Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/gtk/info_bubble_gtk.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/gtk/info_bubble_gtk.cc
diff --git a/chrome/browser/gtk/info_bubble_gtk.cc b/chrome/browser/gtk/info_bubble_gtk.cc
index 68fbc2d3470b9ee904f7fa46bf7ce5c9bd4bffea..a480905abf1ac09c97e67df271877a007c09883a 100644
--- a/chrome/browser/gtk/info_bubble_gtk.cc
+++ b/chrome/browser/gtk/info_bubble_gtk.cc
@@ -47,10 +47,11 @@ const GdkColor kFrameColor = GDK_COLOR_RGB(0x63, 0x63, 0x63);
InfoBubbleGtk* InfoBubbleGtk::Show(GtkWindow* toplevel_window,
const gfx::Rect& rect,
GtkWidget* content,
+ ArrowLocationGtk arrow_location,
GtkThemeProvider* provider,
InfoBubbleGtkDelegate* delegate) {
InfoBubbleGtk* bubble = new InfoBubbleGtk(provider);
- bubble->Init(toplevel_window, rect, content);
+ bubble->Init(toplevel_window, rect, content, arrow_location);
bubble->set_delegate(delegate);
return bubble;
}
@@ -62,7 +63,8 @@ InfoBubbleGtk::InfoBubbleGtk(GtkThemeProvider* provider)
accel_group_(gtk_accel_group_new()),
toplevel_window_(NULL),
mask_region_(NULL),
- arrow_location_(ARROW_LOCATION_TOP_LEFT) {
+ preferred_arrow_location_(ARROW_LOCATION_TOP_LEFT),
+ current_arrow_location_(ARROW_LOCATION_TOP_LEFT) {
}
InfoBubbleGtk::~InfoBubbleGtk() {
@@ -85,10 +87,12 @@ InfoBubbleGtk::~InfoBubbleGtk() {
void InfoBubbleGtk::Init(GtkWindow* toplevel_window,
const gfx::Rect& rect,
- GtkWidget* content) {
+ GtkWidget* content,
+ ArrowLocationGtk arrow_location) {
DCHECK(!window_);
toplevel_window_ = toplevel_window;
rect_ = rect;
+ preferred_arrow_location_ = arrow_location;
window_ = gtk_window_new(GTK_WINDOW_POPUP);
gtk_widget_set_app_paintable(window_, TRUE);
@@ -112,12 +116,7 @@ void InfoBubbleGtk::Init(GtkWindow* toplevel_window,
// HandleSizeAllocate, so the mask can be applied to the GdkWindow.
gtk_widget_realize(window_);
- // For RTL, we will have to move the window again when it is allocated, but
- // this should be somewhat close to its final position.
- MoveWindow();
- GtkRequisition req;
- gtk_widget_size_request(window_, &req);
-
+ UpdateArrowLocation(true); // Force move and reshape.
StackWindow();
gtk_widget_add_events(window_, GDK_BUTTON_PRESS_MASK |
@@ -176,85 +175,84 @@ std::vector<GdkPoint> InfoBubbleGtk::MakeFramePolygonPoints(
using gtk_util::MakeBidiGdkPoint;
std::vector<GdkPoint> points;
- // This name isn't completely accurate; the arrow location can differ from its
- // expected location for LTR/RTL if needed for the bubble to fit onscreen.
- bool ltr = (arrow_location == ARROW_LOCATION_TOP_LEFT);
+ bool on_left = (arrow_location == ARROW_LOCATION_TOP_LEFT);
- // If we have a stroke, we have to offset some of our points by 1 pixel.
- // We have to inset by 1 pixel when we draw horizontal lines that are on the
- // bottom or when we draw vertical lines that are closer to the end (end is
- // right for ltr).
+ // 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;
- // We use this one for LTR.
- int x_off_l = ltr ? y_off : 0;
+ // 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.
- int x_off_r = !ltr ? -y_off : 0;
+ int x_off_r = !on_left ? -y_off : 0;
// Top left corner.
points.push_back(MakeBidiGdkPoint(
- x_off_r, kArrowSize + kCornerSize - 1, width, ltr));
+ x_off_r, kArrowSize + kCornerSize - 1, width, on_left));
points.push_back(MakeBidiGdkPoint(
- kCornerSize + x_off_r - 1, kArrowSize, width, ltr));
+ kCornerSize + x_off_r - 1, kArrowSize, width, on_left));
// The arrow.
points.push_back(MakeBidiGdkPoint(
- kArrowX - kArrowSize + x_off_r, kArrowSize, width, ltr));
+ kArrowX - kArrowSize + x_off_r, kArrowSize, width, on_left));
points.push_back(MakeBidiGdkPoint(
- kArrowX + x_off_r, 0, width, ltr));
+ kArrowX + x_off_r, 0, width, on_left));
points.push_back(MakeBidiGdkPoint(
- kArrowX + 1 + x_off_l, 0, width, ltr));
+ kArrowX + 1 + x_off_l, 0, width, on_left));
points.push_back(MakeBidiGdkPoint(
- kArrowX + kArrowSize + 1 + x_off_l, kArrowSize, width, ltr));
+ kArrowX + kArrowSize + 1 + x_off_l, kArrowSize, width, on_left));
// Top right corner.
points.push_back(MakeBidiGdkPoint(
- width - kCornerSize + 1 + x_off_l, kArrowSize, width, ltr));
+ width - kCornerSize + 1 + x_off_l, kArrowSize, width, on_left));
points.push_back(MakeBidiGdkPoint(
- width + x_off_l, kArrowSize + kCornerSize - 1, width, ltr));
+ width + x_off_l, kArrowSize + kCornerSize - 1, width, on_left));
// Bottom right corner.
points.push_back(MakeBidiGdkPoint(
- width + x_off_l, height - kCornerSize, width, ltr));
+ width + x_off_l, height - kCornerSize, width, on_left));
points.push_back(MakeBidiGdkPoint(
- width - kCornerSize + x_off_r, height + y_off, width, ltr));
+ width - kCornerSize + x_off_r, height + y_off, width, on_left));
// Bottom left corner.
points.push_back(MakeBidiGdkPoint(
- kCornerSize + x_off_l, height + y_off, width, ltr));
+ kCornerSize + x_off_l, height + y_off, width, on_left));
points.push_back(MakeBidiGdkPoint(
- x_off_r, height - kCornerSize, width, ltr));
+ x_off_r, height - kCornerSize, width, on_left));
return points;
}
InfoBubbleGtk::ArrowLocationGtk InfoBubbleGtk::GetArrowLocation(
- int arrow_x, int width) {
- bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT);
+ ArrowLocationGtk preferred_location, int arrow_x, int width) {
+ bool wants_left = (preferred_location == ARROW_LOCATION_TOP_LEFT);
int screen_width = gdk_screen_get_width(gdk_screen_get_default());
bool left_is_onscreen = (arrow_x - kArrowX + width < screen_width);
bool right_is_onscreen = (arrow_x + kArrowX - width >= 0);
- // Use the expected location for our LTR/RTL-ness if it fits onscreen, use
- // whatever fits otherwise, and use the expected location if neither fits.
- if (left_is_onscreen && (ltr || !right_is_onscreen))
+ // Use the requested location if it fits onscreen, use whatever fits
+ // otherwise, and use the requested location if neither fits.
+ if (left_is_onscreen && (wants_left || !right_is_onscreen))
return ARROW_LOCATION_TOP_LEFT;
- if (right_is_onscreen && (!ltr || !left_is_onscreen))
+ if (right_is_onscreen && (!wants_left || !left_is_onscreen))
return ARROW_LOCATION_TOP_RIGHT;
- return (ltr ? ARROW_LOCATION_TOP_LEFT : ARROW_LOCATION_TOP_RIGHT);
+ return (wants_left ? ARROW_LOCATION_TOP_LEFT : ARROW_LOCATION_TOP_RIGHT);
}
-bool InfoBubbleGtk::UpdateArrowLocation() {
+bool InfoBubbleGtk::UpdateArrowLocation(bool force_move_and_reshape) {
gint toplevel_x = 0, toplevel_y = 0;
gdk_window_get_position(
GTK_WIDGET(toplevel_window_)->window, &toplevel_x, &toplevel_y);
- ArrowLocationGtk old_location = arrow_location_;
- arrow_location_ = GetArrowLocation(
+ ArrowLocationGtk old_location = current_arrow_location_;
+ current_arrow_location_ = GetArrowLocation(
+ preferred_arrow_location_,
toplevel_x + rect_.x() + (rect_.width() / 2), // arrow_x
window_->allocation.width);
- if (arrow_location_ != old_location) {
+ if (force_move_and_reshape || current_arrow_location_ != old_location) {
UpdateWindowShape();
MoveWindow();
// We need to redraw the entire window to repaint its border.
@@ -270,7 +268,8 @@ void InfoBubbleGtk::UpdateWindowShape() {
mask_region_ = NULL;
}
std::vector<GdkPoint> points = MakeFramePolygonPoints(
- arrow_location_, window_->allocation.width, window_->allocation.height,
+ current_arrow_location_,
+ window_->allocation.width, window_->allocation.height,
FRAME_MASK);
mask_region_ = gdk_region_polygon(&points[0],
points.size(),
@@ -284,9 +283,9 @@ void InfoBubbleGtk::MoveWindow() {
GTK_WIDGET(toplevel_window_)->window, &toplevel_x, &toplevel_y);
gint screen_x = 0;
- if (arrow_location_ == ARROW_LOCATION_TOP_LEFT) {
+ if (current_arrow_location_ == ARROW_LOCATION_TOP_LEFT) {
screen_x = toplevel_x + rect_.x() + (rect_.width() / 2) - kArrowX;
- } else if (arrow_location_ == ARROW_LOCATION_TOP_RIGHT) {
+ } else if (current_arrow_location_ == ARROW_LOCATION_TOP_RIGHT) {
screen_x = toplevel_x + rect_.x() + (rect_.width() / 2) -
window_->allocation.width + kArrowX;
} else {
@@ -372,7 +371,8 @@ gboolean InfoBubbleGtk::HandleExpose() {
// Stroke the frame border.
std::vector<GdkPoint> points = MakeFramePolygonPoints(
- arrow_location_, window_->allocation.width, window_->allocation.height,
+ current_arrow_location_,
+ window_->allocation.width, window_->allocation.height,
FRAME_STROKE);
gdk_draw_polygon(drawable, gc, FALSE, &points[0], points.size());
@@ -383,9 +383,9 @@ gboolean InfoBubbleGtk::HandleExpose() {
// When our size is initially allocated or changed, we need to recompute
// and apply our shape mask region.
void InfoBubbleGtk::HandleSizeAllocate() {
- if (!UpdateArrowLocation()) {
+ if (!UpdateArrowLocation(false)) {
UpdateWindowShape();
- if (arrow_location_ == ARROW_LOCATION_TOP_RIGHT)
+ if (current_arrow_location_ == ARROW_LOCATION_TOP_RIGHT)
MoveWindow();
}
}
@@ -420,7 +420,7 @@ gboolean InfoBubbleGtk::HandleDestroy() {
}
gboolean InfoBubbleGtk::HandleToplevelConfigure(GdkEventConfigure* event) {
- if (!UpdateArrowLocation())
+ if (!UpdateArrowLocation(false))
MoveWindow();
StackWindow();
return FALSE;
« no previous file with comments | « chrome/browser/gtk/info_bubble_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698