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" |
| 25 #include "ui/aura/client/cursor_client.h" | 27 #include "ui/aura/client/cursor_client.h" |
| 26 #include "ui/aura/window.h" | 28 #include "ui/aura/window.h" |
| 27 #include "ui/aura/window_event_dispatcher.h" | 29 #include "ui/aura/window_event_dispatcher.h" |
| 28 #include "ui/aura/window_targeter.h" | 30 #include "ui/aura/window_targeter.h" |
| 29 #include "ui/aura/window_tree_host.h" | 31 #include "ui/aura/window_tree_host.h" |
| 30 #include "ui/base/accelerators/accelerator.h" | 32 #include "ui/base/accelerators/accelerator.h" |
| 31 #include "ui/base/class_property.h" | 33 #include "ui/base/class_property.h" |
| 34 #include "ui/display/display.h" | |
| 35 #include "ui/display/screen.h" | |
| 32 #include "ui/gfx/path.h" | 36 #include "ui/gfx/path.h" |
| 33 #include "ui/views/widget/widget.h" | 37 #include "ui/views/widget/widget.h" |
| 34 #include "ui/wm/core/coordinate_conversion.h" | 38 #include "ui/wm/core/coordinate_conversion.h" |
| 35 #include "ui/wm/core/shadow.h" | 39 #include "ui/wm/core/shadow.h" |
| 36 #include "ui/wm/core/shadow_controller.h" | 40 #include "ui/wm/core/shadow_controller.h" |
| 37 #include "ui/wm/core/shadow_types.h" | 41 #include "ui/wm/core/shadow_types.h" |
| 38 #include "ui/wm/core/window_animations.h" | 42 #include "ui/wm/core/window_animations.h" |
| 39 #include "ui/wm/core/window_util.h" | 43 #include "ui/wm/core/window_util.h" |
| 40 | 44 |
| 41 #if defined(OS_CHROMEOS) | 45 #if defined(OS_CHROMEOS) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 } | 140 } |
| 137 return aura::WindowTargeter::FindTargetForEvent(root, event); | 141 return aura::WindowTargeter::FindTargetForEvent(root, event); |
| 138 } | 142 } |
| 139 | 143 |
| 140 private: | 144 private: |
| 141 views::Widget* const widget_; | 145 views::Widget* const widget_; |
| 142 | 146 |
| 143 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); | 147 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); |
| 144 }; | 148 }; |
| 145 | 149 |
| 150 // Minimal WindowResizer that unlike DefaultWindowResizer does not handle | |
| 151 // dragging and resizing windows. | |
| 152 class CustomWindowResizer : public ash::WindowResizer { | |
| 153 public: | |
| 154 explicit CustomWindowResizer(ash::wm::WindowState* window_state) | |
| 155 : WindowResizer(window_state), shell_(GetTarget()->GetShell()) { | |
| 156 shell_->LockCursor(); | |
| 157 } | |
| 158 ~CustomWindowResizer() override { shell_->UnlockCursor(); } | |
| 159 | |
| 160 // Overridden from ash::WindowResizer: | |
| 161 void Drag(const gfx::Point& location, int event_flags) override {} | |
| 162 void CompleteDrag() override {} | |
| 163 void RevertDrag() override {} | |
| 164 | |
| 165 private: | |
| 166 ash::WmShell* const shell_; | |
| 167 | |
| 168 DISALLOW_COPY_AND_ASSIGN(CustomWindowResizer); | |
| 169 }; | |
| 170 | |
| 146 class ShellSurfaceWidget : public views::Widget { | 171 class ShellSurfaceWidget : public views::Widget { |
| 147 public: | 172 public: |
| 148 explicit ShellSurfaceWidget(ShellSurface* shell_surface) | 173 explicit ShellSurfaceWidget(ShellSurface* shell_surface) |
| 149 : shell_surface_(shell_surface) {} | 174 : shell_surface_(shell_surface) {} |
| 150 | 175 |
| 151 // Overridden from views::Widget | 176 // Overridden from views::Widget |
| 152 void Close() override { shell_surface_->Close(); } | 177 void Close() override { shell_surface_->Close(); } |
| 153 void OnKeyEvent(ui::KeyEvent* event) override { | 178 void OnKeyEvent(ui::KeyEvent* event) override { |
| 154 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key | 179 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key |
| 155 // to escape pinned mode. | 180 // to escape pinned mode. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 292 ShellSurface* parent, | 317 ShellSurface* parent, |
| 293 BoundsMode bounds_mode, | 318 BoundsMode bounds_mode, |
| 294 const gfx::Point& origin, | 319 const gfx::Point& origin, |
| 295 bool activatable, | 320 bool activatable, |
| 296 bool can_minimize, | 321 bool can_minimize, |
| 297 int container) | 322 int container) |
| 298 : widget_(nullptr), | 323 : widget_(nullptr), |
| 299 surface_(surface), | 324 surface_(surface), |
| 300 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), | 325 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), |
| 301 bounds_mode_(bounds_mode), | 326 bounds_mode_(bounds_mode), |
| 327 primary_display_id_( | |
| 328 display::Screen::GetScreen()->GetPrimaryDisplay().id()), | |
| 302 origin_(origin), | 329 origin_(origin), |
| 303 activatable_(activatable), | 330 activatable_(activatable), |
| 304 can_minimize_(can_minimize), | 331 can_minimize_(can_minimize), |
| 305 container_(container) { | 332 container_(container) { |
| 306 WMHelper::GetInstance()->AddActivationObserver(this); | 333 WMHelper::GetInstance()->AddActivationObserver(this); |
| 334 WMHelper::GetInstance()->AddDisplayConfigurationObserver(this); | |
| 307 surface_->SetSurfaceDelegate(this); | 335 surface_->SetSurfaceDelegate(this); |
| 308 surface_->AddSurfaceObserver(this); | 336 surface_->AddSurfaceObserver(this); |
| 309 surface_->window()->Show(); | 337 surface_->window()->Show(); |
| 310 set_owned_by_client(); | 338 set_owned_by_client(); |
| 311 if (parent_) | 339 if (parent_) |
| 312 parent_->AddObserver(this); | 340 parent_->AddObserver(this); |
| 313 } | 341 } |
| 314 | 342 |
| 315 ShellSurface::ShellSurface(Surface* surface) | 343 ShellSurface::ShellSurface(Surface* surface) |
| 316 : ShellSurface(surface, | 344 : ShellSurface(surface, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 329 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); | 357 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); |
| 330 widget_->GetNativeWindow()->RemoveObserver(this); | 358 widget_->GetNativeWindow()->RemoveObserver(this); |
| 331 // Remove transient children so they are not automatically destroyed. | 359 // Remove transient children so they are not automatically destroyed. |
| 332 for (auto* child : wm::GetTransientChildren(widget_->GetNativeWindow())) | 360 for (auto* child : wm::GetTransientChildren(widget_->GetNativeWindow())) |
| 333 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); | 361 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); |
| 334 if (widget_->IsVisible()) | 362 if (widget_->IsVisible()) |
| 335 widget_->Hide(); | 363 widget_->Hide(); |
| 336 widget_->CloseNow(); | 364 widget_->CloseNow(); |
| 337 } | 365 } |
| 338 WMHelper::GetInstance()->RemoveActivationObserver(this); | 366 WMHelper::GetInstance()->RemoveActivationObserver(this); |
| 367 WMHelper::GetInstance()->RemoveDisplayConfigurationObserver(this); | |
| 339 if (parent_) | 368 if (parent_) |
| 340 parent_->RemoveObserver(this); | 369 parent_->RemoveObserver(this); |
| 341 if (surface_) { | 370 if (surface_) { |
| 342 if (scale_ != 1.0) | 371 if (scale_ != 1.0) |
| 343 surface_->window()->SetTransform(gfx::Transform()); | 372 surface_->window()->SetTransform(gfx::Transform()); |
| 344 surface_->SetSurfaceDelegate(nullptr); | 373 surface_->SetSurfaceDelegate(nullptr); |
| 345 surface_->RemoveSurfaceObserver(this); | 374 surface_->RemoveSurfaceObserver(this); |
| 346 } | 375 } |
| 347 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); | 376 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); |
| 348 } | 377 } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 } | 564 } |
| 536 | 565 |
| 537 void ShellSurface::Move() { | 566 void ShellSurface::Move() { |
| 538 TRACE_EVENT0("exo", "ShellSurface::Move"); | 567 TRACE_EVENT0("exo", "ShellSurface::Move"); |
| 539 | 568 |
| 540 if (!widget_) | 569 if (!widget_) |
| 541 return; | 570 return; |
| 542 | 571 |
| 543 switch (bounds_mode_) { | 572 switch (bounds_mode_) { |
| 544 case BoundsMode::SHELL: | 573 case BoundsMode::SHELL: |
| 574 case BoundsMode::CLIENT: | |
| 545 AttemptToStartDrag(HTCAPTION); | 575 AttemptToStartDrag(HTCAPTION); |
| 546 return; | 576 return; |
| 547 case BoundsMode::CLIENT: | |
| 548 case BoundsMode::FIXED: | 577 case BoundsMode::FIXED: |
| 549 return; | 578 return; |
| 550 } | 579 } |
| 551 | 580 |
| 552 NOTREACHED(); | 581 NOTREACHED(); |
| 553 } | 582 } |
| 554 | 583 |
| 555 void ShellSurface::Resize(int component) { | 584 void ShellSurface::Resize(int component) { |
| 556 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); | 585 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); |
| 557 | 586 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 | 666 |
| 638 void ShellSurface::SetTopInset(int height) { | 667 void ShellSurface::SetTopInset(int height) { |
| 639 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); | 668 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); |
| 640 | 669 |
| 641 pending_top_inset_height_ = height; | 670 pending_top_inset_height_ = height; |
| 642 } | 671 } |
| 643 | 672 |
| 644 void ShellSurface::SetOrigin(const gfx::Point& origin) { | 673 void ShellSurface::SetOrigin(const gfx::Point& origin) { |
| 645 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); | 674 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); |
| 646 | 675 |
| 647 if (origin == origin_) | |
| 648 return; | |
| 649 | |
| 650 if (bounds_mode_ != BoundsMode::CLIENT) { | |
| 651 origin_ = origin; | |
| 652 return; | |
| 653 } | |
| 654 | |
| 655 // If the origin changed, give the client a chance to adjust window positions | |
| 656 // before switching to the new coordinate system. Retain the old origin by | |
| 657 // reverting the origin delta until the next configure is acknowledged. | |
| 658 gfx::Vector2d delta = origin - origin_; | |
| 659 origin_offset_ -= delta; | |
| 660 pending_origin_offset_accumulator_ += delta; | |
| 661 | |
| 662 origin_ = origin; | 676 origin_ = origin; |
| 663 | |
| 664 if (widget_) { | |
| 665 UpdateWidgetBounds(); | |
| 666 UpdateShadow(); | |
| 667 } | |
| 668 | |
| 669 Configure(); | |
| 670 } | 677 } |
| 671 | 678 |
| 672 void ShellSurface::SetActivatable(bool activatable) { | 679 void ShellSurface::SetActivatable(bool activatable) { |
| 673 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", | 680 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", |
| 674 activatable); | 681 activatable); |
| 675 | 682 |
| 676 activatable_ = activatable; | 683 activatable_ = activatable; |
| 677 } | 684 } |
| 678 | 685 |
| 679 void ShellSurface::SetContainer(int container) { | 686 void ShellSurface::SetContainer(int container) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 906 ash::wm::WindowStateType old_type) { | 913 ash::wm::WindowStateType old_type) { |
| 907 ash::wm::WindowStateType new_type = window_state->GetStateType(); | 914 ash::wm::WindowStateType new_type = window_state->GetStateType(); |
| 908 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || | 915 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || |
| 909 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { | 916 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { |
| 910 // When transitioning in/out of maximized or fullscreen mode we need to | 917 // When transitioning in/out of maximized or fullscreen mode we need to |
| 911 // make sure we have a configure callback before we allow the default | 918 // make sure we have a configure callback before we allow the default |
| 912 // cross-fade animations. The configure callback provides a mechanism for | 919 // cross-fade animations. The configure callback provides a mechanism for |
| 913 // the client to inform us that a frame has taken the state change into | 920 // the client to inform us that a frame has taken the state change into |
| 914 // account and without this cross-fade animations are unreliable. | 921 // account and without this cross-fade animations are unreliable. |
| 915 | 922 |
| 916 // TODO(domlaskowski): For shell surfaces whose bounds are controlled by the | 923 // TODO(domlaskowski): For BoundsMode::CLIENT, the configure callback does |
| 917 // client, the configure callback does not yet support window state changes. | 924 // not yet support window state changes. See crbug.com/699746. |
| 918 if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT) | 925 if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT) |
| 919 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); | 926 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); |
| 920 } | 927 } |
| 921 } | 928 } |
| 922 | 929 |
| 923 void ShellSurface::OnPostWindowStateTypeChange( | 930 void ShellSurface::OnPostWindowStateTypeChange( |
| 924 ash::wm::WindowState* window_state, | 931 ash::wm::WindowState* window_state, |
| 925 ash::wm::WindowStateType old_type) { | 932 ash::wm::WindowStateType old_type) { |
| 926 ash::wm::WindowStateType new_type = window_state->GetStateType(); | 933 ash::wm::WindowStateType new_type = window_state->GetStateType(); |
| 927 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || | 934 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 940 // Re-enable animations if they were disabled in pre state change handler. | 947 // Re-enable animations if they were disabled in pre state change handler. |
| 941 scoped_animations_disabled_.reset(); | 948 scoped_animations_disabled_.reset(); |
| 942 } | 949 } |
| 943 | 950 |
| 944 //////////////////////////////////////////////////////////////////////////////// | 951 //////////////////////////////////////////////////////////////////////////////// |
| 945 // aura::WindowObserver overrides: | 952 // aura::WindowObserver overrides: |
| 946 | 953 |
| 947 void ShellSurface::OnWindowBoundsChanged(aura::Window* window, | 954 void ShellSurface::OnWindowBoundsChanged(aura::Window* window, |
| 948 const gfx::Rect& old_bounds, | 955 const gfx::Rect& old_bounds, |
| 949 const gfx::Rect& new_bounds) { | 956 const gfx::Rect& new_bounds) { |
| 950 // TODO(domlaskowski): For shell surfaces whose bounds are controlled by the | 957 // TODO(domlaskowski): For BoundsMode::CLIENT, the configure callback does not |
| 951 // client, the configure callback does not yet support resizing. | 958 // yet support resizing. See crbug.com/699746. |
| 952 if (bounds_mode_ == BoundsMode::CLIENT) | 959 if (bounds_mode_ == BoundsMode::CLIENT) |
| 953 return; | 960 return; |
| 954 | 961 |
| 955 if (!widget_ || !surface_ || ignore_window_bounds_changes_) | 962 if (!widget_ || !surface_ || ignore_window_bounds_changes_) |
| 956 return; | 963 return; |
| 957 | 964 |
| 958 if (window == widget_->GetNativeWindow()) { | 965 if (window == widget_->GetNativeWindow()) { |
| 959 if (new_bounds.size() == old_bounds.size()) | 966 if (new_bounds.size() == old_bounds.size()) |
| 960 return; | 967 return; |
| 961 | 968 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 } | 1013 } |
| 1007 | 1014 |
| 1008 //////////////////////////////////////////////////////////////////////////////// | 1015 //////////////////////////////////////////////////////////////////////////////// |
| 1009 // WMHelper::AccessibilityObserver overrides: | 1016 // WMHelper::AccessibilityObserver overrides: |
| 1010 | 1017 |
| 1011 void ShellSurface::OnAccessibilityModeChanged() { | 1018 void ShellSurface::OnAccessibilityModeChanged() { |
| 1012 UpdateShadow(); | 1019 UpdateShadow(); |
| 1013 } | 1020 } |
| 1014 | 1021 |
| 1015 //////////////////////////////////////////////////////////////////////////////// | 1022 //////////////////////////////////////////////////////////////////////////////// |
| 1023 // WMHelper::DisplayConfigurationObserver overrides: | |
| 1024 | |
| 1025 void ShellSurface::OnDisplayConfigurationChanged() { | |
| 1026 if (bounds_mode_ != BoundsMode::CLIENT) | |
| 1027 return; | |
| 1028 | |
| 1029 const display::Screen* screen = display::Screen::GetScreen(); | |
| 1030 int64_t primary_display_id = screen->GetPrimaryDisplay().id(); | |
| 1031 if (primary_display_id == primary_display_id_) | |
| 1032 return; | |
| 1033 | |
| 1034 display::Display primary_display; | |
|
reveman
2017/03/15 21:26:14
nit: maybe s/primary_display/old_primary_display/
Dominik Laskowski
2017/03/15 21:43:56
Done.
| |
| 1035 if (screen->GetDisplayWithDisplayId(primary_display_id_, &primary_display)) { | |
| 1036 // Give the client a chance to adjust window positions before switching to | |
| 1037 // the new coordinate system. Retain the old origin by reverting the origin | |
| 1038 // delta until the next configure is acknowledged. | |
| 1039 gfx::Vector2d delta = gfx::Point() - primary_display.bounds().origin(); | |
| 1040 origin_offset_ -= delta; | |
| 1041 pending_origin_offset_accumulator_ += delta; | |
| 1042 | |
| 1043 if (widget_) { | |
| 1044 UpdateWidgetBounds(); | |
| 1045 UpdateShadow(); | |
| 1046 } | |
| 1047 | |
| 1048 Configure(); | |
| 1049 } | |
| 1050 | |
| 1051 primary_display_id_ = primary_display_id; | |
| 1052 } | |
| 1053 | |
| 1054 //////////////////////////////////////////////////////////////////////////////// | |
| 1016 // ui::EventHandler overrides: | 1055 // ui::EventHandler overrides: |
| 1017 | 1056 |
| 1018 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { | 1057 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { |
| 1019 if (!resizer_) { | 1058 if (!resizer_) { |
| 1020 views::View::OnKeyEvent(event); | 1059 views::View::OnKeyEvent(event); |
| 1021 return; | 1060 return; |
| 1022 } | 1061 } |
| 1023 | 1062 |
| 1063 // TODO(domlaskowski): For BoundsMode::CLIENT, synchronize the revert with the | |
| 1064 // client, instead of having the client destroy the window on VKEY_ESCAPE. See | |
| 1065 // crbug.com/699746. | |
| 1024 if (event->type() == ui::ET_KEY_PRESSED && | 1066 if (event->type() == ui::ET_KEY_PRESSED && |
| 1025 event->key_code() == ui::VKEY_ESCAPE) { | 1067 event->key_code() == ui::VKEY_ESCAPE) { |
| 1026 EndDrag(true /* revert */); | 1068 EndDrag(true /* revert */); |
| 1027 } | 1069 } |
| 1028 } | 1070 } |
| 1029 | 1071 |
| 1030 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { | 1072 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { |
| 1031 if (!resizer_) { | 1073 if (!resizer_) { |
| 1032 views::View::OnMouseEvent(event); | 1074 views::View::OnMouseEvent(event); |
| 1033 return; | 1075 return; |
| 1034 } | 1076 } |
| 1035 | 1077 |
| 1036 if (event->handled()) | 1078 if (event->handled()) |
| 1037 return; | 1079 return; |
| 1038 | 1080 |
| 1039 if ((event->flags() & | 1081 if ((event->flags() & |
| 1040 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) | 1082 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) |
| 1041 return; | 1083 return; |
| 1042 | 1084 |
| 1043 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { | 1085 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { |
| 1044 // We complete the drag instead of reverting it, as reverting it will | 1086 // We complete the drag instead of reverting it, as reverting it will |
| 1045 // result in a weird behavior when a client produces a modal dialog | 1087 // result in a weird behavior when a client produces a modal dialog |
| 1046 // while the drag is in progress. | 1088 // while the drag is in progress. |
| 1047 EndDrag(false /* revert */); | 1089 EndDrag(false /* revert */); |
| 1048 return; | 1090 return; |
| 1049 } | 1091 } |
| 1050 | 1092 |
| 1051 switch (event->type()) { | 1093 switch (event->type()) { |
| 1052 case ui::ET_MOUSE_DRAGGED: { | 1094 case ui::ET_MOUSE_DRAGGED: { |
| 1095 if (bounds_mode_ == BoundsMode::CLIENT) | |
| 1096 break; | |
| 1097 | |
| 1053 gfx::Point location(event->location()); | 1098 gfx::Point location(event->location()); |
| 1054 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), | 1099 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), |
| 1055 widget_->GetNativeWindow()->parent(), | 1100 widget_->GetNativeWindow()->parent(), |
| 1056 &location); | 1101 &location); |
| 1057 ScopedConfigure scoped_configure(this, false); | 1102 ScopedConfigure scoped_configure(this, false); |
| 1058 resizer_->Drag(location, event->flags()); | 1103 resizer_->Drag(location, event->flags()); |
| 1059 event->StopPropagation(); | 1104 event->StopPropagation(); |
| 1060 break; | 1105 break; |
| 1061 } | 1106 } |
| 1062 case ui::ET_MOUSE_RELEASED: { | 1107 case ui::ET_MOUSE_RELEASED: { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1196 resize_component = window_state->drag_details()->window_component; | 1241 resize_component = window_state->drag_details()->window_component; |
| 1197 } | 1242 } |
| 1198 | 1243 |
| 1199 uint32_t serial = 0; | 1244 uint32_t serial = 0; |
| 1200 if (!configure_callback_.is_null()) { | 1245 if (!configure_callback_.is_null()) { |
| 1201 if (widget_) { | 1246 if (widget_) { |
| 1202 const views::NonClientView* non_client_view = widget_->non_client_view(); | 1247 const views::NonClientView* non_client_view = widget_->non_client_view(); |
| 1203 serial = configure_callback_.Run( | 1248 serial = configure_callback_.Run( |
| 1204 non_client_view->frame_view()->GetBoundsForClientView().size(), | 1249 non_client_view->frame_view()->GetBoundsForClientView().size(), |
| 1205 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), | 1250 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), |
| 1206 IsResizing(), widget_->IsActive(), origin_); | 1251 IsResizing(), widget_->IsActive(), origin_offset); |
| 1207 } else { | 1252 } else { |
| 1208 serial = configure_callback_.Run(gfx::Size(), | 1253 serial = configure_callback_.Run(gfx::Size(), |
| 1209 ash::wm::WINDOW_STATE_TYPE_NORMAL, false, | 1254 ash::wm::WINDOW_STATE_TYPE_NORMAL, false, |
| 1210 false, origin_); | 1255 false, origin_offset); |
| 1211 } | 1256 } |
| 1212 } | 1257 } |
| 1213 | 1258 |
| 1214 if (!serial) { | 1259 if (!serial) { |
| 1215 pending_origin_offset_ += origin_offset; | 1260 pending_origin_offset_ += origin_offset; |
| 1216 pending_resize_component_ = resize_component; | 1261 pending_resize_component_ = resize_component; |
| 1217 return; | 1262 return; |
| 1218 } | 1263 } |
| 1219 | 1264 |
| 1220 // Apply origin offset and resize component at the first Commit() after this | 1265 // Apply origin offset and resize component at the first Commit() after this |
| 1221 // configure request has been acknowledged. | 1266 // configure request has been acknowledged. |
| 1222 pending_configs_.push_back({serial, origin_offset, resize_component}); | 1267 pending_configs_.push_back({serial, origin_offset, resize_component}); |
| 1223 LOG_IF(WARNING, pending_configs_.size() > 100) | 1268 LOG_IF(WARNING, pending_configs_.size() > 100) |
| 1224 << "Number of pending configure acks for shell surface has reached: " | 1269 << "Number of pending configure acks for shell surface has reached: " |
| 1225 << pending_configs_.size(); | 1270 << pending_configs_.size(); |
| 1226 } | 1271 } |
| 1227 | 1272 |
| 1273 aura::Window* ShellSurface::GetDragWindow() const { | |
| 1274 if (bounds_mode_ == BoundsMode::SHELL) | |
|
reveman
2017/03/15 21:26:14
nit: switch statement here without a "default" cas
Dominik Laskowski
2017/03/15 21:43:56
Done.
| |
| 1275 return widget_->GetNativeWindow(); | |
| 1276 | |
| 1277 if (bounds_mode_ == BoundsMode::CLIENT && surface_) | |
| 1278 return surface_->window(); | |
| 1279 | |
| 1280 return nullptr; | |
| 1281 } | |
| 1282 | |
| 1228 void ShellSurface::AttemptToStartDrag(int component) { | 1283 void ShellSurface::AttemptToStartDrag(int component) { |
| 1229 DCHECK(widget_); | 1284 DCHECK(widget_); |
| 1230 | 1285 |
| 1231 // Cannot start another drag if one is already taking place. | 1286 // Cannot start another drag if one is already taking place. |
| 1232 if (resizer_) | 1287 if (resizer_) |
| 1233 return; | 1288 return; |
| 1234 | 1289 |
| 1235 if (widget_->GetNativeWindow()->HasCapture()) | 1290 aura::Window* window = GetDragWindow(); |
| 1291 if (!window || window->HasCapture()) | |
| 1236 return; | 1292 return; |
| 1237 | 1293 |
| 1238 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow(); | 1294 if (bounds_mode_ == BoundsMode::SHELL) { |
| 1239 gfx::Point drag_location = | 1295 // Set the cursor before calling CreateWindowResizer(), as that will |
| 1240 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); | 1296 // eventually call LockCursor() and prevent the cursor from changing. |
| 1241 aura::Window::ConvertPointToTarget( | 1297 aura::client::CursorClient* cursor_client = |
| 1242 root_window, widget_->GetNativeWindow()->parent(), &drag_location); | 1298 aura::client::GetCursorClient(window->GetRootWindow()); |
| 1299 DCHECK(cursor_client); | |
| 1243 | 1300 |
| 1244 // Set the cursor before calling CreateWindowResizer(), as that will | 1301 switch (component) { |
| 1245 // eventually call LockCursor() and prevent the cursor from changing. | 1302 case HTCAPTION: |
| 1246 aura::client::CursorClient* cursor_client = | 1303 cursor_client->SetCursor(ui::kCursorPointer); |
| 1247 aura::client::GetCursorClient(root_window); | 1304 break; |
| 1248 DCHECK(cursor_client); | 1305 case HTTOP: |
| 1306 cursor_client->SetCursor(ui::kCursorNorthResize); | |
| 1307 break; | |
| 1308 case HTTOPRIGHT: | |
| 1309 cursor_client->SetCursor(ui::kCursorNorthEastResize); | |
| 1310 break; | |
| 1311 case HTRIGHT: | |
| 1312 cursor_client->SetCursor(ui::kCursorEastResize); | |
| 1313 break; | |
| 1314 case HTBOTTOMRIGHT: | |
| 1315 cursor_client->SetCursor(ui::kCursorSouthEastResize); | |
| 1316 break; | |
| 1317 case HTBOTTOM: | |
| 1318 cursor_client->SetCursor(ui::kCursorSouthResize); | |
| 1319 break; | |
| 1320 case HTBOTTOMLEFT: | |
| 1321 cursor_client->SetCursor(ui::kCursorSouthWestResize); | |
| 1322 break; | |
| 1323 case HTLEFT: | |
| 1324 cursor_client->SetCursor(ui::kCursorWestResize); | |
| 1325 break; | |
| 1326 case HTTOPLEFT: | |
| 1327 cursor_client->SetCursor(ui::kCursorNorthWestResize); | |
| 1328 break; | |
| 1329 default: | |
| 1330 NOTREACHED(); | |
| 1331 break; | |
| 1332 } | |
| 1249 | 1333 |
| 1250 switch (component) { | 1334 resizer_ = ash::CreateWindowResizer(ash::WmWindow::Get(window), |
| 1251 case HTCAPTION: | 1335 GetMouseLocation(), component, |
| 1252 cursor_client->SetCursor(ui::kCursorPointer); | 1336 aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 1253 break; | 1337 if (!resizer_) |
| 1254 case HTTOP: | 1338 return; |
| 1255 cursor_client->SetCursor(ui::kCursorNorthResize); | 1339 |
| 1256 break; | 1340 // Apply pending origin offsets and resize direction before starting a |
| 1257 case HTTOPRIGHT: | 1341 // new resize operation. These can still be pending if the client has |
| 1258 cursor_client->SetCursor(ui::kCursorNorthEastResize); | 1342 // acknowledged the configure request but not yet called Commit(). |
| 1259 break; | 1343 origin_offset_ += pending_origin_offset_; |
| 1260 case HTRIGHT: | 1344 pending_origin_offset_ = gfx::Vector2d(); |
| 1261 cursor_client->SetCursor(ui::kCursorEastResize); | 1345 resize_component_ = pending_resize_component_; |
| 1262 break; | 1346 } else { |
| 1263 case HTBOTTOMRIGHT: | 1347 DCHECK(bounds_mode_ == BoundsMode::CLIENT); |
| 1264 cursor_client->SetCursor(ui::kCursorSouthEastResize); | 1348 |
| 1265 break; | 1349 ash::wm::WindowState* window_state = |
| 1266 case HTBOTTOM: | 1350 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1267 cursor_client->SetCursor(ui::kCursorSouthResize); | 1351 DCHECK(!window_state->drag_details()); |
| 1268 break; | 1352 DCHECK(component == HTCAPTION); |
| 1269 case HTBOTTOMLEFT: | 1353 window_state->CreateDragDetails(GetMouseLocation(), component, |
| 1270 cursor_client->SetCursor(ui::kCursorSouthWestResize); | 1354 aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 1271 break; | 1355 |
| 1272 case HTLEFT: | 1356 // Chained with a CustomWindowResizer, DragWindowResizer does not handle |
| 1273 cursor_client->SetCursor(ui::kCursorWestResize); | 1357 // dragging. It only renders phantom windows and moves the window to the |
| 1274 break; | 1358 // target root window when dragging ends. |
| 1275 case HTTOPLEFT: | 1359 resizer_.reset(ash::DragWindowResizer::Create( |
| 1276 cursor_client->SetCursor(ui::kCursorNorthWestResize); | 1360 new CustomWindowResizer(window_state), window_state)); |
| 1277 break; | |
| 1278 default: | |
| 1279 NOTREACHED(); | |
| 1280 break; | |
| 1281 } | 1361 } |
| 1282 | 1362 |
| 1283 resizer_ = ash::CreateWindowResizer( | |
| 1284 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, | |
| 1285 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | |
| 1286 if (!resizer_) | |
| 1287 return; | |
| 1288 | |
| 1289 // Apply pending origin offsets and resize direction before starting a new | |
| 1290 // resize operation. These can still be pending if the client has acknowledged | |
| 1291 // the configure request but not yet called Commit(). | |
| 1292 origin_offset_ += pending_origin_offset_; | |
| 1293 pending_origin_offset_ = gfx::Vector2d(); | |
| 1294 resize_component_ = pending_resize_component_; | |
| 1295 | |
| 1296 WMHelper::GetInstance()->AddPreTargetHandler(this); | 1363 WMHelper::GetInstance()->AddPreTargetHandler(this); |
| 1297 widget_->GetNativeWindow()->SetCapture(); | 1364 window->SetCapture(); |
| 1298 | 1365 |
| 1299 // Notify client that resizing state has changed. | 1366 // Notify client that resizing state has changed. |
| 1300 if (IsResizing()) | 1367 if (IsResizing()) |
| 1301 Configure(); | 1368 Configure(); |
| 1302 } | 1369 } |
| 1303 | 1370 |
| 1304 void ShellSurface::EndDrag(bool revert) { | 1371 void ShellSurface::EndDrag(bool revert) { |
| 1305 DCHECK(widget_); | 1372 DCHECK(widget_); |
| 1306 DCHECK(resizer_); | 1373 DCHECK(resizer_); |
| 1307 | 1374 |
| 1375 aura::Window* window = GetDragWindow(); | |
| 1376 DCHECK(window); | |
| 1377 DCHECK(window->HasCapture()); | |
| 1378 | |
| 1308 bool was_resizing = IsResizing(); | 1379 bool was_resizing = IsResizing(); |
| 1309 | 1380 |
| 1310 if (revert) | 1381 if (revert) |
| 1311 resizer_->RevertDrag(); | 1382 resizer_->RevertDrag(); |
| 1312 else | 1383 else |
| 1313 resizer_->CompleteDrag(); | 1384 resizer_->CompleteDrag(); |
| 1314 | 1385 |
| 1315 WMHelper::GetInstance()->RemovePreTargetHandler(this); | 1386 WMHelper::GetInstance()->RemovePreTargetHandler(this); |
| 1316 widget_->GetNativeWindow()->ReleaseCapture(); | 1387 window->ReleaseCapture(); |
| 1317 resizer_.reset(); | 1388 resizer_.reset(); |
| 1318 | 1389 |
| 1319 // Notify client that resizing state has changed. | 1390 // Notify client that resizing state has changed. |
| 1320 if (was_resizing) | 1391 if (was_resizing) |
| 1321 Configure(); | 1392 Configure(); |
| 1322 | 1393 |
| 1323 UpdateWidgetBounds(); | 1394 UpdateWidgetBounds(); |
| 1324 } | 1395 } |
| 1325 | 1396 |
| 1326 bool ShellSurface::IsResizing() const { | 1397 bool ShellSurface::IsResizing() const { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 new_widget_bounds.set_origin( | 1490 new_widget_bounds.set_origin( |
| 1420 widget_->GetWindowBoundsInScreen().origin()); | 1491 widget_->GetWindowBoundsInScreen().origin()); |
| 1421 } | 1492 } |
| 1422 break; | 1493 break; |
| 1423 } | 1494 } |
| 1424 | 1495 |
| 1425 // Set |ignore_window_bounds_changes_| as this change to window bounds | 1496 // Set |ignore_window_bounds_changes_| as this change to window bounds |
| 1426 // should not result in a configure request. | 1497 // should not result in a configure request. |
| 1427 DCHECK(!ignore_window_bounds_changes_); | 1498 DCHECK(!ignore_window_bounds_changes_); |
| 1428 ignore_window_bounds_changes_ = true; | 1499 ignore_window_bounds_changes_ = true; |
| 1429 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) | 1500 const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen(); |
| 1430 widget_->SetBounds(new_widget_bounds); | 1501 if (widget_bounds != new_widget_bounds) { |
| 1502 if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) { | |
| 1503 widget_->SetBounds(new_widget_bounds); | |
| 1504 UpdateSurfaceBounds(); | |
| 1505 } else { | |
| 1506 // TODO(domlaskowski): Synchronize window state transitions with the | |
| 1507 // client, and abort client-side dragging on transition to fullscreen. See | |
| 1508 // crbug.com/699746. | |
| 1509 DLOG_IF(ERROR, widget_bounds.size() != new_widget_bounds.size()) | |
| 1510 << "Window size changed during client-driven drag"; | |
| 1511 | |
| 1512 // Convert from screen to display coordinates. | |
| 1513 gfx::Point origin = new_widget_bounds.origin(); | |
| 1514 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin); | |
| 1515 new_widget_bounds.set_origin(origin); | |
| 1516 | |
| 1517 // Move the window relative to the current display. | |
| 1518 widget_->GetNativeWindow()->SetBounds(new_widget_bounds); | |
| 1519 UpdateSurfaceBounds(); | |
| 1520 | |
| 1521 // Render phantom windows when beyond the current display. | |
| 1522 resizer_->Drag(GetMouseLocation(), 0); | |
| 1523 } | |
| 1524 } | |
| 1525 | |
| 1431 ignore_window_bounds_changes_ = false; | 1526 ignore_window_bounds_changes_ = false; |
| 1432 } | 1527 } |
| 1433 | 1528 |
| 1434 void ShellSurface::UpdateSurfaceBounds() { | 1529 void ShellSurface::UpdateSurfaceBounds() { |
| 1435 gfx::Rect client_view_bounds = | 1530 gfx::Rect client_view_bounds = |
| 1436 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | 1531 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1437 | 1532 |
| 1438 surface_->window()->SetBounds( | 1533 surface_->window()->SetBounds( |
| 1439 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | 1534 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1440 surface_->window()->layer()->size())); | 1535 surface_->window()->layer()->size())); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1584 // Surfaces that can't be activated are usually menus and tooltips. Use a | 1679 // Surfaces that can't be activated are usually menus and tooltips. Use a |
| 1585 // small style shadow for them. | 1680 // small style shadow for them. |
| 1586 if (!activatable_) | 1681 if (!activatable_) |
| 1587 shadow->SetElevation(wm::ShadowElevation::SMALL); | 1682 shadow->SetElevation(wm::ShadowElevation::SMALL); |
| 1588 // We don't have rounded corners unless frame is enabled. | 1683 // We don't have rounded corners unless frame is enabled. |
| 1589 if (!frame_enabled_) | 1684 if (!frame_enabled_) |
| 1590 shadow->SetRoundedCornerRadius(0); | 1685 shadow->SetRoundedCornerRadius(0); |
| 1591 } | 1686 } |
| 1592 } | 1687 } |
| 1593 | 1688 |
| 1689 gfx::Point ShellSurface::GetMouseLocation() const { | |
| 1690 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow(); | |
| 1691 gfx::Point location = | |
| 1692 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); | |
| 1693 aura::Window::ConvertPointToTarget( | |
| 1694 root_window, widget_->GetNativeWindow()->parent(), &location); | |
| 1695 return location; | |
| 1696 } | |
| 1697 | |
| 1594 } // namespace exo | 1698 } // namespace exo |
| OLD | NEW |