diff options
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/browser.cc | 10 | ||||
-rw-r--r-- | chrome/browser/browser.h | 6 | ||||
-rw-r--r-- | chrome/browser/cocoa/status_bubble_mac.h | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/status_bubble_mac.mm | 10 | ||||
-rw-r--r-- | chrome/browser/gtk/download_shelf_gtk.cc | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/rounded_window.cc | 18 | ||||
-rw-r--r-- | chrome/browser/gtk/rounded_window.h | 14 | ||||
-rw-r--r-- | chrome/browser/gtk/status_bubble_gtk.cc | 140 | ||||
-rw-r--r-- | chrome/browser/gtk/status_bubble_gtk.h | 35 | ||||
-rw-r--r-- | chrome/browser/gtk/tab_contents_container_gtk.cc | 14 | ||||
-rw-r--r-- | chrome/browser/status_bubble.h | 9 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_delegate.h | 9 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_mac.mm | 7 | ||||
-rw-r--r-- | chrome/browser/views/status_bubble_views.cc | 35 | ||||
-rw-r--r-- | chrome/browser/views/status_bubble_views.h | 7 | ||||
-rw-r--r-- | chrome/browser/views/tab_contents/tab_contents_view_gtk.cc | 10 | ||||
-rw-r--r-- | chrome/browser/views/tab_contents/tab_contents_view_win.cc | 10 |
18 files changed, 275 insertions, 74 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 7b728e3..ebca665 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -7,6 +7,7 @@ #include "app/animation.h" #include "app/l10n_util.h" #include "base/command_line.h" +#include "base/gfx/point.h" #include "base/keyboard_codes.h" #include "base/logging.h" #include "base/string_util.h" @@ -2020,16 +2021,15 @@ void Browser::URLStarredChanged(TabContents* source, bool starred) { window_->SetStarredState(starred); } -void Browser::ContentsMouseEvent(TabContents* source, bool motion) { +void Browser::ContentsMouseEvent( + TabContents* source, const gfx::Point& location, bool motion) { if (!GetStatusBubble()) return; if (source == GetSelectedTabContents()) { - if (motion) { - GetStatusBubble()->MouseMoved(); - } else { + GetStatusBubble()->MouseMoved(location, !motion); + if (!motion) GetStatusBubble()->SetURL(GURL(), std::wstring()); - } } } diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 243b464..6e65c6a 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -35,6 +35,9 @@ class Profile; class SkBitmap; class StatusBubble; class TabNavigation; +namespace gfx { +class Point; +} class Browser : public TabStripModelDelegate, public TabStripModelObserver, @@ -542,7 +545,8 @@ class Browser : public TabStripModelDelegate, 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 ContentsMouseEvent(TabContents* source, bool motion); + virtual void ContentsMouseEvent( + TabContents* source, const gfx::Point& location, bool motion); virtual void ContentsZoomChange(bool zoom_in); virtual void TabContentsFocused(TabContents* tab_content); virtual bool TakeFocus(bool reverse); diff --git a/chrome/browser/cocoa/status_bubble_mac.h b/chrome/browser/cocoa/status_bubble_mac.h index f110b1d..8d33f04 100644 --- a/chrome/browser/cocoa/status_bubble_mac.h +++ b/chrome/browser/cocoa/status_bubble_mac.h @@ -36,7 +36,7 @@ class StatusBubbleMac : public StatusBubble { virtual void SetStatus(const std::wstring& status); virtual void SetURL(const GURL& url, const std::wstring& languages); virtual void Hide(); - virtual void MouseMoved(); + virtual void MouseMoved(const gfx::Point& location, bool left_content); virtual void UpdateDownloadShelfVisibility(bool visible); // Mac-specific method: Update the size and position of the status bubble to diff --git a/chrome/browser/cocoa/status_bubble_mac.mm b/chrome/browser/cocoa/status_bubble_mac.mm index 9305100..55b57df 100644 --- a/chrome/browser/cocoa/status_bubble_mac.mm +++ b/chrome/browser/cocoa/status_bubble_mac.mm @@ -8,6 +8,7 @@ #include "app/gfx/text_elider.h" #include "base/compiler_specific.h" +#include "base/gfx/point.h" #include "base/message_loop.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" @@ -206,10 +207,15 @@ void StatusBubbleMac::Hide() { url_text_ = nil; } -void StatusBubbleMac::MouseMoved() { +void StatusBubbleMac::MouseMoved( + const gfx::Point& location, bool left_content) { + if (left_content) + return; + if (!window_) return; + // TODO(thakis): Use 'location' here instead of NSEvent. NSPoint cursor_location = [NSEvent mouseLocation]; --cursor_location.y; // docs say the y coord starts at 1 not 0; don't ask why @@ -330,7 +336,7 @@ void StatusBubbleMac::Create() { Attach(); [view setCornerFlags:kRoundedTopRightCorner]; - MouseMoved(); + MouseMoved(gfx::Point(), false); } void StatusBubbleMac::Attach() { diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index 336454f..1e13892 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -127,7 +127,7 @@ DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent) FALSE, FALSE, 0); // Make sure we are at the very end. gtk_box_reorder_child(GTK_BOX(parent), slide_widget_->widget(), 0); - slide_widget_->Open(); + Show(); } DownloadShelfGtk::~DownloadShelfGtk() { @@ -155,6 +155,7 @@ bool DownloadShelfGtk::IsClosing() const { void DownloadShelfGtk::Show() { slide_widget_->Open(); + browser_->UpdateDownloadShelfVisibility(true); } void DownloadShelfGtk::Close() { @@ -162,8 +163,6 @@ void DownloadShelfGtk::Close() { // we are on top. gdk_window_raise(shelf_.get()->window); slide_widget_->Close(); - - // TODO(estade): Remove. The status bubble should query its window instead. browser_->UpdateDownloadShelfVisibility(false); } @@ -224,8 +223,6 @@ void DownloadShelfGtk::RemoveDownloadItem(DownloadItemGtk* download_item) { delete download_item; if (download_items_.empty()) { slide_widget_->CloseWithoutAnimation(); - - // TODO(estade): Remove. The status bubble should query its window instead. browser_->UpdateDownloadShelfVisibility(false); } } diff --git a/chrome/browser/gtk/rounded_window.cc b/chrome/browser/gtk/rounded_window.cc index 79af804..b6174b4 100644 --- a/chrome/browser/gtk/rounded_window.cc +++ b/chrome/browser/gtk/rounded_window.cc @@ -184,6 +184,8 @@ void ActAsRoundedWindow( GtkWidget* widget, const GdkColor& color, int corner_size, int rounded_edges, int drawn_borders) { DCHECK(widget); + DCHECK(!g_object_get_data(G_OBJECT(widget), kRoundedData)); + gtk_widget_set_app_paintable(widget, TRUE); g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(OnRoundedWindowExpose), NULL); @@ -209,10 +211,26 @@ void StopActingAsRoundedWindow(GtkWidget* widget) { g_signal_handlers_disconnect_by_func(widget, reinterpret_cast<gpointer>(OnStyleSet), NULL); + delete static_cast<RoundedWindowData*>( + g_object_steal_data(G_OBJECT(widget), kRoundedData)); + if (GTK_WIDGET_REALIZED(widget)) gdk_window_shape_combine_mask(widget->window, NULL, 0, 0); } +void SetRoundedWindowEdgesAndBorders(GtkWidget* widget, + int corner_size, + int rounded_edges, + int drawn_borders) { + DCHECK(widget); + RoundedWindowData* data = static_cast<RoundedWindowData*>( + g_object_get_data(G_OBJECT(widget), kRoundedData)); + DCHECK(data); + data->corner_size = corner_size; + data->rounded_edges = rounded_edges; + data->drawn_borders = drawn_borders; +} + void SetRoundedWindowBorderColor(GtkWidget* widget, GdkColor color) { DCHECK(widget); RoundedWindowData* data = static_cast<RoundedWindowData*>( diff --git a/chrome/browser/gtk/rounded_window.h b/chrome/browser/gtk/rounded_window.h index 46287ff..95f91d9 100644 --- a/chrome/browser/gtk/rounded_window.h +++ b/chrome/browser/gtk/rounded_window.h @@ -39,13 +39,21 @@ void ActAsRoundedWindow( GtkWidget* widget, const GdkColor& color, int corner_size, int rounded_edges, int drawn_borders); -// Undo most of the actions of ActAsRoundedWindow. +// Undoes most of the actions of ActAsRoundedWindow(). void StopActingAsRoundedWindow(GtkWidget* widget); -// Sets the color of the border on a widget that was returned from -// ActAsRoundedWindow(). +// Sets edge and border properties on a widget that has already been configured +// with ActAsRoundedWindow(). +void SetRoundedWindowEdgesAndBorders(GtkWidget* widget, + int corner_size, + int rounded_edges, + int drawn_borders); + +// Sets the color of the border on a widget that has already been configured +// with ActAsRoundedWindow(). void SetRoundedWindowBorderColor(GtkWidget* widget, GdkColor color); + } // namespace gtk_util #endif // CHROME_BROWSER_GTK_ROUNDED_WINDOW_H_ diff --git a/chrome/browser/gtk/status_bubble_gtk.cc b/chrome/browser/gtk/status_bubble_gtk.cc index 5ee330d..a57c05b 100644 --- a/chrome/browser/gtk/status_bubble_gtk.cc +++ b/chrome/browser/gtk/status_bubble_gtk.cc @@ -30,11 +30,20 @@ const int kCornerSize = 3; // Milliseconds before we hide the status bubble widget when you mouseout. const int kHideDelay = 250; +// How close the mouse can get to the infobubble before it starts sliding +// off-screen. +const int kMousePadding = 20; + } // namespace StatusBubbleGtk::StatusBubbleGtk(Profile* profile) : theme_provider_(GtkThemeProvider::GetFrom(profile)), - timer_factory_(this) { + padding_(NULL), + label_(NULL), + timer_factory_(this), + flip_horizontally_(false), + y_offset_(0), + download_shelf_is_visible_(false) { InitWidgets(); theme_provider_->InitThemesFor(this); @@ -114,13 +123,77 @@ void StatusBubbleGtk::HideInASecond() { kHideDelay); } -void StatusBubbleGtk::MouseMoved() { - // We can't do that fancy sliding behaviour where the status bubble slides - // out of the window because the window manager gets in the way. So totally - // ignore this message for now. - // - // TODO(erg): At least get some sliding behaviour so that it slides out of - // the way to hide the status bubble on mouseover. +void StatusBubbleGtk::MouseMoved( + const gfx::Point& location, bool left_content) { + if (!GTK_WIDGET_REALIZED(container_.get())) + return; + + GtkWidget* parent = gtk_widget_get_parent(container_.get()); + if (!parent || !GTK_WIDGET_REALIZED(parent)) + return; + + int old_y_offset = y_offset_; + bool old_flip_horizontally = flip_horizontally_; + + if (left_content) { + SetFlipHorizontally(false); + y_offset_ = 0; + } else { + GtkWidget* toplevel = gtk_widget_get_toplevel(container_.get()); + if (!toplevel || !GTK_WIDGET_REALIZED(toplevel)) + return; + + bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT); + + GtkRequisition requisition; + gtk_widget_size_request(container_.get(), &requisition); + + // Get our base position (that is, not including the current offset) + // relative to the origin of the root window. + gint toplevel_x = 0, toplevel_y = 0; + gdk_window_get_position(toplevel->window, &toplevel_x, &toplevel_y); + gfx::Rect parent_rect = + gtk_util::GetWidgetRectRelativeToToplevel(parent); + gfx::Rect bubble_rect( + toplevel_x + parent_rect.x() + + (ltr ? 0 : parent->allocation.width - requisition.width), + toplevel_y + parent_rect.y() + + parent->allocation.height - requisition.height, + requisition.width, + requisition.height); + + int left_threshold = + bubble_rect.x() - bubble_rect.height() - kMousePadding; + int right_threshold = + bubble_rect.right() + bubble_rect.height() + kMousePadding; + int top_threshold = bubble_rect.y() - kMousePadding; + + if (((ltr && location.x() < right_threshold) || + (!ltr && location.x() > left_threshold)) && + location.y() > top_threshold) { + if (download_shelf_is_visible_) { + SetFlipHorizontally(true); + y_offset_ = 0; + } else { + SetFlipHorizontally(false); + int distance = std::max(ltr ? + location.x() - right_threshold : + left_threshold - location.x(), + top_threshold - location.y()); + y_offset_ = std::min(-1 * distance, requisition.height); + } + } else { + SetFlipHorizontally(false); + y_offset_ = 0; + } + } + + if (y_offset_ != old_y_offset || flip_horizontally_ != old_flip_horizontally) + gtk_widget_queue_resize_no_redraw(parent); +} + +void StatusBubbleGtk::UpdateDownloadShelfVisibility(bool visible) { + download_shelf_is_visible_ = visible; } void StatusBubbleGtk::Observe(NotificationType type, @@ -132,14 +205,16 @@ void StatusBubbleGtk::Observe(NotificationType type, } void StatusBubbleGtk::InitWidgets() { + bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT); + label_ = gtk_label_new(NULL); - GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); - gtk_alignment_set_padding(GTK_ALIGNMENT(padding), + padding_ = gtk_alignment_new(0, 0, 1, 1); + gtk_alignment_set_padding(GTK_ALIGNMENT(padding_), kInternalTopBottomPadding, kInternalTopBottomPadding, - kInternalLeftRightPadding, - kInternalLeftRightPadding + kCornerSize); - gtk_container_add(GTK_CONTAINER(padding), label_); + kInternalLeftRightPadding + (ltr ? 0 : kCornerSize), + kInternalLeftRightPadding + (ltr ? kCornerSize : 0)); + gtk_container_add(GTK_CONTAINER(padding_), label_); container_.Own(gtk_event_box_new()); gtk_util::ActAsRoundedWindow( @@ -147,7 +222,14 @@ void StatusBubbleGtk::InitWidgets() { gtk_util::ROUNDED_TOP_RIGHT, gtk_util::BORDER_TOP | gtk_util::BORDER_RIGHT); gtk_widget_set_name(container_.get(), "status-bubble"); - gtk_container_add(GTK_CONTAINER(container_.get()), padding); + gtk_container_add(GTK_CONTAINER(container_.get()), padding_); + + // We need to listen for mouse motion events, since a fast-moving pointer may + // enter our window without us getting any motion events on the browser near + // enough for us to run away. + gtk_widget_add_events(container_.get(), GDK_POINTER_MOTION_MASK); + g_signal_connect(container_.get(), "motion-notify-event", + G_CALLBACK(HandleMotionNotifyThunk), this); UserChangedTheme(); } @@ -172,3 +254,33 @@ void StatusBubbleGtk::UserChangedTheme() { gtk_util::SetRoundedWindowBorderColor(container_.get(), theme_provider_->GetBorderColor()); } + +void StatusBubbleGtk::SetFlipHorizontally(bool flip_horizontally) { + if (flip_horizontally == flip_horizontally_) + return; + + flip_horizontally_ = flip_horizontally; + + bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT); + bool on_left = (ltr && !flip_horizontally) || (!ltr && flip_horizontally); + + gtk_alignment_set_padding(GTK_ALIGNMENT(padding_), + kInternalTopBottomPadding, kInternalTopBottomPadding, + kInternalLeftRightPadding + (on_left ? 0 : kCornerSize), + kInternalLeftRightPadding + (on_left ? kCornerSize : 0)); + // The rounded window code flips these arguments if we're RTL. + gtk_util::SetRoundedWindowEdgesAndBorders( + container_.get(), + kCornerSize, + flip_horizontally ? + gtk_util::ROUNDED_TOP_LEFT : + gtk_util::ROUNDED_TOP_RIGHT, + gtk_util::BORDER_TOP | + (flip_horizontally ? gtk_util::BORDER_LEFT : gtk_util::BORDER_RIGHT)); + gtk_widget_queue_draw(container_.get()); +} + +gboolean StatusBubbleGtk::HandleMotionNotify(GdkEventMotion* event) { + MouseMoved(gfx::Point(event->x_root, event->y_root), false); + return FALSE; +} diff --git a/chrome/browser/gtk/status_bubble_gtk.h b/chrome/browser/gtk/status_bubble_gtk.h index 87b43d3..9784668 100644 --- a/chrome/browser/gtk/status_bubble_gtk.h +++ b/chrome/browser/gtk/status_bubble_gtk.h @@ -9,6 +9,7 @@ #include <string> +#include "base/gfx/point.h" #include "base/scoped_ptr.h" #include "base/task.h" #include "chrome/browser/status_bubble.h" @@ -30,16 +31,19 @@ class StatusBubbleGtk : public StatusBubble, explicit StatusBubbleGtk(Profile* profile); virtual ~StatusBubbleGtk(); + bool flip_horizontally() const { return flip_horizontally_; } + int y_offset() const { return y_offset_; } + // StatusBubble implementation. virtual void SetStatus(const std::wstring& status); virtual void SetURL(const GURL& url, const std::wstring& languages); virtual void Hide(); - virtual void MouseMoved(); + virtual void MouseMoved(const gfx::Point& location, bool left_content); // Called when the download shelf becomes visible or invisible. // This is used by to ensure that the status bubble does not obscure // the download shelf, when it is visible. - virtual void UpdateDownloadShelfVisibility(bool visible) { } + virtual void UpdateDownloadShelfVisibility(bool visible); // Overridden from NotificationObserver: void Observe(NotificationType type, @@ -69,6 +73,19 @@ class StatusBubbleGtk : public StatusBubble, // Notification from the window that we should retheme ourself. void UserChangedTheme(); + // Sets whether the bubble should be flipped horizontally and displayed on the + // opposite side of the tab contents. Reshapes the container and queues a + // redraw if necessary. + void SetFlipHorizontally(bool flip_horizontally); + + static gboolean HandleMotionNotifyThunk(GtkWidget* widget, + GdkEventMotion* event, + gpointer user_data) { + return reinterpret_cast<StatusBubbleGtk*>(user_data)-> + HandleMotionNotify(event); + } + gboolean HandleMotionNotify(GdkEventMotion* event); + NotificationRegistrar registrar_; // Provides colors. @@ -77,6 +94,9 @@ class StatusBubbleGtk : public StatusBubble, // The toplevel event box. OwnedWidgetGtk container_; + // The GtkAlignment holding |label_|. + GtkWidget* padding_; + // The GtkLabel holding the text. GtkWidget* label_; @@ -88,6 +108,17 @@ class StatusBubbleGtk : public StatusBubble, // A timer that hides our window after a delay. ScopedRunnableMethodFactory<StatusBubbleGtk> timer_factory_; + + // Should the bubble be flipped horizontally (e.g. displayed on the right for + // an LTR language)? We move the bubble to the other side of the tab contents + // rather than sliding it down when the download shelf is visible. + bool flip_horizontally_; + + // Vertical offset used to hide the status bubble as the pointer nears it. + int y_offset_; + + // If the download shelf is visible, do not obscure it. + bool download_shelf_is_visible_; }; #endif // CHROME_BROWSER_GTK_STATUS_BUBBLE_GTK_H_ diff --git a/chrome/browser/gtk/tab_contents_container_gtk.cc b/chrome/browser/gtk/tab_contents_container_gtk.cc index 9425194..a4fe973 100644 --- a/chrome/browser/gtk/tab_contents_container_gtk.cc +++ b/chrome/browser/gtk/tab_contents_container_gtk.cc @@ -188,26 +188,28 @@ void TabContentsContainerGtk::OnFixedSizeAllocate( void TabContentsContainerGtk::OnSetFloatingPosition( GtkFloatingContainer* floating_container, GtkAllocation* allocation, TabContentsContainerGtk* tab_contents_container) { - GtkWidget* status = tab_contents_container->status_bubble_->widget(); + StatusBubbleGtk* status = tab_contents_container->status_bubble_; // Look at the size request of the status bubble and tell the // GtkFloatingContainer where we want it positioned. GtkRequisition requisition; - gtk_widget_size_request(status, &requisition); + gtk_widget_size_request(status->widget(), &requisition); + + bool ltr = (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT); GValue value = { 0, }; g_value_init(&value, G_TYPE_INT); - if (l10n_util::GetTextDirection() == l10n_util::LEFT_TO_RIGHT) + if (ltr ^ status->flip_horizontally()) // Is it on the left? g_value_set_int(&value, 0); else g_value_set_int(&value, allocation->width - requisition.width); gtk_container_child_set_property(GTK_CONTAINER(floating_container), - status, "x", &value); + status->widget(), "x", &value); int child_y = std::max( allocation->y + allocation->height - requisition.height, 0); - g_value_set_int(&value, child_y); + g_value_set_int(&value, child_y + status->y_offset()); gtk_container_child_set_property(GTK_CONTAINER(floating_container), - status, "y", &value); + status->widget(), "y", &value); g_value_unset(&value); } diff --git a/chrome/browser/status_bubble.h b/chrome/browser/status_bubble.h index 9203b80..81379d0 100644 --- a/chrome/browser/status_bubble.h +++ b/chrome/browser/status_bubble.h @@ -8,6 +8,9 @@ #include <string> class GURL; +namespace gfx { +class Point; +} //////////////////////////////////////////////////////////////////////////////// // StatusBubble interface @@ -37,8 +40,10 @@ class StatusBubble { // Called when the user's mouse has moved over web content. This is used to // determine when the status area should move out of the way of the user's // mouse. This may be windows specific pain due to the way messages are - // processed for child HWNDs. - virtual void MouseMoved() = 0; + // processed for child HWNDs. |position| is the absolute position of the + // pointer, and |left_content| is true if the mouse just left the content + // area. + virtual void MouseMoved(const gfx::Point& position, bool left_content) = 0; // Called when the download shelf becomes visible or invisible. // This is used by to ensure that the status bubble does not obscure diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index f5fdfcf..b4d3009 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -94,11 +94,14 @@ class TabContentsDelegate { // Notification that the starredness of the current URL changed. virtual void URLStarredChanged(TabContents* source, bool starred) = 0; - // Notification that the target URL has changed + // Notification that the target URL has changed. virtual void UpdateTargetURL(TabContents* source, const GURL& url) = 0; - // Notification that there was a mouse event - virtual void ContentsMouseEvent(TabContents* source, bool motion) { } + // Notification that there was a mouse event, along with the absolute + // coordinates of the mouse pointer and whether it was a normal motion event + // (otherwise, the pointer left the contents area). + virtual void ContentsMouseEvent( + TabContents* source, const gfx::Point& location, bool motion) { } // Request the delegate to change the zoom level of the current tab. virtual void ContentsZoomChange(bool zoom_in) { } diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index 332c7cd..61c685e 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -69,7 +69,8 @@ gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus, gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event, TabContents* tab_contents) { if (tab_contents->delegate()) - tab_contents->delegate()->ContentsMouseEvent(tab_contents, false); + tab_contents->delegate()->ContentsMouseEvent( + tab_contents, gfx::Point(event->x_root, event->y_root), false); return FALSE; } @@ -77,7 +78,8 @@ gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event, gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event, TabContents* tab_contents) { if (tab_contents->delegate()) - tab_contents->delegate()->ContentsMouseEvent(tab_contents, true); + tab_contents->delegate()->ContentsMouseEvent( + tab_contents, gfx::Point(event->x_root, event->y_root), true); return FALSE; } diff --git a/chrome/browser/tab_contents/tab_contents_view_mac.mm b/chrome/browser/tab_contents/tab_contents_view_mac.mm index 9a06d66..60bc43a 100644 --- a/chrome/browser/tab_contents/tab_contents_view_mac.mm +++ b/chrome/browser/tab_contents/tab_contents_view_mac.mm @@ -406,10 +406,13 @@ void TabContentsViewMac::Observe(NotificationType type, - (void)mouseEvent:(NSEvent *)theEvent { TabContents* tabContents = [self tabContents]; if (tabContents->delegate()) { + NSPoint location = [NSEvent mouseLocation]; if ([theEvent type] == NSMouseMoved) - tabContents->delegate()->ContentsMouseEvent(tabContents, true); + tabContents->delegate()->ContentsMouseEvent( + tabContents, gfx::Point(location.x, location.y), true); if ([theEvent type] == NSMouseExited) - tabContents->delegate()->ContentsMouseEvent(tabContents, false); + tabContents->delegate()->ContentsMouseEvent( + tabContents, gfx::Point(location.x, location.y), false); } } diff --git a/chrome/browser/views/status_bubble_views.cc b/chrome/browser/views/status_bubble_views.cc index 9642294..fbf8153 100644 --- a/chrome/browser/views/status_bubble_views.cc +++ b/chrome/browser/views/status_bubble_views.cc @@ -11,6 +11,7 @@ #include "app/l10n_util.h" #include "app/animation.h" #include "app/resource_bundle.h" +#include "base/gfx/point.h" #include "base/message_loop.h" #include "base/string_util.h" #include "chrome/browser/browser_theme_provider.h" @@ -572,14 +573,18 @@ void StatusBubbleViews::Hide() { view_->Hide(); } -void StatusBubbleViews::MouseMoved() { +void StatusBubbleViews::MouseMoved(const gfx::Point& location, + bool left_content) { + if (left_content) + return; + if (view_) { view_->ResetTimer(); if (view_->GetState() != StatusView::BUBBLE_HIDDEN && view_->GetState() != StatusView::BUBBLE_HIDING_FADE && view_->GetState() != StatusView::BUBBLE_HIDING_TIMER) { - AvoidMouse(); + AvoidMouse(location); } } } @@ -588,42 +593,40 @@ void StatusBubbleViews::UpdateDownloadShelfVisibility(bool visible) { download_shelf_is_visible_ = visible; } -void StatusBubbleViews::AvoidMouse() { +void StatusBubbleViews::AvoidMouse(const gfx::Point& location) { // Get the position of the frame. gfx::Point top_left; views::RootView* root = frame_->GetRootView(); views::View::ConvertPointToScreen(root, &top_left); int window_width = root->GetLocalBounds(true).width(); // border included. - // Our status bubble is located in screen coordinates, so we should get - // those rather than attempting to reverse decode the web contents - // coordinates. - gfx::Point cursor_location = views::Screen::GetCursorScreenPoint(); - // Get the cursor position relative to the popup. + gfx::Point relative_location = location; if (view_->UILayoutIsRightToLeft()) { int top_right_x = top_left.x() + window_width; - cursor_location.set_x(top_right_x - cursor_location.x()); + relative_location.set_x(top_right_x - relative_location.x()); } else { - cursor_location.set_x(cursor_location.x() - (top_left.x() + position_.x())); + relative_location.set_x( + relative_location.x() - (top_left.x() + position_.x())); } - cursor_location.set_y(cursor_location.y() - (top_left.y() + position_.y())); + relative_location.set_y( + relative_location.y() - (top_left.y() + position_.y())); // If the mouse is in a position where we think it would move the // status bubble, figure out where and how the bubble should be moved. - if (cursor_location.y() > -kMousePadding && - cursor_location.x() < size_.width() + kMousePadding) { - int offset = kMousePadding + cursor_location.y(); + if (relative_location.y() > -kMousePadding && + relative_location.x() < size_.width() + kMousePadding) { + int offset = kMousePadding + relative_location.y(); // Make the movement non-linear. offset = offset * offset / kMousePadding; // When the mouse is entering from the right, we want the offset to be // scaled by how horizontally far away the cursor is from the bubble. - if (cursor_location.x() > size_.width()) { + if (relative_location.x() > size_.width()) { offset = static_cast<int>(static_cast<float>(offset) * ( static_cast<float>(kMousePadding - - (cursor_location.x() - size_.width())) / + (relative_location.x() - size_.width())) / static_cast<float>(kMousePadding))); } diff --git a/chrome/browser/views/status_bubble_views.h b/chrome/browser/views/status_bubble_views.h index 06bf6bd..78d3265 100644 --- a/chrome/browser/views/status_bubble_views.h +++ b/chrome/browser/views/status_bubble_views.h @@ -11,6 +11,9 @@ #include "chrome/browser/status_bubble.h" class GURL; +namespace gfx { +class Point; +} namespace views { class Widget; } @@ -44,7 +47,7 @@ class StatusBubbleViews : public StatusBubble { virtual void SetStatus(const std::wstring& status); virtual void SetURL(const GURL& url, const std::wstring& languages); virtual void Hide(); - virtual void MouseMoved(); + virtual void MouseMoved(const gfx::Point& location, bool left_content); virtual void UpdateDownloadShelfVisibility(bool visible); private: @@ -55,7 +58,7 @@ class StatusBubbleViews : public StatusBubble { // Attempt to move the status bubble out of the way of the cursor, allowing // users to see links in the region normally occupied by the status bubble. - void AvoidMouse(); + void AvoidMouse(const gfx::Point& location); // Returns true if the frame_ is visible and not minimized. bool IsFrameVisible(); diff --git a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc index fce6c9c..7db5ad4 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/views/tab_contents/tab_contents_view_gtk.cc @@ -26,8 +26,9 @@ #include "chrome/browser/views/blocked_popup_container_view_views.h" #include "chrome/browser/views/sad_tab_view.h" #include "chrome/browser/views/tab_contents/render_view_context_menu_win.h" -#include "views/focus/view_storage.h" #include "views/controls/native/native_view_host.h" +#include "views/focus/view_storage.h" +#include "views/screen.h" #include "views/widget/root_view.h" using WebKit::WebDragOperation; @@ -62,7 +63,8 @@ gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus, gboolean OnLeaveNotify2(GtkWidget* widget, GdkEventCrossing* event, TabContents* tab_contents) { if (tab_contents->delegate()) - tab_contents->delegate()->ContentsMouseEvent(tab_contents, false); + tab_contents->delegate()->ContentsMouseEvent( + tab_contents, views::Screen::GetCursorScreenPoint(), false); return FALSE; } @@ -70,7 +72,8 @@ gboolean OnLeaveNotify2(GtkWidget* widget, GdkEventCrossing* event, gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event, TabContents* tab_contents) { if (tab_contents->delegate()) - tab_contents->delegate()->ContentsMouseEvent(tab_contents, true); + tab_contents->delegate()->ContentsMouseEvent( + tab_contents, views::Screen::GetCursorScreenPoint(), true); return FALSE; } @@ -423,4 +426,3 @@ void TabContentsViewGtk::SetFloatingPosition(const gfx::Size& size) { PositionChild(widget, child_x, 0, requisition.width, requisition.height); } } - diff --git a/chrome/browser/views/tab_contents/tab_contents_view_win.cc b/chrome/browser/views/tab_contents/tab_contents_view_win.cc index a0a0beb..9c79650 100644 --- a/chrome/browser/views/tab_contents/tab_contents_view_win.cc +++ b/chrome/browser/views/tab_contents/tab_contents_view_win.cc @@ -31,6 +31,7 @@ #include "chrome/common/url_constants.h" #include "net/base/net_util.h" #include "views/focus/view_storage.h" +#include "views/screen.h" #include "views/widget/root_view.h" #include "webkit/glue/webdropdata.h" @@ -474,7 +475,8 @@ void TabContentsViewWin::OnMouseLeave() { // Let our delegate know that the mouse moved (useful for resetting status // bubble state). if (tab_contents()->delegate()) - tab_contents()->delegate()->ContentsMouseEvent(tab_contents(), false); + tab_contents()->delegate()->ContentsMouseEvent( + tab_contents(), views::Screen::GetCursorScreenPoint(), false); SetMsgHandled(FALSE); } @@ -496,9 +498,9 @@ LRESULT TabContentsViewWin::OnMouseRange(UINT msg, case WM_MOUSEMOVE: // Let our delegate know that the mouse moved (useful for resetting status // bubble state). - if (tab_contents()->delegate()) { - tab_contents()->delegate()->ContentsMouseEvent(tab_contents(), true); - } + if (tab_contents()->delegate()) + tab_contents()->delegate()->ContentsMouseEvent( + tab_contents(), views::Screen::GetCursorScreenPoint(), true); break; default: break; |