diff options
author | mdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-18 21:15:54 +0000 |
---|---|---|
committer | mdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-18 21:15:54 +0000 |
commit | 90a4d8d75125e009a415277589b3f0630164001b (patch) | |
tree | 2584ecaf6882453251c196dfc5fe745919420c71 | |
parent | 4b3a7628515d7211d1b64b720c4996991da3448b (diff) | |
download | chromium_src-90a4d8d75125e009a415277589b3f0630164001b.zip chromium_src-90a4d8d75125e009a415277589b3f0630164001b.tar.gz chromium_src-90a4d8d75125e009a415277589b3f0630164001b.tar.bz2 |
Linux: avoid browser windows moving around by the size of WM decorations over restart.
Use a debounce timer to get the true window position shortly after the last reconfigure event is delivered, and save that.
BUG=18771
TEST=none
Review URL: http://codereview.chromium.org/203027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26617 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 40 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 4 |
2 files changed, 40 insertions, 4 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 2bd3b2f..6586ecd 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -125,6 +125,10 @@ const int kContentShadowThickness = 2; // is off. const int kCustomFrameBackgroundVerticalOffset = 15; +// 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; + base::LazyInstance<ActiveWindowWatcher> g_active_window_watcher(base::LINKER_INITIALIZED); @@ -1361,6 +1365,31 @@ void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) { bounds_ = bounds; if (!IsFullscreen() && !IsMaximized()) restored_bounds_ = bounds; + + // When a window is moved or resized, GTK will call MainWindowConfigured() + // above. The GdkEventConfigure* that it gets 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(base::TimeDelta::FromMilliseconds( + kDebounceTimeoutMilliseconds), this, + &BrowserWindowGtk::OnDebouncedBoundsChanged); +} + +void BrowserWindowGtk::OnDebouncedBoundsChanged() { + gint x, y; + gtk_window_get_position(window_, &x, &y); + gfx::Point origin(x, y); + bounds_.set_origin(origin); + if (!IsFullscreen() && !IsMaximized()) + restored_bounds_.set_origin(origin); SaveWindowPosition(); } @@ -1484,13 +1513,16 @@ void BrowserWindowGtk::SetGeometryHints() { maximize_after_show_ = browser_->GetSavedMaximizedState(); gfx::Rect bounds = browser_->GetSavedWindowBounds(); - // We don't blindly call SetBounds here, that sets a forced position + // We don't blindly call SetBounds here: that sets a forced position // on the window and we intentionally *don't* do that for normal - // windows. We tested many programs and none of them restored their - // position on Linux. + // windows. Most programs do not restore their window position on + // Linux, instead letting the window manager choose a position. // // However, in cases like dropping a tab where the bounds are - // specifically set, we do want to position explicitly. + // specifically set, we do want to position explicitly. We also + // force the position as part of session restore, as applications + // that restore other, similar state (for instance GIMP, audacity, + // pidgin, dia, and gkrellm) do tend to restore their positions. if (browser_->bounds_overridden()) { // For popups, bounds are set in terms of the client area rather than the // entire window. diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index a43e6eb..107ab60 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -140,6 +140,7 @@ class BrowserWindowGtk : public BrowserWindow, void UpdateUIForContents(TabContents* contents); void OnBoundsChanged(const gfx::Rect& bounds); + void OnDebouncedBoundsChanged(); void OnStateChanged(GdkWindowState state, GdkWindowState changed_mask); // Returns false if we're not ready to close yet. E.g., a tab may have an @@ -361,6 +362,9 @@ class BrowserWindowGtk : public BrowserWindow, // The timer used to update frames for the Loading Animation. base::RepeatingTimer<BrowserWindowGtk> loading_animation_timer_; + // The timer used to save the window position for session restore. + base::OneShotTimer<BrowserWindowGtk> window_configure_debounce_timer_; + // Whether the custom chrome frame pref is set. Normally you want to use // UseCustomFrame() above to determine whether to use the custom frame or // not. |