Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1043)

Side by Side Diff: chrome/browser/gtk/browser_titlebar.cc

Issue 2095001: GTK: Support Ambiance/Radiance and Dust button ordering. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Move the new class into its own file Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/gtk/browser_titlebar.h" 5 #include "chrome/browser/gtk/browser_titlebar.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 9
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "app/l10n_util.h" 13 #include "app/l10n_util.h"
14 #include "app/resource_bundle.h" 14 #include "app/resource_bundle.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/singleton.h" 16 #include "base/singleton.h"
17 #include "base/string_piece.h"
18 #include "base/string_tokenizer.h"
17 #include "chrome/app/chrome_dll_resource.h" 19 #include "chrome/app/chrome_dll_resource.h"
18 #include "chrome/browser/browser.h" 20 #include "chrome/browser/browser.h"
19 #include "chrome/browser/encoding_menu_controller.h" 21 #include "chrome/browser/encoding_menu_controller.h"
20 #include "chrome/browser/gtk/accelerators_gtk.h" 22 #include "chrome/browser/gtk/accelerators_gtk.h"
21 #include "chrome/browser/gtk/browser_window_gtk.h" 23 #include "chrome/browser/gtk/browser_window_gtk.h"
22 #include "chrome/browser/gtk/custom_button.h" 24 #include "chrome/browser/gtk/custom_button.h"
25 #include "chrome/browser/gtk/gconf_titlebar_listener.h"
23 #include "chrome/browser/gtk/gtk_theme_provider.h" 26 #include "chrome/browser/gtk/gtk_theme_provider.h"
24 #include "chrome/browser/gtk/gtk_util.h" 27 #include "chrome/browser/gtk/gtk_util.h"
25 #include "chrome/browser/gtk/menu_gtk.h" 28 #include "chrome/browser/gtk/menu_gtk.h"
26 #include "chrome/browser/gtk/nine_box.h" 29 #include "chrome/browser/gtk/nine_box.h"
27 #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" 30 #include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
28 #include "chrome/browser/page_menu_model.h" 31 #include "chrome/browser/page_menu_model.h"
29 #include "chrome/browser/pref_service.h" 32 #include "chrome/browser/pref_service.h"
30 #include "chrome/browser/profile.h" 33 #include "chrome/browser/profile.h"
31 #include "chrome/browser/tab_contents/tab_contents.h" 34 #include "chrome/browser/tab_contents/tab_contents.h"
32 #include "chrome/common/notification_service.h" 35 #include "chrome/common/notification_service.h"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 if (two_difference > one_difference + 0.1) 124 if (two_difference > one_difference + 0.1)
122 return *two; 125 return *two;
123 else 126 else
124 return *one; 127 return *one;
125 } 128 }
126 129
127 } // namespace 130 } // namespace
128 131
129 BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window, 132 BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window,
130 GtkWindow* window) 133 GtkWindow* window)
131 : browser_window_(browser_window), window_(window), 134 : browser_window_(browser_window),
135 window_(window),
136 titlebar_left_buttons_vbox_(NULL),
137 titlebar_right_buttons_vbox_(NULL),
138 titlebar_left_buttons_hbox_(NULL),
139 titlebar_right_buttons_hbox_(NULL),
140 top_padding_left_(NULL),
141 top_padding_right_(NULL),
132 app_mode_favicon_(NULL), 142 app_mode_favicon_(NULL),
133 app_mode_title_(NULL), 143 app_mode_title_(NULL),
134 using_custom_frame_(false), 144 using_custom_frame_(false),
135 window_has_focus_(false), 145 window_has_focus_(false),
136 theme_provider_(NULL) { 146 theme_provider_(NULL) {
137 Init(); 147 Init();
138 } 148 }
139 149
140 void BrowserTitlebar::Init() { 150 void BrowserTitlebar::Init() {
141 // The widget hierarchy is shown below. 151 // The widget hierarchy is shown below.
142 // 152 //
143 // +- EventBox (container_) -------------------------------------------------+ 153 // +- EventBox (container_) -------------------------------------+
144 // +- HBox (container_hbox) -------------------------------------------------+ 154 // +- HBox (container_hbox_) ------------------------------------+
145 // |+- Algn. -++- Alignment --------------++- VBox (titlebar_buttons_box_) -+| 155 // |+ VBox ---++- Algn. -++- Alignment --------------++ VBox ---+|
146 // ||+ Image +|| (titlebar_alignment_) ||+ - Fixed (top_padding_) ------+|| 156 // || titlebar||+ Image +|| (titlebar_alignment_) || titlebar||
147 // ||| ||| ||+- HBox -----------------------+|| 157 // || left ||| ||| || right ||
148 // |||spy_guy||| |||+- button -++- button -+ ||| 158 // || button |||spy_guy||| || button ||
149 // ||| |||+- TabStripGtk ---------+|||| minimize || restore | ... ||| 159 // || vbox ||| |||+- TabStripGtk ---------+|| vbox ||
150 // ||| )8\ |||| tab tab tabclose ||||+----------++----------+ ||| 160 // || ||| )8\ |||| tab tab tabclose ||| ||
151 // ||+-------+||+------------------------+||+------------------------------+|| 161 // || ||+-------+||+------------------------+|| ||
152 // |+---------++--------------------------++--------------------------------+| 162 // |+---------++---------++--------------------------++---------+|
153 // +-------------------------------------------------------------------------+ 163 // +-------------------------------------------------------------+
164 //
165 // There are two vboxes on either side of |container_hbox_| because when the
166 // desktop is GNOME, the button placement is configurable based on a metacity
167 // gconf key. We can't just have one vbox and move it back and forth because
168 // the gconf language allows you to place buttons on both sides of the
169 // window. This being Linux, I'm sure there's a bunch of people who have
170 // already configured their window manager to do so and we don't want to get
171 // confused when that happens. The actual contents of these vboxes are lazily
172 // generated so they don't interfere with alignment when everything is
173 // stuffed in the other box.
174 //
175 // Each vbox has the contains the following hierarchy if it contains buttons:
176 //
177 // +- VBox (titlebar_{l,r}_buttons_vbox_) ---------+
178 // |+- Fixed (top_padding_{l,r}_) ----------------+|
179 // ||+- HBox (titlebar_{l,r}_buttons_hbox_ ------+||
180 // ||| (buttons of a configurable layout) |||
181 // ||+-------------------------------------------+||
182 // |+---------------------------------------------+|
183 // +-----------------------------------------------+
154 // 184 //
155 // If we're a popup window or in app mode, we don't display the spy guy or 185 // If we're a popup window or in app mode, we don't display the spy guy or
156 // the tab strip. Instead, put an hbox in titlebar_alignment_ in place of 186 // the tab strip. Instead, put an hbox in titlebar_alignment_ in place of
157 // the tab strip. 187 // the tab strip.
158 // +- Alignment (titlebar_alignment_) -----------------------------------+ 188 // +- Alignment (titlebar_alignment_) -----------------------------------+
159 // |+ HBox -------------------------------------------------------------+| 189 // |+ HBox -------------------------------------------------------------+|
160 // ||+- TabStripGtk -++- Image ----------------++- Label --------------+|| 190 // ||+- TabStripGtk -++- Image ----------------++- Label --------------+||
161 // ||| hidden ++ (app_mode_favicon_) || (app_mode_title_) ||| 191 // ||| hidden ++ (app_mode_favicon_) || (app_mode_title_) |||
162 // ||| || favicon || page title ||| 192 // ||| || favicon || page title |||
163 // ||+---------------++------------------------++----------------------+|| 193 // ||+---------------++------------------------++----------------------+||
164 // |+-------------------------------------------------------------------+| 194 // |+-------------------------------------------------------------------+|
165 // +---------------------------------------------------------------------+ 195 // +---------------------------------------------------------------------+
166 GtkWidget* container_hbox = gtk_hbox_new(FALSE, 0); 196 container_hbox_ = gtk_hbox_new(FALSE, 0);
167 197
168 container_ = gtk_event_box_new(); 198 container_ = gtk_event_box_new();
169 gtk_widget_set_name(container_, "chrome-browser-titlebar"); 199 gtk_widget_set_name(container_, "chrome-browser-titlebar");
170 gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE); 200 gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE);
171 gtk_container_add(GTK_CONTAINER(container_), container_hbox); 201 gtk_container_add(GTK_CONTAINER(container_), container_hbox_);
172 202
173 g_signal_connect(container_, "scroll-event", G_CALLBACK(OnScroll), this); 203 g_signal_connect(container_, "scroll-event", G_CALLBACK(OnScroll), this);
174 204
175 g_signal_connect(window_, "window-state-event", 205 g_signal_connect(window_, "window-state-event",
176 G_CALLBACK(OnWindowStateChanged), this); 206 G_CALLBACK(OnWindowStateChanged), this);
177 207
208 // Allocate the two button boxes on the left and right parts of the bar.
209 titlebar_left_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
210 gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_left_buttons_vbox_,
211 FALSE, FALSE, 0);
212 titlebar_right_buttons_vbox_ = gtk_vbox_new(FALSE, 0);
213 gtk_box_pack_end(GTK_BOX(container_hbox_), titlebar_right_buttons_vbox_,
214 FALSE, FALSE, 0);
215
216 // Either read the gconf database and register for updates (on GNOME), or use
217 // the default value (anywhere else).
218 Singleton<GConfTitlebarListener>()->SetTitlebarButtons(this);
219
178 if (browser_window_->browser()->profile()->IsOffTheRecord() && 220 if (browser_window_->browser()->profile()->IsOffTheRecord() &&
179 browser_window_->browser()->type() == Browser::TYPE_NORMAL) { 221 browser_window_->browser()->type() == Browser::TYPE_NORMAL) {
180 GtkWidget* spy_guy = gtk_image_new_from_pixbuf(GetOTRAvatar()); 222 GtkWidget* spy_guy = gtk_image_new_from_pixbuf(GetOTRAvatar());
181 gtk_misc_set_alignment(GTK_MISC(spy_guy), 0.0, 1.0); 223 gtk_misc_set_alignment(GTK_MISC(spy_guy), 0.0, 1.0);
182 GtkWidget* spy_frame = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 224 GtkWidget* spy_frame = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
183 // We use this alignment rather than setting padding on the GtkImage because 225 // We use this alignment rather than setting padding on the GtkImage because
184 // the image's intrinsic padding doesn't clip the pixbuf during painting. 226 // the image's intrinsic padding doesn't clip the pixbuf during painting.
185 gtk_alignment_set_padding(GTK_ALIGNMENT(spy_frame), 0, 227 gtk_alignment_set_padding(GTK_ALIGNMENT(spy_frame), 0,
186 kOTRBottomSpacing, kOTRSideSpacing, kOTRSideSpacing); 228 kOTRBottomSpacing, kOTRSideSpacing, kOTRSideSpacing);
187 gtk_widget_set_size_request(spy_guy, -1, 0); 229 gtk_widget_set_size_request(spy_guy, -1, 0);
188 gtk_container_add(GTK_CONTAINER(spy_frame), spy_guy); 230 gtk_container_add(GTK_CONTAINER(spy_frame), spy_guy);
189 gtk_box_pack_start(GTK_BOX(container_hbox), spy_frame, FALSE, FALSE, 0); 231 gtk_box_pack_start(GTK_BOX(container_hbox_), spy_frame, FALSE, FALSE, 0);
190 } 232 }
191 233
192 // We use an alignment to control the titlebar height. 234 // We use an alignment to control the titlebar height.
193 titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 235 titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
194 if (browser_window_->browser()->type() == Browser::TYPE_NORMAL) { 236 if (browser_window_->browser()->type() == Browser::TYPE_NORMAL) {
195 gtk_box_pack_start(GTK_BOX(container_hbox), titlebar_alignment_, TRUE, 237 gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_alignment_, TRUE,
196 TRUE, 0); 238 TRUE, 0);
197 239
198 // Put the tab strip in the titlebar. 240 // Put the tab strip in the titlebar.
199 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), 241 gtk_container_add(GTK_CONTAINER(titlebar_alignment_),
200 browser_window_->tabstrip()->widget()); 242 browser_window_->tabstrip()->widget());
201 } else { 243 } else {
202 // App mode specific widgets. 244 // App mode specific widgets.
203 gtk_box_pack_start(GTK_BOX(container_hbox), titlebar_alignment_, TRUE, 245 gtk_box_pack_start(GTK_BOX(container_hbox_), titlebar_alignment_, TRUE,
204 TRUE, 0); 246 TRUE, 0);
205 GtkWidget* app_mode_hbox = gtk_hbox_new(FALSE, kIconTitleSpacing); 247 GtkWidget* app_mode_hbox = gtk_hbox_new(FALSE, kIconTitleSpacing);
206 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), app_mode_hbox); 248 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), app_mode_hbox);
207 249
208 // Put the tab strip in the hbox even though we don't show it. Sometimes 250 // Put the tab strip in the hbox even though we don't show it. Sometimes
209 // we need the position of the tab strip so make sure it's in our widget 251 // we need the position of the tab strip so make sure it's in our widget
210 // hierarchy. 252 // hierarchy.
211 gtk_box_pack_start(GTK_BOX(app_mode_hbox), 253 gtk_box_pack_start(GTK_BOX(app_mode_hbox),
212 browser_window_->tabstrip()->widget(), FALSE, FALSE, 0); 254 browser_window_->tabstrip()->widget(), FALSE, FALSE, 0);
213 255
(...skipping 21 matching lines...) Expand all
235 // Register with the theme provider to set the |app_mode_title_| label 277 // Register with the theme provider to set the |app_mode_title_| label
236 // color. 278 // color.
237 theme_provider_ = GtkThemeProvider::GetFrom( 279 theme_provider_ = GtkThemeProvider::GetFrom(
238 browser_window_->browser()->profile()); 280 browser_window_->browser()->profile());
239 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, 281 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
240 NotificationService::AllSources()); 282 NotificationService::AllSources());
241 theme_provider_->InitThemesFor(this); 283 theme_provider_->InitThemesFor(this);
242 UpdateTitleAndIcon(); 284 UpdateTitleAndIcon();
243 } 285 }
244 286
245 // We put the min/max/restore/close buttons in a vbox so they are top aligned
246 // (up to padding) and don't vertically stretch.
247 titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0);
248 GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, kButtonSpacing);
249 top_padding_ = gtk_fixed_new();
250 gtk_widget_set_size_request(top_padding_, -1, kButtonOuterPadding);
251 gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), top_padding_, FALSE, FALSE,
252 0);
253 gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE,
254 FALSE, 0);
255
256 close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H,
257 buttons_hbox,
258 IDS_XPFRAME_CLOSE_TOOLTIP));
259
260 restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
261 IDR_RESTORE_H, buttons_hbox,
262 IDS_XPFRAME_RESTORE_TOOLTIP));
263 maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
264 IDR_MAXIMIZE_H, buttons_hbox,
265 IDS_XPFRAME_MAXIMIZE_TOOLTIP));
266 minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
267 IDR_MINIMIZE_H, buttons_hbox,
268 IDS_XPFRAME_MINIMIZE_TOOLTIP));
269
270 gtk_util::SetButtonClickableByMouseButtons(maximize_button_->widget(),
271 true, true, true);
272
273 gtk_widget_size_request(close_button_->widget(), &close_button_req_);
274 gtk_widget_size_request(minimize_button_->widget(), &minimize_button_req_);
275 gtk_widget_size_request(restore_button_->widget(), &restore_button_req_);
276
277 gtk_box_pack_end(GTK_BOX(container_hbox), titlebar_buttons_box_, FALSE,
278 FALSE, 0);
279
280 gtk_widget_show_all(container_); 287 gtk_widget_show_all(container_);
281 288
282 ActiveWindowWatcherX::AddObserver(this); 289 ActiveWindowWatcherX::AddObserver(this);
283 } 290 }
284 291
285 BrowserTitlebar::~BrowserTitlebar() { 292 BrowserTitlebar::~BrowserTitlebar() {
286 ActiveWindowWatcherX::RemoveObserver(this); 293 ActiveWindowWatcherX::RemoveObserver(this);
294 Singleton<GConfTitlebarListener>()->RemoveObserver(this);
295 }
296
297 void BrowserTitlebar::BuildButtons(const std::string& button_string) {
298 // Clear out all previous data.
299 close_button_.reset();
300 restore_button_.reset();
301 maximize_button_.reset();
302 minimize_button_.reset();
303 gtk_util::RemoveAllChildren(titlebar_left_buttons_vbox_);
304 gtk_util::RemoveAllChildren(titlebar_right_buttons_vbox_);
305 titlebar_left_buttons_hbox_ = NULL;
306 titlebar_right_buttons_hbox_ = NULL;
307 top_padding_left_ = NULL;
308 top_padding_right_ = NULL;
309
310 bool left_side = true;
311 StringTokenizer tokenizer(button_string, ":,");
312 tokenizer.set_options(StringTokenizer::RETURN_DELIMS);
313 while (tokenizer.GetNext()) {
314 if (tokenizer.token_is_delim()) {
315 if (*tokenizer.token_begin() == ':')
316 left_side = false;
317 } else {
318 base::StringPiece token = tokenizer.token_piece();
319 if (token == "minimize") {
320 GtkWidget* parent_box = GetButtonHBox(left_side);
321 minimize_button_.reset(
322 BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
323 IDR_MINIMIZE_H, parent_box,
324 IDS_XPFRAME_MINIMIZE_TOOLTIP));
325
326 gtk_widget_size_request(minimize_button_->widget(),
327 &minimize_button_req_);
328 } else if (token == "maximize") {
329 GtkWidget* parent_box = GetButtonHBox(left_side);
330 restore_button_.reset(
331 BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
332 IDR_RESTORE_H, parent_box,
333 IDS_XPFRAME_RESTORE_TOOLTIP));
334 maximize_button_.reset(
335 BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
336 IDR_MAXIMIZE_H, parent_box,
337 IDS_XPFRAME_MAXIMIZE_TOOLTIP));
338
339 gtk_util::SetButtonClickableByMouseButtons(maximize_button_->widget(),
340 true, true, true);
341 gtk_widget_size_request(restore_button_->widget(),
342 &restore_button_req_);
343 } else if (token == "close") {
344 GtkWidget* parent_box = GetButtonHBox(left_side);
345 close_button_.reset(
346 BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P,
347 IDR_CLOSE_H, parent_box,
348 IDS_XPFRAME_CLOSE_TOOLTIP));
349
350 gtk_widget_size_request(close_button_->widget(), &close_button_req_);
351 }
352 // Ignore any other values like "pin" since we don't have images for
353 // those.
354 }
355 }
356
357 // Now show the correct widgets in the two hierarchies.
358 gtk_widget_show_all(titlebar_left_buttons_vbox_);
359 gtk_widget_show_all(titlebar_right_buttons_vbox_);
360 UpdateMaximizeRestoreVisibility();
361 }
362
363 GtkWidget* BrowserTitlebar::GetButtonHBox(bool left_side) {
364 if (left_side && titlebar_left_buttons_hbox_)
365 return titlebar_left_buttons_hbox_;
366 else if (!left_side && titlebar_right_buttons_hbox_)
367 return titlebar_right_buttons_hbox_;
368
369 // We put the min/max/restore/close buttons in a vbox so they are top aligned
370 // (up to padding) and don't vertically stretch.
371 GtkWidget* vbox = left_side ? titlebar_left_buttons_vbox_ :
372 titlebar_right_buttons_vbox_;
373
374 GtkWidget* top_padding = gtk_fixed_new();
375 gtk_widget_set_size_request(top_padding, -1, kButtonOuterPadding);
376 gtk_box_pack_start(GTK_BOX(vbox), top_padding, FALSE, FALSE, 0);
377
378 GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, kButtonSpacing);
379 gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 0);
380
381 if (left_side) {
382 titlebar_left_buttons_hbox_ = buttons_hbox;
383 top_padding_left_ = top_padding;
384 } else {
385 titlebar_right_buttons_hbox_ = buttons_hbox;
386 top_padding_right_ = top_padding;
387 }
388
389 return buttons_hbox;
287 } 390 }
288 391
289 CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image, 392 CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image,
290 int image_pressed, int image_hot, GtkWidget* box, int tooltip) { 393 int image_pressed, int image_hot, GtkWidget* box, int tooltip) {
291 CustomDrawButton* button = new CustomDrawButton(image, image_pressed, 394 CustomDrawButton* button = new CustomDrawButton(image, image_pressed,
292 image_hot, 0); 395 image_hot, 0);
293 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK); 396 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
294 g_signal_connect(button->widget(), "clicked", 397 g_signal_connect(button->widget(), "clicked",
295 G_CALLBACK(OnButtonClickedThunk), this); 398 G_CALLBACK(OnButtonClickedThunk), this);
296 g_signal_connect(button->widget(), "motion-notify-event", 399 g_signal_connect(button->widget(), "motion-notify-event",
297 G_CALLBACK(OnMouseMoveEvent), browser_window_); 400 G_CALLBACK(OnMouseMoveEvent), browser_window_);
298 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip); 401 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip);
299 gtk_widget_set_tooltip_text(button->widget(), 402 gtk_widget_set_tooltip_text(button->widget(),
300 localized_tooltip.c_str()); 403 localized_tooltip.c_str());
301 gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0); 404 gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
302 return button; 405 return button;
303 } 406 }
304 407
305 void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) { 408 void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) {
306 using_custom_frame_ = use_custom_frame; 409 using_custom_frame_ = use_custom_frame;
307 if (use_custom_frame) 410 if (use_custom_frame) {
308 gtk_widget_show(titlebar_buttons_box_); 411 if (titlebar_left_buttons_vbox_)
309 else 412 gtk_widget_show(titlebar_left_buttons_vbox_);
310 gtk_widget_hide(titlebar_buttons_box_); 413 if (titlebar_right_buttons_vbox_)
414 gtk_widget_show(titlebar_right_buttons_vbox_);
415 } else {
416 if (titlebar_left_buttons_vbox_)
417 gtk_widget_hide(titlebar_left_buttons_vbox_);
418 if (titlebar_right_buttons_vbox_)
419 gtk_widget_hide(titlebar_right_buttons_vbox_);
420 }
311 UpdateTitlebarAlignment(); 421 UpdateTitlebarAlignment();
312 } 422 }
313 423
314 void BrowserTitlebar::UpdateTitleAndIcon() { 424 void BrowserTitlebar::UpdateTitleAndIcon() {
315 if (!app_mode_title_) 425 if (!app_mode_title_)
316 return; 426 return;
317 427
318 // Get the page title and elide it to the available space. 428 // Get the page title and elide it to the available space.
319 string16 title = browser_window_->browser()->GetWindowTitleForCurrentTab(); 429 string16 title = browser_window_->browser()->GetWindowTitleForCurrentTab();
320 gtk_label_set_text(GTK_LABEL(app_mode_title_), UTF16ToUTF8(title).c_str()); 430 gtk_label_set_text(GTK_LABEL(app_mode_title_), UTF16ToUTF8(title).c_str());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 // Resize the buttons so that the clickable area extends all the way to the 508 // Resize the buttons so that the clickable area extends all the way to the
399 // edge of the browser window. 509 // edge of the browser window.
400 GtkRequisition close_button_req = close_button_req_; 510 GtkRequisition close_button_req = close_button_req_;
401 GtkRequisition minimize_button_req = minimize_button_req_; 511 GtkRequisition minimize_button_req = minimize_button_req_;
402 GtkRequisition restore_button_req = restore_button_req_; 512 GtkRequisition restore_button_req = restore_button_req_;
403 if (using_custom_frame_ && browser_window_->IsMaximized()) { 513 if (using_custom_frame_ && browser_window_->IsMaximized()) {
404 close_button_req.width += kButtonOuterPadding; 514 close_button_req.width += kButtonOuterPadding;
405 close_button_req.height += kButtonOuterPadding; 515 close_button_req.height += kButtonOuterPadding;
406 minimize_button_req.height += kButtonOuterPadding; 516 minimize_button_req.height += kButtonOuterPadding;
407 restore_button_req.height += kButtonOuterPadding; 517 restore_button_req.height += kButtonOuterPadding;
408 gtk_widget_hide(top_padding_); 518 if (top_padding_left_)
519 gtk_widget_hide(top_padding_left_);
520 if (top_padding_right_)
521 gtk_widget_hide(top_padding_right_);
409 } else { 522 } else {
410 gtk_widget_show(top_padding_); 523 if (top_padding_left_)
524 gtk_widget_show(top_padding_left_);
525 if (top_padding_right_)
526 gtk_widget_show(top_padding_right_);
411 } 527 }
412 gtk_widget_set_size_request(close_button_->widget(), 528 if (close_button_.get()) {
413 close_button_req.width, close_button_req.height); 529 gtk_widget_set_size_request(close_button_->widget(),
414 gtk_widget_set_size_request(minimize_button_->widget(), 530 close_button_req.width,
415 minimize_button_req.width, 531 close_button_req.height);
416 minimize_button_req.height); 532 }
417 gtk_widget_set_size_request(restore_button_->widget(), 533 if (minimize_button_.get()) {
418 restore_button_req.width, 534 gtk_widget_set_size_request(minimize_button_->widget(),
419 restore_button_req.height); 535 minimize_button_req.width,
536 minimize_button_req.height);
537 }
538 if (maximize_button_.get()) {
539 gtk_widget_set_size_request(restore_button_->widget(),
540 restore_button_req.width,
541 restore_button_req.height);
542 }
420 } 543 }
421 544
422 void BrowserTitlebar::UpdateTextColor() { 545 void BrowserTitlebar::UpdateTextColor() {
423 if (app_mode_title_ && theme_provider_) { 546 if (app_mode_title_ && theme_provider_) {
424 if (theme_provider_->UseGtkTheme()) { 547 if (theme_provider_->UseGtkTheme()) {
425 // We don't really have any good options here. 548 // We don't really have any good options here.
426 // 549 //
427 // Colors from window manager themes aren't exposed in GTK; the window 550 // Colors from window manager themes aren't exposed in GTK; the window
428 // manager is a separate component and when there is information sharing 551 // manager is a separate component and when there is information sharing
429 // (in the case of metacity), it's one way where the window manager reads 552 // (in the case of metacity), it's one way where the window manager reads
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 } else if (event->button.button == 2) { 611 } else if (event->button.button == 2) {
489 y = 0; 612 y = 0;
490 height = screen_rect.height; 613 height = screen_rect.height;
491 } 614 }
492 615
493 browser_window_->SetBounds(gfx::Rect(x, y, width, height)); 616 browser_window_->SetBounds(gfx::Rect(x, y, width, height));
494 } 617 }
495 gdk_event_free(event); 618 gdk_event_free(event);
496 } 619 }
497 620
621 void BrowserTitlebar::UpdateMaximizeRestoreVisibility() {
622 if (maximize_button_.get()) {
623 if (browser_window_->IsMaximized()) {
624 gtk_widget_hide(maximize_button_->widget());
625 gtk_widget_show(restore_button_->widget());
626 } else {
627 gtk_widget_hide(restore_button_->widget());
628 gtk_widget_show(maximize_button_->widget());
629 }
630 }
631 }
632
498 // static 633 // static
499 gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window, 634 gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
500 GdkEventWindowState* event, BrowserTitlebar* titlebar) { 635 GdkEventWindowState* event, BrowserTitlebar* titlebar) {
501 // Update the maximize/restore button. 636 titlebar->UpdateMaximizeRestoreVisibility();
502 if (titlebar->browser_window_->IsMaximized()) {
503 gtk_widget_hide(titlebar->maximize_button_->widget());
504 gtk_widget_show(titlebar->restore_button_->widget());
505 } else {
506 gtk_widget_hide(titlebar->restore_button_->widget());
507 gtk_widget_show(titlebar->maximize_button_->widget());
508 }
509 titlebar->UpdateTitlebarAlignment(); 637 titlebar->UpdateTitlebarAlignment();
510 titlebar->UpdateTextColor(); 638 titlebar->UpdateTextColor();
511 return FALSE; 639 return FALSE;
512 } 640 }
513 641
514 // static 642 // static
515 gboolean BrowserTitlebar::OnScroll(GtkWidget* widget, GdkEventScroll* event, 643 gboolean BrowserTitlebar::OnScroll(GtkWidget* widget, GdkEventScroll* event,
516 BrowserTitlebar* titlebar) { 644 BrowserTitlebar* titlebar) {
517 TabStripModel* tabstrip_model = 645 TabStripModel* tabstrip_model =
518 titlebar->browser_window_->browser()->tabstrip_model(); 646 titlebar->browser_window_->browser()->tabstrip_model();
519 int index = tabstrip_model->selected_index(); 647 int index = tabstrip_model->selected_index();
520 if (event->direction == GDK_SCROLL_LEFT || 648 if (event->direction == GDK_SCROLL_LEFT ||
521 event->direction == GDK_SCROLL_UP) { 649 event->direction == GDK_SCROLL_UP) {
522 if (index != 0) 650 if (index != 0)
523 tabstrip_model->SelectPreviousTab(); 651 tabstrip_model->SelectPreviousTab();
524 } else if (index + 1 < tabstrip_model->count()) { 652 } else if (index + 1 < tabstrip_model->count()) {
525 tabstrip_model->SelectNextTab(); 653 tabstrip_model->SelectNextTab();
526 } 654 }
527 return TRUE; 655 return TRUE;
528 } 656 }
529 657
530 // static 658 // static
531 void BrowserTitlebar::OnButtonClicked(GtkWidget* button) { 659 void BrowserTitlebar::OnButtonClicked(GtkWidget* button) {
532 if (close_button_->widget() == button) { 660 if (close_button_.get() && close_button_->widget() == button) {
533 browser_window_->Close(); 661 browser_window_->Close();
534 } else if (restore_button_->widget() == button) { 662 } else if (restore_button_.get() && restore_button_->widget() == button) {
535 browser_window_->UnMaximize(); 663 browser_window_->UnMaximize();
536 } else if (maximize_button_->widget() == button) { 664 } else if (maximize_button_.get() && maximize_button_->widget() == button) {
537 MaximizeButtonClicked(); 665 MaximizeButtonClicked();
538 } else if (minimize_button_->widget() == button) { 666 } else if (minimize_button_.get() && minimize_button_->widget() == button) {
539 gtk_window_iconify(window_); 667 gtk_window_iconify(window_);
540 } 668 }
541 } 669 }
542 670
543 // static 671 // static
544 gboolean BrowserTitlebar::OnButtonPressed(GtkWidget* widget, 672 gboolean BrowserTitlebar::OnButtonPressed(GtkWidget* widget,
545 GdkEventButton* event, 673 GdkEventButton* event,
546 BrowserTitlebar* titlebar) { 674 BrowserTitlebar* titlebar) {
547 if (event->button != 1) 675 if (event->button != 1)
548 return FALSE; 676 return FALSE;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 menus::SimpleMenuModel::Delegate* delegate) 822 menus::SimpleMenuModel::Delegate* delegate)
695 : SimpleMenuModel(delegate) { 823 : SimpleMenuModel(delegate) {
696 AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB); 824 AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB);
697 AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); 825 AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB);
698 AddSeparator(); 826 AddSeparator();
699 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 827 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
700 AddSeparator(); 828 AddSeparator();
701 AddCheckItemWithStringId(kShowWindowDecorationsCommand, 829 AddCheckItemWithStringId(kShowWindowDecorationsCommand,
702 IDS_SHOW_WINDOW_DECORATIONS_MENU); 830 IDS_SHOW_WINDOW_DECORATIONS_MENU);
703 } 831 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698