Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/shell_surface.h" | 5 #include "components/exo/shell_surface.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/common/frame/custom_frame_view_ash.h" | 9 #include "ash/common/frame/custom_frame_view_ash.h" |
| 10 #include "ash/common/shelf/wm_shelf.h" | 10 #include "ash/common/shelf/wm_shelf.h" |
| 11 #include "ash/common/wm/window_resizer.h" | 11 #include "ash/common/wm/window_resizer.h" |
| 12 #include "ash/common/wm/window_state.h" | 12 #include "ash/common/wm/window_state.h" |
| 13 #include "ash/common/wm_shell.h" | |
| 13 #include "ash/common/wm_window.h" | 14 #include "ash/common/wm_window.h" |
| 14 #include "ash/public/cpp/shell_window_ids.h" | 15 #include "ash/public/cpp/shell_window_ids.h" |
| 16 #include "ash/wm/drag_window_resizer.h" | |
| 15 #include "ash/wm/window_state_aura.h" | 17 #include "ash/wm/window_state_aura.h" |
| 16 #include "ash/wm/window_util.h" | 18 #include "ash/wm/window_util.h" |
| 17 #include "base/logging.h" | 19 #include "base/logging.h" |
| 18 #include "base/macros.h" | 20 #include "base/macros.h" |
| 19 #include "base/memory/ptr_util.h" | 21 #include "base/memory/ptr_util.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/trace_event/trace_event.h" | 23 #include "base/trace_event/trace_event.h" |
| 22 #include "base/trace_event/trace_event_argument.h" | 24 #include "base/trace_event/trace_event_argument.h" |
| 23 #include "components/exo/surface.h" | 25 #include "components/exo/surface.h" |
| 24 #include "ui/aura/client/aura_constants.h" | 26 #include "ui/aura/client/aura_constants.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 } | 138 } |
| 137 return aura::WindowTargeter::FindTargetForEvent(root, event); | 139 return aura::WindowTargeter::FindTargetForEvent(root, event); |
| 138 } | 140 } |
| 139 | 141 |
| 140 private: | 142 private: |
| 141 views::Widget* const widget_; | 143 views::Widget* const widget_; |
| 142 | 144 |
| 143 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); | 145 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); |
| 144 }; | 146 }; |
| 145 | 147 |
| 148 class CustomWindowResizer : public ash::WindowResizer { | |
| 149 public: | |
| 150 explicit CustomWindowResizer(ash::wm::WindowState* window_state) | |
| 151 : WindowResizer(window_state), shell_(GetTarget()->GetShell()) { | |
| 152 shell_->LockCursor(); | |
| 153 } | |
| 154 | |
|
reveman
2017/03/02 02:00:38
nit: remove this blank line
Dominik Laskowski
2017/03/03 13:50:40
Done.
| |
| 155 ~CustomWindowResizer() override { shell_->UnlockCursor(); } | |
| 156 | |
| 157 // ash::WindowResizer: | |
|
reveman
2017/03/02 02:00:38
nit: // Overridden from ash::WindowResizer:
Dominik Laskowski
2017/03/03 13:50:40
Done.
| |
| 158 void Drag(const gfx::Point& location, int event_flags) override {} | |
| 159 void CompleteDrag() override {} | |
| 160 void RevertDrag() override {} | |
| 161 | |
| 162 private: | |
| 163 ash::WmShell* const shell_; | |
| 164 | |
| 165 DISALLOW_COPY_AND_ASSIGN(CustomWindowResizer); | |
| 166 }; | |
| 167 | |
| 146 class ShellSurfaceWidget : public views::Widget { | 168 class ShellSurfaceWidget : public views::Widget { |
| 147 public: | 169 public: |
| 148 explicit ShellSurfaceWidget(ShellSurface* shell_surface) | 170 explicit ShellSurfaceWidget(ShellSurface* shell_surface) |
| 149 : shell_surface_(shell_surface) {} | 171 : shell_surface_(shell_surface) {} |
| 150 | 172 |
| 151 // Overridden from views::Widget | 173 // Overridden from views::Widget |
| 152 void Close() override { shell_surface_->Close(); } | 174 void Close() override { shell_surface_->Close(); } |
| 153 void OnKeyEvent(ui::KeyEvent* event) override { | 175 void OnKeyEvent(ui::KeyEvent* event) override { |
| 154 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key | 176 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key |
| 155 // to escape pinned mode. | 177 // to escape pinned mode. |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 int container) | 319 int container) |
| 298 : widget_(nullptr), | 320 : widget_(nullptr), |
| 299 surface_(surface), | 321 surface_(surface), |
| 300 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), | 322 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), |
| 301 bounds_mode_(bounds_mode), | 323 bounds_mode_(bounds_mode), |
| 302 origin_(origin), | 324 origin_(origin), |
| 303 activatable_(activatable), | 325 activatable_(activatable), |
| 304 can_minimize_(can_minimize), | 326 can_minimize_(can_minimize), |
| 305 container_(container) { | 327 container_(container) { |
| 306 WMHelper::GetInstance()->AddActivationObserver(this); | 328 WMHelper::GetInstance()->AddActivationObserver(this); |
| 329 WMHelper::GetInstance()->AddDisplayConfigurationObserver(this); | |
| 307 surface_->SetSurfaceDelegate(this); | 330 surface_->SetSurfaceDelegate(this); |
| 308 surface_->AddSurfaceObserver(this); | 331 surface_->AddSurfaceObserver(this); |
| 309 surface_->window()->Show(); | 332 surface_->window()->Show(); |
| 310 set_owned_by_client(); | 333 set_owned_by_client(); |
| 311 if (parent_) | 334 if (parent_) |
| 312 parent_->AddObserver(this); | 335 parent_->AddObserver(this); |
| 313 } | 336 } |
| 314 | 337 |
| 315 ShellSurface::ShellSurface(Surface* surface) | 338 ShellSurface::ShellSurface(Surface* surface) |
| 316 : ShellSurface(surface, | 339 : ShellSurface(surface, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 329 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); | 352 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); |
| 330 widget_->GetNativeWindow()->RemoveObserver(this); | 353 widget_->GetNativeWindow()->RemoveObserver(this); |
| 331 // Remove transient children so they are not automatically destroyed. | 354 // Remove transient children so they are not automatically destroyed. |
| 332 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow())) | 355 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow())) |
| 333 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); | 356 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); |
| 334 if (widget_->IsVisible()) | 357 if (widget_->IsVisible()) |
| 335 widget_->Hide(); | 358 widget_->Hide(); |
| 336 widget_->CloseNow(); | 359 widget_->CloseNow(); |
| 337 } | 360 } |
| 338 WMHelper::GetInstance()->RemoveActivationObserver(this); | 361 WMHelper::GetInstance()->RemoveActivationObserver(this); |
| 362 WMHelper::GetInstance()->RemoveDisplayConfigurationObserver(this); | |
| 339 if (parent_) | 363 if (parent_) |
| 340 parent_->RemoveObserver(this); | 364 parent_->RemoveObserver(this); |
| 341 if (surface_) { | 365 if (surface_) { |
| 342 if (scale_ != 1.0) | 366 if (scale_ != 1.0) |
| 343 surface_->window()->SetTransform(gfx::Transform()); | 367 surface_->window()->SetTransform(gfx::Transform()); |
| 344 surface_->SetSurfaceDelegate(nullptr); | 368 surface_->SetSurfaceDelegate(nullptr); |
| 345 surface_->RemoveSurfaceObserver(this); | 369 surface_->RemoveSurfaceObserver(this); |
| 346 } | 370 } |
| 347 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); | 371 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); |
| 348 } | 372 } |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 void ShellSurface::SetApplicationId(const std::string& application_id) { | 541 void ShellSurface::SetApplicationId(const std::string& application_id) { |
| 518 // Store the value in |application_id_| in case the window does not exist yet. | 542 // Store the value in |application_id_| in case the window does not exist yet. |
| 519 application_id_ = application_id; | 543 application_id_ = application_id; |
| 520 if (widget_ && widget_->GetNativeWindow()) | 544 if (widget_ && widget_->GetNativeWindow()) |
| 521 SetApplicationId(widget_->GetNativeWindow(), application_id); | 545 SetApplicationId(widget_->GetNativeWindow(), application_id); |
| 522 } | 546 } |
| 523 | 547 |
| 524 void ShellSurface::Move() { | 548 void ShellSurface::Move() { |
| 525 TRACE_EVENT0("exo", "ShellSurface::Move"); | 549 TRACE_EVENT0("exo", "ShellSurface::Move"); |
| 526 | 550 |
| 527 if (!widget_) | 551 if (!widget_ || resizer_) |
|
reveman
2017/03/02 02:00:38
why is this needed now?
Dominik Laskowski
2017/03/03 13:50:40
This check was pulled out from AttemptToStartDrag
| |
| 528 return; | 552 return; |
| 529 | 553 |
| 530 switch (bounds_mode_) { | 554 switch (bounds_mode_) { |
| 531 case BoundsMode::SHELL: | 555 case BoundsMode::SHELL: |
| 532 AttemptToStartDrag(HTCAPTION); | 556 AttemptToStartDrag(HTCAPTION); |
| 533 return; | 557 return; |
| 534 case BoundsMode::CLIENT: | 558 case BoundsMode::CLIENT: |
| 559 AttemptToStartClientDrag(); | |
|
reveman
2017/03/02 02:00:38
nit: please move switch statement into AttemptToSt
Dominik Laskowski
2017/03/03 13:50:40
Merged AttemptToStartClientDrag into AttemptToStar
| |
| 560 return; | |
| 535 case BoundsMode::FIXED: | 561 case BoundsMode::FIXED: |
| 536 return; | 562 return; |
| 537 } | 563 } |
| 538 | 564 |
| 539 NOTREACHED(); | 565 NOTREACHED(); |
| 540 } | 566 } |
| 541 | 567 |
| 542 void ShellSurface::Resize(int component) { | 568 void ShellSurface::Resize(int component) { |
| 543 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); | 569 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); |
| 544 | 570 |
| 545 if (!widget_) | 571 if (!widget_ || resizer_) |
|
reveman
2017/03/02 02:00:38
why is this needed now?
Dominik Laskowski
2017/03/03 13:50:40
See above.
| |
| 546 return; | 572 return; |
| 547 | 573 |
| 548 switch (bounds_mode_) { | 574 switch (bounds_mode_) { |
| 549 case BoundsMode::SHELL: | 575 case BoundsMode::SHELL: |
| 550 AttemptToStartDrag(component); | 576 AttemptToStartDrag(component); |
| 551 return; | 577 return; |
| 552 case BoundsMode::CLIENT: | 578 case BoundsMode::CLIENT: |
| 553 case BoundsMode::FIXED: | 579 case BoundsMode::FIXED: |
| 554 return; | 580 return; |
| 555 } | 581 } |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 991 } | 1017 } |
| 992 | 1018 |
| 993 //////////////////////////////////////////////////////////////////////////////// | 1019 //////////////////////////////////////////////////////////////////////////////// |
| 994 // WMHelper::AccessibilityObserver overrides: | 1020 // WMHelper::AccessibilityObserver overrides: |
| 995 | 1021 |
| 996 void ShellSurface::OnAccessibilityModeChanged() { | 1022 void ShellSurface::OnAccessibilityModeChanged() { |
| 997 UpdateShadow(); | 1023 UpdateShadow(); |
| 998 } | 1024 } |
| 999 | 1025 |
| 1000 //////////////////////////////////////////////////////////////////////////////// | 1026 //////////////////////////////////////////////////////////////////////////////// |
| 1027 // WMHelper::DisplayConfigurationObserver overrides: | |
| 1028 | |
| 1029 void ShellSurface::OnDisplayConfigurationChanged() { | |
| 1030 if (!display_config_changed_callback_.is_null()) | |
| 1031 display_config_changed_callback_.Run(); | |
|
reveman
2017/03/02 02:00:38
why not send a configure request and adjust origin
Dominik Laskowski
2017/03/03 13:50:40
Given that the origin is part of the public ShellS
reveman
2017/03/06 19:02:13
As other changes to origin happen internally and r
Dominik Laskowski
2017/03/08 23:13:22
But then ShellSurface would contain logic specific
| |
| 1032 } | |
| 1033 | |
| 1034 //////////////////////////////////////////////////////////////////////////////// | |
| 1001 // ui::EventHandler overrides: | 1035 // ui::EventHandler overrides: |
| 1002 | 1036 |
| 1003 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { | 1037 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { |
| 1004 if (!resizer_) { | 1038 if (!resizer_) { |
| 1005 views::View::OnKeyEvent(event); | 1039 views::View::OnKeyEvent(event); |
| 1006 return; | 1040 return; |
| 1007 } | 1041 } |
| 1008 | 1042 |
| 1009 if (event->type() == ui::ET_KEY_PRESSED && | 1043 if (bounds_mode_ == BoundsMode::SHELL && |
|
reveman
2017/03/02 02:00:38
We should be allowed to cancel a client drag too.
Dominik Laskowski
2017/03/03 13:50:40
We need to sync window states to revert dragging p
reveman
2017/03/06 19:02:13
Please leave this the way it's supposed to work lo
Dominik Laskowski
2017/03/08 23:13:22
Reverted and added TODO.
| |
| 1044 event->type() == ui::ET_KEY_PRESSED && | |
| 1010 event->key_code() == ui::VKEY_ESCAPE) { | 1045 event->key_code() == ui::VKEY_ESCAPE) { |
| 1011 EndDrag(true /* revert */); | 1046 EndDrag(true /* revert */); |
| 1012 } | 1047 } |
| 1013 } | 1048 } |
| 1014 | 1049 |
| 1015 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { | 1050 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { |
| 1016 if (!resizer_) { | 1051 if (!resizer_) { |
| 1017 views::View::OnMouseEvent(event); | 1052 views::View::OnMouseEvent(event); |
| 1018 return; | 1053 return; |
| 1019 } | 1054 } |
| 1020 | 1055 |
| 1021 if (event->handled()) | 1056 if (event->handled()) |
| 1022 return; | 1057 return; |
| 1023 | 1058 |
| 1024 if ((event->flags() & | 1059 if ((event->flags() & |
| 1025 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) | 1060 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) |
| 1026 return; | 1061 return; |
| 1027 | 1062 |
| 1028 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { | 1063 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { |
| 1029 // We complete the drag instead of reverting it, as reverting it will | 1064 // We complete the drag instead of reverting it, as reverting it will |
| 1030 // result in a weird behavior when a client produces a modal dialog | 1065 // result in a weird behavior when a client produces a modal dialog |
| 1031 // while the drag is in progress. | 1066 // while the drag is in progress. |
| 1032 EndDrag(false /* revert */); | 1067 EndDrag(false /* revert */); |
| 1033 return; | 1068 return; |
| 1034 } | 1069 } |
| 1035 | 1070 |
| 1036 switch (event->type()) { | 1071 switch (event->type()) { |
| 1037 case ui::ET_MOUSE_DRAGGED: { | 1072 case ui::ET_MOUSE_DRAGGED: { |
| 1073 if (bounds_mode_ == BoundsMode::CLIENT) | |
| 1074 break; | |
| 1075 | |
| 1038 gfx::Point location(event->location()); | 1076 gfx::Point location(event->location()); |
| 1039 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), | 1077 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), |
| 1040 widget_->GetNativeWindow()->parent(), | 1078 widget_->GetNativeWindow()->parent(), |
| 1041 &location); | 1079 &location); |
| 1042 ScopedConfigure scoped_configure(this, false); | 1080 ScopedConfigure scoped_configure(this, false); |
| 1043 resizer_->Drag(location, event->flags()); | 1081 resizer_->Drag(location, event->flags()); |
| 1044 event->StopPropagation(); | 1082 event->StopPropagation(); |
| 1045 break; | 1083 break; |
| 1046 } | 1084 } |
| 1047 case ui::ET_MOUSE_RELEASED: { | 1085 case ui::ET_MOUSE_RELEASED: { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1206 // configure request has been acknowledged. | 1244 // configure request has been acknowledged. |
| 1207 pending_configs_.push_back({serial, origin_offset, resize_component}); | 1245 pending_configs_.push_back({serial, origin_offset, resize_component}); |
| 1208 LOG_IF(WARNING, pending_configs_.size() > 100) | 1246 LOG_IF(WARNING, pending_configs_.size() > 100) |
| 1209 << "Number of pending configure acks for shell surface has reached: " | 1247 << "Number of pending configure acks for shell surface has reached: " |
| 1210 << pending_configs_.size(); | 1248 << pending_configs_.size(); |
| 1211 } | 1249 } |
| 1212 | 1250 |
| 1213 void ShellSurface::AttemptToStartDrag(int component) { | 1251 void ShellSurface::AttemptToStartDrag(int component) { |
| 1214 DCHECK(widget_); | 1252 DCHECK(widget_); |
| 1215 | 1253 |
| 1216 // Cannot start another drag if one is already taking place. | |
|
reveman
2017/03/02 02:00:38
why remove this?
Dominik Laskowski
2017/03/03 13:50:40
See above.
| |
| 1217 if (resizer_) | |
| 1218 return; | |
| 1219 | |
| 1220 if (widget_->GetNativeWindow()->HasCapture()) | 1254 if (widget_->GetNativeWindow()->HasCapture()) |
| 1221 return; | 1255 return; |
| 1222 | 1256 |
| 1223 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow(); | |
| 1224 gfx::Point drag_location = | |
| 1225 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); | |
| 1226 aura::Window::ConvertPointToTarget( | |
| 1227 root_window, widget_->GetNativeWindow()->parent(), &drag_location); | |
| 1228 | |
| 1229 // Set the cursor before calling CreateWindowResizer(), as that will | 1257 // Set the cursor before calling CreateWindowResizer(), as that will |
| 1230 // eventually call LockCursor() and prevent the cursor from changing. | 1258 // eventually call LockCursor() and prevent the cursor from changing. |
| 1231 aura::client::CursorClient* cursor_client = | 1259 aura::client::CursorClient* cursor_client = aura::client::GetCursorClient( |
| 1232 aura::client::GetCursorClient(root_window); | 1260 widget_->GetNativeWindow()->GetRootWindow()); |
| 1233 DCHECK(cursor_client); | 1261 DCHECK(cursor_client); |
| 1234 | 1262 |
| 1235 switch (component) { | 1263 switch (component) { |
| 1236 case HTCAPTION: | 1264 case HTCAPTION: |
| 1237 cursor_client->SetCursor(ui::kCursorPointer); | 1265 cursor_client->SetCursor(ui::kCursorPointer); |
| 1238 break; | 1266 break; |
| 1239 case HTTOP: | 1267 case HTTOP: |
| 1240 cursor_client->SetCursor(ui::kCursorNorthResize); | 1268 cursor_client->SetCursor(ui::kCursorNorthResize); |
| 1241 break; | 1269 break; |
| 1242 case HTTOPRIGHT: | 1270 case HTTOPRIGHT: |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1259 break; | 1287 break; |
| 1260 case HTTOPLEFT: | 1288 case HTTOPLEFT: |
| 1261 cursor_client->SetCursor(ui::kCursorNorthWestResize); | 1289 cursor_client->SetCursor(ui::kCursorNorthWestResize); |
| 1262 break; | 1290 break; |
| 1263 default: | 1291 default: |
| 1264 NOTREACHED(); | 1292 NOTREACHED(); |
| 1265 break; | 1293 break; |
| 1266 } | 1294 } |
| 1267 | 1295 |
| 1268 resizer_ = ash::CreateWindowResizer( | 1296 resizer_ = ash::CreateWindowResizer( |
| 1269 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, | 1297 ash::WmWindow::Get(widget_->GetNativeWindow()), GetMouseLocation(), |
| 1270 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | 1298 component, aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 1271 if (!resizer_) | 1299 if (!resizer_) |
| 1272 return; | 1300 return; |
| 1273 | 1301 |
| 1274 // Apply pending origin offsets and resize direction before starting a new | 1302 // Apply pending origin offsets and resize direction before starting a new |
| 1275 // resize operation. These can still be pending if the client has acknowledged | 1303 // resize operation. These can still be pending if the client has acknowledged |
| 1276 // the configure request but not yet called Commit(). | 1304 // the configure request but not yet called Commit(). |
| 1277 origin_offset_ += pending_origin_offset_; | 1305 origin_offset_ += pending_origin_offset_; |
| 1278 pending_origin_offset_ = gfx::Vector2d(); | 1306 pending_origin_offset_ = gfx::Vector2d(); |
| 1279 resize_component_ = pending_resize_component_; | 1307 resize_component_ = pending_resize_component_; |
| 1280 | 1308 |
| 1281 WMHelper::GetInstance()->AddPreTargetHandler(this); | 1309 WMHelper::GetInstance()->AddPreTargetHandler(this); |
| 1282 widget_->GetNativeWindow()->SetCapture(); | 1310 widget_->GetNativeWindow()->SetCapture(); |
| 1283 | 1311 |
| 1284 // Notify client that resizing state has changed. | 1312 // Notify client that resizing state has changed. |
| 1285 if (IsResizing()) | 1313 if (IsResizing()) |
| 1286 Configure(); | 1314 Configure(); |
| 1287 } | 1315 } |
| 1288 | 1316 |
| 1317 void ShellSurface::AttemptToStartClientDrag() { | |
| 1318 DCHECK(widget_); | |
| 1319 | |
| 1320 if (surface_->window()->HasCapture()) | |
| 1321 return; | |
| 1322 | |
| 1323 ash::wm::WindowState* const window_state = | |
| 1324 ash::wm::GetWindowState(widget_->GetNativeWindow()); | |
| 1325 | |
| 1326 DCHECK(!window_state->drag_details()); | |
| 1327 window_state->CreateDragDetails(GetMouseLocation(), HTCAPTION, | |
| 1328 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | |
| 1329 | |
| 1330 // The resizer renders phantom windows, but does not control window movement. | |
| 1331 resizer_.reset(ash::DragWindowResizer::Create( | |
| 1332 new CustomWindowResizer(window_state), window_state)); | |
| 1333 | |
| 1334 WMHelper::GetInstance()->AddPreTargetHandler(this); | |
| 1335 surface_->window()->SetCapture(); | |
| 1336 } | |
| 1337 | |
| 1289 void ShellSurface::EndDrag(bool revert) { | 1338 void ShellSurface::EndDrag(bool revert) { |
| 1290 DCHECK(widget_); | 1339 DCHECK(widget_); |
| 1291 DCHECK(resizer_); | 1340 DCHECK(resizer_); |
| 1292 | 1341 |
| 1293 bool was_resizing = IsResizing(); | 1342 switch (bounds_mode_) { |
| 1343 case BoundsMode::SHELL: { | |
| 1344 bool was_resizing = IsResizing(); | |
| 1294 | 1345 |
| 1346 EndDrag(widget_->GetNativeWindow(), revert); | |
| 1347 | |
| 1348 // Notify client that resizing state has changed. | |
| 1349 if (was_resizing) | |
| 1350 Configure(); | |
| 1351 | |
| 1352 UpdateWidgetBounds(); | |
| 1353 return; | |
| 1354 } | |
| 1355 case BoundsMode::CLIENT: | |
| 1356 EndDrag(surface_->window(), revert); | |
|
reveman
2017/03/02 02:00:38
why are we using surface_->window() here instead o
Dominik Laskowski
2017/03/03 13:50:40
The surface window needs to have capture, because
reveman
2017/03/06 19:02:13
The general idea of doing a capture on the surface
Dominik Laskowski
2017/03/08 23:13:22
Filed crbug.com/699746 and added TODOs.
| |
| 1357 return; | |
| 1358 case BoundsMode::FIXED: | |
| 1359 break; | |
| 1360 } | |
| 1361 | |
| 1362 NOTREACHED(); | |
| 1363 } | |
| 1364 | |
| 1365 void ShellSurface::EndDrag(aura::Window* window, bool revert) { | |
| 1295 if (revert) | 1366 if (revert) |
| 1296 resizer_->RevertDrag(); | 1367 resizer_->RevertDrag(); |
| 1297 else | 1368 else |
| 1298 resizer_->CompleteDrag(); | 1369 resizer_->CompleteDrag(); |
| 1299 | 1370 |
| 1300 WMHelper::GetInstance()->RemovePreTargetHandler(this); | 1371 WMHelper::GetInstance()->RemovePreTargetHandler(this); |
| 1301 widget_->GetNativeWindow()->ReleaseCapture(); | 1372 window->ReleaseCapture(); |
| 1302 resizer_.reset(); | 1373 resizer_.reset(); |
| 1303 | |
|
reveman
2017/03/02 02:00:38
why not keep this the way it is?
Dominik Laskowski
2017/03/03 13:50:40
Refactored to be consistent with AttemptToStartDra
| |
| 1304 // Notify client that resizing state has changed. | |
| 1305 if (was_resizing) | |
| 1306 Configure(); | |
| 1307 | |
| 1308 UpdateWidgetBounds(); | |
| 1309 } | 1374 } |
| 1310 | 1375 |
| 1311 bool ShellSurface::IsResizing() const { | 1376 bool ShellSurface::IsResizing() const { |
| 1312 ash::wm::WindowState* window_state = | 1377 ash::wm::WindowState* window_state = |
| 1313 ash::wm::GetWindowState(widget_->GetNativeWindow()); | 1378 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1314 if (!window_state->is_dragged()) | 1379 if (!window_state->is_dragged()) |
| 1315 return false; | 1380 return false; |
| 1316 | 1381 |
| 1317 return window_state->drag_details()->bounds_change & | 1382 return window_state->drag_details()->bounds_change & |
| 1318 ash::WindowResizer::kBoundsChange_Resizes; | 1383 ash::WindowResizer::kBoundsChange_Resizes; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1404 new_widget_bounds.set_origin( | 1469 new_widget_bounds.set_origin( |
| 1405 widget_->GetWindowBoundsInScreen().origin()); | 1470 widget_->GetWindowBoundsInScreen().origin()); |
| 1406 } | 1471 } |
| 1407 break; | 1472 break; |
| 1408 } | 1473 } |
| 1409 | 1474 |
| 1410 // Set |ignore_window_bounds_changes_| as this change to window bounds | 1475 // Set |ignore_window_bounds_changes_| as this change to window bounds |
| 1411 // should not result in a configure request. | 1476 // should not result in a configure request. |
| 1412 DCHECK(!ignore_window_bounds_changes_); | 1477 DCHECK(!ignore_window_bounds_changes_); |
| 1413 ignore_window_bounds_changes_ = true; | 1478 ignore_window_bounds_changes_ = true; |
| 1414 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) | 1479 const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen(); |
| 1415 widget_->SetBounds(new_widget_bounds); | 1480 if (widget_bounds != new_widget_bounds) { |
| 1481 if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) { | |
| 1482 widget_->SetBounds(new_widget_bounds); | |
| 1483 UpdateSurfaceBounds(); | |
| 1484 } else { | |
| 1485 // TODO(domlaskowski): Synchronize window state transitions with the | |
| 1486 // client, and abort client-side dragging on transition to fullscreen. | |
| 1487 LOG_IF(ERROR, widget_bounds.size() != new_widget_bounds.size()) | |
| 1488 << "Window size changed during client-driven drag"; | |
| 1489 | |
| 1490 // Convert from screen to display coordinates. | |
| 1491 gfx::Point origin = new_widget_bounds.origin(); | |
| 1492 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin); | |
| 1493 new_widget_bounds.set_origin(origin); | |
| 1494 | |
| 1495 // Move the window relative to the current display. | |
| 1496 widget_->GetNativeWindow()->SetBounds(new_widget_bounds); | |
| 1497 UpdateSurfaceBounds(); | |
| 1498 | |
| 1499 // Render phantom windows when beyond the current display. | |
| 1500 resizer_->Drag(GetMouseLocation(), 0); | |
| 1501 } | |
| 1502 } | |
| 1503 | |
| 1416 ignore_window_bounds_changes_ = false; | 1504 ignore_window_bounds_changes_ = false; |
| 1417 } | 1505 } |
| 1418 | 1506 |
| 1419 void ShellSurface::UpdateSurfaceBounds() { | 1507 void ShellSurface::UpdateSurfaceBounds() { |
| 1420 gfx::Rect client_view_bounds = | 1508 gfx::Rect client_view_bounds = |
| 1421 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | 1509 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1422 | 1510 |
| 1423 surface_->window()->SetBounds( | 1511 surface_->window()->SetBounds( |
| 1424 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | 1512 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1425 surface_->window()->layer()->size())); | 1513 surface_->window()->layer()->size())); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1569 // Surfaces that can't be activated are usually menus and tooltips. Use a | 1657 // Surfaces that can't be activated are usually menus and tooltips. Use a |
| 1570 // small style shadow for them. | 1658 // small style shadow for them. |
| 1571 if (!activatable_) | 1659 if (!activatable_) |
| 1572 shadow->SetElevation(wm::ShadowElevation::SMALL); | 1660 shadow->SetElevation(wm::ShadowElevation::SMALL); |
| 1573 // We don't have rounded corners unless frame is enabled. | 1661 // We don't have rounded corners unless frame is enabled. |
| 1574 if (!frame_enabled_) | 1662 if (!frame_enabled_) |
| 1575 shadow->SetRoundedCornerRadius(0); | 1663 shadow->SetRoundedCornerRadius(0); |
| 1576 } | 1664 } |
| 1577 } | 1665 } |
| 1578 | 1666 |
| 1667 gfx::Point ShellSurface::GetMouseLocation() const { | |
| 1668 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow(); | |
| 1669 gfx::Point location = | |
| 1670 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); | |
| 1671 aura::Window::ConvertPointToTarget( | |
| 1672 root_window, widget_->GetNativeWindow()->parent(), &location); | |
| 1673 return location; | |
| 1674 } | |
| 1675 | |
| 1579 } // namespace exo | 1676 } // namespace exo |
| OLD | NEW |