OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/gtk/reload_button_gtk.h" | 5 #include "chrome/browser/ui/gtk/reload_button_gtk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "chrome/app/chrome_command_ids.h" | 11 #include "chrome/app/chrome_command_ids.h" |
12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/browser_commands.h" | 13 #include "chrome/browser/ui/browser_commands.h" |
| 14 #include "chrome/browser/ui/gtk/accelerators_gtk.h" |
14 #include "chrome/browser/ui/gtk/event_utils.h" | 15 #include "chrome/browser/ui/gtk/event_utils.h" |
15 #include "chrome/browser/ui/gtk/gtk_chrome_button.h" | 16 #include "chrome/browser/ui/gtk/gtk_chrome_button.h" |
16 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | 17 #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
17 #include "chrome/browser/ui/gtk/gtk_util.h" | 18 #include "chrome/browser/ui/gtk/gtk_util.h" |
18 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" | 19 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" |
19 #include "chrome/common/chrome_notification_types.h" | 20 #include "chrome/common/chrome_notification_types.h" |
20 #include "content/public/browser/notification_source.h" | 21 #include "content/public/browser/notification_source.h" |
21 #include "grit/generated_resources.h" | 22 #include "grit/generated_resources.h" |
22 #include "grit/theme_resources.h" | 23 #include "grit/theme_resources.h" |
| 24 #include "ui/base/accelerators/accelerator_gtk.h" |
23 #include "ui/base/l10n/l10n_util.h" | 25 #include "ui/base/l10n/l10n_util.h" |
24 | 26 |
25 // The width of this button in GTK+ theme mode. The Stop and Refresh stock icons | 27 // The width of this button in GTK+ theme mode. The Stop and Refresh stock icons |
26 // can be different sizes; this variable is used to make sure that the button | 28 // can be different sizes; this variable is used to make sure that the button |
27 // doesn't change sizes when switching between the two. | 29 // doesn't change sizes when switching between the two. |
28 static int GtkButtonWidth = 0; | 30 static int GtkButtonWidth = 0; |
29 | 31 |
| 32 // The time in milliseconds between when the user clicks and the menu appears. |
| 33 static const int kReloadMenuTimerDelay = 500; |
| 34 |
| 35 // Content of the Reload drop-down menu. |
| 36 static const int kReloadMenuItems[] = { |
| 37 IDS_RELOAD_MENU_NORMAL_RELOAD_ITEM, |
| 38 IDS_RELOAD_MENU_HARD_RELOAD_ITEM, |
| 39 IDS_RELOAD_MENU_EMPTY_AND_HARD_RELOAD_ITEM, |
| 40 }; |
| 41 |
30 //////////////////////////////////////////////////////////////////////////////// | 42 //////////////////////////////////////////////////////////////////////////////// |
31 // ReloadButton, public: | 43 // ReloadButton, public: |
32 | 44 |
33 ReloadButtonGtk::ReloadButtonGtk(LocationBarViewGtk* location_bar, | 45 ReloadButtonGtk::ReloadButtonGtk(LocationBarViewGtk* location_bar, |
34 Browser* browser) | 46 Browser* browser) |
35 : location_bar_(location_bar), | 47 : location_bar_(location_bar), |
36 browser_(browser), | 48 browser_(browser), |
37 intended_mode_(MODE_RELOAD), | 49 intended_mode_(MODE_RELOAD), |
38 visible_mode_(MODE_RELOAD), | 50 visible_mode_(MODE_RELOAD), |
39 theme_service_(browser ? | 51 theme_service_(browser ? |
40 GtkThemeService::GetFrom(browser->profile()) : NULL), | 52 GtkThemeService::GetFrom(browser->profile()) : NULL), |
41 reload_(theme_service_, IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0), | 53 reload_(theme_service_, IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0), |
42 stop_(theme_service_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, IDR_STOP_D), | 54 stop_(theme_service_, IDR_STOP, IDR_STOP_P, IDR_STOP_H, IDR_STOP_D), |
43 widget_(gtk_chrome_button_new()), | 55 widget_(gtk_chrome_button_new()), |
44 stop_to_reload_timer_delay_(base::TimeDelta::FromMilliseconds(1350)), | 56 stop_to_reload_timer_delay_(base::TimeDelta::FromMilliseconds(1350)), |
| 57 weak_factory_(this), |
| 58 menu_visible_(false), |
45 testing_mouse_hovered_(false), | 59 testing_mouse_hovered_(false), |
46 testing_reload_count_(0) { | 60 testing_reload_count_(0) { |
| 61 menu_model_.reset(new ui::SimpleMenuModel(this)); |
| 62 for (size_t i = 0; i < arraysize(kReloadMenuItems); i++) { |
| 63 menu_model_->AddItemWithStringId(kReloadMenuItems[i], kReloadMenuItems[i]); |
| 64 } |
| 65 |
47 gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height()); | 66 gtk_widget_set_size_request(widget(), reload_.Width(), reload_.Height()); |
48 | 67 |
49 gtk_widget_set_app_paintable(widget(), TRUE); | 68 gtk_widget_set_app_paintable(widget(), TRUE); |
50 | 69 |
51 g_signal_connect(widget(), "clicked", G_CALLBACK(OnClickedThunk), this); | 70 g_signal_connect(widget(), "clicked", G_CALLBACK(OnClickedThunk), this); |
52 g_signal_connect(widget(), "expose-event", G_CALLBACK(OnExposeThunk), this); | 71 g_signal_connect(widget(), "expose-event", G_CALLBACK(OnExposeThunk), this); |
53 g_signal_connect(widget(), "leave-notify-event", | 72 g_signal_connect(widget(), "leave-notify-event", |
54 G_CALLBACK(OnLeaveNotifyThunk), this); | 73 G_CALLBACK(OnLeaveNotifyThunk), this); |
55 gtk_widget_set_can_focus(widget(), FALSE); | 74 gtk_widget_set_can_focus(widget(), FALSE); |
56 | 75 |
57 gtk_widget_set_has_tooltip(widget(), TRUE); | 76 gtk_widget_set_has_tooltip(widget(), TRUE); |
58 g_signal_connect(widget(), "query-tooltip", G_CALLBACK(OnQueryTooltipThunk), | 77 g_signal_connect(widget(), "query-tooltip", G_CALLBACK(OnQueryTooltipThunk), |
59 this); | 78 this); |
60 | 79 |
| 80 g_signal_connect(widget(), "button-press-event", |
| 81 G_CALLBACK(OnButtonPressThunk), this); |
| 82 gtk_widget_add_events(widget(), GDK_POINTER_MOTION_MASK); |
| 83 g_signal_connect(widget(), "motion-notify-event", |
| 84 G_CALLBACK(OnMouseMoveThunk), this); |
| 85 |
| 86 // Popup the menu as left-aligned relative to this widget rather than the |
| 87 // default of right aligned. |
| 88 g_object_set_data(G_OBJECT(widget()), "left-align-popup", |
| 89 reinterpret_cast<void*>(true)); |
| 90 |
61 hover_controller_.Init(widget()); | 91 hover_controller_.Init(widget()); |
62 gtk_util::SetButtonTriggersNavigation(widget()); | 92 gtk_util::SetButtonTriggersNavigation(widget()); |
63 | 93 |
64 if (theme_service_) { | 94 if (theme_service_) { |
65 theme_service_->InitThemesFor(this); | 95 theme_service_->InitThemesFor(this); |
66 registrar_.Add(this, | 96 registrar_.Add(this, |
67 chrome::NOTIFICATION_BROWSER_THEME_CHANGED, | 97 chrome::NOTIFICATION_BROWSER_THEME_CHANGED, |
68 content::Source<ThemeService>(theme_service_)); | 98 content::Source<ThemeService>(theme_service_)); |
69 } | 99 } |
70 | 100 |
(...skipping 15 matching lines...) Expand all Loading... |
86 // If the change is forced, or the user isn't hovering the icon, or it's safe | 116 // If the change is forced, or the user isn't hovering the icon, or it's safe |
87 // to change it to the other image type, make the change immediately; | 117 // to change it to the other image type, make the change immediately; |
88 // otherwise we'll let it happen later. | 118 // otherwise we'll let it happen later. |
89 if (force || ((gtk_widget_get_state(widget()) == GTK_STATE_NORMAL) && | 119 if (force || ((gtk_widget_get_state(widget()) == GTK_STATE_NORMAL) && |
90 !testing_mouse_hovered_) || ((mode == MODE_STOP) ? | 120 !testing_mouse_hovered_) || ((mode == MODE_STOP) ? |
91 !double_click_timer_.IsRunning() : (visible_mode_ != MODE_STOP))) { | 121 !double_click_timer_.IsRunning() : (visible_mode_ != MODE_STOP))) { |
92 double_click_timer_.Stop(); | 122 double_click_timer_.Stop(); |
93 stop_to_reload_timer_.Stop(); | 123 stop_to_reload_timer_.Stop(); |
94 visible_mode_ = mode; | 124 visible_mode_ = mode; |
95 | 125 |
96 stop_.set_paint_override(-1); | 126 // Do not change the state of the button if menu is currently visible. |
97 gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(widget_.get())); | 127 if (!menu_visible_) { |
| 128 stop_.set_paint_override(-1); |
| 129 gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(widget_.get())); |
| 130 } |
98 | 131 |
99 UpdateThemeButtons(); | 132 UpdateThemeButtons(); |
100 gtk_widget_queue_draw(widget()); | 133 gtk_widget_queue_draw(widget()); |
101 } else if (visible_mode_ != MODE_RELOAD) { | 134 } else if (visible_mode_ != MODE_RELOAD) { |
102 // If you read the views implementation of reload_button.cc, you'll see | 135 // If you read the views implementation of reload_button.cc, you'll see |
103 // that instead of screwing with paint states, the views implementation | 136 // that instead of screwing with paint states, the views implementation |
104 // just changes whether the view is enabled. We can't do that here because | 137 // just changes whether the view is enabled. We can't do that here because |
105 // changing the widget state to GTK_STATE_INSENSITIVE will cause a cascade | 138 // changing the widget state to GTK_STATE_INSENSITIVE will cause a cascade |
106 // of messages on all its children and will also trigger a synthesized | 139 // of messages on all its children and will also trigger a synthesized |
107 // leave notification and prevent the real leave notification from turning | 140 // leave notification and prevent the real leave notification from turning |
(...skipping 28 matching lines...) Expand all Loading... |
136 DCHECK(chrome::NOTIFICATION_BROWSER_THEME_CHANGED == type); | 169 DCHECK(chrome::NOTIFICATION_BROWSER_THEME_CHANGED == type); |
137 | 170 |
138 GtkThemeService* provider = static_cast<GtkThemeService*>( | 171 GtkThemeService* provider = static_cast<GtkThemeService*>( |
139 content::Source<ThemeService>(source).ptr()); | 172 content::Source<ThemeService>(source).ptr()); |
140 DCHECK_EQ(provider, theme_service_); | 173 DCHECK_EQ(provider, theme_service_); |
141 GtkButtonWidth = 0; | 174 GtkButtonWidth = 0; |
142 UpdateThemeButtons(); | 175 UpdateThemeButtons(); |
143 } | 176 } |
144 | 177 |
145 //////////////////////////////////////////////////////////////////////////////// | 178 //////////////////////////////////////////////////////////////////////////////// |
| 179 // ReloadButtonGtk, MenuGtk::Delegate implementation: |
| 180 |
| 181 void ReloadButtonGtk::StoppedShowing() { |
| 182 menu_visible_ = false; |
| 183 ChangeMode(intended_mode_, true); |
| 184 } |
| 185 |
| 186 //////////////////////////////////////////////////////////////////////////////// |
| 187 // ReloadButtonGtk, SimpleMenuModel::Delegate implementation: |
| 188 |
| 189 bool ReloadButtonGtk::IsCommandIdChecked(int command_id) const { |
| 190 return false; |
| 191 } |
| 192 |
| 193 bool ReloadButtonGtk::IsCommandIdEnabled(int command_id) const { |
| 194 return true; |
| 195 } |
| 196 |
| 197 bool ReloadButtonGtk::IsCommandIdVisible(int command_id) const { |
| 198 return true; |
| 199 } |
| 200 |
| 201 bool ReloadButtonGtk::GetAcceleratorForCommandId(int command_id, |
| 202 ui::Accelerator* accelerator) { |
| 203 int command = 0; |
| 204 switch (command_id) { |
| 205 case IDS_RELOAD_MENU_NORMAL_RELOAD_ITEM: |
| 206 command = IDC_RELOAD; |
| 207 break; |
| 208 case IDS_RELOAD_MENU_HARD_RELOAD_ITEM: |
| 209 command = IDC_RELOAD_IGNORING_CACHE; |
| 210 break; |
| 211 case IDS_RELOAD_MENU_EMPTY_AND_HARD_RELOAD_ITEM: |
| 212 // No accelerator. |
| 213 break; |
| 214 default: |
| 215 LOG(ERROR) << "Unknown reload menu command"; |
| 216 } |
| 217 |
| 218 bool accelerator_set = false; |
| 219 if (command) { |
| 220 const ui::AcceleratorGtk* accelerator_gtk = |
| 221 AcceleratorsGtk::GetInstance()-> |
| 222 GetPrimaryAcceleratorForCommand(command); |
| 223 if (accelerator_gtk) { |
| 224 *accelerator = *accelerator_gtk; |
| 225 accelerator_set = true; |
| 226 } |
| 227 } |
| 228 return accelerator_set; |
| 229 } |
| 230 |
| 231 void ReloadButtonGtk::ExecuteCommand(int command_id) { |
| 232 switch (command_id) { |
| 233 case IDS_RELOAD_MENU_NORMAL_RELOAD_ITEM: |
| 234 DoReload(IDC_RELOAD); |
| 235 break; |
| 236 case IDS_RELOAD_MENU_HARD_RELOAD_ITEM: |
| 237 DoReload(IDC_RELOAD_IGNORING_CACHE); |
| 238 break; |
| 239 case IDS_RELOAD_MENU_EMPTY_AND_HARD_RELOAD_ITEM: |
| 240 ClearCache(); |
| 241 DoReload(IDC_RELOAD_IGNORING_CACHE); |
| 242 break; |
| 243 default: |
| 244 LOG(ERROR) << "Unknown reload menu command"; |
| 245 } |
| 246 } |
| 247 |
| 248 //////////////////////////////////////////////////////////////////////////////// |
146 // ReloadButtonGtk, private: | 249 // ReloadButtonGtk, private: |
147 | 250 |
148 void ReloadButtonGtk::OnClicked(GtkWidget* /* sender */) { | 251 void ReloadButtonGtk::OnClicked(GtkWidget* /* sender */) { |
| 252 weak_factory_.InvalidateWeakPtrs(); |
149 if (visible_mode_ == MODE_STOP) { | 253 if (visible_mode_ == MODE_STOP) { |
150 // Do nothing if Stop was disabled due to an attempt to change back to | 254 // Do nothing if Stop was disabled due to an attempt to change back to |
151 // RELOAD mode while hovered. | 255 // RELOAD mode while hovered. |
152 if (stop_.paint_override() == GTK_STATE_INSENSITIVE) | 256 if (stop_.paint_override() == GTK_STATE_INSENSITIVE) |
153 return; | 257 return; |
154 | 258 |
155 if (browser_) | 259 if (browser_) |
156 chrome::Stop(browser_); | 260 chrome::Stop(browser_); |
157 | 261 |
158 // The user has clicked, so we can feel free to update the button, | 262 // The user has clicked, so we can feel free to update the button, |
159 // even if the mouse is still hovering. | 263 // even if the mouse is still hovering. |
160 ChangeMode(MODE_RELOAD, true); | 264 ChangeMode(MODE_RELOAD, true); |
161 } else if (!double_click_timer_.IsRunning()) { | 265 } else if (!double_click_timer_.IsRunning()) { |
162 // Shift-clicking or Ctrl-clicking the reload button means we should ignore | 266 DoReload(0); |
163 // any cached content. | |
164 int command; | |
165 GdkModifierType modifier_state; | |
166 gtk_get_current_event_state(&modifier_state); | |
167 guint modifier_state_uint = modifier_state; | |
168 if (modifier_state_uint & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) { | |
169 command = IDC_RELOAD_IGNORING_CACHE; | |
170 // Mask off Shift and Control so they don't affect the disposition below. | |
171 modifier_state_uint &= ~(GDK_SHIFT_MASK | GDK_CONTROL_MASK); | |
172 } else { | |
173 command = IDC_RELOAD; | |
174 } | |
175 | |
176 WindowOpenDisposition disposition = | |
177 event_utils::DispositionFromGdkState(modifier_state_uint); | |
178 if ((disposition == CURRENT_TAB) && location_bar_) { | |
179 // Forcibly reset the location bar, since otherwise it won't discard any | |
180 // ongoing user edits, since it doesn't realize this is a user-initiated | |
181 // action. | |
182 location_bar_->Revert(); | |
183 } | |
184 | |
185 // Start a timer - while this timer is running, the reload button cannot be | |
186 // changed to a stop button. We do not set |intended_mode_| to MODE_STOP | |
187 // here as the browser will do that when it actually starts loading (which | |
188 // may happen synchronously, thus the need to do this before telling the | |
189 // browser to execute the reload command). | |
190 double_click_timer_.Start(FROM_HERE, double_click_timer_delay_, this, | |
191 &ReloadButtonGtk::OnDoubleClickTimer); | |
192 | |
193 if (browser_) | |
194 chrome::ExecuteCommandWithDisposition(browser_, command, disposition); | |
195 ++testing_reload_count_; | |
196 } | 267 } |
197 } | 268 } |
198 | 269 |
199 gboolean ReloadButtonGtk::OnExpose(GtkWidget* widget, | 270 gboolean ReloadButtonGtk::OnExpose(GtkWidget* widget, |
200 GdkEventExpose* e) { | 271 GdkEventExpose* e) { |
201 TRACE_EVENT0("ui::gtk", "ReloadButtonGtk::OnExpose"); | 272 TRACE_EVENT0("ui::gtk", "ReloadButtonGtk::OnExpose"); |
202 if (theme_service_ && theme_service_->UsingNativeTheme()) | 273 if (theme_service_ && theme_service_->UsingNativeTheme()) |
203 return FALSE; | 274 return FALSE; |
204 return ((visible_mode_ == MODE_RELOAD) ? reload_ : stop_).OnExpose( | 275 return ((visible_mode_ == MODE_RELOAD) ? reload_ : stop_).OnExpose( |
205 widget, e, hover_controller_.GetCurrentValue()); | 276 widget, e, hover_controller_.GetCurrentValue()); |
206 } | 277 } |
207 | 278 |
208 gboolean ReloadButtonGtk::OnLeaveNotify(GtkWidget* /* widget */, | 279 gboolean ReloadButtonGtk::OnLeaveNotify(GtkWidget* /* widget */, |
209 GdkEventCrossing* /* event */) { | 280 GdkEventCrossing* /* event */) { |
210 ChangeMode(intended_mode_, true); | 281 ChangeMode(intended_mode_, true); |
211 return FALSE; | 282 return FALSE; |
212 } | 283 } |
213 | 284 |
214 gboolean ReloadButtonGtk::OnQueryTooltip(GtkWidget* /* sender */, | 285 gboolean ReloadButtonGtk::OnQueryTooltip(GtkWidget* /* sender */, |
215 gint /* x */, | 286 gint /* x */, |
216 gint /* y */, | 287 gint /* y */, |
217 gboolean /* keyboard_mode */, | 288 gboolean /* keyboard_mode */, |
218 GtkTooltip* tooltip) { | 289 GtkTooltip* tooltip) { |
219 // |location_bar_| can be NULL in tests. | 290 // |location_bar_| can be NULL in tests. |
220 if (!location_bar_) | 291 if (!location_bar_) |
221 return FALSE; | 292 return FALSE; |
222 | 293 |
| 294 int reload_tooltip = ReloadMenuEnabled() ? |
| 295 IDS_TOOLTIP_RELOAD_WITH_MENU : IDS_TOOLTIP_RELOAD; |
223 gtk_tooltip_set_text(tooltip, l10n_util::GetStringUTF8( | 296 gtk_tooltip_set_text(tooltip, l10n_util::GetStringUTF8( |
224 (visible_mode_ == MODE_RELOAD) ? | 297 (visible_mode_ == MODE_RELOAD) ? |
225 IDS_TOOLTIP_RELOAD : IDS_TOOLTIP_STOP).c_str()); | 298 reload_tooltip : IDS_TOOLTIP_STOP).c_str()); |
226 return TRUE; | 299 return TRUE; |
227 } | 300 } |
228 | 301 |
| 302 gboolean ReloadButtonGtk::OnButtonPress(GtkWidget* widget, |
| 303 GdkEventButton* event) { |
| 304 if (!ReloadMenuEnabled() || visible_mode_ == MODE_STOP) |
| 305 return FALSE; |
| 306 |
| 307 if (event->button == 3) |
| 308 ShowReloadMenu(event->button, event->time); |
| 309 |
| 310 if (event->button != 1) |
| 311 return FALSE; |
| 312 |
| 313 y_position_of_last_press_ = static_cast<int>(event->y); |
| 314 MessageLoop::current()->PostDelayedTask( |
| 315 FROM_HERE, |
| 316 base::Bind(&ReloadButtonGtk::ShowReloadMenu, |
| 317 weak_factory_.GetWeakPtr(), |
| 318 event->button, |
| 319 event->time), |
| 320 base::TimeDelta::FromMilliseconds(kReloadMenuTimerDelay)); |
| 321 return FALSE; |
| 322 } |
| 323 |
| 324 gboolean ReloadButtonGtk::OnMouseMove(GtkWidget* widget, |
| 325 GdkEventMotion* event) { |
| 326 // If we aren't waiting to show the back forward menu, do nothing. |
| 327 if (!weak_factory_.HasWeakPtrs()) |
| 328 return FALSE; |
| 329 |
| 330 // We only count moves about a certain threshold. |
| 331 GtkSettings* settings = gtk_widget_get_settings(widget); |
| 332 int drag_min_distance; |
| 333 g_object_get(settings, "gtk-dnd-drag-threshold", &drag_min_distance, NULL); |
| 334 if (event->y - y_position_of_last_press_ < drag_min_distance) |
| 335 return FALSE; |
| 336 |
| 337 // We will show the menu now. Cancel the delayed event. |
| 338 weak_factory_.InvalidateWeakPtrs(); |
| 339 ShowReloadMenu(/* button */ 1, event->time); |
| 340 return FALSE; |
| 341 } |
| 342 |
229 void ReloadButtonGtk::UpdateThemeButtons() { | 343 void ReloadButtonGtk::UpdateThemeButtons() { |
230 bool use_gtk = theme_service_ && theme_service_->UsingNativeTheme(); | 344 bool use_gtk = theme_service_ && theme_service_->UsingNativeTheme(); |
231 | 345 |
232 if (use_gtk) { | 346 if (use_gtk) { |
233 gtk_widget_ensure_style(widget()); | 347 gtk_widget_ensure_style(widget()); |
234 GtkStyle* style = gtk_widget_get_style(widget()); | 348 GtkStyle* style = gtk_widget_get_style(widget()); |
235 GtkIconSet* icon_set = gtk_style_lookup_icon_set( | 349 GtkIconSet* icon_set = gtk_style_lookup_icon_set( |
236 style, | 350 style, |
237 (visible_mode_ == MODE_RELOAD) ? GTK_STOCK_REFRESH : GTK_STOCK_STOP); | 351 (visible_mode_ == MODE_RELOAD) ? GTK_STOCK_REFRESH : GTK_STOCK_STOP); |
238 if (icon_set) { | 352 if (icon_set) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(widget()), use_gtk); | 389 gtk_chrome_button_set_use_gtk_rendering(GTK_CHROME_BUTTON(widget()), use_gtk); |
276 } | 390 } |
277 | 391 |
278 void ReloadButtonGtk::OnDoubleClickTimer() { | 392 void ReloadButtonGtk::OnDoubleClickTimer() { |
279 ChangeMode(intended_mode_, false); | 393 ChangeMode(intended_mode_, false); |
280 } | 394 } |
281 | 395 |
282 void ReloadButtonGtk::OnStopToReloadTimer() { | 396 void ReloadButtonGtk::OnStopToReloadTimer() { |
283 ChangeMode(intended_mode_, true); | 397 ChangeMode(intended_mode_, true); |
284 } | 398 } |
| 399 |
| 400 void ReloadButtonGtk::ShowReloadMenu(int button, guint32 event_time) { |
| 401 if (!ReloadMenuEnabled() || visible_mode_ == MODE_STOP) |
| 402 return; |
| 403 |
| 404 menu_visible_ = true; |
| 405 menu_.reset(new MenuGtk(this, menu_model_.get())); |
| 406 reload_.set_paint_override(GTK_STATE_ACTIVE); |
| 407 gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(widget_.get()), |
| 408 GTK_STATE_ACTIVE); |
| 409 gtk_widget_queue_draw(widget()); |
| 410 menu_->PopupForWidget(widget(), button, event_time); |
| 411 } |
| 412 |
| 413 void ReloadButtonGtk::DoReload(int command) { |
| 414 // Shift-clicking or Ctrl-clicking the reload button means we should ignore |
| 415 // any cached content. |
| 416 GdkModifierType modifier_state; |
| 417 gtk_get_current_event_state(&modifier_state); |
| 418 guint modifier_state_uint = modifier_state; |
| 419 |
| 420 // Default reload behaviour. |
| 421 if (command == 0) { |
| 422 if (modifier_state_uint & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) { |
| 423 command = IDC_RELOAD_IGNORING_CACHE; |
| 424 // Mask off Shift and Control so they don't affect the disposition below. |
| 425 modifier_state_uint &= ~(GDK_SHIFT_MASK | GDK_CONTROL_MASK); |
| 426 } else { |
| 427 command = IDC_RELOAD; |
| 428 } |
| 429 } |
| 430 |
| 431 WindowOpenDisposition disposition = |
| 432 event_utils::DispositionFromGdkState(modifier_state_uint); |
| 433 if ((disposition == CURRENT_TAB) && location_bar_) { |
| 434 // Forcibly reset the location bar, since otherwise it won't discard any |
| 435 // ongoing user edits, since it doesn't realize this is a user-initiated |
| 436 // action. |
| 437 location_bar_->Revert(); |
| 438 } |
| 439 |
| 440 // Start a timer - while this timer is running, the reload button cannot be |
| 441 // changed to a stop button. We do not set |intended_mode_| to MODE_STOP |
| 442 // here as the browser will do that when it actually starts loading (which |
| 443 // may happen synchronously, thus the need to do this before telling the |
| 444 // browser to execute the reload command). |
| 445 double_click_timer_.Start(FROM_HERE, double_click_timer_delay_, this, |
| 446 &ReloadButtonGtk::OnDoubleClickTimer); |
| 447 |
| 448 if (browser_) |
| 449 chrome::ExecuteCommandWithDisposition(browser_, command, disposition); |
| 450 ++testing_reload_count_; |
| 451 } |
| 452 |
| 453 bool ReloadButtonGtk::ReloadMenuEnabled() { |
| 454 if (!browser_) |
| 455 return false; |
| 456 return chrome::IsDebuggerAttachedToCurrentTab(browser_); |
| 457 } |
| 458 |
| 459 void ReloadButtonGtk::ClearCache() { |
| 460 if (browser_) |
| 461 chrome::ClearCache(browser_); |
| 462 } |
| 463 |
OLD | NEW |