Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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_window_gtk.h" | 5 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 6 | 6 |
| 7 #include <gdk/gdkkeysyms.h> | |
| 8 | |
| 7 #include "base/base_paths_linux.h" | 9 #include "base/base_paths_linux.h" |
| 8 #include "base/logging.h" | 10 #include "base/logging.h" |
| 9 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 10 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "chrome/app/chrome_dll_resource.h" | |
| 11 #include "chrome/browser/browser.h" | 14 #include "chrome/browser/browser.h" |
| 12 #include "chrome/browser/find_bar_controller.h" | 15 #include "chrome/browser/find_bar_controller.h" |
| 13 #include "chrome/browser/gtk/browser_toolbar_gtk.h" | 16 #include "chrome/browser/gtk/browser_toolbar_gtk.h" |
| 14 #include "chrome/browser/gtk/find_bar_gtk.h" | 17 #include "chrome/browser/gtk/find_bar_gtk.h" |
| 15 #include "chrome/browser/gtk/nine_box.h" | 18 #include "chrome/browser/gtk/nine_box.h" |
| 16 #include "chrome/browser/gtk/status_bubble_gtk.h" | 19 #include "chrome/browser/gtk/status_bubble_gtk.h" |
| 17 #include "chrome/browser/gtk/tab_contents_container_gtk.h" | 20 #include "chrome/browser/gtk/tab_contents_container_gtk.h" |
| 18 #include "chrome/browser/location_bar.h" | 21 #include "chrome/browser/location_bar.h" |
| 19 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 22 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 20 #include "chrome/browser/tab_contents/web_contents.h" | 23 #include "chrome/browser/tab_contents/web_contents.h" |
| 21 | |
| 22 #include "chrome/common/resource_bundle.h" | 24 #include "chrome/common/resource_bundle.h" |
| 23 #include "grit/theme_resources.h" | 25 #include "grit/theme_resources.h" |
| 24 | 26 |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 static GdkPixbuf* LoadThemeImage(int resource_id) { | 29 static GdkPixbuf* LoadThemeImage(int resource_id) { |
| 28 // TODO(mmoss) refactor -- stolen from custom_button.cc | 30 // TODO(mmoss) refactor -- stolen from custom_button.cc |
| 29 if (0 == resource_id) | 31 if (0 == resource_id) |
| 30 return NULL; | 32 return NULL; |
| 31 | 33 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 // Using gtk_window_get_position/size creates a race condition, so only use | 70 // Using gtk_window_get_position/size creates a race condition, so only use |
| 69 // this to get the initial bounds. After window creation, we pick up the | 71 // this to get the initial bounds. After window creation, we pick up the |
| 70 // normal bounds by connecting to the configure-event signal. | 72 // normal bounds by connecting to the configure-event signal. |
| 71 gfx::Rect GetInitialWindowBounds(GtkWindow* window) { | 73 gfx::Rect GetInitialWindowBounds(GtkWindow* window) { |
| 72 gint x, y, width, height; | 74 gint x, y, width, height; |
| 73 gtk_window_get_position(window, &x, &y); | 75 gtk_window_get_position(window, &x, &y); |
| 74 gtk_window_get_size(window, &width, &height); | 76 gtk_window_get_size(window, &width, &height); |
| 75 return gfx::Rect(x, y, width, height); | 77 return gfx::Rect(x, y, width, height); |
| 76 } | 78 } |
| 77 | 79 |
| 80 static const guint kFocusLocationKey = GDK_l; | |
| 81 static const guint kFocusSearchKey = GDK_k; | |
| 82 static const guint kOpenFileKey = GDK_o; | |
|
Dean McNamee
2009/03/16 19:19:02
there are in a namespace (so shouldn't be static)
| |
| 83 | |
| 84 static int GetCommandFromKeyval(guint accel_key) { | |
| 85 switch (accel_key) { | |
| 86 case kFocusLocationKey: | |
| 87 return IDC_FOCUS_LOCATION; | |
| 88 case kFocusSearchKey: | |
| 89 return IDC_FOCUS_SEARCH; | |
| 90 case kOpenFileKey: | |
| 91 return IDC_OPEN_FILE; | |
| 92 default: | |
| 93 NOTREACHED(); | |
| 94 return 0; | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 // Usually accelerators are checked before propagating the key event, but in our | |
| 99 // case we want to reverse the order of things to allow webkit to handle key | |
| 100 // events like ctrl-l. If the window's children can handle the key event, this | |
| 101 // will return TRUE and the signal won't be propagated further. If the window's | |
| 102 // children cannot handle the key event then this will return FALSE and the | |
| 103 // default GtkWindow key press handler will be invoked. | |
| 104 gboolean OnKeyPress(GtkWindow* window, GdkEventKey* event, gpointer userdata) { | |
| 105 return gtk_window_propagate_key_event(window, event); | |
| 106 } | |
| 107 | |
| 78 } // namespace | 108 } // namespace |
| 79 | 109 |
| 80 BrowserWindowGtk::BrowserWindowGtk(Browser* browser) | 110 BrowserWindowGtk::BrowserWindowGtk(Browser* browser) |
| 81 : browser_(browser), | 111 : browser_(browser), |
| 82 // TODO(port): make this a pref. | 112 // TODO(port): make this a pref. |
| 83 custom_frame_(false) { | 113 custom_frame_(false) { |
| 84 Init(); | 114 Init(); |
| 85 browser_->tabstrip_model()->AddObserver(this); | 115 browser_->tabstrip_model()->AddObserver(this); |
| 86 } | 116 } |
| 87 | 117 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 -1, -1, | 153 -1, -1, |
| 124 GDK_RGB_DITHER_NORMAL, 0, 0); | 154 GDK_RGB_DITHER_NORMAL, 0, 0); |
| 125 gdk_pixbuf_unref(pixbuf); | 155 gdk_pixbuf_unref(pixbuf); |
| 126 | 156 |
| 127 return FALSE; // Allow subwidgets to paint. | 157 return FALSE; // Allow subwidgets to paint. |
| 128 } | 158 } |
| 129 | 159 |
| 130 void BrowserWindowGtk::Init() { | 160 void BrowserWindowGtk::Init() { |
| 131 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); | 161 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); |
| 132 gtk_window_set_default_size(window_, 640, 480); | 162 gtk_window_set_default_size(window_, 640, 480); |
| 133 g_signal_connect(G_OBJECT(window_), "destroy", | 163 g_signal_connect(window_, "destroy", |
| 134 G_CALLBACK(OnWindowDestroyed), this); | 164 G_CALLBACK(OnWindowDestroyed), this); |
| 135 g_signal_connect(G_OBJECT(window_), "configure-event", | 165 g_signal_connect(window_, "configure-event", |
| 136 G_CALLBACK(MainWindowConfigured), this); | 166 G_CALLBACK(MainWindowConfigured), this); |
| 137 g_signal_connect(G_OBJECT(window_), "window-state-event", | 167 g_signal_connect(window_, "window-state-event", |
| 138 G_CALLBACK(MainWindowStateChanged), this); | 168 G_CALLBACK(MainWindowStateChanged), this); |
| 169 g_signal_connect(window_, "key-press-event", | |
| 170 G_CALLBACK(OnKeyPress), NULL); | |
| 171 ConnectAccelerators(); | |
| 139 bounds_ = GetInitialWindowBounds(window_); | 172 bounds_ = GetInitialWindowBounds(window_); |
| 140 | 173 |
| 141 GtkAccelGroup* accel_group = gtk_accel_group_new(); | |
| 142 gtk_window_add_accel_group(window_, accel_group); | |
| 143 | |
| 144 GdkPixbuf* images[9] = { | 174 GdkPixbuf* images[9] = { |
| 145 LoadThemeImage(IDR_CONTENT_TOP_LEFT_CORNER), | 175 LoadThemeImage(IDR_CONTENT_TOP_LEFT_CORNER), |
| 146 LoadThemeImage(IDR_CONTENT_TOP_CENTER), | 176 LoadThemeImage(IDR_CONTENT_TOP_CENTER), |
| 147 LoadThemeImage(IDR_CONTENT_TOP_RIGHT_CORNER), | 177 LoadThemeImage(IDR_CONTENT_TOP_RIGHT_CORNER), |
| 148 LoadThemeImage(IDR_CONTENT_LEFT_SIDE), | 178 LoadThemeImage(IDR_CONTENT_LEFT_SIDE), |
| 149 NULL, | 179 NULL, |
| 150 LoadThemeImage(IDR_CONTENT_RIGHT_SIDE), | 180 LoadThemeImage(IDR_CONTENT_RIGHT_SIDE), |
| 151 LoadThemeImage(IDR_CONTENT_BOTTOM_LEFT_CORNER), | 181 LoadThemeImage(IDR_CONTENT_BOTTOM_LEFT_CORNER), |
| 152 LoadThemeImage(IDR_CONTENT_BOTTOM_CENTER), | 182 LoadThemeImage(IDR_CONTENT_BOTTOM_CENTER), |
| 153 LoadThemeImage(IDR_CONTENT_BOTTOM_RIGHT_CORNER) | 183 LoadThemeImage(IDR_CONTENT_BOTTOM_RIGHT_CORNER) |
| 154 }; | 184 }; |
| 155 content_area_ninebox_.reset(new NineBox(images)); | 185 content_area_ninebox_.reset(new NineBox(images)); |
| 156 | 186 |
| 157 // This vbox is intended to surround the "content": toolbar+page. | 187 // This vbox is intended to surround the "content": toolbar+page. |
| 158 // When we add the tab strip, it should go in a vbox surrounding this one. | 188 // When we add the tab strip, it should go in a vbox surrounding this one. |
| 159 vbox_ = gtk_vbox_new(FALSE, 0); | 189 vbox_ = gtk_vbox_new(FALSE, 0); |
| 160 gtk_widget_set_app_paintable(vbox_, TRUE); | 190 gtk_widget_set_app_paintable(vbox_, TRUE); |
| 161 gtk_widget_set_double_buffered(vbox_, FALSE); | 191 gtk_widget_set_double_buffered(vbox_, FALSE); |
| 162 g_signal_connect(G_OBJECT(vbox_), "expose-event", | 192 g_signal_connect(G_OBJECT(vbox_), "expose-event", |
| 163 G_CALLBACK(&OnContentAreaExpose), this); | 193 G_CALLBACK(&OnContentAreaExpose), this); |
| 164 | 194 |
| 165 toolbar_.reset(new BrowserToolbarGtk(browser_.get())); | 195 toolbar_.reset(new BrowserToolbarGtk(browser_.get())); |
| 166 toolbar_->Init(browser_->profile(), accel_group); | 196 toolbar_->Init(browser_->profile(), window_); |
| 167 toolbar_->AddToolbarToBox(vbox_); | 197 toolbar_->AddToolbarToBox(vbox_); |
| 168 | 198 |
| 169 FindBarGtk* find_bar_gtk = new FindBarGtk(); | 199 FindBarGtk* find_bar_gtk = new FindBarGtk(); |
| 170 find_bar_controller_.reset(new FindBarController(find_bar_gtk)); | 200 find_bar_controller_.reset(new FindBarController(find_bar_gtk)); |
| 171 find_bar_gtk->set_find_bar_controller(find_bar_controller_.get()); | 201 find_bar_gtk->set_find_bar_controller(find_bar_controller_.get()); |
| 172 | 202 |
| 173 contents_container_.reset(new TabContentsContainerGtk( | 203 contents_container_.reset(new TabContentsContainerGtk( |
| 174 find_bar_gtk->gtk_widget())); | 204 find_bar_gtk->gtk_widget())); |
| 175 | 205 |
| 176 contents_container_->AddContainerToBox(vbox_); | 206 contents_container_->AddContainerToBox(vbox_); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 bool BrowserWindowGtk::IsActive() const { | 253 bool BrowserWindowGtk::IsActive() const { |
| 224 NOTIMPLEMENTED(); | 254 NOTIMPLEMENTED(); |
| 225 return true; | 255 return true; |
| 226 } | 256 } |
| 227 | 257 |
| 228 void BrowserWindowGtk::FlashFrame() { | 258 void BrowserWindowGtk::FlashFrame() { |
| 229 // May not be respected by all window managers. | 259 // May not be respected by all window managers. |
| 230 gtk_window_set_urgency_hint(window_, TRUE); | 260 gtk_window_set_urgency_hint(window_, TRUE); |
| 231 } | 261 } |
| 232 | 262 |
| 233 void* BrowserWindowGtk::GetNativeHandle() { | 263 gfx::NativeWindow BrowserWindowGtk::GetNativeHandle() { |
| 234 return window_; | 264 return window_; |
| 235 } | 265 } |
| 236 | 266 |
| 237 BrowserWindowTesting* BrowserWindowGtk::GetBrowserWindowTesting() { | 267 BrowserWindowTesting* BrowserWindowGtk::GetBrowserWindowTesting() { |
| 238 NOTIMPLEMENTED(); | 268 NOTIMPLEMENTED(); |
| 239 return NULL; | 269 return NULL; |
| 240 } | 270 } |
| 241 | 271 |
| 242 StatusBubble* BrowserWindowGtk::GetStatusBubble() { | 272 StatusBubble* BrowserWindowGtk::GetStatusBubble() { |
| 243 return status_bubble_.get(); | 273 return status_bubble_.get(); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 414 } | 444 } |
| 415 | 445 |
| 416 void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) { | 446 void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) { |
| 417 bounds_ = bounds; | 447 bounds_ = bounds; |
| 418 } | 448 } |
| 419 | 449 |
| 420 void BrowserWindowGtk::OnStateChanged(GdkWindowState state) { | 450 void BrowserWindowGtk::OnStateChanged(GdkWindowState state) { |
| 421 state_ = state; | 451 state_ = state; |
| 422 } | 452 } |
| 423 | 453 |
| 454 void BrowserWindowGtk::ConnectAccelerators() { | |
| 455 GtkAccelGroup* accel_group = gtk_accel_group_new(); | |
| 456 gtk_window_add_accel_group(window_, accel_group); | |
| 457 // The window now owns |accel_group|. | |
|
Dean McNamee
2009/03/16 19:19:02
Same here, it's confusing.
| |
| 458 g_object_unref(accel_group); | |
| 459 | |
| 460 gtk_accel_group_connect( | |
| 461 accel_group, kFocusLocationKey, GDK_CONTROL_MASK, GtkAccelFlags(0), | |
| 462 g_cclosure_new(G_CALLBACK(OnAccelerator), this, NULL)); | |
| 463 gtk_accel_group_connect( | |
| 464 accel_group, kFocusSearchKey, GDK_CONTROL_MASK, GtkAccelFlags(0), | |
| 465 g_cclosure_new(G_CALLBACK(OnAccelerator), this, NULL)); | |
| 466 gtk_accel_group_connect( | |
| 467 accel_group, kOpenFileKey, GDK_CONTROL_MASK, GtkAccelFlags(0), | |
| 468 g_cclosure_new(G_CALLBACK(OnAccelerator), this, NULL)); | |
| 469 } | |
| 470 | |
| 424 void BrowserWindowGtk::SetCustomFrame(bool custom_frame) { | 471 void BrowserWindowGtk::SetCustomFrame(bool custom_frame) { |
| 425 custom_frame_ = custom_frame; | 472 custom_frame_ = custom_frame; |
| 426 if (custom_frame_) { | 473 if (custom_frame_) { |
| 427 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 2); | 474 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 2); |
| 428 // TODO(port): all the crazy blue title bar, etc. | 475 // TODO(port): all the crazy blue title bar, etc. |
| 429 NOTIMPLEMENTED(); | 476 NOTIMPLEMENTED(); |
| 430 } else { | 477 } else { |
| 431 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 0); | 478 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 0); |
| 432 } | 479 } |
| 433 } | 480 } |
| 434 | 481 |
| 435 // static | 482 // static |
| 436 gboolean BrowserWindowGtk::OnWindowDestroyed(GtkWidget* window, | 483 gboolean BrowserWindowGtk::OnWindowDestroyed(GtkWidget* window, |
| 437 BrowserWindowGtk* browser_win) { | 484 BrowserWindowGtk* browser_win) { |
| 438 // BUG 8712. When we gtk_widget_destroy() in Close(), this will emit the | 485 // BUG 8712. When we gtk_widget_destroy() in Close(), this will emit the |
| 439 // signal right away, and we will be here (while Close() is still in the | 486 // signal right away, and we will be here (while Close() is still in the |
| 440 // call stack). In order to not reenter Close(), and to also follow the | 487 // call stack). In order to not reenter Close(), and to also follow the |
| 441 // expectations of BrowserList, we should run the BrowserWindowGtk destructor | 488 // expectations of BrowserList, we should run the BrowserWindowGtk destructor |
| 442 // not now, but after the run loop goes back to process messages. Otherwise | 489 // not now, but after the run loop goes back to process messages. Otherwise |
| 443 // we will remove ourself from BrowserList while it's being iterated. | 490 // we will remove ourself from BrowserList while it's being iterated. |
| 444 // Additionally, now that we know the window is gone, we need to make sure to | 491 // Additionally, now that we know the window is gone, we need to make sure to |
| 445 // set window_ to NULL, otherwise we will try to close the window again when | 492 // set window_ to NULL, otherwise we will try to close the window again when |
| 446 // we call Close() in the destructor. | 493 // we call Close() in the destructor. |
| 447 browser_win->window_ = NULL; | 494 browser_win->window_ = NULL; |
| 448 MessageLoop::current()->DeleteSoon(FROM_HERE, browser_win); | 495 MessageLoop::current()->DeleteSoon(FROM_HERE, browser_win); |
| 449 return FALSE; // Don't stop this message. | 496 return FALSE; // Don't stop this message. |
| 450 } | 497 } |
| 451 | 498 |
| 499 // static | |
| 500 gboolean BrowserWindowGtk::OnAccelerator(GtkAccelGroup* accel_group, | |
| 501 GObject* acceleratable, | |
| 502 guint keyval, | |
| 503 GdkModifierType modifier, | |
| 504 BrowserWindowGtk* browser_window) { | |
| 505 browser_window->browser_->ExecuteCommand(GetCommandFromKeyval(keyval)); | |
| 506 return TRUE; | |
| 507 } | |
| OLD | NEW |