Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "chrome/browser/profiles/profile.h" | 7 #include "chrome/browser/profiles/profile.h" |
| 8 #include "chrome/browser/ui/gtk/gtk_window_util.h" | 8 #include "chrome/browser/ui/gtk/gtk_window_util.h" |
| 9 #include "chrome/browser/web_applications/web_app.h" | 9 #include "chrome/browser/web_applications/web_app.h" |
| 10 #include "chrome/common/extensions/draggable_region.h" | 10 #include "chrome/common/extensions/draggable_region.h" |
| 11 #include "chrome/common/extensions/extension.h" | 11 #include "chrome/common/extensions/extension.h" |
| 12 #include "content/public/browser/render_view_host.h" | 12 #include "content/public/browser/render_view_host.h" |
| 13 #include "content/public/browser/render_widget_host_view.h" | 13 #include "content/public/browser/render_widget_host_view.h" |
| 14 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
| 15 #include "content/public/browser/web_contents_view.h" | 15 #include "content/public/browser/web_contents_view.h" |
| 16 #include "ui/base/x/active_window_watcher_x.h" | 16 #include "ui/base/x/active_window_watcher_x.h" |
| 17 #include "ui/gfx/rect.h" | 17 #include "ui/gfx/rect.h" |
| 18 | 18 |
| 19 namespace { | |
| 20 | |
| 21 // The timeout in milliseconds before we'll get the true window position with | |
| 22 // gtk_window_get_position() after the last GTK configure-event signal. | |
| 23 const int kDebounceTimeoutMilliseconds = 100; | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 19 ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window, | 27 ShellWindowGtk::ShellWindowGtk(ShellWindow* shell_window, |
| 20 const ShellWindow::CreateParams& params) | 28 const ShellWindow::CreateParams& params) |
| 21 : shell_window_(shell_window), | 29 : shell_window_(shell_window), |
| 22 state_(GDK_WINDOW_STATE_WITHDRAWN), | 30 state_(GDK_WINDOW_STATE_WITHDRAWN), |
| 23 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), | 31 is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), |
| 24 content_thinks_its_fullscreen_(false), | 32 content_thinks_its_fullscreen_(false), |
| 25 frameless_(params.frame == ShellWindow::CreateParams::FRAME_NONE) { | 33 frameless_(params.frame == ShellWindow::CreateParams::FRAME_NONE) { |
| 26 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); | 34 window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); |
| 27 | 35 |
| 28 gfx::NativeView native_view = | 36 gfx::NativeView native_view = |
| 29 web_contents()->GetView()->GetNativeView(); | 37 web_contents()->GetView()->GetNativeView(); |
| 30 gtk_container_add(GTK_CONTAINER(window_), native_view); | 38 gtk_container_add(GTK_CONTAINER(window_), native_view); |
| 31 | 39 |
| 40 if (params.bounds.x() >= 0 && params.bounds.y() >= 0) | |
| 41 gtk_window_move(window_, params.bounds.x(), params.bounds.y()); | |
| 42 | |
| 32 gtk_window_set_default_size( | 43 gtk_window_set_default_size( |
| 33 window_, params.bounds.width(), params.bounds.height()); | 44 window_, params.bounds.width(), params.bounds.height()); |
| 34 | 45 |
| 46 // make sure bounds_ and restored_bounds_ have correct values until we | |
| 47 // get our first configure-event | |
| 48 bounds_ = restored_bounds_ = params.bounds; | |
| 49 gint x, y; | |
| 50 gtk_window_get_position(window_, &x, &y); | |
| 51 bounds_.set_origin(gfx::Point(x, y)); | |
| 52 | |
| 35 // Hide titlebar when {frame: 'none'} specified on ShellWindow. | 53 // Hide titlebar when {frame: 'none'} specified on ShellWindow. |
| 36 if (frameless_) | 54 if (frameless_) |
| 37 gtk_window_set_decorated(window_, false); | 55 gtk_window_set_decorated(window_, false); |
| 38 | 56 |
| 39 int min_width = params.minimum_size.width(); | 57 int min_width = params.minimum_size.width(); |
| 40 int min_height = params.minimum_size.height(); | 58 int min_height = params.minimum_size.height(); |
| 41 int max_width = params.maximum_size.width(); | 59 int max_width = params.maximum_size.width(); |
| 42 int max_height = params.maximum_size.height(); | 60 int max_height = params.maximum_size.height(); |
| 43 GdkGeometry hints; | 61 GdkGeometry hints; |
| 44 int hints_mask = 0; | 62 int hints_mask = 0; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 void ShellWindowGtk::Show() { | 140 void ShellWindowGtk::Show() { |
| 123 gtk_window_present(window_); | 141 gtk_window_present(window_); |
| 124 } | 142 } |
| 125 | 143 |
| 126 void ShellWindowGtk::ShowInactive() { | 144 void ShellWindowGtk::ShowInactive() { |
| 127 gtk_window_set_focus_on_map(window_, false); | 145 gtk_window_set_focus_on_map(window_, false); |
| 128 gtk_widget_show(GTK_WIDGET(window_)); | 146 gtk_widget_show(GTK_WIDGET(window_)); |
| 129 } | 147 } |
| 130 | 148 |
| 131 void ShellWindowGtk::Close() { | 149 void ShellWindowGtk::Close() { |
| 150 shell_window_->SaveWindowPosition(); | |
| 151 | |
| 152 // Cancel any pending callback from the window configure debounce timer. | |
| 153 window_configure_debounce_timer_.Stop(); | |
| 154 | |
| 132 GtkWidget* window = GTK_WIDGET(window_); | 155 GtkWidget* window = GTK_WIDGET(window_); |
| 133 // To help catch bugs in any event handlers that might get fired during the | 156 // To help catch bugs in any event handlers that might get fired during the |
| 134 // destruction, set window_ to NULL before any handlers will run. | 157 // destruction, set window_ to NULL before any handlers will run. |
| 135 window_ = NULL; | 158 window_ = NULL; |
| 136 | 159 |
| 137 // OnNativeClose does a delete this so no other members should | 160 // OnNativeClose does a delete this so no other members should |
| 138 // be accessed after. gtk_widget_destroy is safe (and must | 161 // be accessed after. gtk_widget_destroy is safe (and must |
| 139 // be last). | 162 // be last). |
| 140 shell_window_->OnNativeClose(); | 163 shell_window_->OnNativeClose(); |
| 141 gtk_widget_destroy(window); | 164 gtk_widget_destroy(window); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 GdkEvent* event) { | 216 GdkEvent* event) { |
| 194 Close(); | 217 Close(); |
| 195 | 218 |
| 196 // Return true to prevent the GTK window from being destroyed. Close will | 219 // Return true to prevent the GTK window from being destroyed. Close will |
| 197 // destroy it for us. | 220 // destroy it for us. |
| 198 return TRUE; | 221 return TRUE; |
| 199 } | 222 } |
| 200 | 223 |
| 201 gboolean ShellWindowGtk::OnConfigure(GtkWidget* widget, | 224 gboolean ShellWindowGtk::OnConfigure(GtkWidget* widget, |
| 202 GdkEventConfigure* event) { | 225 GdkEventConfigure* event) { |
| 203 // TODO(mihaip): Do we need an explicit gtk_window_get_position call like in | 226 // We update |bounds_| but not |restored_bounds_| here. The latter needs |
| 204 // in BrowserWindowGtk::OnConfigure? | 227 // to be updated conditionally when the window is non-maximized and non- |
| 228 // fullscreen, but whether those state updates have been processed yet is | |
| 229 // window-manager specific. We update |restored_bounds_| in the debounced | |
| 230 // handler below, after the window state has been updated. | |
| 205 bounds_.SetRect(event->x, event->y, event->width, event->height); | 231 bounds_.SetRect(event->x, event->y, event->width, event->height); |
| 206 if (!IsMaximized()) | 232 |
| 233 // The GdkEventConfigure* we get here doesn't have quite the right | |
| 234 // coordinates though (they're relative to the drawable window area, rather | |
| 235 // than any window manager decorations, if enabled), so we need to call | |
| 236 // gtk_window_get_position() to get the right values. (Otherwise session | |
| 237 // restore, if enabled, will restore windows to incorrect positions.) That's | |
| 238 // a round trip to the X server though, so we set a debounce timer and only | |
| 239 // call it (in OnDebouncedBoundsChanged() below) after we haven't seen a | |
| 240 // reconfigure event in a short while. | |
| 241 // We don't use Reset() because the timer may not yet be running. | |
| 242 // (In that case Stop() is a no-op.) | |
| 243 window_configure_debounce_timer_.Stop(); | |
| 244 window_configure_debounce_timer_.Start(FROM_HERE, | |
| 245 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), this, | |
| 246 &ShellWindowGtk::OnDebouncedBoundsChanged); | |
| 247 | |
| 248 return FALSE; | |
| 249 } | |
| 250 | |
| 251 void ShellWindowGtk::OnDebouncedBoundsChanged() { | |
| 252 gint x, y; | |
| 253 gtk_window_get_position(window_, &x, &y); | |
| 254 bounds_.set_origin(gfx::Point(x, y)); | |
| 255 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
| |
| 207 restored_bounds_ = bounds_; | 256 restored_bounds_ = bounds_; |
| 208 | 257 |
| 209 return FALSE; | 258 shell_window_->SaveWindowPosition(); |
| 210 } | 259 } |
| 211 | 260 |
| 212 gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender, | 261 gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender, |
| 213 GdkEventWindowState* event) { | 262 GdkEventWindowState* event) { |
| 214 state_ = event->new_window_state; | 263 state_ = event->new_window_state; |
| 215 | 264 |
| 216 if (content_thinks_its_fullscreen_ && | 265 if (content_thinks_its_fullscreen_ && |
| 217 !(state_ & GDK_WINDOW_STATE_FULLSCREEN)) { | 266 !(state_ & GDK_WINDOW_STATE_FULLSCREEN)) { |
| 218 content_thinks_its_fullscreen_ = false; | 267 content_thinks_its_fullscreen_ = false; |
| 219 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); | 268 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 } | 351 } |
| 303 | 352 |
| 304 draggable_region_ = draggable_region; | 353 draggable_region_ = draggable_region; |
| 305 } | 354 } |
| 306 | 355 |
| 307 // static | 356 // static |
| 308 NativeShellWindow* NativeShellWindow::Create( | 357 NativeShellWindow* NativeShellWindow::Create( |
| 309 ShellWindow* shell_window, const ShellWindow::CreateParams& params) { | 358 ShellWindow* shell_window, const ShellWindow::CreateParams& params) { |
| 310 return new ShellWindowGtk(shell_window, params); | 359 return new ShellWindowGtk(shell_window, params); |
| 311 } | 360 } |
| OLD | NEW |