summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/reload_button_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/gtk/reload_button_gtk.cc')
-rw-r--r--chrome/browser/gtk/reload_button_gtk.cc157
1 files changed, 97 insertions, 60 deletions
diff --git a/chrome/browser/gtk/reload_button_gtk.cc b/chrome/browser/gtk/reload_button_gtk.cc
index 8e3cb8f..e5e8857 100644
--- a/chrome/browser/gtk/reload_button_gtk.cc
+++ b/chrome/browser/gtk/reload_button_gtk.cc
@@ -31,26 +31,22 @@ ReloadButtonGtk::ReloadButtonGtk(LocationBarViewGtk* location_bar,
visible_mode_(MODE_RELOAD),
theme_provider_(browser ?
GtkThemeProvider::GetFrom(browser->profile()) : NULL),
- reload_(theme_provider_, IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0,
- IDR_BUTTON_MASK),
- stop_(theme_provider_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, 0,
- IDR_BUTTON_MASK),
+ reload_(theme_provider_, IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0),
+ stop_(theme_provider_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, IDR_STOP_D),
widget_(gtk_chrome_button_new()) {
- gtk_widget_set_size_request(widget_.get(), reload_.Width(), reload_.Height());
+ gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height());
- gtk_widget_set_app_paintable(widget_.get(), TRUE);
+ gtk_widget_set_app_paintable(widget(), TRUE);
- g_signal_connect(widget_.get(), "expose-event",
- G_CALLBACK(OnExposeThunk), this);
- g_signal_connect(widget_.get(), "leave-notify-event",
+ g_signal_connect(widget(), "clicked", G_CALLBACK(OnClickedThunk), this);
+ g_signal_connect(widget(), "expose-event", G_CALLBACK(OnExposeThunk), this);
+ g_signal_connect(widget(), "leave-notify-event",
G_CALLBACK(OnLeaveNotifyThunk), this);
- g_signal_connect(widget_.get(), "clicked",
- G_CALLBACK(OnClickedThunk), this);
- GTK_WIDGET_UNSET_FLAGS(widget_.get(), GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS(widget(), GTK_CAN_FOCUS);
- gtk_widget_set_has_tooltip(widget_.get(), TRUE);
- g_signal_connect(widget_.get(), "query-tooltip",
- G_CALLBACK(OnQueryTooltipThunk), this);
+ gtk_widget_set_has_tooltip(widget(), TRUE);
+ g_signal_connect(widget(), "query-tooltip", G_CALLBACK(OnQueryTooltipThunk),
+ this);
hover_controller_.Init(widget());
gtk_util::SetButtonTriggersNavigation(widget());
@@ -78,8 +74,30 @@ void ReloadButtonGtk::ChangeMode(Mode mode, bool force) {
!timer_running() : (visible_mode_ != MODE_STOP))) {
timer_.Stop();
visible_mode_ = mode;
- gtk_widget_queue_draw(widget_.get());
+ stop_.set_paint_override(-1);
+ gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(widget_.get()));
+
+ UpdateThemeButtons();
+ gtk_widget_queue_draw(widget());
+ } else if (visible_mode_ != MODE_RELOAD) {
+ // If you read the views implementation of reload_button.cc, you'll see
+ // that instead of screwing with paint states, the views implementation
+ // just changes whether the view is enabled. We can't do that here because
+ // changing the widget state to GTK_STATE_INSENSITIVE will cause a cascade
+ // of messages on all its children and will also trigger a synthesized
+ // leave notification and prevent the real leave notification from turning
+ // the button back to normal. So instead, override the stop_ paint state
+ // for chrome-theme mode, and use this as a flag to discard click events.
+ stop_.set_paint_override(GTK_STATE_INSENSITIVE);
+
+ // Also set the gtk_chrome_button paint state to insensitive to hide
+ // the border drawn around the stop icon.
+ gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(widget_.get()),
+ GTK_STATE_INSENSITIVE);
+
+ // If we're in GTK theme mode, we need to also render the correct icon for
+ // the stop/insensitive since we won't be using |stop_| to render the icon.
UpdateThemeButtons();
}
}
@@ -97,25 +115,16 @@ void ReloadButtonGtk::Observe(NotificationType type,
}
void ReloadButtonGtk::OnButtonTimer() {
- ChangeMode(intended_mode_, true);
-}
-
-gboolean ReloadButtonGtk::OnExpose(GtkWidget* widget,
- GdkEventExpose* e) {
- if (theme_provider_ && theme_provider_->UseGtkTheme())
- return FALSE;
- return ((visible_mode_ == MODE_RELOAD) ? reload_ : stop_).OnExpose(
- widget, e, hover_controller_.GetCurrentValue());
-}
-
-gboolean ReloadButtonGtk::OnLeaveNotify(GtkWidget* widget,
- GdkEventCrossing* event) {
- ChangeMode(intended_mode_, true);
- return FALSE;
+ ChangeMode(intended_mode_, false);
}
void ReloadButtonGtk::OnClicked(GtkWidget* sender) {
if (visible_mode_ == MODE_STOP) {
+ // The stop button is disabled because the user hovered over the button
+ // until the stop action is no longer selectable.
+ if (stop_.paint_override() == GTK_STATE_INSENSITIVE)
+ return;
+
if (browser_)
browser_->Stop();
@@ -129,11 +138,10 @@ void ReloadButtonGtk::OnClicked(GtkWidget* sender) {
GdkModifierType modifier_state;
gtk_get_current_event_state(&modifier_state);
guint modifier_state_uint = modifier_state;
- if (modifier_state_uint & GDK_SHIFT_MASK) {
+ if (modifier_state_uint & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) {
command = IDC_RELOAD_IGNORING_CACHE;
- // Mask off shift so it isn't interpreted as affecting the disposition
- // below.
- modifier_state_uint &= ~GDK_SHIFT_MASK;
+ // Mask off Shift and Control so they don't affect the disposition below.
+ modifier_state_uint &= ~(GDK_SHIFT_MASK | GDK_CONTROL_MASK);
} else {
command = IDC_RELOAD;
}
@@ -147,9 +155,6 @@ void ReloadButtonGtk::OnClicked(GtkWidget* sender) {
location_bar_->Revert();
}
- if (browser_)
- browser_->ExecuteCommandWithDisposition(command, disposition);
-
// Figure out the system double-click time.
if (button_delay_ == 0) {
GtkSettings* settings = gtk_settings_get_default();
@@ -157,18 +162,34 @@ void ReloadButtonGtk::OnClicked(GtkWidget* sender) {
NULL);
}
- // Stop the timer.
- timer_.Stop();
-
// Start a timer - while this timer is running, the reload button cannot be
// changed to a stop button. We do not set |intended_mode_| to MODE_STOP
- // here as we want to wait for the browser to tell us that it has started
- // loading (and this may occur only after some delay).
+ // here as the browser will do that when it actually starts loading (which
+ // may happen synchronously, thus the need to do this before telling the
+ // browser to execute the reload command).
+ timer_.Stop();
timer_.Start(base::TimeDelta::FromMilliseconds(button_delay_), this,
&ReloadButtonGtk::OnButtonTimer);
+
+ if (browser_)
+ browser_->ExecuteCommandWithDisposition(command, disposition);
}
}
+gboolean ReloadButtonGtk::OnExpose(GtkWidget* widget,
+ GdkEventExpose* e) {
+ if (theme_provider_ && theme_provider_->UseGtkTheme())
+ return FALSE;
+ return ((visible_mode_ == MODE_RELOAD) ? reload_ : stop_).OnExpose(
+ widget, e, hover_controller_.GetCurrentValue());
+}
+
+gboolean ReloadButtonGtk::OnLeaveNotify(GtkWidget* widget,
+ GdkEventCrossing* event) {
+ ChangeMode(intended_mode_, true);
+ return FALSE;
+}
+
gboolean ReloadButtonGtk::OnQueryTooltip(GtkWidget* sender,
gint x,
gint y,
@@ -188,31 +209,47 @@ void ReloadButtonGtk::UpdateThemeButtons() {
bool use_gtk = theme_provider_ && theme_provider_->UseGtkTheme();
if (use_gtk) {
- GdkPixbuf* pixbuf = gtk_widget_render_icon(widget(),
- (intended_mode_ == MODE_RELOAD) ? GTK_STOCK_REFRESH : GTK_STOCK_STOP,
- GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
-
- gtk_button_set_image(GTK_BUTTON(widget_.get()),
- gtk_image_new_from_pixbuf(pixbuf));
- g_object_unref(pixbuf);
+ gtk_widget_ensure_style(widget());
+ GtkIconSet* icon_set = gtk_style_lookup_icon_set(
+ widget()->style,
+ (visible_mode_ == MODE_RELOAD) ? GTK_STOCK_REFRESH : GTK_STOCK_STOP);
+ if (icon_set) {
+ GtkStateType state = static_cast<GtkStateType>(
+ GTK_WIDGET_STATE(widget()));
+ if (visible_mode_ == MODE_STOP && stop_.paint_override() != -1)
+ state = static_cast<GtkStateType>(stop_.paint_override());
+
+ GdkPixbuf* pixbuf = gtk_icon_set_render_icon(
+ icon_set,
+ widget()->style,
+ gtk_widget_get_direction(widget()),
+ state,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ widget(),
+ NULL);
+
+ gtk_button_set_image(GTK_BUTTON(widget()),
+ gtk_image_new_from_pixbuf(pixbuf));
+ g_object_unref(pixbuf);
+ }
- gtk_widget_set_size_request(widget_.get(), -1, -1);
+ gtk_widget_set_size_request(widget(), -1, -1);
GtkRequisition req;
gtk_widget_size_request(widget(), &req);
GtkButtonWidth = std::max(GtkButtonWidth, req.width);
- gtk_widget_set_size_request(widget_.get(), GtkButtonWidth, -1);
+ gtk_widget_set_size_request(widget(), GtkButtonWidth, -1);
- gtk_widget_set_app_paintable(widget_.get(), FALSE);
- gtk_widget_set_double_buffered(widget_.get(), TRUE);
+ gtk_widget_set_app_paintable(widget(), FALSE);
+ gtk_widget_set_double_buffered(widget(), TRUE);
} else {
- gtk_widget_set_size_request(widget_.get(), reload_.Width(),
- reload_.Height());
+ gtk_button_set_image(GTK_BUTTON(widget()), NULL);
+
+ gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height());
- gtk_widget_set_app_paintable(widget_.get(), TRUE);
+ gtk_widget_set_app_paintable(widget(), TRUE);
// We effectively double-buffer by virtue of having only one image...
- gtk_widget_set_double_buffered(widget_.get(), FALSE);
+ gtk_widget_set_double_buffered(widget(), FALSE);
}
- gtk_chrome_button_set_use_gtk_rendering(
- GTK_CHROME_BUTTON(widget_.get()), use_gtk);
+ gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(widget()), use_gtk);
}