summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-19 23:44:34 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-19 23:44:34 +0000
commit06416f79b380fe5378bc3fd305e89c762c8408ea (patch)
treeb573c2d4c334f7ab19a68fecba3cb3fa499ada4a /chrome/browser
parentaec3525822420bd1386af1a3cfd9fe3f6d0dbe90 (diff)
downloadchromium_src-06416f79b380fe5378bc3fd305e89c762c8408ea.zip
chromium_src-06416f79b380fe5378bc3fd305e89c762c8408ea.tar.gz
chromium_src-06416f79b380fe5378bc3fd305e89c762c8408ea.tar.bz2
Handle non-composited WMs when rendering the dragged tab. Also moves rendering of the close button to TabRendererGtk (where it belongs).
Review URL: http://codereview.chromium.org/115543 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16437 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_gtk.cc69
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_gtk.h18
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.cc37
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.h13
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.cc120
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.h34
6 files changed, 184 insertions, 107 deletions
diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc
index 6caa70c0..699fdb7 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc
+++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc
@@ -7,6 +7,7 @@
#include <gdk/gdk.h>
#include "app/gfx/canvas.h"
+#include "app/gfx/gtk_util.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/gtk/tabs/tab_renderer_gtk.h"
@@ -23,6 +24,11 @@ const float kScalingFactor = 0.5;
const int kAnimateToBoundsDurationMs = 150;
+bool IsScreenComposited() {
+ GdkScreen* screen = gdk_screen_get_default();
+ return gdk_screen_is_composited(screen) == TRUE;
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -43,7 +49,8 @@ DraggedTabGtk::DraggedTabGtk(TabContents* datasource,
SetContainerColorMap();
gtk_widget_set_app_paintable(container_, TRUE);
g_signal_connect(G_OBJECT(container_), "expose-event",
- G_CALLBACK(OnExpose), this);
+ G_CALLBACK(OnExposeEvent), this);
+ gtk_widget_add_events(container_, GDK_STRUCTURE_MASK);
gtk_container_add(GTK_CONTAINER(container_), renderer_->widget());
gtk_widget_show_all(container_);
}
@@ -140,6 +147,13 @@ int DraggedTabGtk::ScaleValue(int value) {
return attached_ ? value : static_cast<int>(value * kScalingFactor);
}
+gfx::Rect DraggedTabGtk::bounds() const {
+ gint x, y, width, height;
+ gtk_window_get_position(GTK_WINDOW(container_), &x, &y);
+ gtk_window_get_size(GTK_WINDOW(container_), &width, &height);
+ return gfx::Rect(x, y, width, height);
+}
+
void DraggedTabGtk::SetContainerColorMap() {
GdkScreen* screen = gtk_widget_get_screen(container_);
GdkColormap* colormap = gdk_screen_get_rgba_colormap(screen);
@@ -151,23 +165,58 @@ void DraggedTabGtk::SetContainerColorMap() {
gtk_widget_set_colormap(container_, colormap);
}
-// static
-gboolean DraggedTabGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event,
- DraggedTabGtk* dragged_tab) {
- cairo_t* cairo_context = gdk_cairo_create(widget->window);
+void DraggedTabGtk::SetContainerTransparency() {
+ cairo_t* cairo_context = gdk_cairo_create(container_->window);
if (!cairo_context)
- return FALSE;
+ return;
// Make the background of the dragged tab window fully transparent. All of
// the content of the window (child widgets) will be completely opaque.
- gint width, height;
- gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
- cairo_scale(cairo_context, static_cast<double>(width),
- static_cast<double>(height));
+ gfx::Size size = bounds().size();
+ cairo_scale(cairo_context, static_cast<double>(size.width()),
+ static_cast<double>(size.height()));
cairo_set_source_rgba(cairo_context, 1.0f, 1.0f, 1.0f, 0.0f);
cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
cairo_paint(cairo_context);
cairo_destroy(cairo_context);
+}
+
+void DraggedTabGtk::SetContainerShapeMask() {
+ // Render the tab as a bitmap.
+ SkBitmap tab = renderer_->PaintBitmap();
+ GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&tab);
+
+ // Create a 1bpp bitmap the size of |container_|.
+ gfx::Size size = bounds().size();
+ GdkPixmap* pixmap = gdk_pixmap_new(NULL, size.width(), size.height(), 1);
+ cairo_t* cairo_context = gdk_cairo_create(GDK_DRAWABLE(pixmap));
+
+ // Set the transparency.
+ cairo_set_source_rgba(cairo_context, 1, 1, 1, 0);
+
+ // Blit the rendered bitmap into a pixmap. Any pixel set in the pixmap will
+ // be opaque in the container window.
+ cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
+ gdk_cairo_set_source_pixbuf(cairo_context, pixbuf, 0, 0);
+ cairo_paint(cairo_context);
+ cairo_destroy(cairo_context);
+
+ // Set the shape mask.
+ gdk_window_shape_combine_mask(container_->window, pixmap, 0, 0);
+ g_object_unref(pixbuf);
+ g_object_unref(pixmap);
+}
+
+// static
+gboolean DraggedTabGtk::OnExposeEvent(GtkWidget* widget,
+ GdkEventExpose* event,
+ DraggedTabGtk* dragged_tab) {
+ printf("OnExposeEvent\n");
+ if (IsScreenComposited()) {
+ dragged_tab->SetContainerTransparency();
+ } else {
+ dragged_tab->SetContainerShapeMask();
+ }
return FALSE;
}
diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.h b/chrome/browser/gtk/tabs/dragged_tab_gtk.h
index 3a65b2d..cedce9d 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_gtk.h
+++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.h
@@ -61,13 +61,25 @@ class DraggedTabGtk : public AnimationDelegate {
// Utility for scaling a size by the current scaling factor.
int ScaleValue(int value);
+ // Returns the bounds of the container window.
+ gfx::Rect bounds() const;
+
// Sets the color map of the container window to allow the window to be
// transparent.
void SetContainerColorMap();
- // expose-event handler that redraws the dragged tab.
- static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* event,
- DraggedTabGtk* dragged_tab);
+ // Sets full transparency for the container window. This is used if
+ // compositing is available for the screen.
+ void SetContainerTransparency();
+
+ // Sets the shape mask for the container window to emulate a transparent
+ // container window. This is used if compositing is not available for the
+ // screen.
+ void SetContainerShapeMask();
+
+ // expose-event handler that notifies when the tab needs to be redrawn.
+ static gboolean OnExposeEvent(GtkWidget* widget, GdkEventExpose* event,
+ DraggedTabGtk* dragged_tab);
// The window that contains the dragged tab or tab contents.
GtkWidget* container_;
diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc
index 4bc7b85..7981759 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_gtk.cc
@@ -7,7 +7,6 @@
#include "app/gfx/path.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
-#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -126,8 +125,6 @@ TabGtk::TabGtk(TabDelegate* delegate)
GDK_LEAVE_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
gtk_container_add(GTK_CONTAINER(event_box_.get()), TabRendererGtk::widget());
gtk_widget_show_all(event_box_.get());
-
- close_button_.reset(MakeCloseButton());
}
TabGtk::~TabGtk() {
@@ -260,31 +257,13 @@ void TabGtk::SetVisible(bool visible) const {
}
}
-void TabGtk::CloseButtonResized(const gfx::Rect& bounds) {
- if (!bounds.IsEmpty()) {
- gtk_fixed_move(GTK_FIXED(TabRendererGtk::widget()),
- close_button_.get()->widget(), bounds.x(), bounds.y());
- gtk_widget_show(close_button_.get()->widget());
- } else {
- gtk_widget_hide(close_button_.get()->widget());
- }
-}
-
-void TabGtk::Paint(GdkEventExpose* event) {
- TabRendererGtk::Paint(event);
-
- gtk_container_propagate_expose(GTK_CONTAINER(TabRendererGtk::widget()),
- close_button_.get()->widget(), event);
+void TabGtk::CloseButtonClicked() {
+ delegate_->CloseTab(this);
}
///////////////////////////////////////////////////////////////////////////////
// TabGtk, private:
-// static
-void TabGtk::OnCloseButtonClicked(GtkWidget* widget, TabGtk* tab) {
- tab->delegate_->CloseTab(tab);
-}
-
void TabGtk::ShowContextMenu() {
if (!menu_controller_.get())
menu_controller_.reset(new ContextMenuController(this));
@@ -296,15 +275,3 @@ void TabGtk::ContextMenuClosed() {
delegate()->StopAllHighlighting();
menu_controller_.reset();
}
-
-CustomDrawButton* TabGtk::MakeCloseButton() {
- CustomDrawButton* button = new CustomDrawButton(IDR_TAB_CLOSE,
- IDR_TAB_CLOSE_P, IDR_TAB_CLOSE_H, IDR_TAB_CLOSE);
-
- g_signal_connect(G_OBJECT(button->widget()), "clicked",
- G_CALLBACK(OnCloseButtonClicked), this);
- GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS);
- gtk_fixed_put(GTK_FIXED(TabRendererGtk::widget()), button->widget(), 0, 0);
-
- return button;
-}
diff --git a/chrome/browser/gtk/tabs/tab_gtk.h b/chrome/browser/gtk/tabs/tab_gtk.h
index 044718f..df8dfe9 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_gtk.h
@@ -13,8 +13,6 @@ namespace gfx {
class Path;
}
-class CustomDrawButton;
-
class TabGtk : public TabRendererGtk {
public:
// An interface implemented by an object that can help this Tab complete
@@ -82,8 +80,7 @@ class TabGtk : public TabRendererGtk {
virtual bool IsSelected() const;
virtual bool IsVisible() const;
virtual void SetVisible(bool visible) const;
- virtual void CloseButtonResized(const gfx::Rect& bounds);
- virtual void Paint(GdkEventExpose* event);
+ virtual void CloseButtonClicked();
// The callback that is called for every gdk event. We use it to inspect for
// drag-motion events when the drag is outside of the source tab.
@@ -126,17 +123,12 @@ class TabGtk : public TabRendererGtk {
class ContextMenuController;
friend class ContextMenuController;
- // Handles the clicked signal for the close button.
- static void OnCloseButtonClicked(GtkWidget* widget, TabGtk* tab);
-
// Shows the context menu.
void ShowContextMenu();
// Invoked when the context menu closes.
void ContextMenuClosed();
- CustomDrawButton* MakeCloseButton();
-
// An instance of a delegate object that can perform various actions based on
// user gestures.
TabDelegate* delegate_;
@@ -147,9 +139,6 @@ class TabGtk : public TabRendererGtk {
// The context menu controller.
scoped_ptr<ContextMenuController> menu_controller_;
- // The close button.
- scoped_ptr<CustomDrawButton> close_button_;
-
// The windowless widget used to collect input events for the tab.
OwnedWidgetGtk event_box_;
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index 38cba8f..6bcc6fc 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -8,6 +8,7 @@
#include "app/resource_bundle.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_theme_provider.h"
+#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
@@ -182,6 +183,7 @@ TabRendererGtk::TabRendererGtk()
gtk_widget_set_app_paintable(tab_.get(), TRUE);
g_signal_connect(G_OBJECT(tab_.get()), "expose-event",
G_CALLBACK(OnExpose), this);
+ close_button_.reset(MakeCloseButton());
gtk_widget_show(tab_.get());
hover_animation_.reset(new SlideAnimation(this));
@@ -241,10 +243,6 @@ void TabRendererGtk::SetVisible(bool visible) const {
}
}
-void TabRendererGtk::CloseButtonResized(const gfx::Rect& bounds) {
- // Nothing to do.
-}
-
void TabRendererGtk::ValidateLoadingAnimation(AnimationState animation_state) {
loading_animation_.ValidateLoadingAnimation(animation_state);
}
@@ -371,11 +369,7 @@ void TabRendererGtk::ResetCrashedFavIcon() {
should_display_crashed_favicon_ = false;
}
-void TabRendererGtk::Paint(GdkEventExpose* event) {
- gfx::CanvasPaint canvas(event, false);
- if (canvas.isEmpty())
- return;
-
+void TabRendererGtk::Paint(gfx::Canvas* canvas) {
// Don't paint if we're narrower than we can render correctly. (This should
// only happen during animations).
if (width() < GetMinimumUnselectedSize().width())
@@ -390,42 +384,42 @@ void TabRendererGtk::Paint(GdkEventExpose* event) {
show_close_button != showing_close_button_)
Layout();
- PaintTabBackground(&canvas);
+ PaintTabBackground(canvas);
if (show_icon) {
if (loading_animation_.animation_state() != ANIMATION_NONE) {
- PaintLoadingAnimation(&canvas);
+ PaintLoadingAnimation(canvas);
} else {
- canvas.save();
- canvas.ClipRectInt(0, 0, width(), height() - kFavIconTitleSpacing);
+ canvas->save();
+ canvas->ClipRectInt(0, 0, width(), height() - kFavIconTitleSpacing);
if (should_display_crashed_favicon_) {
- canvas.DrawBitmapInt(*crashed_fav_icon, 0, 0,
- crashed_fav_icon->width(),
- crashed_fav_icon->height(),
- favicon_bounds_.x(),
- favicon_bounds_.y() + fav_icon_hiding_offset_,
- kFavIconSize, kFavIconSize,
- true);
+ canvas->DrawBitmapInt(*crashed_fav_icon, 0, 0,
+ crashed_fav_icon->width(),
+ crashed_fav_icon->height(),
+ favicon_bounds_.x(),
+ favicon_bounds_.y() + fav_icon_hiding_offset_,
+ kFavIconSize, kFavIconSize,
+ true);
} else {
if (!data_.favicon.isNull()) {
// TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch
// to using that class to render the favicon).
- canvas.DrawBitmapInt(data_.favicon, 0, 0,
- data_.favicon.width(),
- data_.favicon.height(),
- favicon_bounds_.x(),
- favicon_bounds_.y() + fav_icon_hiding_offset_,
- kFavIconSize, kFavIconSize,
- true);
+ canvas->DrawBitmapInt(data_.favicon, 0, 0,
+ data_.favicon.width(),
+ data_.favicon.height(),
+ favicon_bounds_.x(),
+ favicon_bounds_.y() + fav_icon_hiding_offset_,
+ kFavIconSize, kFavIconSize,
+ true);
}
}
- canvas.restore();
+ canvas->restore();
}
}
if (show_download_icon) {
- canvas.DrawBitmapInt(*download_icon_,
- download_icon_bounds_.x(), download_icon_bounds_.y());
+ canvas->DrawBitmapInt(*download_icon_,
+ download_icon_bounds_.x(), download_icon_bounds_.y());
}
// Paint the Title.
@@ -442,9 +436,15 @@ void TabRendererGtk::Paint(GdkEventExpose* event) {
SkColor title_color = IsSelected() ? kSelectedTitleColor
: kUnselectedTitleColor;
- canvas.DrawStringInt(title, *title_font_, title_color, title_bounds_.x(),
- title_bounds_.y(), title_bounds_.width(),
- title_bounds_.height());
+ canvas->DrawStringInt(title, *title_font_, title_color, title_bounds_.x(),
+ title_bounds_.y(), title_bounds_.width(),
+ title_bounds_.height());
+}
+
+SkBitmap TabRendererGtk::PaintBitmap() {
+ gfx::Canvas canvas(width(), height(), false);
+ Paint(&canvas);
+ return canvas.ExtractBitmap();
}
void TabRendererGtk::SchedulePaint() {
@@ -492,7 +492,7 @@ void TabRendererGtk::Layout() {
close_button_bounds_.SetRect(0, 0, 0, 0);
}
- CloseButtonResized(close_button_bounds_);
+ MoveCloseButtonWidget();
// Size the Title text to fill the remaining space.
int title_left = favicon_bounds_.right() + kFavIconTitleSpacing;
@@ -520,7 +520,25 @@ void TabRendererGtk::Layout() {
// TODO(jhawkins): Handle RTL layout.
}
-void TabRendererGtk::PaintTabBackground(gfx::CanvasPaint* canvas) {
+void TabRendererGtk::MoveCloseButtonWidget() {
+ if (!close_button_bounds_.IsEmpty()) {
+ gtk_fixed_move(GTK_FIXED(tab_.get()), close_button_.get()->widget(),
+ close_button_bounds_.x(), close_button_bounds_.y());
+ gtk_widget_show(close_button_.get()->widget());
+ } else {
+ gtk_widget_hide(close_button_.get()->widget());
+ }
+}
+
+void TabRendererGtk::PaintTab(GdkEventExpose* event) {
+ gfx::CanvasPaint canvas(event, false);
+ if (canvas.isEmpty())
+ return;
+
+ Paint(&canvas);
+}
+
+void TabRendererGtk::PaintTabBackground(gfx::Canvas* canvas) {
if (IsSelected()) {
// Sometimes detaching a tab quickly can result in the model reporting it
// as not being selected, so is_drag_clone_ ensures that we always paint
@@ -549,7 +567,7 @@ void TabRendererGtk::PaintTabBackground(gfx::CanvasPaint* canvas) {
}
}
-void TabRendererGtk::PaintInactiveTabBackground(gfx::CanvasPaint* canvas) {
+void TabRendererGtk::PaintInactiveTabBackground(gfx::Canvas* canvas) {
bool is_otr = data_.off_the_record;
// The tab image needs to be lined up with the background image
@@ -600,7 +618,7 @@ void TabRendererGtk::PaintInactiveTabBackground(gfx::CanvasPaint* canvas) {
bounds_.x() + width() - tab_inactive_.r_width, bounds_.y());
}
-void TabRendererGtk::PaintActiveTabBackground(gfx::CanvasPaint* canvas) {
+void TabRendererGtk::PaintActiveTabBackground(gfx::Canvas* canvas) {
int offset = 1;
SkBitmap* tab_bg = theme_provider_->GetBitmapNamed(IDR_THEME_TOOLBAR);
@@ -636,7 +654,7 @@ void TabRendererGtk::PaintActiveTabBackground(gfx::CanvasPaint* canvas) {
bounds_.x() + width() - tab_active_.r_width, bounds_.y());
}
-void TabRendererGtk::PaintLoadingAnimation(gfx::CanvasPaint* canvas) {
+void TabRendererGtk::PaintLoadingAnimation(gfx::Canvas* canvas) {
const SkBitmap* frames =
(loading_animation_.animation_state() == ANIMATION_WAITING) ?
loading_animation_.waiting_animation_frames() :
@@ -678,10 +696,34 @@ bool TabRendererGtk::ShouldShowCloseBox() const {
return IsSelected() || IconCapacity() >= 3;
}
+CustomDrawButton* TabRendererGtk::MakeCloseButton() {
+ CustomDrawButton* button = new CustomDrawButton(IDR_TAB_CLOSE,
+ IDR_TAB_CLOSE_P, IDR_TAB_CLOSE_H, IDR_TAB_CLOSE);
+
+ g_signal_connect(G_OBJECT(button->widget()), "clicked",
+ G_CALLBACK(OnCloseButtonClicked), this);
+ GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS);
+ gtk_fixed_put(GTK_FIXED(tab_.get()), button->widget(), 0, 0);
+
+ return button;
+}
+
+void TabRendererGtk::CloseButtonClicked() {
+ // Nothing to do.
+}
+
+// static
+void TabRendererGtk::OnCloseButtonClicked(GtkWidget* widget,
+ TabRendererGtk* tab) {
+ tab->CloseButtonClicked();
+}
+
// static
gboolean TabRendererGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event,
TabRendererGtk* tab) {
- tab->Paint(event);
+ tab->PaintTab(event);
+ gtk_container_propagate_expose(GTK_CONTAINER(tab->tab_.get()),
+ tab->close_button_.get()->widget(), event);
return TRUE;
}
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
index f93681d..b353049 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
@@ -20,6 +20,7 @@ namespace gfx {
class Size;
} // namespace gfx
+class CustomDrawButton;
class TabContents;
class ThemeProvider;
@@ -90,16 +91,19 @@ class TabRendererGtk : public AnimationDelegate {
// Sets the visibility of the Tab.
virtual void SetVisible(bool visible) const;
- // Notifies subclasses that the close button has been resized to |bounds|.
- virtual void CloseButtonResized(const gfx::Rect& bounds);
-
// Paints the tab into |canvas|.
- virtual void Paint(GdkEventExpose* event);
+ virtual void Paint(gfx::Canvas* canvas);
+
+ // Paints the tab into a SkBitmap.
+ virtual SkBitmap PaintBitmap();
// There is no PaintNow available, so the fastest we can do is schedule a
// paint with the windowing system.
virtual void SchedulePaint();
+ // Notifies the Tab that the close button has been clicked.
+ virtual void CloseButtonClicked();
+
// Advance the loading animation to the next frame, or hide the animation if
// the tab isn't loading.
void ValidateLoadingAnimation(AnimationState animation_state);
@@ -190,14 +194,20 @@ class TabRendererGtk : public AnimationDelegate {
// Generates the bounds for the interior items of the tab.
void Layout();
+ // Moves the close button widget within the GtkFixed container.
+ void MoveCloseButtonWidget();
+
// Returns the largest of the favicon, title text, and the close button.
static int GetContentHeight();
+ // Paints the tab, minus the close button.
+ void PaintTab(GdkEventExpose* event);
+
// Paint various portions of the Tab
- void PaintTabBackground(gfx::CanvasPaint* canvas);
- void PaintInactiveTabBackground(gfx::CanvasPaint* canvas);
- void PaintActiveTabBackground(gfx::CanvasPaint* canvas);
- void PaintLoadingAnimation(gfx::CanvasPaint* canvas);
+ void PaintTabBackground(gfx::Canvas* canvas);
+ void PaintInactiveTabBackground(gfx::Canvas* canvas);
+ void PaintActiveTabBackground(gfx::Canvas* canvas);
+ void PaintLoadingAnimation(gfx::Canvas* canvas);
// Returns the number of favicon-size elements that can fit in the tab's
// current size.
@@ -209,6 +219,11 @@ class TabRendererGtk : public AnimationDelegate {
// Returns whether the Tab should display a close button.
bool ShouldShowCloseBox() const;
+ CustomDrawButton* MakeCloseButton();
+
+ // Handles the clicked signal for the close button.
+ static void OnCloseButtonClicked(GtkWidget* widget, TabRendererGtk* tab);
+
// expose-event handler that redraws the tab.
static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e,
TabRendererGtk* tab);
@@ -276,6 +291,9 @@ class TabRendererGtk : public AnimationDelegate {
// still render the old theme for this tab.
ThemeProvider* theme_provider_;
+ // The close button.
+ scoped_ptr<CustomDrawButton> close_button_;
+
DISALLOW_COPY_AND_ASSIGN(TabRendererGtk);
};