diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-13 03:49:13 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-13 03:49:13 +0000 |
commit | 4845d5f6661bf58e556da21c36c1472125e81327 (patch) | |
tree | 9c0f3e674d66c4f1224447b64f8ea15f6a4376d2 /chrome | |
parent | a3340f3d323f769460a1b269eb8198faf071e2a2 (diff) | |
download | chromium_src-4845d5f6661bf58e556da21c36c1472125e81327.zip chromium_src-4845d5f6661bf58e556da21c36c1472125e81327.tar.gz chromium_src-4845d5f6661bf58e556da21c36c1472125e81327.tar.bz2 |
Gtk: Make click target of tabs match their appearance.
BUG=87856
TEST=See bug
Review URL: http://codereview.chromium.org/7640004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96674 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/ui/gtk/gtk_input_event_box.cc | 159 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/gtk_input_event_box.h | 57 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/tabs/tab_gtk.cc | 23 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/tabs/tab_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc | 36 | ||||
-rw-r--r-- | chrome/browser/ui/gtk/tabs/tab_strip_gtk.h | 12 | ||||
-rw-r--r-- | chrome/browser/ui/tabs/tab_resources.cc | 44 | ||||
-rw-r--r-- | chrome/browser/ui/tabs/tab_resources.h | 22 | ||||
-rw-r--r-- | chrome/browser/ui/views/tabs/tab.cc | 30 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 5 |
11 files changed, 361 insertions, 34 deletions
diff --git a/chrome/browser/ui/gtk/gtk_input_event_box.cc b/chrome/browser/ui/gtk/gtk_input_event_box.cc new file mode 100644 index 0000000..c554834 --- /dev/null +++ b/chrome/browser/ui/gtk/gtk_input_event_box.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/gtk/gtk_input_event_box.h" + +#include <gdk/gdkwindow.h> +#include <gtk/gtk.h> +#include <gtk/gtkwidget.h> +#include <gtk/gtkbin.h> + +G_BEGIN_DECLS + +#define GTK_INPUT_EVENT_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + GTK_TYPE_INPUT_EVENT_BOX, \ + GtkInputEventBoxPrivate)) + +typedef struct _GtkInputEventBoxPrivate GtkInputEventBoxPrivate; + +struct _GtkInputEventBoxPrivate { + GdkWindow* event_window; +}; + +G_DEFINE_TYPE(GtkInputEventBox, gtk_input_event_box, GTK_TYPE_BIN) + +static void gtk_input_event_box_realize(GtkWidget* widget); +static void gtk_input_event_box_unrealize(GtkWidget* widget); +static void gtk_input_event_box_map(GtkWidget* widget); +static void gtk_input_event_box_unmap(GtkWidget* widget); +static void gtk_input_event_box_size_allocate(GtkWidget* widget, + GtkAllocation* allocation); +static void gtk_input_event_box_size_request(GtkWidget* widget, + GtkRequisition* requisition); + +static void gtk_input_event_box_class_init(GtkInputEventBoxClass* klass) { + GtkWidgetClass* widget_class = reinterpret_cast<GtkWidgetClass*>(klass); + widget_class->realize = gtk_input_event_box_realize; + widget_class->unrealize = gtk_input_event_box_unrealize; + widget_class->map = gtk_input_event_box_map; + widget_class->unmap = gtk_input_event_box_unmap; + widget_class->size_allocate = gtk_input_event_box_size_allocate; + widget_class->size_request = gtk_input_event_box_size_request; + + GObjectClass* gobject_class = G_OBJECT_CLASS(klass); + g_type_class_add_private(gobject_class, sizeof(GtkInputEventBoxPrivate)); +} + +static void gtk_input_event_box_init(GtkInputEventBox* widget) { + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + priv->event_window = NULL; +} + +GtkWidget* gtk_input_event_box_new() { + return GTK_WIDGET(g_object_new(GTK_TYPE_INPUT_EVENT_BOX, NULL)); +} + +static void gtk_input_event_box_realize(GtkWidget* widget) { + g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget)); + + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + + GdkWindow* parent = gtk_widget_get_parent_window(widget); + GdkWindowAttr attributes; + GtkAllocation allocation; + gint attributes_mask = GDK_WA_X | GDK_WA_Y; + + gtk_widget_get_allocation(widget, &allocation); + + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_ONLY; + + attributes.event_mask = gtk_widget_get_events(widget) + | GDK_BUTTON_MOTION_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_EXPOSURE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK; + + priv->event_window = gdk_window_new(parent, &attributes, attributes_mask); + gdk_window_set_user_data(priv->event_window, widget); + + GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->realize(widget); +} + +static void gtk_input_event_box_unrealize(GtkWidget* widget) { + g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget)); + + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + if (priv->event_window) { + gdk_window_set_user_data(priv->event_window, NULL); + gdk_window_destroy(priv->event_window); + priv->event_window = NULL; + } + + GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->unrealize(widget); +} + +static void gtk_input_event_box_map(GtkWidget* widget) { + g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget)); + + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + if (priv->event_window) + gdk_window_show(priv->event_window); + + GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->map(widget); +} + +static void gtk_input_event_box_unmap(GtkWidget* widget) { + g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget)); + + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + if (priv->event_window) + gdk_window_hide(priv->event_window); + + GTK_WIDGET_CLASS(gtk_input_event_box_parent_class)->unmap(widget); +} + +static void gtk_input_event_box_size_allocate(GtkWidget* widget, + GtkAllocation* allocation) { + g_return_if_fail(GTK_IS_INPUT_EVENT_BOX(widget)); + + widget->allocation = *allocation; + + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + if (priv->event_window) { + gdk_window_move_resize(priv->event_window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); + } + + GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget)); + if (child) + gtk_widget_size_allocate(child, allocation); +} + +static void gtk_input_event_box_size_request(GtkWidget* widget, + GtkRequisition* requisition) { + + GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget)); + if (child) + gtk_widget_size_request(child, requisition); +} + +GdkWindow* gtk_input_event_box_get_window(GtkInputEventBox* widget) { + g_return_val_if_fail(GTK_IS_INPUT_EVENT_BOX(widget), NULL); + + GtkInputEventBoxPrivate* priv = GTK_INPUT_EVENT_BOX_GET_PRIVATE(widget); + return priv->event_window; +} + +G_END_DECLS diff --git a/chrome/browser/ui/gtk/gtk_input_event_box.h b/chrome/browser/ui/gtk/gtk_input_event_box.h new file mode 100644 index 0000000..365dbb6 --- /dev/null +++ b/chrome/browser/ui/gtk/gtk_input_event_box.h @@ -0,0 +1,57 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_GTK_GTK_INPUT_EVENT_BOX_H_ +#define CHROME_BROWSER_UI_GTK_GTK_INPUT_EVENT_BOX_H_ +#pragma once + +#include <gdk/gdk.h> +#include <gtk/gtk.h> + +// GtkInputEventBox is like GtkEventBox, but with the following differences: +// 1. Only supports input (like gtk_event_box_set_visible_window(foo, FALSE). +// 2. Provides a method to get the GdkWindow (gtk_input_event_box_get_window). +// (The GdkWindow created by GtkEventBox cannot be retrieved unless you use it +// in visible mode.) + +G_BEGIN_DECLS + +#define GTK_TYPE_INPUT_EVENT_BOX \ + (gtk_input_event_box_get_type()) +#define GTK_INPUT_EVENT_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INPUT_EVENT_BOX, \ + GtkInputEventBox)) +#define GTK_INPUT_EVENT_BOX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INPUT_EVENT_BOX, \ + GtkInputEventBoxClass)) +#define GTK_IS_INPUT_EVENT_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INPUT_EVENT_BOX)) +#define GTK_IS_INPUT_EVENT_BOX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INPUT_EVENT_BOX)) +#define GTK_INPUT_EVENT_BOX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INPUT_EVENT_BOX, \ + GtkInputEventBoxClass)) + +typedef struct _GtkInputEventBox GtkInputEventBox; +typedef struct _GtkInputEventBoxClass GtkInputEventBoxClass; + +struct _GtkInputEventBox { + // Parent class. + GtkBin bin; +}; + +struct _GtkInputEventBoxClass { + GtkBinClass parent_class; +}; + +GType gtk_input_event_box_get_type(); +GtkWidget* gtk_input_event_box_new(); + +// Get the GdkWindow |widget| uses for handling input events. Will be NULL if +// the widget has not been realized yet. +GdkWindow* gtk_input_event_box_get_window(GtkInputEventBox* widget); + +G_END_DECLS + +#endif // CHROME_BROWSER_UI_GTK_GTK_INPUT_EVENT_BOX_H_ diff --git a/chrome/browser/ui/gtk/tabs/tab_gtk.cc b/chrome/browser/ui/gtk/tabs/tab_gtk.cc index c8e4a51..c4c6399 100644 --- a/chrome/browser/ui/gtk/tabs/tab_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/tab_gtk.cc @@ -10,12 +10,15 @@ #include "base/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ui/gtk/accelerators_gtk.h" +#include "chrome/browser/ui/gtk/gtk_input_event_box.h" #include "chrome/browser/ui/gtk/menu_gtk.h" #include "chrome/browser/ui/gtk/tabs/tab_strip_menu_controller.h" #include "chrome/browser/ui/tabs/tab_menu_model.h" +#include "chrome/browser/ui/tabs/tab_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "ui/base/dragdrop/gtk_dnd_util.h" +#include "ui/base/gtk/scoped_handle_gtk.h" #include "ui/base/models/accelerator_gtk.h" #include "ui/gfx/path.h" @@ -62,8 +65,7 @@ TabGtk::TabGtk(TabDelegate* delegate) title_width_(0), ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(drag_end_factory_(this)) { - event_box_ = gtk_event_box_new(); - gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_), FALSE); + event_box_ = gtk_input_event_box_new(); g_signal_connect(event_box_, "button-press-event", G_CALLBACK(OnButtonPressEventThunk), this); g_signal_connect(event_box_, "button-release-event", @@ -97,6 +99,12 @@ TabGtk::~TabGtk() { } } +void TabGtk::Raise() const { + GdkWindow* window = gtk_input_event_box_get_window( + GTK_INPUT_EVENT_BOX(event_box_)); + gdk_window_raise(window); +} + gboolean TabGtk::OnButtonPressEvent(GtkWidget* widget, GdkEventButton* event) { // Every button press ensures either a button-release-event or a drag-fail // signal for |widget|. @@ -257,6 +265,17 @@ void TabGtk::UpdateData(TabContents* contents, bool app, bool loading_only) { void TabGtk::SetBounds(const gfx::Rect& bounds) { TabRendererGtk::SetBounds(bounds); + + if (gtk_input_event_box_get_window(GTK_INPUT_EVENT_BOX(event_box_))) { + gfx::Path mask; + TabResources::GetHitTestMask(bounds.width(), bounds.height(), &mask); + ui::ScopedRegion region(mask.CreateNativeRegion()); + gdk_window_input_shape_combine_region( + gtk_input_event_box_get_window(GTK_INPUT_EVENT_BOX(event_box_)), + region.Get(), + 0, 0); + } + UpdateTooltipState(); } diff --git a/chrome/browser/ui/gtk/tabs/tab_gtk.h b/chrome/browser/ui/gtk/tabs/tab_gtk.h index bfa64e0..84df548 100644 --- a/chrome/browser/ui/gtk/tabs/tab_gtk.h +++ b/chrome/browser/ui/gtk/tabs/tab_gtk.h @@ -113,6 +113,9 @@ class TabGtk : public TabRendererGtk, void set_dragging(bool dragging) { dragging_ = dragging; } bool dragging() const { return dragging_; } + // Raise to top of Z-order. + void Raise() const; + // TabRendererGtk overrides: virtual bool IsActive() const; virtual bool IsSelected() const; diff --git a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc index ad9e9681..6289ba2 100644 --- a/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/tab_renderer_gtk.cc @@ -72,10 +72,6 @@ const double kMiniTitleChangeThrobOpacity = 0.75; // Duration for when the title of an inactive mini-tab changes. const int kMiniTitleChangeThrobDuration = 1000; -const SkScalar kTabCapWidth = 15; -const SkScalar kTabTopCurveWidth = 4; -const SkScalar kTabBottomCurveWidth = 3; - // The vertical and horizontal offset used to position the close button // in the tab. TODO(jhawkins): Ask pkasting what the Fuzz is about. const int kCloseButtonVertFuzz = 0; diff --git a/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc index 142e4cb..d1eb188 100644 --- a/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc @@ -750,6 +750,8 @@ void TabStripGtk::Init() { -1 }; ui::SetDestTargetList(tabstrip_.get(), targets); + g_signal_connect(tabstrip_.get(), "map", + G_CALLBACK(OnMapThunk), this); g_signal_connect(tabstrip_.get(), "expose-event", G_CALLBACK(OnExposeThunk), this); g_signal_connect(tabstrip_.get(), "size-allocate", @@ -1006,6 +1008,8 @@ void TabStripGtk::TabInsertedAt(TabContentsWrapper* contents, } else { Layout(); } + + ReStack(); } void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { @@ -1017,6 +1021,13 @@ void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { GetTabAt(index)->set_closing(true); } +void TabStripGtk::ActiveTabChanged(TabContentsWrapper* old_contents, + TabContentsWrapper* new_contents, + int index, + bool user_gesture) { + ReStack(); +} + void TabStripGtk::TabSelectionChanged(const TabStripSelectionModel& old_model) { // We have "tiny tabs" if the tabs are so tiny that the unselected ones are // a different size to the selected ones. @@ -1075,6 +1086,7 @@ void TabStripGtk::TabMoved(TabContentsWrapper* contents, tab_data_.insert(tab_data_.begin() + to_index, data); GenerateIdealBounds(); StartMoveTabAnimation(from_index, to_index); + ReStack(); } void TabStripGtk::TabChangedAt(TabContentsWrapper* contents, int index, @@ -1580,6 +1592,26 @@ bool TabStripGtk::IsCursorInTabStripZone() const { return bds.Contains(cursor_point); } +void TabStripGtk::ReStack() { + if (!GTK_WIDGET_REALIZED(tabstrip_.get())) { + // If the window isn't realized yet, we can't stack them yet. It will be + // done by the OnMap signal handler. + return; + } + int tab_count = GetTabCount(); + TabGtk* active_tab = NULL; + for (int i = tab_count - 1; i >= 0; --i) { + TabGtk* tab = GetTabAt(i); + if (tab->IsActive()) + active_tab = tab; + else + tab->Raise(); + } + if (active_tab) + active_tab->Raise(); +} + + void TabStripGtk::AddMessageLoopObserver() { if (!added_as_message_loop_observer_) { MessageLoopForUI::current()->AddObserver(this); @@ -1937,6 +1969,10 @@ void TabStripGtk::FinishAnimation(TabStripGtk::TabAnimation* animation, Layout(); } +void TabStripGtk::OnMap(GtkWidget* widget) { + ReStack(); +} + gboolean TabStripGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) { if (gdk_region_empty(event->region)) return TRUE; diff --git a/chrome/browser/ui/gtk/tabs/tab_strip_gtk.h b/chrome/browser/ui/gtk/tabs/tab_strip_gtk.h index 98c7a85..c10e097 100644 --- a/chrome/browser/ui/gtk/tabs/tab_strip_gtk.h +++ b/chrome/browser/ui/gtk/tabs/tab_strip_gtk.h @@ -110,6 +110,10 @@ class TabStripGtk : public TabStripModelObserver, virtual void TabMoved(TabContentsWrapper* contents, int from_index, int to_index); + virtual void ActiveTabChanged(TabContentsWrapper* old_contents, + TabContentsWrapper* new_contents, + int index, + bool user_gesture); virtual void TabSelectionChanged(const TabStripSelectionModel& old_model); virtual void TabChangedAt(TabContentsWrapper* contents, int index, TabChangeType change_type); @@ -228,6 +232,11 @@ class TabStripGtk : public TabStripModelObserver, DISALLOW_COPY_AND_ASSIGN(DropInfo); }; + // Map signal handler that sets initial z-ordering. The widgets need to be + // realized before we can set the stacking. We use the "map" signal since the + // "realize" signal is called before the child widgets get realized. + CHROMEGTK_CALLBACK_0(TabStripGtk, void, OnMap); + // expose-event handler that redraws the tabstrip CHROMEGTK_CALLBACK_1(TabStripGtk, gboolean, OnExpose, GdkEventExpose*); @@ -321,6 +330,9 @@ class TabStripGtk : public TabStripModelObserver, // which is defined as the region above the TabStrip and a bit below it. bool IsCursorInTabStripZone() const; + // Reset the Z-ordering of tabs. + void ReStack(); + // Ensure that the message loop observer used for event spying is added and // removed appropriately so we can tell when to resize layout the tab strip. void AddMessageLoopObserver(); diff --git a/chrome/browser/ui/tabs/tab_resources.cc b/chrome/browser/ui/tabs/tab_resources.cc new file mode 100644 index 0000000..45f06c3 --- /dev/null +++ b/chrome/browser/ui/tabs/tab_resources.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/tabs/tab_resources.h" + +#include "base/logging.h" +#include "ui/gfx/path.h" + +namespace { + +// Hit mask constants. +const SkScalar kTabCapWidth = 15; +const SkScalar kTabTopCurveWidth = 4; +const SkScalar kTabBottomCurveWidth = 3; + +} // namespace + +// static +void TabResources::GetHitTestMask(int width, int height, gfx::Path* path) { + DCHECK(path); + + SkScalar h = SkIntToScalar(height); + SkScalar w = SkIntToScalar(width); + + path->moveTo(0, h); + + // Left end cap. + path->lineTo(kTabBottomCurveWidth, h - kTabBottomCurveWidth); + path->lineTo(kTabCapWidth - kTabTopCurveWidth, kTabTopCurveWidth); + path->lineTo(kTabCapWidth, 0); + + // Connect to the right cap. + path->lineTo(w - kTabCapWidth, 0); + + // Right end cap. + path->lineTo(w - kTabCapWidth + kTabTopCurveWidth, kTabTopCurveWidth); + path->lineTo(w - kTabBottomCurveWidth, h - kTabBottomCurveWidth); + path->lineTo(w, h); + + // Close out the path. + path->lineTo(0, h); + path->close(); +} diff --git a/chrome/browser/ui/tabs/tab_resources.h b/chrome/browser/ui/tabs/tab_resources.h new file mode 100644 index 0000000..975ccd0 --- /dev/null +++ b/chrome/browser/ui/tabs/tab_resources.h @@ -0,0 +1,22 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_TABS_TAB_RESOURCES_H_ +#define CHROME_BROWSER_UI_TABS_TAB_RESOURCES_H_ +#pragma once + +namespace gfx { +class Path; +} + +// Common resources for tab widgets. Currently this is used on Views and Gtk, +// but not on Cocoa. +class TabResources { + public: + // Return a |path| containing the region that matches the bitmap display of + // a tab of the given |width| and |height|, for input event hit testing. + static void GetHitTestMask(int width, int height, gfx::Path* path); +}; + +#endif // CHROME_BROWSER_UI_TABS_TAB_RESOURCES_H_ diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index b675565..be385c3 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc @@ -9,6 +9,7 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/defaults.h" #include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/ui/tabs/tab_resources.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "grit/theme_resources_standard.h" @@ -84,11 +85,6 @@ static const SkColor kMiniTitleChangeGradientColor1 = SK_ColorWHITE; static const SkColor kMiniTitleChangeGradientColor2 = SkColorSetARGB(0, 255, 255, 255); -// Hit mask constants. -static const SkScalar kTabCapWidth = 15; -static const SkScalar kTabTopCurveWidth = 4; -static const SkScalar kTabBottomCurveWidth = 3; - // static const char Tab::kViewClassName[] = "browser/tabs/Tab"; @@ -325,29 +321,7 @@ bool Tab::HasHitTestMask() const { } void Tab::GetHitTestMask(gfx::Path* path) const { - DCHECK(path); - - SkScalar h = SkIntToScalar(height()); - SkScalar w = SkIntToScalar(width()); - - path->moveTo(0, h); - - // Left end cap. - path->lineTo(kTabBottomCurveWidth, h - kTabBottomCurveWidth); - path->lineTo(kTabCapWidth - kTabTopCurveWidth, kTabTopCurveWidth); - path->lineTo(kTabCapWidth, 0); - - // Connect to the right cap. - path->lineTo(w - kTabCapWidth, 0); - - // Right end cap. - path->lineTo(w - kTabCapWidth + kTabTopCurveWidth, kTabTopCurveWidth); - path->lineTo(w - kTabBottomCurveWidth, h - kTabBottomCurveWidth); - path->lineTo(w, h); - - // Close out the path. - path->lineTo(0, h); - path->close(); + TabResources::GetHitTestMask(width(), height(), path); } bool Tab::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin) { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index f546423..076be2e 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2874,6 +2874,8 @@ 'browser/ui/gtk/gtk_expanded_container.h', 'browser/ui/gtk/gtk_floating_container.cc', 'browser/ui/gtk/gtk_floating_container.h', + 'browser/ui/gtk/gtk_input_event_box.cc', + 'browser/ui/gtk/gtk_input_event_box.h', 'browser/ui/gtk/gtk_theme_service.cc', 'browser/ui/gtk/gtk_theme_service.h', 'browser/ui/gtk/gtk_tree.cc', @@ -3051,6 +3053,8 @@ 'browser/ui/tabs/hover_tab_selector.h', 'browser/ui/tabs/tab_menu_model.cc', 'browser/ui/tabs/tab_menu_model.h', + 'browser/ui/tabs/tab_resources.cc', + 'browser/ui/tabs/tab_resources.h', 'browser/ui/toolbar/back_forward_menu_model.cc', 'browser/ui/toolbar/back_forward_menu_model.h', 'browser/ui/toolbar/encoding_menu_controller.cc', @@ -4051,6 +4055,7 @@ 'browser/ui/panels/panel_browser_view.cc', 'browser/ui/panels/panel_browser_view.h', 'browser/ui/tabs/dock_info.cc', + 'browser/ui/tabs/tab_resources.cc', 'browser/ui/views/extensions/extension_view.cc', 'browser/ui/views/extensions/extension_view.h', ], |