Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: chrome/browser/ui/gtk/extensions/shell_window_gtk.cc

Issue 10871087: GTK implementation of remembering platform app window geometry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/gtk/extensions/shell_window_gtk.h" 5 #include "chrome/browser/ui/gtk/extensions/shell_window_gtk.h"
6 6
7 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/profiles/profile.h" 8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ui/gtk/gtk_window_util.h" 9 #include "chrome/browser/ui/gtk/gtk_window_util.h"
10 #include "chrome/browser/web_applications/web_app.h" 10 #include "chrome/browser/web_applications/web_app.h"
11 #include "chrome/common/extensions/draggable_region.h" 11 #include "chrome/common/extensions/draggable_region.h"
12 #include "chrome/common/extensions/extension.h" 12 #include "chrome/common/extensions/extension.h"
13 #include "content/public/browser/render_view_host.h" 13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/render_widget_host_view.h" 14 #include "content/public/browser/render_widget_host_view.h"
15 #include "content/public/browser/web_contents.h" 15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_view.h" 16 #include "content/public/browser/web_contents_view.h"
17 #include "ui/base/x/active_window_watcher_x.h" 17 #include "ui/base/x/active_window_watcher_x.h"
18 #include "ui/gfx/rect.h" 18 #include "ui/gfx/rect.h"
19 19
20 namespace {
21
22 // The timeout in milliseconds before we'll get the true window position with
23 // gtk_window_get_position() after the last GTK configure-event signal.
24 const int kDebounceTimeoutMilliseconds = 100;
25
26 } // namespace
27
20 ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window, 28 ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window,
21 const ShellWindow::CreateParams& params) 29 const ShellWindow::CreateParams& params)
22 : shell_window_(shell_window), 30 : shell_window_(shell_window),
23 state_(GDK_WINDOW_STATE_WITHDRAWN), 31 state_(GDK_WINDOW_STATE_WITHDRAWN),
24 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), 32 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()),
25 content_thinks_its_fullscreen_(false), 33 content_thinks_its_fullscreen_(false),
26 frameless_(params.frame == ShellWindow::CreateParams::FRAME_NONE) { 34 frameless_(params.frame == ShellWindow::CreateParams::FRAME_NONE) {
27 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); 35 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
28 36
29 gfx::NativeView native_view = 37 gfx::NativeView native_view =
30 web_contents()->GetView()->GetNativeView(); 38 web_contents()->GetView()->GetNativeView();
31 gtk_container_add(GTK_CONTAINER(window_), native_view); 39 gtk_container_add(GTK_CONTAINER(window_), native_view);
32 40
41 if (params.bounds.x() >= 0 && params.bounds.y() >= 0)
42 gtk_window_move(window_, params.bounds.x(), params.bounds.y());
43
33 // This is done to avoid a WM "feature" where setting the window size to 44 // This is done to avoid a WM "feature" where setting the window size to
34 // the monitor size causes the WM to set the EWMH for full screen mode. 45 // the monitor size causes the WM to set the EWMH for full screen mode.
35 if (frameless_ && 46 if (frameless_ &&
36 gtk_window_util::BoundsMatchMonitorSize(window_, params.bounds)) { 47 gtk_window_util::BoundsMatchMonitorSize(window_, params.bounds)) {
37 gtk_window_set_default_size( 48 gtk_window_set_default_size(
38 window_, params.bounds.width(), params.bounds.height() - 1); 49 window_, params.bounds.width(), params.bounds.height() - 1);
39 } else { 50 } else {
40 gtk_window_set_default_size( 51 gtk_window_set_default_size(
41 window_, params.bounds.width(), params.bounds.height()); 52 window_, params.bounds.width(), params.bounds.height());
42 } 53 }
43 54
55 // make sure bounds_ and restored_bounds_ have correct values until we
56 // get our first configure-event
57 bounds_ = restored_bounds_ = params.bounds;
58 gint x, y;
59 gtk_window_get_position(window_, &x, &y);
60 bounds_.set_origin(gfx::Point(x, y));
61
44 // Hide titlebar when {frame: 'none'} specified on ShellWindow. 62 // Hide titlebar when {frame: 'none'} specified on ShellWindow.
45 if (frameless_) 63 if (frameless_)
46 gtk_window_set_decorated(window_, false); 64 gtk_window_set_decorated(window_, false);
47 65
48 int min_width = params.minimum_size.width(); 66 int min_width = params.minimum_size.width();
49 int min_height = params.minimum_size.height(); 67 int min_height = params.minimum_size.height();
50 int max_width = params.maximum_size.width(); 68 int max_width = params.maximum_size.width();
51 int max_height = params.maximum_size.height(); 69 int max_height = params.maximum_size.height();
52 GdkGeometry hints; 70 GdkGeometry hints;
53 int hints_mask = 0; 71 int hints_mask = 0;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 void ShellWindowGtk::Show() { 148 void ShellWindowGtk::Show() {
131 gtk_window_present(window_); 149 gtk_window_present(window_);
132 } 150 }
133 151
134 void ShellWindowGtk::ShowInactive() { 152 void ShellWindowGtk::ShowInactive() {
135 gtk_window_set_focus_on_map(window_, false); 153 gtk_window_set_focus_on_map(window_, false);
136 gtk_widget_show(GTK_WIDGET(window_)); 154 gtk_widget_show(GTK_WIDGET(window_));
137 } 155 }
138 156
139 void ShellWindowGtk::Close() { 157 void ShellWindowGtk::Close() {
158 shell_window_->SaveWindowPosition();
159
160 // Cancel any pending callback from the window configure debounce timer.
161 window_configure_debounce_timer_.Stop();
162
140 GtkWidget* window = GTK_WIDGET(window_); 163 GtkWidget* window = GTK_WIDGET(window_);
141 // To help catch bugs in any event handlers that might get fired during the 164 // To help catch bugs in any event handlers that might get fired during the
142 // destruction, set window_ to NULL before any handlers will run. 165 // destruction, set window_ to NULL before any handlers will run.
143 window_ = NULL; 166 window_ = NULL;
144 167
145 // OnNativeClose does a delete this so no other members should 168 // OnNativeClose does a delete this so no other members should
146 // be accessed after. gtk_widget_destroy is safe (and must 169 // be accessed after. gtk_widget_destroy is safe (and must
147 // be last). 170 // be last).
148 shell_window_->OnNativeClose(); 171 shell_window_->OnNativeClose();
149 gtk_widget_destroy(window); 172 gtk_widget_destroy(window);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 GdkEvent* event) { 223 GdkEvent* event) {
201 Close(); 224 Close();
202 225
203 // Return true to prevent the GTK window from being destroyed. Close will 226 // Return true to prevent the GTK window from being destroyed. Close will
204 // destroy it for us. 227 // destroy it for us.
205 return TRUE; 228 return TRUE;
206 } 229 }
207 230
208 gboolean ShellWindowGtk::OnConfigure(GtkWidget* widget, 231 gboolean ShellWindowGtk::OnConfigure(GtkWidget* widget,
209 GdkEventConfigure* event) { 232 GdkEventConfigure* event) {
210 // TODO(mihaip): Do we need an explicit gtk_window_get_position call like in 233 // We update |bounds_| but not |restored_bounds_| here. The latter needs
211 // in BrowserWindowGtk::OnConfigure? 234 // to be updated conditionally when the window is non-maximized and non-
235 // fullscreen, but whether those state updates have been processed yet is
236 // window-manager specific. We update |restored_bounds_| in the debounced
237 // handler below, after the window state has been updated.
212 bounds_.SetRect(event->x, event->y, event->width, event->height); 238 bounds_.SetRect(event->x, event->y, event->width, event->height);
213 if (!IsMaximized()) 239
214 restored_bounds_ = bounds_; 240 // The GdkEventConfigure* we get here doesn't have quite the right
241 // coordinates though (they're relative to the drawable window area, rather
242 // than any window manager decorations, if enabled), so we need to call
243 // gtk_window_get_position() to get the right values. (Otherwise session
244 // restore, if enabled, will restore windows to incorrect positions.) That's
245 // a round trip to the X server though, so we set a debounce timer and only
246 // call it (in OnDebouncedBoundsChanged() below) after we haven't seen a
247 // reconfigure event in a short while.
248 // We don't use Reset() because the timer may not yet be running.
249 // (In that case Stop() is a no-op.)
250 window_configure_debounce_timer_.Stop();
251 window_configure_debounce_timer_.Start(FROM_HERE,
252 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), this,
253 &ShellWindowGtk::OnDebouncedBoundsChanged);
215 254
216 return FALSE; 255 return FALSE;
217 } 256 }
218 257
258 void ShellWindowGtk::OnDebouncedBoundsChanged() {
259 gtk_window_util::UpdateWindowPosition(this, &bounds_, &restored_bounds_);
260 shell_window_->SaveWindowPosition();
261 }
262
219 gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender, 263 gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender,
220 GdkEventWindowState* event) { 264 GdkEventWindowState* event) {
221 state_ = event->new_window_state; 265 state_ = event->new_window_state;
222 266
223 if (content_thinks_its_fullscreen_ && 267 if (content_thinks_its_fullscreen_ &&
224 !(state_ & GDK_WINDOW_STATE_FULLSCREEN)) { 268 !(state_ & GDK_WINDOW_STATE_FULLSCREEN)) {
225 content_thinks_its_fullscreen_ = false; 269 content_thinks_its_fullscreen_ = false;
226 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); 270 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
227 if (rvh) 271 if (rvh)
228 rvh->ExitFullscreen(); 272 rvh->ExitFullscreen();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 354 }
311 355
312 draggable_region_ = draggable_region; 356 draggable_region_ = draggable_region;
313 } 357 }
314 358
315 // static 359 // static
316 NativeShellWindow* NativeShellWindow::Create( 360 NativeShellWindow* NativeShellWindow::Create(
317 ShellWindow* shell_window, const ShellWindow::CreateParams& params) { 361 ShellWindow* shell_window, const ShellWindow::CreateParams& params) {
318 return new ShellWindowGtk(shell_window, params); 362 return new ShellWindowGtk(shell_window, params);
319 } 363 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/extensions/shell_window_gtk.h ('k') | chrome/browser/ui/gtk/gtk_window_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698