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 "base/base_paths_linux.h" | |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 8 #include "base/base_paths_linux.h" | 9 #include "base/message_loop.h" |
| 9 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 10 #include "chrome/browser/browser.h" | 11 #include "chrome/browser/browser.h" |
| 11 #include "chrome/browser/gtk/browser_toolbar_gtk.h" | 12 #include "chrome/browser/gtk/browser_toolbar_gtk.h" |
| 12 #include "chrome/browser/gtk/find_bar_gtk.h" | 13 #include "chrome/browser/gtk/find_bar_gtk.h" |
| 13 #include "chrome/browser/gtk/nine_box.h" | 14 #include "chrome/browser/gtk/nine_box.h" |
| 14 #include "chrome/browser/gtk/status_bubble_gtk.h" | 15 #include "chrome/browser/gtk/status_bubble_gtk.h" |
| 15 #include "chrome/browser/gtk/tab_contents_container_gtk.h" | 16 #include "chrome/browser/gtk/tab_contents_container_gtk.h" |
| 16 #include "chrome/browser/location_bar.h" | 17 #include "chrome/browser/location_bar.h" |
| 17 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 18 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 18 #include "chrome/browser/tab_contents/web_contents.h" | 19 #include "chrome/browser/tab_contents/web_contents.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 43 DCHECK(pixbuf) << "failed to load " << resource_id << " " << data.size(); | 44 DCHECK(pixbuf) << "failed to load " << resource_id << " " << data.size(); |
| 44 | 45 |
| 45 // The pixbuf is owned by the loader, so add a ref so when we delete the | 46 // The pixbuf is owned by the loader, so add a ref so when we delete the |
| 46 // loader, the pixbuf still exists. | 47 // loader, the pixbuf still exists. |
| 47 g_object_ref(pixbuf); | 48 g_object_ref(pixbuf); |
| 48 g_object_unref(loader); | 49 g_object_unref(loader); |
| 49 | 50 |
| 50 return pixbuf; | 51 return pixbuf; |
| 51 } | 52 } |
| 52 | 53 |
| 53 gboolean MainWindowDestroyed(GtkWindow* window, BrowserWindowGtk* browser_win) { | |
| 54 delete browser_win; | |
| 55 return FALSE; // Don't stop this message. | |
| 56 } | |
| 57 | |
| 58 gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event, | 54 gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event, |
| 59 BrowserWindowGtk* browser_win) { | 55 BrowserWindowGtk* browser_win) { |
| 60 gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height); | 56 gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height); |
| 61 browser_win->OnBoundsChanged(bounds); | 57 browser_win->OnBoundsChanged(bounds); |
| 62 return FALSE; | 58 return FALSE; |
| 63 } | 59 } |
| 64 | 60 |
| 65 gboolean MainWindowStateChanged(GtkWindow* window, GdkEventWindowState* event, | 61 gboolean MainWindowStateChanged(GtkWindow* window, GdkEventWindowState* event, |
| 66 BrowserWindowGtk* browser_win) { | 62 BrowserWindowGtk* browser_win) { |
| 67 browser_win->OnStateChanged(event->new_window_state); | 63 browser_win->OnStateChanged(event->new_window_state); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 GDK_RGB_DITHER_NORMAL, 0, 0); | 123 GDK_RGB_DITHER_NORMAL, 0, 0); |
| 128 gdk_pixbuf_unref(pixbuf); | 124 gdk_pixbuf_unref(pixbuf); |
| 129 | 125 |
| 130 return FALSE; // Allow subwidgets to paint. | 126 return FALSE; // Allow subwidgets to paint. |
| 131 } | 127 } |
| 132 | 128 |
| 133 void BrowserWindowGtk::Init() { | 129 void BrowserWindowGtk::Init() { |
| 134 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); | 130 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); |
| 135 gtk_window_set_default_size(window_, 640, 480); | 131 gtk_window_set_default_size(window_, 640, 480); |
| 136 g_signal_connect(G_OBJECT(window_), "destroy", | 132 g_signal_connect(G_OBJECT(window_), "destroy", |
| 137 G_CALLBACK(MainWindowDestroyed), this); | 133 G_CALLBACK(OnWindowDestroyed), this); |
| 138 g_signal_connect(G_OBJECT(window_), "configure-event", | 134 g_signal_connect(G_OBJECT(window_), "configure-event", |
| 139 G_CALLBACK(MainWindowConfigured), this); | 135 G_CALLBACK(MainWindowConfigured), this); |
| 140 g_signal_connect(G_OBJECT(window_), "window-state-event", | 136 g_signal_connect(G_OBJECT(window_), "window-state-event", |
| 141 G_CALLBACK(MainWindowStateChanged), this); | 137 G_CALLBACK(MainWindowStateChanged), this); |
| 142 bounds_ = GetInitialWindowBounds(window_); | 138 bounds_ = GetInitialWindowBounds(window_); |
| 143 | 139 |
| 144 GtkAccelGroup* accel_group = gtk_accel_group_new(); | 140 GtkAccelGroup* accel_group = gtk_accel_group_new(); |
| 145 gtk_window_add_accel_group(window_, accel_group); | 141 gtk_window_add_accel_group(window_, accel_group); |
| 146 | 142 |
| 147 GdkPixbuf* images[9] = { | 143 GdkPixbuf* images[9] = { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 gint height = static_cast<gint>(bounds.height()); | 194 gint height = static_cast<gint>(bounds.height()); |
| 199 | 195 |
| 200 gtk_window_move(window_, x, y); | 196 gtk_window_move(window_, x, y); |
| 201 gtk_window_resize(window_, width, height); | 197 gtk_window_resize(window_, width, height); |
| 202 } | 198 } |
| 203 | 199 |
| 204 void BrowserWindowGtk::Close() { | 200 void BrowserWindowGtk::Close() { |
| 205 if (!window_) | 201 if (!window_) |
| 206 return; | 202 return; |
| 207 | 203 |
| 208 gtk_widget_destroy(GTK_WIDGET(window_)); | 204 GtkWidget* window = GTK_WIDGET(window_); |
| 205 // To help catch bugs in any event handlers that might get fired during the | |
| 206 // destruction, set window_ to NULL before any handlers will run. | |
| 209 window_ = NULL; | 207 window_ = NULL; |
| 208 gtk_widget_destroy(window); | |
| 210 } | 209 } |
| 211 | 210 |
| 212 void BrowserWindowGtk::Activate() { | 211 void BrowserWindowGtk::Activate() { |
| 213 gtk_window_present(window_); | 212 gtk_window_present(window_); |
| 214 } | 213 } |
| 215 | 214 |
| 216 bool BrowserWindowGtk::IsActive() const { | 215 bool BrowserWindowGtk::IsActive() const { |
| 217 NOTIMPLEMENTED(); | 216 NOTIMPLEMENTED(); |
| 218 return true; | 217 return true; |
| 219 } | 218 } |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 void BrowserWindowGtk::SetCustomFrame(bool custom_frame) { | 410 void BrowserWindowGtk::SetCustomFrame(bool custom_frame) { |
| 412 custom_frame_ = custom_frame; | 411 custom_frame_ = custom_frame; |
| 413 if (custom_frame_) { | 412 if (custom_frame_) { |
| 414 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 2); | 413 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 2); |
| 415 // TODO(port): all the crazy blue title bar, etc. | 414 // TODO(port): all the crazy blue title bar, etc. |
| 416 NOTIMPLEMENTED(); | 415 NOTIMPLEMENTED(); |
| 417 } else { | 416 } else { |
| 418 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 0); | 417 gtk_container_set_border_width(GTK_CONTAINER(vbox_), 0); |
| 419 } | 418 } |
| 420 } | 419 } |
| 420 | |
| 421 // static | |
| 422 gboolean BrowserWindowGtk::OnWindowDestroyed(GtkWidget* window, | |
| 423 BrowserWindowGtk* browser_win) { | |
| 424 // BUG 8712. When we gtk_widget_destroy() in Close(), this will emit the | |
| 425 // signal right away, and we will be here (while Close() is still in the | |
| 426 // call stack). In order to not reenter Close(), and to also follow the | |
| 427 // expectations of BrowserList, we should run the BrowserWindowGtk destructor | |
| 428 // not now, but after the run loop goes back to process messages. Otherwise | |
| 429 // we will remove ourself from BrowserList while it's being iterated. | |
| 430 // Additionally, now that we know the window is gone, we need to make sure to | |
| 431 // set window_ to NULL, otherwise we will try to close the window again when | |
| 432 // we call Close() in the destructor. | |
| 433 browser_win->window_ = NULL; | |
| 434 MessageLoop::current()->DeleteSoon(FROM_HERE, browser_win); | |
|
darin (slow to review)
2009/03/12 22:26:25
i love problems like this :-P
this LGTM. DeleteS
| |
| 435 return FALSE; // Don't stop this message. | |
| 436 } | |
| 437 | |
| OLD | NEW |