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 "ash/wm/workspace/multi_window_resize_controller.h" | 5 #include "ash/wm/common/workspace/multi_window_resize_controller.h" |
| 6 | 6 |
| 7 #include "ash/screen_util.h" | 7 #include "ash/wm/common/wm_root_window_controller.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/wm/common/wm_shell_window_ids.h" |
| 9 #include "ash/shell_window_ids.h" | 9 #include "ash/wm/common/wm_window.h" |
| 10 #include "ash/wm/aura/wm_window_aura.h" | |
| 11 #include "ash/wm/common/workspace/workspace_window_resizer.h" | 10 #include "ash/wm/common/workspace/workspace_window_resizer.h" |
| 12 #include "ash/wm/window_animations.h" | |
| 13 #include "ash/wm/window_state_aura.h" | |
| 14 #include "ash/wm/workspace/workspace_event_handler.h" | |
| 15 #include "grit/ash_resources.h" | 11 #include "grit/ash_resources.h" |
| 16 #include "ui/aura/client/screen_position_client.h" | 12 #include "ui/base/cursor/cursor.h" |
| 17 #include "ui/aura/window.h" | |
| 18 #include "ui/aura/window_delegate.h" | |
| 19 #include "ui/aura/window_event_dispatcher.h" | |
| 20 #include "ui/base/hit_test.h" | 13 #include "ui/base/hit_test.h" |
| 21 #include "ui/base/resource/resource_bundle.h" | 14 #include "ui/base/resource/resource_bundle.h" |
| 22 #include "ui/display/screen.h" | 15 #include "ui/display/screen.h" |
| 23 #include "ui/events/event_targeter.h" | |
| 24 #include "ui/events/event_utils.h" | |
| 25 #include "ui/gfx/canvas.h" | 16 #include "ui/gfx/canvas.h" |
| 26 #include "ui/gfx/image/image.h" | 17 #include "ui/gfx/image/image.h" |
| 27 #include "ui/views/view.h" | 18 #include "ui/views/view.h" |
| 28 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
| 29 #include "ui/views/widget/widget_delegate.h" | 20 #include "ui/views/widget/widget_delegate.h" |
| 30 #include "ui/wm/core/compound_event_filter.h" | 21 #include "ui/wm/core/compound_event_filter.h" |
| 31 #include "ui/wm/core/coordinate_conversion.h" | |
| 32 | |
| 33 using aura::Window; | |
| 34 | 22 |
| 35 namespace ash { | 23 namespace ash { |
| 36 namespace { | 24 namespace { |
| 37 | 25 |
| 38 // Delay before showing. | 26 // Delay before showing. |
| 39 const int kShowDelayMS = 400; | 27 const int kShowDelayMS = 400; |
| 40 | 28 |
| 41 // Delay before hiding. | 29 // Delay before hiding. |
| 42 const int kHideDelayMS = 500; | 30 const int kHideDelayMS = 500; |
| 43 | 31 |
| 44 // Padding from the bottom/right edge the resize widget is shown at. | 32 // Padding from the bottom/right edge the resize widget is shown at. |
| 45 const int kResizeWidgetPadding = 15; | 33 const int kResizeWidgetPadding = 15; |
| 46 | 34 |
| 47 bool ContainsX(Window* window, int x) { | 35 bool ContainsX(wm::WmWindow* window, int x) { |
| 48 return x >= 0 && x <= window->bounds().width(); | 36 return x >= 0 && x <= window->GetBounds().width(); |
| 49 } | 37 } |
| 50 | 38 |
| 51 bool ContainsScreenX(Window* window, int x_in_screen) { | 39 bool ContainsScreenX(wm::WmWindow* window, int x_in_screen) { |
| 52 gfx::Point window_loc(x_in_screen, 0); | 40 gfx::Point window_loc = |
| 53 ::wm::ConvertPointFromScreen(window, &window_loc); | 41 window->ConvertPointFromScreen(gfx::Point(x_in_screen, 0)); |
| 54 return ContainsX(window, window_loc.x()); | 42 return ContainsX(window, window_loc.x()); |
| 55 } | 43 } |
| 56 | 44 |
| 57 bool ContainsY(Window* window, int y) { | 45 bool ContainsY(wm::WmWindow* window, int y) { |
| 58 return y >= 0 && y <= window->bounds().height(); | 46 return y >= 0 && y <= window->GetBounds().height(); |
| 59 } | 47 } |
| 60 | 48 |
| 61 bool ContainsScreenY(Window* window, int y_in_screen) { | 49 bool ContainsScreenY(wm::WmWindow* window, int y_in_screen) { |
| 62 gfx::Point window_loc(0, y_in_screen); | 50 gfx::Point window_loc = |
| 63 ::wm::ConvertPointFromScreen(window, &window_loc); | 51 window->ConvertPointFromScreen(gfx::Point(0, y_in_screen)); |
| 64 return ContainsY(window, window_loc.y()); | 52 return ContainsY(window, window_loc.y()); |
| 65 } | 53 } |
| 66 | 54 |
| 67 bool Intersects(int x1, int max_1, int x2, int max_2) { | 55 bool Intersects(int x1, int max_1, int x2, int max_2) { |
| 68 return x2 <= max_1 && max_2 > x1; | 56 return x2 <= max_1 && max_2 > x1; |
| 69 } | 57 } |
| 70 | 58 |
| 71 } // namespace | 59 } // namespace |
| 72 | 60 |
| 73 // View contained in the widget. Passes along mouse events to the | 61 // View contained in the widget. Passes along mouse events to the |
| 74 // MultiWindowResizeController so that it can start/stop the resize loop. | 62 // MultiWindowResizeController so that it can start/stop the resize loop. |
| 75 class MultiWindowResizeController::ResizeView : public views::View { | 63 class MultiWindowResizeController::ResizeView : public views::View { |
| 76 public: | 64 public: |
| 77 explicit ResizeView(MultiWindowResizeController* controller, | 65 explicit ResizeView(MultiWindowResizeController* controller, |
| 78 Direction direction) | 66 Direction direction) |
| 79 : controller_(controller), | 67 : controller_(controller), direction_(direction), image_(NULL) { |
| 80 direction_(direction), | |
| 81 image_(NULL) { | |
| 82 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 68 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 83 int image_id = | 69 int image_id = direction == TOP_BOTTOM ? IDR_AURA_MULTI_WINDOW_RESIZE_H |
| 84 direction == TOP_BOTTOM ? IDR_AURA_MULTI_WINDOW_RESIZE_H : | 70 : IDR_AURA_MULTI_WINDOW_RESIZE_V; |
| 85 IDR_AURA_MULTI_WINDOW_RESIZE_V; | |
| 86 image_ = rb.GetImageNamed(image_id).ToImageSkia(); | 71 image_ = rb.GetImageNamed(image_id).ToImageSkia(); |
| 87 } | 72 } |
| 88 | 73 |
| 89 // views::View overrides: | 74 // views::View overrides: |
| 90 gfx::Size GetPreferredSize() const override { | 75 gfx::Size GetPreferredSize() const override { |
| 91 return gfx::Size(image_->width(), image_->height()); | 76 return gfx::Size(image_->width(), image_->height()); |
| 92 } | 77 } |
| 93 void OnPaint(gfx::Canvas* canvas) override { | 78 void OnPaint(gfx::Canvas* canvas) override { |
| 94 canvas->DrawImageInt(*image_, 0, 0); | 79 canvas->DrawImageInt(*image_, 0, 0); |
| 95 } | 80 } |
| 96 bool OnMousePressed(const ui::MouseEvent& event) override { | 81 bool OnMousePressed(const ui::MouseEvent& event) override { |
| 97 gfx::Point location(event.location()); | 82 gfx::Point location(event.location()); |
| 98 views::View::ConvertPointToScreen(this, &location); | 83 views::View::ConvertPointToScreen(this, &location); |
| 99 controller_->StartResize(location); | 84 controller_->StartResize(location); |
| 100 return true; | 85 return true; |
| 101 } | 86 } |
| 102 bool OnMouseDragged(const ui::MouseEvent& event) override { | 87 bool OnMouseDragged(const ui::MouseEvent& event) override { |
| 103 gfx::Point location(event.location()); | 88 gfx::Point location(event.location()); |
| 104 views::View::ConvertPointToScreen(this, &location); | 89 views::View::ConvertPointToScreen(this, &location); |
| 105 controller_->Resize(location, event.flags()); | 90 controller_->Resize(location, event.flags()); |
| 106 return true; | 91 return true; |
| 107 } | 92 } |
| 108 void OnMouseReleased(const ui::MouseEvent& event) override { | 93 void OnMouseReleased(const ui::MouseEvent& event) override { |
| 109 controller_->CompleteResize(); | 94 controller_->CompleteResize(); |
| 110 } | 95 } |
| 111 void OnMouseCaptureLost() override { controller_->CancelResize(); } | 96 void OnMouseCaptureLost() override { controller_->CancelResize(); } |
| 112 gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override { | 97 gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override { |
| 113 int component = (direction_ == LEFT_RIGHT) ? HTRIGHT : HTBOTTOM; | 98 int component = (direction_ == LEFT_RIGHT) ? HTRIGHT : HTBOTTOM; |
| 114 return ::wm::CompoundEventFilter::CursorForWindowComponent( | 99 return ::wm::CompoundEventFilter::CursorForWindowComponent(component); |
| 115 component); | |
| 116 } | 100 } |
| 117 | 101 |
| 118 private: | 102 private: |
| 119 MultiWindowResizeController* controller_; | 103 MultiWindowResizeController* controller_; |
| 120 const Direction direction_; | 104 const Direction direction_; |
| 121 const gfx::ImageSkia* image_; | 105 const gfx::ImageSkia* image_; |
| 122 | 106 |
| 123 DISALLOW_COPY_AND_ASSIGN(ResizeView); | 107 DISALLOW_COPY_AND_ASSIGN(ResizeView); |
| 124 }; | 108 }; |
| 125 | 109 |
| 126 // MouseWatcherHost implementation for MultiWindowResizeController. Forwards | 110 // MouseWatcherHost implementation for MultiWindowResizeController. Forwards |
| 127 // Contains() to MultiWindowResizeController. | 111 // Contains() to MultiWindowResizeController. |
| 128 class MultiWindowResizeController::ResizeMouseWatcherHost : | 112 class MultiWindowResizeController::ResizeMouseWatcherHost |
| 129 public views::MouseWatcherHost { | 113 : public views::MouseWatcherHost { |
| 130 public: | 114 public: |
| 131 ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {} | 115 ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {} |
| 132 | 116 |
| 133 // MouseWatcherHost overrides: | 117 // MouseWatcherHost overrides: |
| 134 bool Contains(const gfx::Point& point_in_screen, | 118 bool Contains(const gfx::Point& point_in_screen, |
| 135 MouseEventType type) override { | 119 MouseEventType type) override { |
| 136 return (type == MOUSE_PRESS) | 120 return (type == MOUSE_PRESS) ? host_->IsOverResizeWidget(point_in_screen) |
| 137 ? host_->IsOverResizeWidget(point_in_screen) | 121 : host_->IsOverWindows(point_in_screen); |
| 138 : host_->IsOverWindows(point_in_screen); | |
| 139 } | 122 } |
| 140 | 123 |
| 141 private: | 124 private: |
| 142 MultiWindowResizeController* host_; | 125 MultiWindowResizeController* host_; |
| 143 | 126 |
| 144 DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost); | 127 DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost); |
| 145 }; | 128 }; |
| 146 | 129 |
| 147 MultiWindowResizeController::ResizeWindows::ResizeWindows() | 130 MultiWindowResizeController::ResizeWindows::ResizeWindows() |
| 148 : window1(NULL), | 131 : window1(nullptr), window2(nullptr), direction(TOP_BOTTOM) {} |
| 149 window2(NULL), | |
| 150 direction(TOP_BOTTOM){ | |
| 151 } | |
| 152 | 132 |
| 153 MultiWindowResizeController::ResizeWindows::ResizeWindows( | 133 MultiWindowResizeController::ResizeWindows::ResizeWindows( |
| 154 const ResizeWindows& other) = default; | 134 const ResizeWindows& other) = default; |
| 155 | 135 |
| 156 MultiWindowResizeController::ResizeWindows::~ResizeWindows() { | 136 MultiWindowResizeController::ResizeWindows::~ResizeWindows() {} |
| 157 } | |
| 158 | 137 |
| 159 bool MultiWindowResizeController::ResizeWindows::Equals( | 138 bool MultiWindowResizeController::ResizeWindows::Equals( |
| 160 const ResizeWindows& other) const { | 139 const ResizeWindows& other) const { |
| 161 return window1 == other.window1 && | 140 return window1 == other.window1 && window2 == other.window2 && |
| 162 window2 == other.window2 && | 141 direction == other.direction; |
| 163 direction == other.direction; | |
| 164 } | 142 } |
| 165 | 143 |
| 166 MultiWindowResizeController::MultiWindowResizeController() { | 144 MultiWindowResizeController::MultiWindowResizeController() {} |
| 167 } | |
| 168 | 145 |
| 169 MultiWindowResizeController::~MultiWindowResizeController() { | 146 MultiWindowResizeController::~MultiWindowResizeController() { |
| 170 window_resizer_.reset(); | 147 window_resizer_.reset(); |
| 171 Hide(); | 148 Hide(); |
| 172 } | 149 } |
| 173 | 150 |
| 174 void MultiWindowResizeController::Show(Window* window, | 151 void MultiWindowResizeController::Show(wm::WmWindow* window, |
| 175 int component, | 152 int component, |
| 176 const gfx::Point& point_in_window) { | 153 const gfx::Point& point_in_window) { |
| 177 // When the resize widget is showing we ignore Show() requests. Instead we | 154 // When the resize widget is showing we ignore Show() requests. Instead we |
| 178 // only care about mouse movements from MouseWatcher. This is necessary as | 155 // only care about mouse movements from MouseWatcher. This is necessary as |
| 179 // WorkspaceEventHandler only sees mouse movements over the windows, not all | 156 // WorkspaceEventHandler only sees mouse movements over the windows, not all |
| 180 // windows or over the desktop. | 157 // windows or over the desktop. |
| 181 if (resize_widget_) | 158 if (resize_widget_) |
| 182 return; | 159 return; |
| 183 | 160 |
| 184 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); | 161 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); |
| 185 if (IsShowing() && windows_.Equals(windows)) | 162 if (IsShowing() && windows_.Equals(windows)) |
| 186 return; | 163 return; |
| 187 | 164 |
| 188 Hide(); | 165 Hide(); |
| 189 if (!windows.is_valid()) { | 166 if (!windows.is_valid()) { |
| 190 windows_ = ResizeWindows(); | 167 windows_ = ResizeWindows(); |
| 191 return; | 168 return; |
| 192 } | 169 } |
| 193 | 170 |
| 194 windows_ = windows; | 171 windows_ = windows; |
| 195 windows_.window1->AddObserver(this); | 172 windows_.window1->AddObserver(this); |
| 196 windows_.window2->AddObserver(this); | 173 windows_.window2->AddObserver(this); |
| 197 show_location_in_parent_ = point_in_window; | 174 show_location_in_parent_ = |
| 198 Window::ConvertPointToTarget( | 175 window->ConvertPointToTarget(window->GetParent(), point_in_window); |
| 199 window, window->parent(), &show_location_in_parent_); | 176 show_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS), |
| 200 show_timer_.Start( | 177 this, |
| 201 FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS), | 178 &MultiWindowResizeController::ShowIfValidMouseLocation); |
| 202 this, &MultiWindowResizeController::ShowIfValidMouseLocation); | |
| 203 } | 179 } |
| 204 | 180 |
| 205 void MultiWindowResizeController::Hide() { | 181 void MultiWindowResizeController::Hide() { |
| 206 if (window_resizer_) | 182 if (window_resizer_) |
| 207 return; // Ignore hides while actively resizing. | 183 return; // Ignore hides while actively resizing. |
| 208 | 184 |
| 209 if (windows_.window1) { | 185 if (windows_.window1) { |
| 210 windows_.window1->RemoveObserver(this); | 186 windows_.window1->RemoveObserver(this); |
| 211 windows_.window1 = NULL; | 187 windows_.window1 = NULL; |
| 212 } | 188 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 224 windows_.other_windows[i]->RemoveObserver(this); | 200 windows_.other_windows[i]->RemoveObserver(this); |
| 225 mouse_watcher_.reset(); | 201 mouse_watcher_.reset(); |
| 226 resize_widget_.reset(); | 202 resize_widget_.reset(); |
| 227 windows_ = ResizeWindows(); | 203 windows_ = ResizeWindows(); |
| 228 } | 204 } |
| 229 | 205 |
| 230 void MultiWindowResizeController::MouseMovedOutOfHost() { | 206 void MultiWindowResizeController::MouseMovedOutOfHost() { |
| 231 Hide(); | 207 Hide(); |
| 232 } | 208 } |
| 233 | 209 |
| 234 void MultiWindowResizeController::OnWindowDestroying( | 210 void MultiWindowResizeController::OnWindowDestroying(wm::WmWindow* window) { |
| 235 aura::Window* window) { | |
| 236 // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing. | 211 // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing. |
| 237 window_resizer_.reset(); | 212 window_resizer_.reset(); |
| 238 Hide(); | 213 Hide(); |
| 239 } | 214 } |
| 240 | 215 |
| 241 MultiWindowResizeController::ResizeWindows | 216 MultiWindowResizeController::ResizeWindows |
| 242 MultiWindowResizeController::DetermineWindowsFromScreenPoint( | 217 MultiWindowResizeController::DetermineWindowsFromScreenPoint( |
| 243 aura::Window* window) const { | 218 wm::WmWindow* window) const { |
| 244 gfx::Point mouse_location( | 219 gfx::Point mouse_location( |
| 245 display::Screen::GetScreen()->GetCursorScreenPoint()); | 220 display::Screen::GetScreen()->GetCursorScreenPoint()); |
| 246 ::wm::ConvertPointFromScreen(window, &mouse_location); | 221 mouse_location = window->ConvertPointFromScreen(mouse_location); |
| 247 const int component = | 222 const int component = window->GetNonClientComponent(mouse_location); |
| 248 window->delegate()->GetNonClientComponent(mouse_location); | |
| 249 return DetermineWindows(window, component, mouse_location); | 223 return DetermineWindows(window, component, mouse_location); |
| 250 } | 224 } |
| 251 | 225 |
| 252 void MultiWindowResizeController::CreateMouseWatcher() { | 226 void MultiWindowResizeController::CreateMouseWatcher() { |
| 253 mouse_watcher_.reset(new views::MouseWatcher( | 227 mouse_watcher_.reset( |
| 254 new ResizeMouseWatcherHost(this), this)); | 228 new views::MouseWatcher(new ResizeMouseWatcherHost(this), this)); |
| 255 mouse_watcher_->set_notify_on_exit_time( | 229 mouse_watcher_->set_notify_on_exit_time( |
| 256 base::TimeDelta::FromMilliseconds(kHideDelayMS)); | 230 base::TimeDelta::FromMilliseconds(kHideDelayMS)); |
| 257 mouse_watcher_->Start(); | 231 mouse_watcher_->Start(); |
| 258 } | 232 } |
| 259 | 233 |
| 260 MultiWindowResizeController::ResizeWindows | 234 MultiWindowResizeController::ResizeWindows |
| 261 MultiWindowResizeController::DetermineWindows( | 235 MultiWindowResizeController::DetermineWindows(wm::WmWindow* window, |
| 262 Window* window, | 236 int window_component, |
| 263 int window_component, | 237 const gfx::Point& point) const { |
| 264 const gfx::Point& point) const { | |
| 265 ResizeWindows result; | 238 ResizeWindows result; |
| 266 gfx::Point point_in_parent(point); | 239 gfx::Point point_in_parent = |
| 267 Window::ConvertPointToTarget(window, window->parent(), &point_in_parent); | 240 window->ConvertPointToTarget(window->GetParent(), point); |
| 268 switch (window_component) { | 241 switch (window_component) { |
| 269 case HTRIGHT: | 242 case HTRIGHT: |
| 270 result.direction = LEFT_RIGHT; | 243 result.direction = LEFT_RIGHT; |
| 271 result.window1 = window; | 244 result.window1 = window; |
| 272 result.window2 = FindWindowByEdge( | 245 result.window2 = FindWindowByEdge( |
| 273 window, HTLEFT, window->bounds().right(), point_in_parent.y()); | 246 window, HTLEFT, window->GetBounds().right(), point_in_parent.y()); |
| 274 break; | 247 break; |
| 275 case HTLEFT: | 248 case HTLEFT: |
| 276 result.direction = LEFT_RIGHT; | 249 result.direction = LEFT_RIGHT; |
| 277 result.window1 = FindWindowByEdge( | 250 result.window1 = FindWindowByEdge( |
| 278 window, HTRIGHT, window->bounds().x(), point_in_parent.y()); | 251 window, HTRIGHT, window->GetBounds().x(), point_in_parent.y()); |
| 279 result.window2 = window; | 252 result.window2 = window; |
| 280 break; | 253 break; |
| 281 case HTTOP: | 254 case HTTOP: |
| 282 result.direction = TOP_BOTTOM; | 255 result.direction = TOP_BOTTOM; |
| 283 result.window1 = FindWindowByEdge( | 256 result.window1 = FindWindowByEdge(window, HTBOTTOM, point_in_parent.x(), |
| 284 window, HTBOTTOM, point_in_parent.x(), window->bounds().y()); | 257 window->GetBounds().y()); |
| 285 result.window2 = window; | 258 result.window2 = window; |
| 286 break; | 259 break; |
| 287 case HTBOTTOM: | 260 case HTBOTTOM: |
| 288 result.direction = TOP_BOTTOM; | 261 result.direction = TOP_BOTTOM; |
| 289 result.window1 = window; | 262 result.window1 = window; |
| 290 result.window2 = FindWindowByEdge( | 263 result.window2 = FindWindowByEdge(window, HTTOP, point_in_parent.x(), |
| 291 window, HTTOP, point_in_parent.x(), window->bounds().bottom()); | 264 window->GetBounds().bottom()); |
| 292 break; | 265 break; |
| 293 default: | 266 default: |
| 294 break; | 267 break; |
| 295 } | 268 } |
| 296 return result; | 269 return result; |
| 297 } | 270 } |
| 298 | 271 |
| 299 Window* MultiWindowResizeController::FindWindowByEdge( | 272 wm::WmWindow* MultiWindowResizeController::FindWindowByEdge( |
| 300 Window* window_to_ignore, | 273 wm::WmWindow* window_to_ignore, |
| 301 int edge_want, | 274 int edge_want, |
| 302 int x_in_parent, | 275 int x_in_parent, |
| 303 int y_in_parent) const { | 276 int y_in_parent) const { |
| 304 Window* parent = window_to_ignore->parent(); | 277 wm::WmWindow* parent = window_to_ignore->GetParent(); |
| 305 const Window::Windows& windows(parent->children()); | 278 std::vector<wm::WmWindow*> windows = parent->GetChildren(); |
| 306 for (Window::Windows::const_reverse_iterator i = windows.rbegin(); | 279 for (auto i = windows.rbegin(); i != windows.rend(); ++i) { |
| 307 i != windows.rend(); ++i) { | 280 wm::WmWindow* window = *i; |
| 308 Window* window = *i; | |
| 309 if (window == window_to_ignore || !window->IsVisible()) | 281 if (window == window_to_ignore || !window->IsVisible()) |
| 310 continue; | 282 continue; |
| 311 | 283 |
| 312 // Ignore windows without a delegate. A delegate is necessary to query the | 284 // Ignore windows without a non-client area. |
| 313 // non-client component. | 285 if (!window->HasNonClientArea()) |
| 314 if (!window->delegate()) | |
| 315 continue; | 286 continue; |
| 316 | 287 |
| 317 gfx::Point p(x_in_parent, y_in_parent); | 288 gfx::Point p = parent->ConvertPointToTarget( |
| 318 aura::Window::ConvertPointToTarget(parent, window, &p); | 289 window, gfx::Point(x_in_parent, y_in_parent)); |
| 319 switch (edge_want) { | 290 switch (edge_want) { |
| 320 case HTLEFT: | 291 case HTLEFT: |
| 321 if (ContainsY(window, p.y()) && p.x() == 0) | 292 if (ContainsY(window, p.y()) && p.x() == 0) |
| 322 return window; | 293 return window; |
| 323 break; | 294 break; |
| 324 case HTRIGHT: | 295 case HTRIGHT: |
| 325 if (ContainsY(window, p.y()) && p.x() == window->bounds().width()) | 296 if (ContainsY(window, p.y()) && p.x() == window->GetBounds().width()) |
| 326 return window; | 297 return window; |
| 327 break; | 298 break; |
| 328 case HTTOP: | 299 case HTTOP: |
| 329 if (ContainsX(window, p.x()) && p.y() == 0) | 300 if (ContainsX(window, p.x()) && p.y() == 0) |
| 330 return window; | 301 return window; |
| 331 break; | 302 break; |
| 332 case HTBOTTOM: | 303 case HTBOTTOM: |
| 333 if (ContainsX(window, p.x()) && p.y() == window->bounds().height()) | 304 if (ContainsX(window, p.x()) && p.y() == window->GetBounds().height()) |
| 334 return window; | 305 return window; |
| 335 break; | 306 break; |
| 336 default: | 307 default: |
| 337 NOTREACHED(); | 308 NOTREACHED(); |
| 338 } | 309 } |
| 339 // Window doesn't contain the edge, but if window contains |point| | 310 // Window doesn't contain the edge, but if window contains |point| |
| 340 // it's obscuring any other window that could be at the location. | 311 // it's obscuring any other window that could be at the location. |
| 341 if (window->bounds().Contains(x_in_parent, y_in_parent)) | 312 if (window->GetBounds().Contains(x_in_parent, y_in_parent)) |
| 342 return NULL; | 313 return NULL; |
| 343 } | 314 } |
| 344 return NULL; | 315 return NULL; |
| 345 } | 316 } |
| 346 | 317 |
| 347 aura::Window* MultiWindowResizeController::FindWindowTouching( | 318 wm::WmWindow* MultiWindowResizeController::FindWindowTouching( |
| 348 aura::Window* window, | 319 wm::WmWindow* window, |
| 349 Direction direction) const { | 320 Direction direction) const { |
| 350 int right = window->bounds().right(); | 321 int right = window->GetBounds().right(); |
| 351 int bottom = window->bounds().bottom(); | 322 int bottom = window->GetBounds().bottom(); |
| 352 Window* parent = window->parent(); | 323 wm::WmWindow* parent = window->GetParent(); |
| 353 const Window::Windows& windows(parent->children()); | 324 std::vector<wm::WmWindow*> windows = parent->GetChildren(); |
| 354 for (Window::Windows::const_reverse_iterator i = windows.rbegin(); | 325 for (auto i = windows.rbegin(); i != windows.rend(); ++i) { |
| 355 i != windows.rend(); ++i) { | 326 wm::WmWindow* other = *i; |
| 356 Window* other = *i; | |
| 357 if (other == window || !other->IsVisible()) | 327 if (other == window || !other->IsVisible()) |
| 358 continue; | 328 continue; |
| 359 switch (direction) { | 329 switch (direction) { |
| 360 case TOP_BOTTOM: | 330 case TOP_BOTTOM: |
| 361 if (other->bounds().y() == bottom && | 331 if (other->GetBounds().y() == bottom && |
| 362 Intersects(other->bounds().x(), other->bounds().right(), | 332 Intersects(other->GetBounds().x(), other->GetBounds().right(), |
| 363 window->bounds().x(), window->bounds().right())) { | 333 window->GetBounds().x(), window->GetBounds().right())) { |
| 364 return other; | 334 return other; |
| 365 } | 335 } |
| 366 break; | 336 break; |
| 367 case LEFT_RIGHT: | 337 case LEFT_RIGHT: |
| 368 if (other->bounds().x() == right && | 338 if (other->GetBounds().x() == right && |
| 369 Intersects(other->bounds().y(), other->bounds().bottom(), | 339 Intersects(other->GetBounds().y(), other->GetBounds().bottom(), |
| 370 window->bounds().y(), window->bounds().bottom())) { | 340 window->GetBounds().y(), window->GetBounds().bottom())) { |
| 371 return other; | 341 return other; |
| 372 } | 342 } |
| 373 break; | 343 break; |
| 374 default: | 344 default: |
| 375 NOTREACHED(); | 345 NOTREACHED(); |
| 376 } | 346 } |
| 377 } | 347 } |
| 378 return NULL; | 348 return NULL; |
| 379 } | 349 } |
| 380 | 350 |
| 381 void MultiWindowResizeController::FindWindowsTouching( | 351 void MultiWindowResizeController::FindWindowsTouching( |
| 382 aura::Window* start, | 352 wm::WmWindow* start, |
| 383 Direction direction, | 353 Direction direction, |
| 384 std::vector<aura::Window*>* others) const { | 354 std::vector<wm::WmWindow*>* others) const { |
| 385 while (start) { | 355 while (start) { |
| 386 start = FindWindowTouching(start, direction); | 356 start = FindWindowTouching(start, direction); |
| 387 if (start) | 357 if (start) |
| 388 others->push_back(start); | 358 others->push_back(start); |
| 389 } | 359 } |
| 390 } | 360 } |
| 391 | 361 |
| 392 void MultiWindowResizeController::ShowIfValidMouseLocation() { | 362 void MultiWindowResizeController::ShowIfValidMouseLocation() { |
| 393 if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) || | 363 if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) || |
| 394 DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) { | 364 DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) { |
| 395 ShowNow(); | 365 ShowNow(); |
| 396 } else { | 366 } else { |
| 397 Hide(); | 367 Hide(); |
| 398 } | 368 } |
| 399 } | 369 } |
| 400 | 370 |
| 401 void MultiWindowResizeController::ShowNow() { | 371 void MultiWindowResizeController::ShowNow() { |
| 402 DCHECK(!resize_widget_.get()); | 372 DCHECK(!resize_widget_.get()); |
| 403 DCHECK(windows_.is_valid()); | 373 DCHECK(windows_.is_valid()); |
| 404 show_timer_.Stop(); | 374 show_timer_.Stop(); |
| 405 resize_widget_.reset(new views::Widget); | 375 resize_widget_.reset(new views::Widget); |
| 406 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 376 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
| 377 params.name = "MultiWindowResizeController"; | |
|
James Cook
2016/05/02 19:12:45
Hooray for names via InitParams!
| |
| 407 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 378 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 408 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 379 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 409 params.parent = Shell::GetContainer(Shell::GetTargetRootWindow(), | 380 windows_.window1->GetRootWindowController() |
| 410 kShellWindowId_AlwaysOnTopContainer); | 381 ->ConfigureWidgetInitParamsForContainer( |
|
James Cook
2016/05/02 19:12:45
Out of curiosity, why does ConfigureWidgetInitPara
sky
2016/05/02 21:00:52
It's needed given construction order of mus. It ma
| |
| 382 resize_widget_.get(), kShellWindowId_AlwaysOnTopContainer, ¶ms); | |
| 411 ResizeView* view = new ResizeView(this, windows_.direction); | 383 ResizeView* view = new ResizeView(this, windows_.direction); |
| 412 resize_widget_->set_focus_on_creation(false); | 384 resize_widget_->set_focus_on_creation(false); |
| 413 resize_widget_->Init(params); | 385 resize_widget_->Init(params); |
| 414 ::wm::SetWindowVisibilityAnimationType( | 386 wm::WmWindow::Get(resize_widget_.get()) |
| 415 resize_widget_->GetNativeWindow(), | 387 ->SetVisibilityAnimationType(::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 416 ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | |
| 417 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); | |
| 418 resize_widget_->SetContentsView(view); | 388 resize_widget_->SetContentsView(view); |
| 419 show_bounds_in_screen_ = ScreenUtil::ConvertRectToScreen( | 389 show_bounds_in_screen_ = windows_.window1->GetParent()->ConvertRectToScreen( |
| 420 windows_.window1->parent(), | |
| 421 CalculateResizeWidgetBounds(show_location_in_parent_)); | 390 CalculateResizeWidgetBounds(show_location_in_parent_)); |
| 422 resize_widget_->SetBounds(show_bounds_in_screen_); | 391 resize_widget_->SetBounds(show_bounds_in_screen_); |
| 423 resize_widget_->Show(); | 392 resize_widget_->Show(); |
| 424 CreateMouseWatcher(); | 393 CreateMouseWatcher(); |
| 425 } | 394 } |
| 426 | 395 |
| 427 bool MultiWindowResizeController::IsShowing() const { | 396 bool MultiWindowResizeController::IsShowing() const { |
| 428 return resize_widget_.get() || show_timer_.IsRunning(); | 397 return resize_widget_.get() || show_timer_.IsRunning(); |
| 429 } | 398 } |
| 430 | 399 |
| 431 void MultiWindowResizeController::StartResize( | 400 void MultiWindowResizeController::StartResize( |
| 432 const gfx::Point& location_in_screen) { | 401 const gfx::Point& location_in_screen) { |
| 433 DCHECK(!window_resizer_.get()); | 402 DCHECK(!window_resizer_.get()); |
| 434 DCHECK(windows_.is_valid()); | 403 DCHECK(windows_.is_valid()); |
| 435 gfx::Point location_in_parent(location_in_screen); | 404 gfx::Point location_in_parent = |
| 436 aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())-> | 405 windows_.window2->GetParent()->ConvertPointFromScreen(location_in_screen); |
| 437 ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent); | 406 std::vector<wm::WmWindow*> windows; |
| 438 std::vector<aura::Window*> windows; | |
| 439 windows.push_back(windows_.window2); | 407 windows.push_back(windows_.window2); |
| 440 DCHECK(windows_.other_windows.empty()); | 408 DCHECK(windows_.other_windows.empty()); |
| 441 FindWindowsTouching(windows_.window2, windows_.direction, | 409 FindWindowsTouching(windows_.window2, windows_.direction, |
| 442 &windows_.other_windows); | 410 &windows_.other_windows); |
| 443 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { | 411 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { |
| 444 windows_.other_windows[i]->AddObserver(this); | 412 windows_.other_windows[i]->AddObserver(this); |
| 445 windows.push_back(windows_.other_windows[i]); | 413 windows.push_back(windows_.other_windows[i]); |
| 446 } | 414 } |
| 447 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; | 415 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; |
| 448 wm::WindowState* window_state = wm::GetWindowState(windows_.window1); | 416 wm::WindowState* window_state = windows_.window1->GetWindowState(); |
| 449 window_state->CreateDragDetails(location_in_parent, component, | 417 window_state->CreateDragDetails(location_in_parent, component, |
| 450 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | 418 aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 451 window_resizer_.reset(WorkspaceWindowResizer::Create( | 419 window_resizer_.reset(WorkspaceWindowResizer::Create(window_state, windows)); |
| 452 window_state, wm::WmWindowAura::FromAuraWindows(windows))); | |
| 453 | 420 |
| 454 // Do not hide the resize widget while a drag is active. | 421 // Do not hide the resize widget while a drag is active. |
| 455 mouse_watcher_.reset(); | 422 mouse_watcher_.reset(); |
| 456 } | 423 } |
| 457 | 424 |
| 458 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, | 425 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, |
| 459 int event_flags) { | 426 int event_flags) { |
| 460 gfx::Point location_in_parent(location_in_screen); | 427 gfx::Point location_in_parent = |
| 461 aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())-> | 428 windows_.window1->GetParent()->ConvertPointFromScreen(location_in_screen); |
| 462 ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent); | |
| 463 window_resizer_->Drag(location_in_parent, event_flags); | 429 window_resizer_->Drag(location_in_parent, event_flags); |
| 464 gfx::Rect bounds = ScreenUtil::ConvertRectToScreen( | 430 gfx::Rect bounds = windows_.window1->GetParent()->ConvertRectToScreen( |
| 465 windows_.window1->parent(), | |
| 466 CalculateResizeWidgetBounds(location_in_parent)); | 431 CalculateResizeWidgetBounds(location_in_parent)); |
| 467 | 432 |
| 468 if (windows_.direction == LEFT_RIGHT) | 433 if (windows_.direction == LEFT_RIGHT) |
| 469 bounds.set_y(show_bounds_in_screen_.y()); | 434 bounds.set_y(show_bounds_in_screen_.y()); |
| 470 else | 435 else |
| 471 bounds.set_x(show_bounds_in_screen_.x()); | 436 bounds.set_x(show_bounds_in_screen_.x()); |
| 472 resize_widget_->SetBounds(bounds); | 437 resize_widget_->SetBounds(bounds); |
| 473 } | 438 } |
| 474 | 439 |
| 475 void MultiWindowResizeController::CompleteResize() { | 440 void MultiWindowResizeController::CompleteResize() { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 500 window_resizer_->GetTarget()->GetWindowState()->DeleteDragDetails(); | 465 window_resizer_->GetTarget()->GetWindowState()->DeleteDragDetails(); |
| 501 window_resizer_.reset(); | 466 window_resizer_.reset(); |
| 502 Hide(); | 467 Hide(); |
| 503 } | 468 } |
| 504 | 469 |
| 505 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( | 470 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( |
| 506 const gfx::Point& location_in_parent) const { | 471 const gfx::Point& location_in_parent) const { |
| 507 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); | 472 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); |
| 508 int x = 0, y = 0; | 473 int x = 0, y = 0; |
| 509 if (windows_.direction == LEFT_RIGHT) { | 474 if (windows_.direction == LEFT_RIGHT) { |
| 510 x = windows_.window1->bounds().right() - pref.width() / 2; | 475 x = windows_.window1->GetBounds().right() - pref.width() / 2; |
| 511 y = location_in_parent.y() + kResizeWidgetPadding; | 476 y = location_in_parent.y() + kResizeWidgetPadding; |
| 512 if (y + pref.height() / 2 > windows_.window1->bounds().bottom() && | 477 if (y + pref.height() / 2 > windows_.window1->GetBounds().bottom() && |
| 513 y + pref.height() / 2 > windows_.window2->bounds().bottom()) { | 478 y + pref.height() / 2 > windows_.window2->GetBounds().bottom()) { |
| 514 y = location_in_parent.y() - kResizeWidgetPadding - pref.height(); | 479 y = location_in_parent.y() - kResizeWidgetPadding - pref.height(); |
| 515 } | 480 } |
| 516 } else { | 481 } else { |
| 517 x = location_in_parent.x() + kResizeWidgetPadding; | 482 x = location_in_parent.x() + kResizeWidgetPadding; |
| 518 if (x + pref.height() / 2 > windows_.window1->bounds().right() && | 483 if (x + pref.height() / 2 > windows_.window1->GetBounds().right() && |
| 519 x + pref.height() / 2 > windows_.window2->bounds().right()) { | 484 x + pref.height() / 2 > windows_.window2->GetBounds().right()) { |
| 520 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); | 485 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); |
| 521 } | 486 } |
| 522 y = windows_.window1->bounds().bottom() - pref.height() / 2; | 487 y = windows_.window1->GetBounds().bottom() - pref.height() / 2; |
| 523 } | 488 } |
| 524 return gfx::Rect(x, y, pref.width(), pref.height()); | 489 return gfx::Rect(x, y, pref.width(), pref.height()); |
| 525 } | 490 } |
| 526 | 491 |
| 527 bool MultiWindowResizeController::IsOverResizeWidget( | 492 bool MultiWindowResizeController::IsOverResizeWidget( |
| 528 const gfx::Point& location_in_screen) const { | 493 const gfx::Point& location_in_screen) const { |
| 529 return resize_widget_->GetWindowBoundsInScreen().Contains( | 494 return resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen); |
| 530 location_in_screen); | |
| 531 } | 495 } |
| 532 | 496 |
| 533 bool MultiWindowResizeController::IsOverWindows( | 497 bool MultiWindowResizeController::IsOverWindows( |
| 534 const gfx::Point& location_in_screen) const { | 498 const gfx::Point& location_in_screen) const { |
| 535 if (IsOverResizeWidget(location_in_screen)) | 499 if (IsOverResizeWidget(location_in_screen)) |
| 536 return true; | 500 return true; |
| 537 | 501 |
| 538 if (windows_.direction == TOP_BOTTOM) { | 502 if (windows_.direction == TOP_BOTTOM) { |
| 539 if (!ContainsScreenX(windows_.window1, location_in_screen.x()) || | 503 if (!ContainsScreenX(windows_.window1, location_in_screen.x()) || |
| 540 !ContainsScreenX(windows_.window2, location_in_screen.x())) { | 504 !ContainsScreenX(windows_.window2, location_in_screen.x())) { |
| 541 return false; | 505 return false; |
| 542 } | 506 } |
| 543 } else { | 507 } else { |
| 544 if (!ContainsScreenY(windows_.window1, location_in_screen.y()) || | 508 if (!ContainsScreenY(windows_.window1, location_in_screen.y()) || |
| 545 !ContainsScreenY(windows_.window2, location_in_screen.y())) { | 509 !ContainsScreenY(windows_.window2, location_in_screen.y())) { |
| 546 return false; | 510 return false; |
| 547 } | 511 } |
| 548 } | 512 } |
| 549 | 513 |
| 550 // Check whether |location_in_screen| is in the event target's resize region. | 514 // Check whether |location_in_screen| is in the event target's resize region. |
| 551 // This is tricky because a window's resize region can extend outside a | 515 // This is tricky because a window's resize region can extend outside a |
| 552 // window's bounds. | 516 // window's bounds. |
| 553 gfx::Point location_in_root(location_in_screen); | 517 wm::WmWindow* target = |
| 554 aura::Window* root = windows_.window1->GetRootWindow(); | 518 windows_.window1->GetRootWindowController()->FindEventTarget( |
| 555 ::wm::ConvertPointFromScreen(root, &location_in_root); | 519 location_in_screen); |
| 556 ui::MouseEvent test_event(ui::ET_MOUSE_MOVED, location_in_root, | 520 if (target == windows_.window1) { |
| 557 location_in_root, ui::EventTimeForNow(), | |
| 558 ui::EF_NONE, ui::EF_NONE); | |
| 559 ui::EventTarget* event_handler = static_cast<ui::EventTarget*>(root) | |
| 560 ->GetEventTargeter() | |
| 561 ->FindTargetForEvent(root, &test_event); | |
| 562 if (event_handler == windows_.window1) { | |
| 563 return IsOverComponent( | 521 return IsOverComponent( |
| 564 windows_.window1, | 522 windows_.window1, location_in_screen, |
| 565 location_in_screen, | |
| 566 windows_.direction == TOP_BOTTOM ? HTBOTTOM : HTRIGHT); | 523 windows_.direction == TOP_BOTTOM ? HTBOTTOM : HTRIGHT); |
| 567 } else if (event_handler == windows_.window2) { | 524 } |
| 568 return IsOverComponent( | 525 if (target == windows_.window2) { |
| 569 windows_.window2, | 526 return IsOverComponent(windows_.window2, location_in_screen, |
| 570 location_in_screen, | 527 windows_.direction == TOP_BOTTOM ? HTTOP : HTLEFT); |
| 571 windows_.direction == TOP_BOTTOM ? HTTOP : HTLEFT); | |
| 572 } | 528 } |
| 573 return false; | 529 return false; |
| 574 } | 530 } |
| 575 | 531 |
| 576 bool MultiWindowResizeController::IsOverComponent( | 532 bool MultiWindowResizeController::IsOverComponent( |
| 577 aura::Window* window, | 533 wm::WmWindow* window, |
| 578 const gfx::Point& location_in_screen, | 534 const gfx::Point& location_in_screen, |
| 579 int component) const { | 535 int component) const { |
| 580 gfx::Point window_loc(location_in_screen); | 536 gfx::Point window_loc = window->ConvertPointFromScreen(location_in_screen); |
| 581 ::wm::ConvertPointFromScreen(window, &window_loc); | 537 return window->GetNonClientComponent(window_loc) == component; |
| 582 return window->delegate()->GetNonClientComponent(window_loc) == component; | |
| 583 } | 538 } |
| 584 | 539 |
| 585 } // namespace ash | 540 } // namespace ash |
| OLD | NEW |