Chromium Code Reviews| Index: chrome/browser/ui/gtk/extensions/shell_window_gtk.cc |
| diff --git a/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc b/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc |
| index 8927361b19a1cd886162a4408427684eec9396ef..a9e3f6523eb75c8a4d5147bb5c748541bd89306b 100644 |
| --- a/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc |
| +++ b/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc |
| @@ -16,6 +16,14 @@ |
| #include "ui/base/x/active_window_watcher_x.h" |
| #include "ui/gfx/rect.h" |
| +namespace { |
| + |
| +// The timeout in milliseconds before we'll get the true window position with |
| +// gtk_window_get_position() after the last GTK configure-event signal. |
| +const int kDebounceTimeoutMilliseconds = 100; |
| + |
| +} // namespace |
| + |
| ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window, |
| const ShellWindow::CreateParams& params) |
| : shell_window_(shell_window), |
| @@ -29,9 +37,19 @@ ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window, |
| web_contents()->GetView()->GetNativeView(); |
| gtk_container_add(GTK_CONTAINER(window_), native_view); |
| + if (params.bounds.x() >= 0 && params.bounds.y() >= 0) |
| + gtk_window_move(window_, params.bounds.x(), params.bounds.y()); |
| + |
| gtk_window_set_default_size( |
| window_, params.bounds.width(), params.bounds.height()); |
| + // make sure bounds_ and restored_bounds_ have correct values until we |
| + // get our first configure-event |
| + bounds_ = restored_bounds_ = params.bounds; |
| + gint x, y; |
| + gtk_window_get_position(window_, &x, &y); |
| + bounds_.set_origin(gfx::Point(x, y)); |
| + |
| // Hide titlebar when {frame: 'none'} specified on ShellWindow. |
| if (frameless_) |
| gtk_window_set_decorated(window_, false); |
| @@ -129,6 +147,11 @@ void ShellWindowGtk::ShowInactive() { |
| } |
| void ShellWindowGtk::Close() { |
| + shell_window_->SaveWindowPosition(); |
| + |
| + // Cancel any pending callback from the window configure debounce timer. |
| + window_configure_debounce_timer_.Stop(); |
| + |
| GtkWidget* window = GTK_WIDGET(window_); |
| // To help catch bugs in any event handlers that might get fired during the |
| // destruction, set window_ to NULL before any handlers will run. |
| @@ -200,15 +223,41 @@ gboolean ShellWindowGtk::OnMainWindowDeleteEvent(GtkWidget* widget, |
| gboolean ShellWindowGtk::OnConfigure(GtkWidget* widget, |
| GdkEventConfigure* event) { |
| - // TODO(mihaip): Do we need an explicit gtk_window_get_position call like in |
| - // in BrowserWindowGtk::OnConfigure? |
| + // We update |bounds_| but not |restored_bounds_| here. The latter needs |
| + // to be updated conditionally when the window is non-maximized and non- |
| + // fullscreen, but whether those state updates have been processed yet is |
| + // window-manager specific. We update |restored_bounds_| in the debounced |
| + // handler below, after the window state has been updated. |
| bounds_.SetRect(event->x, event->y, event->width, event->height); |
| - if (!IsMaximized()) |
| - restored_bounds_ = bounds_; |
| + |
| + // The GdkEventConfigure* we get here doesn't have quite the right |
| + // coordinates though (they're relative to the drawable window area, rather |
| + // than any window manager decorations, if enabled), so we need to call |
| + // gtk_window_get_position() to get the right values. (Otherwise session |
| + // restore, if enabled, will restore windows to incorrect positions.) That's |
| + // a round trip to the X server though, so we set a debounce timer and only |
| + // call it (in OnDebouncedBoundsChanged() below) after we haven't seen a |
| + // reconfigure event in a short while. |
| + // We don't use Reset() because the timer may not yet be running. |
| + // (In that case Stop() is a no-op.) |
| + window_configure_debounce_timer_.Stop(); |
| + window_configure_debounce_timer_.Start(FROM_HERE, |
| + base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), this, |
| + &ShellWindowGtk::OnDebouncedBoundsChanged); |
| return FALSE; |
| } |
| +void ShellWindowGtk::OnDebouncedBoundsChanged() { |
| + gint x, y; |
| + gtk_window_get_position(window_, &x, &y); |
| + bounds_.set_origin(gfx::Point(x, y)); |
| + if (!IsFullscreen() && !IsMaximized()) |
|
Evan Stade
2012/08/29 21:51:11
don't copy paste code. Refactor as much as you can
Marijn Kruisselbrink
2012/08/30 16:46:12
Yeah, I noticed there seeming to be quite some dup
|
| + restored_bounds_ = bounds_; |
| + |
| + shell_window_->SaveWindowPosition(); |
| +} |
| + |
| gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender, |
| GdkEventWindowState* event) { |
| state_ = event->new_window_state; |