| 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..faf69a8462b1912ffce87a8d8b02110cfe301fe4 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,36 @@ 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() {
|
| + gtk_window_util::UpdateWindowPosition(this, &bounds_, &restored_bounds_);
|
| + shell_window_->SaveWindowPosition();
|
| +}
|
| +
|
| gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender,
|
| GdkEventWindowState* event) {
|
| state_ = event->new_window_state;
|
|
|