| Index: chrome/browser/ui/views/tabs/tab.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
|
| index be34f25a98ff8985fe21dc55286388f44300e882..d0c2ca440cd8e095630dbdb71c4d3dfd0f83f40f 100644
|
| --- a/chrome/browser/ui/views/tabs/tab.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab.cc
|
| @@ -39,8 +39,11 @@
|
| #include "ui/gfx/font.h"
|
| #include "ui/gfx/image/image_skia_operations.h"
|
| #include "ui/gfx/path.h"
|
| +#include "ui/gfx/rect_conversions.h"
|
| +#include "ui/gfx/skia_util.h"
|
| #include "ui/gfx/text_elider.h"
|
| #include "ui/views/controls/button/image_button.h"
|
| +#include "ui/views/rect_based_targeting_utils.h"
|
| #include "ui/views/widget/tooltip_manager.h"
|
| #include "ui/views/widget/widget.h"
|
| #include "ui/views/window/non_client_view.h"
|
| @@ -248,6 +251,8 @@ const double kProjectingFaviconResizeScale = 0.75;
|
| // Scale to resize the projection sheet glow by.
|
| const double kProjectingGlowResizeScale = 2.0;
|
|
|
| +const char kTabCloseButtonName[] = "TabCloseButton";
|
| +
|
| void DrawIconAtLocation(gfx::Canvas* canvas,
|
| const gfx::ImageSkia& image,
|
| int image_offset,
|
| @@ -357,21 +362,24 @@ class Tab::TabCloseButton : public views::ImageButton {
|
| virtual ~TabCloseButton() {}
|
|
|
| // Overridden from views::View.
|
| - virtual View* GetEventHandlerForPoint(const gfx::Point& point) OVERRIDE {
|
| + virtual View* GetEventHandlerForRect(const gfx::Rect& rect) OVERRIDE {
|
| + if (!views::UsePointBasedTargeting(rect))
|
| + return View::GetEventHandlerForRect(rect);
|
| +
|
| // Ignore the padding set on the button.
|
| - gfx::Rect rect = GetContentsBounds();
|
| - rect.set_x(GetMirroredXForRect(rect));
|
| + gfx::Rect contents_bounds = GetContentsBounds();
|
| + contents_bounds.set_x(GetMirroredXForRect(contents_bounds));
|
|
|
| #if defined(USE_ASH)
|
| // Include the padding in hit-test for touch events.
|
| if (aura::Env::GetInstance()->is_touch_down())
|
| - rect = GetLocalBounds();
|
| + contents_bounds = GetLocalBounds();
|
| #elif defined(OS_WIN)
|
| // TODO(sky): Use local-bounds if a touch-point is active.
|
| // http://crbug.com/145258
|
| #endif
|
|
|
| - return rect.Contains(point) ? this : parent();
|
| + return contents_bounds.Intersects(rect) ? this : parent();
|
| }
|
|
|
| // Overridden from views::View.
|
| @@ -414,6 +422,39 @@ class Tab::TabCloseButton : public views::ImageButton {
|
| event->SetHandled();
|
| }
|
|
|
| + virtual bool HasHitTestMask() const OVERRIDE {
|
| + return true;
|
| + }
|
| +
|
| + virtual void GetHitTestMask(gfx::Path* path) const OVERRIDE {
|
| + // Use the button's contents bounds (which does not include padding)
|
| + // and the hit test mask of our parent |tab_| to determine if the
|
| + // button is completely hidden behind another tab.
|
| + gfx::Path tab_mask;
|
| + tab_->GetHitTestMask(&tab_mask);
|
| +
|
| + gfx::Rect button_bounds(GetContentsBounds());
|
| + gfx::Rect tab_bounds(
|
| + gfx::ToEnclosingRect(gfx::SkRectToRectF(tab_mask.getBounds())));
|
| + views::View::ConvertRectToTarget(tab_, this, &tab_bounds);
|
| +
|
| + // If the button is completely hidden behind another tab, the hit test
|
| + // mask is empty. Otherwise set the hit test mask to be the contents bounds.
|
| + path->reset();
|
| + if (tab_bounds.Contains(button_bounds)) {
|
| +#if defined(USE_ASH)
|
| + // Include the padding in the hit test mask for touch events.
|
| + if (aura::Env::GetInstance()->is_touch_down())
|
| + button_bounds = GetLocalBounds();
|
| +#endif
|
| + path->addRect(RectToSkRect(button_bounds));
|
| + }
|
| + }
|
| +
|
| + virtual const char* GetClassName() const OVERRIDE {
|
| + return kTabCloseButtonName;
|
| + }
|
| +
|
| private:
|
| Tab* tab_;
|
|
|
| @@ -882,6 +923,20 @@ void Tab::GetHitTestMask(gfx::Path* path) const {
|
| bool include_top_shadow =
|
| widget && (widget->IsMaximized() || widget->IsFullscreen());
|
| TabResources::GetHitTestMask(width(), height(), include_top_shadow, path);
|
| +
|
| + // It is possible for a portion of the tab to be occluded if tabs are
|
| + // stacked, so modify the hit test mask to only include the visible
|
| + // region of the tab.
|
| + if (controller()) {
|
| + gfx::Rect clip;
|
| + controller()->ShouldPaintTab(this, &clip);
|
| + if (clip.size().GetArea()) {
|
| + SkRect intersection(path->getBounds());
|
| + intersection.intersect(RectToSkRect(clip));
|
| + path->reset();
|
| + path->addRect(intersection);
|
| + }
|
| + }
|
| }
|
|
|
| bool Tab::GetTooltipText(const gfx::Point& p, string16* tooltip) const {
|
|
|