Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "apps/shell_window.h" | 5 #include "apps/shell_window.h" | 
| 6 | 6 | 
| 7 #include "apps/native_app_window.h" | 7 #include "apps/native_app_window.h" | 
| 8 #include "apps/shell_window_geometry_cache.h" | 8 #include "apps/shell_window_geometry_cache.h" | 
| 9 #include "apps/shell_window_registry.h" | 9 #include "apps/shell_window_registry.h" | 
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 using web_modal::WebContentsModalDialogManager; | 49 using web_modal::WebContentsModalDialogManager; | 
| 50 | 50 | 
| 51 namespace { | 51 namespace { | 
| 52 const int kDefaultWidth = 512; | 52 const int kDefaultWidth = 512; | 
| 53 const int kDefaultHeight = 384; | 53 const int kDefaultHeight = 384; | 
| 54 | 54 | 
| 55 } // namespace | 55 } // namespace | 
| 56 | 56 | 
| 57 namespace apps { | 57 namespace apps { | 
| 58 | 58 | 
| 59 ShellWindow::SizeConstraints::SizeConstraints() | |
| 60 : maximum_size_(kUnboundedSize, kUnboundedSize) { | |
| 61 } | |
| 62 | |
| 63 ShellWindow::SizeConstraints::SizeConstraints(const gfx::Size& min_size, | |
| 64 const gfx::Size& max_size) | |
| 65 : minimum_size_(min_size), | |
| 66 maximum_size_(max_size) { | |
| 67 } | |
| 68 | |
| 69 ShellWindow::SizeConstraints::~SizeConstraints() {} | |
| 70 | |
| 71 gfx::Size ShellWindow::SizeConstraints::ClampSize(gfx::Size size) const { | |
| 72 if (GetMaximumSize().width() != kUnboundedSize) | |
| 
 
tapted
2013/10/15 03:33:04
nit: (since it does a bit of work), perhaps a temp
 
jackhou1
2013/10/15 05:07:13
Done.
 
 | |
| 73 size.set_width(std::min(size.width(), GetMaximumSize().width())); | |
| 74 if (GetMaximumSize().height() != kUnboundedSize) | |
| 75 size.set_height(std::min(size.height(), GetMaximumSize().height())); | |
| 76 size.SetToMax(GetMinimumSize()); | |
| 77 return size; | |
| 78 } | |
| 79 | |
| 80 bool ShellWindow::SizeConstraints::HasMinimumSize() const { | |
| 81 return GetMinimumSize().width() != kUnboundedSize || | |
| 82 GetMinimumSize().height() != kUnboundedSize; | |
| 83 } | |
| 84 | |
| 85 bool ShellWindow::SizeConstraints::HasMaximumSize() const { | |
| 86 return GetMaximumSize().width() != kUnboundedSize || | |
| 87 GetMaximumSize().height() != kUnboundedSize; | |
| 88 } | |
| 89 | |
| 90 bool ShellWindow::SizeConstraints::HasFixedSize() const { | |
| 91 return !GetMinimumSize().IsEmpty() && GetMinimumSize() == GetMaximumSize(); | |
| 92 } | |
| 93 | |
| 94 gfx::Size ShellWindow::SizeConstraints::GetMinimumSize() const { | |
| 95 return minimum_size_; | |
| 96 } | |
| 97 | |
| 98 gfx::Size ShellWindow::SizeConstraints::GetMaximumSize() const { | |
| 99 return gfx::Size( | |
| 100 maximum_size_.width() == kUnboundedSize ? | |
| 101 kUnboundedSize : | |
| 102 std::max(maximum_size_.width(), minimum_size_.width()), | |
| 103 maximum_size_.height() == kUnboundedSize ? | |
| 104 kUnboundedSize : | |
| 105 std::max(maximum_size_.height(), minimum_size_.height())); | |
| 106 } | |
| 107 | |
| 59 ShellWindow::CreateParams::CreateParams() | 108 ShellWindow::CreateParams::CreateParams() | 
| 60 : window_type(ShellWindow::WINDOW_TYPE_DEFAULT), | 109 : window_type(ShellWindow::WINDOW_TYPE_DEFAULT), | 
| 61 frame(ShellWindow::FRAME_CHROME), | 110 frame(ShellWindow::FRAME_CHROME), | 
| 62 transparent_background(false), | 111 transparent_background(false), | 
| 63 bounds(INT_MIN, INT_MIN, 0, 0), | 112 bounds(INT_MIN, INT_MIN, 0, 0), | 
| 64 creator_process_id(0), | 113 creator_process_id(0), | 
| 65 state(ui::SHOW_STATE_DEFAULT), | 114 state(ui::SHOW_STATE_DEFAULT), | 
| 66 hidden(false), | 115 hidden(false), | 
| 67 resizable(true), | 116 resizable(true), | 
| 68 focused(true) {} | 117 focused(true) {} | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 94 WebContents* web_contents = shell_window_contents_->GetWebContents(); | 143 WebContents* web_contents = shell_window_contents_->GetWebContents(); | 
| 95 delegate_->InitWebContents(web_contents); | 144 delegate_->InitWebContents(web_contents); | 
| 96 WebContentsModalDialogManager::CreateForWebContents(web_contents); | 145 WebContentsModalDialogManager::CreateForWebContents(web_contents); | 
| 97 | 146 | 
| 98 web_contents->SetDelegate(this); | 147 web_contents->SetDelegate(this); | 
| 99 WebContentsModalDialogManager::FromWebContents(web_contents)-> | 148 WebContentsModalDialogManager::FromWebContents(web_contents)-> | 
| 100 SetDelegate(this); | 149 SetDelegate(this); | 
| 101 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); | 150 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); | 
| 102 | 151 | 
| 103 // Initialize the window | 152 // Initialize the window | 
| 104 window_type_ = params.window_type; | 153 CreateParams new_params = LoadDefaultsAndConstrain(params); | 
| 105 | 154 window_type_ = new_params.window_type; | 
| 106 gfx::Rect bounds = params.bounds; | 155 window_key_ = new_params.window_key; | 
| 107 | |
| 108 if (bounds.width() == 0) | |
| 109 bounds.set_width(kDefaultWidth); | |
| 110 if (bounds.height() == 0) | |
| 111 bounds.set_height(kDefaultHeight); | |
| 112 | |
| 113 // If left and top are left undefined, the native shell window will center | |
| 114 // the window on the main screen in a platform-defined manner. | |
| 115 | |
| 116 CreateParams new_params = params; | |
| 117 | |
| 118 // Load cached state if it exists. | |
| 119 if (!params.window_key.empty()) { | |
| 120 window_key_ = params.window_key; | |
| 121 | |
| 122 ShellWindowGeometryCache* cache = ShellWindowGeometryCache::Get(profile()); | |
| 123 | |
| 124 gfx::Rect cached_bounds; | |
| 125 gfx::Rect cached_screen_bounds; | |
| 126 ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; | |
| 127 if (cache->GetGeometry(extension()->id(), params.window_key, &cached_bounds, | |
| 128 &cached_screen_bounds, &cached_state)) { | |
| 129 // App window has cached screen bounds, make sure it fits on screen in | |
| 130 // case the screen resolution changed. | |
| 131 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 132 gfx::Display display = screen->GetDisplayMatching(cached_bounds); | |
| 133 gfx::Rect current_screen_bounds = display.work_area(); | |
| 134 AdjustBoundsToBeVisibleOnScreen(cached_bounds, | |
| 135 cached_screen_bounds, | |
| 136 current_screen_bounds, | |
| 137 params.minimum_size, | |
| 138 &bounds); | |
| 139 new_params.state = cached_state; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 gfx::Size& minimum_size = new_params.minimum_size; | |
| 144 gfx::Size& maximum_size = new_params.maximum_size; | |
| 145 | |
| 146 // In the case that minimum size > maximum size, we consider the minimum | |
| 147 // size to be more important. | |
| 148 if (maximum_size.width() && maximum_size.width() < minimum_size.width()) | |
| 149 maximum_size.set_width(minimum_size.width()); | |
| 150 if (maximum_size.height() && maximum_size.height() < minimum_size.height()) | |
| 151 maximum_size.set_height(minimum_size.height()); | |
| 152 | |
| 153 if (maximum_size.width() && bounds.width() > maximum_size.width()) | |
| 154 bounds.set_width(maximum_size.width()); | |
| 155 if (bounds.width() != INT_MIN && bounds.width() < minimum_size.width()) | |
| 156 bounds.set_width(minimum_size.width()); | |
| 157 | |
| 158 if (maximum_size.height() && bounds.height() > maximum_size.height()) | |
| 159 bounds.set_height(maximum_size.height()); | |
| 160 if (bounds.height() != INT_MIN && bounds.height() < minimum_size.height()) | |
| 161 bounds.set_height(minimum_size.height()); | |
| 162 | |
| 163 new_params.bounds = bounds; | |
| 164 | |
| 165 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); | 156 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); | 
| 166 | 157 | 
| 167 if (!new_params.hidden) { | 158 if (!new_params.hidden) { | 
| 168 if (window_type_is_panel()) | 159 if (window_type_is_panel()) | 
| 169 GetBaseWindow()->ShowInactive(); // Panels are not activated by default. | 160 GetBaseWindow()->ShowInactive(); // Panels are not activated by default. | 
| 170 else | 161 else | 
| 171 GetBaseWindow()->Show(); | 162 GetBaseWindow()->Show(); | 
| 172 } | 163 } | 
| 173 | 164 | 
| 174 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) | 165 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) | 
| 175 Fullscreen(); | 166 Fullscreen(); | 
| 176 else if (new_params.state == ui::SHOW_STATE_MAXIMIZED) | 167 else if (new_params.state == ui::SHOW_STATE_MAXIMIZED) | 
| 177 Maximize(); | 168 Maximize(); | 
| 178 else if (new_params.state == ui::SHOW_STATE_MINIMIZED) | 169 else if (new_params.state == ui::SHOW_STATE_MINIMIZED) | 
| 179 Minimize(); | 170 Minimize(); | 
| 180 | 171 | 
| 181 OnNativeWindowChanged(); | 172 OnNativeWindowChanged(); | 
| 182 | 173 | 
| 183 // When the render view host is changed, the native window needs to know | 174 // When the render view host is changed, the native window needs to know | 
| 184 // about it in case it has any setup to do to make the renderer appear | 175 // about it in case it has any setup to do to make the renderer appear | 
| 185 // properly. In particular, on Windows, the view's clickthrough region needs | 176 // properly. In particular, on Windows, the view's clickthrough region needs | 
| 186 // to be set. | 177 // to be set. | 
| 187 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 178 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 
| 188 content::Source<Profile>(profile_)); | 179 content::Source<Profile>(profile_)); | 
| 189 // Close when the browser process is exiting. | 180 // Close when the browser process is exiting. | 
| 190 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 181 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 
| 191 content::NotificationService::AllSources()); | 182 content::NotificationService::AllSources()); | 
| 192 | 183 | 
| 193 shell_window_contents_->LoadContents(params.creator_process_id); | 184 shell_window_contents_->LoadContents(new_params.creator_process_id); | 
| 194 | 185 | 
| 195 // Prevent the browser process from shutting down while this window is open. | 186 // Prevent the browser process from shutting down while this window is open. | 
| 196 chrome::StartKeepAlive(); | 187 chrome::StartKeepAlive(); | 
| 197 | 188 | 
| 198 UpdateExtensionAppIcon(); | 189 UpdateExtensionAppIcon(); | 
| 199 | 190 | 
| 200 ShellWindowRegistry::Get(profile_)->AddShellWindow(this); | 191 ShellWindowRegistry::Get(profile_)->AddShellWindow(this); | 
| 201 } | 192 } | 
| 202 | 193 | 
| 203 ShellWindow::~ShellWindow() { | 194 ShellWindow::~ShellWindow() { | 
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 std::max(current_screen_bounds.x(), | 627 std::max(current_screen_bounds.x(), | 
| 637 std::min(bounds->x(), | 628 std::min(bounds->x(), | 
| 638 current_screen_bounds.right() - bounds->width()))); | 629 current_screen_bounds.right() - bounds->width()))); | 
| 639 bounds->set_y( | 630 bounds->set_y( | 
| 640 std::max(current_screen_bounds.y(), | 631 std::max(current_screen_bounds.y(), | 
| 641 std::min(bounds->y(), | 632 std::min(bounds->y(), | 
| 642 current_screen_bounds.bottom() - bounds->height()))); | 633 current_screen_bounds.bottom() - bounds->height()))); | 
| 643 } | 634 } | 
| 644 } | 635 } | 
| 645 | 636 | 
| 637 ShellWindow::CreateParams ShellWindow::LoadDefaultsAndConstrain( | |
| 638 CreateParams params) const { | |
| 639 gfx::Rect bounds = params.bounds; | |
| 640 | |
| 641 if (bounds.width() == 0) | |
| 642 bounds.set_width(kDefaultWidth); | |
| 643 if (bounds.height() == 0) | |
| 644 bounds.set_height(kDefaultHeight); | |
| 645 | |
| 646 // If left and top are left undefined, the native shell window will center | |
| 647 // the window on the main screen in a platform-defined manner. | |
| 648 | |
| 649 // Load cached state if it exists. | |
| 650 if (!params.window_key.empty()) { | |
| 651 ShellWindowGeometryCache* cache = ShellWindowGeometryCache::Get(profile()); | |
| 652 | |
| 653 gfx::Rect cached_bounds; | |
| 654 gfx::Rect cached_screen_bounds; | |
| 655 ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; | |
| 656 if (cache->GetGeometry(extension()->id(), params.window_key, | |
| 657 &cached_bounds, &cached_screen_bounds, | |
| 658 &cached_state)) { | |
| 659 // App window has cached screen bounds, make sure it fits on screen in | |
| 660 // case the screen resolution changed. | |
| 661 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | |
| 662 gfx::Display display = screen->GetDisplayMatching(cached_bounds); | |
| 663 gfx::Rect current_screen_bounds = display.work_area(); | |
| 664 AdjustBoundsToBeVisibleOnScreen(cached_bounds, | |
| 665 cached_screen_bounds, | |
| 666 current_screen_bounds, | |
| 667 params.minimum_size, | |
| 668 &bounds); | |
| 669 params.state = cached_state; | |
| 670 } | |
| 671 } | |
| 672 | |
| 673 SizeConstraints size_constraints(params.minimum_size, params.maximum_size); | |
| 674 params.bounds.set_size(size_constraints.ClampSize(bounds.size())); | |
| 675 params.minimum_size = size_constraints.GetMinimumSize(); | |
| 676 params.minimum_size = size_constraints.GetMaximumSize(); | |
| 677 | |
| 678 return params; | |
| 679 } | |
| 680 | |
| 646 // static | 681 // static | 
| 647 SkRegion* ShellWindow::RawDraggableRegionsToSkRegion( | 682 SkRegion* ShellWindow::RawDraggableRegionsToSkRegion( | 
| 648 const std::vector<extensions::DraggableRegion>& regions) { | 683 const std::vector<extensions::DraggableRegion>& regions) { | 
| 649 SkRegion* sk_region = new SkRegion; | 684 SkRegion* sk_region = new SkRegion; | 
| 650 for (std::vector<extensions::DraggableRegion>::const_iterator iter = | 685 for (std::vector<extensions::DraggableRegion>::const_iterator iter = | 
| 651 regions.begin(); | 686 regions.begin(); | 
| 652 iter != regions.end(); ++iter) { | 687 iter != regions.end(); ++iter) { | 
| 653 const extensions::DraggableRegion& region = *iter; | 688 const extensions::DraggableRegion& region = *iter; | 
| 654 sk_region->op( | 689 sk_region->op( | 
| 655 region.bounds.x(), | 690 region.bounds.x(), | 
| 656 region.bounds.y(), | 691 region.bounds.y(), | 
| 657 region.bounds.right(), | 692 region.bounds.right(), | 
| 658 region.bounds.bottom(), | 693 region.bounds.bottom(), | 
| 659 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 694 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 
| 660 } | 695 } | 
| 661 return sk_region; | 696 return sk_region; | 
| 662 } | 697 } | 
| 663 | 698 | 
| 664 } // namespace apps | 699 } // namespace apps | 
| OLD | NEW |