Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: components/exo/shell_surface.cc

Issue 2645663004: exo: Initial support for multiple displays in ARC (Closed)
Patch Set: Address nits Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/exo/shell_surface.h ('k') | components/exo/shell_surface_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 old_primary_display;
1035 if (screen->GetDisplayWithDisplayId(primary_display_id_,
1036 &old_primary_display)) {
1037 // Give the client a chance to adjust window positions before switching to
1038 // the new coordinate system. Retain the old origin by reverting the origin
1039 // delta until the next configure is acknowledged.
1040 gfx::Vector2d delta = gfx::Point() - old_primary_display.bounds().origin();
1041 origin_offset_ -= delta;
1042 pending_origin_offset_accumulator_ += delta;
1043
1044 if (widget_) {
1045 UpdateWidgetBounds();
1046 UpdateShadow();
1047 }
1048
1049 Configure();
1050 }
1051
1052 primary_display_id_ = primary_display_id;
1053 }
1054
1055 ////////////////////////////////////////////////////////////////////////////////
1016 // ui::EventHandler overrides: 1056 // ui::EventHandler overrides:
1017 1057
1018 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { 1058 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) {
1019 if (!resizer_) { 1059 if (!resizer_) {
1020 views::View::OnKeyEvent(event); 1060 views::View::OnKeyEvent(event);
1021 return; 1061 return;
1022 } 1062 }
1023 1063
1064 // TODO(domlaskowski): For BoundsMode::CLIENT, synchronize the revert with the
1065 // client, instead of having the client destroy the window on VKEY_ESCAPE. See
1066 // crbug.com/699746.
1024 if (event->type() == ui::ET_KEY_PRESSED && 1067 if (event->type() == ui::ET_KEY_PRESSED &&
1025 event->key_code() == ui::VKEY_ESCAPE) { 1068 event->key_code() == ui::VKEY_ESCAPE) {
1026 EndDrag(true /* revert */); 1069 EndDrag(true /* revert */);
1027 } 1070 }
1028 } 1071 }
1029 1072
1030 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { 1073 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) {
1031 if (!resizer_) { 1074 if (!resizer_) {
1032 views::View::OnMouseEvent(event); 1075 views::View::OnMouseEvent(event);
1033 return; 1076 return;
1034 } 1077 }
1035 1078
1036 if (event->handled()) 1079 if (event->handled())
1037 return; 1080 return;
1038 1081
1039 if ((event->flags() & 1082 if ((event->flags() &
1040 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) 1083 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0)
1041 return; 1084 return;
1042 1085
1043 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { 1086 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) {
1044 // We complete the drag instead of reverting it, as reverting it will 1087 // 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 1088 // result in a weird behavior when a client produces a modal dialog
1046 // while the drag is in progress. 1089 // while the drag is in progress.
1047 EndDrag(false /* revert */); 1090 EndDrag(false /* revert */);
1048 return; 1091 return;
1049 } 1092 }
1050 1093
1051 switch (event->type()) { 1094 switch (event->type()) {
1052 case ui::ET_MOUSE_DRAGGED: { 1095 case ui::ET_MOUSE_DRAGGED: {
1096 if (bounds_mode_ == BoundsMode::CLIENT)
1097 break;
1098
1053 gfx::Point location(event->location()); 1099 gfx::Point location(event->location());
1054 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), 1100 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(),
1055 widget_->GetNativeWindow()->parent(), 1101 widget_->GetNativeWindow()->parent(),
1056 &location); 1102 &location);
1057 ScopedConfigure scoped_configure(this, false); 1103 ScopedConfigure scoped_configure(this, false);
1058 resizer_->Drag(location, event->flags()); 1104 resizer_->Drag(location, event->flags());
1059 event->StopPropagation(); 1105 event->StopPropagation();
1060 break; 1106 break;
1061 } 1107 }
1062 case ui::ET_MOUSE_RELEASED: { 1108 case ui::ET_MOUSE_RELEASED: {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 resize_component = window_state->drag_details()->window_component; 1242 resize_component = window_state->drag_details()->window_component;
1197 } 1243 }
1198 1244
1199 uint32_t serial = 0; 1245 uint32_t serial = 0;
1200 if (!configure_callback_.is_null()) { 1246 if (!configure_callback_.is_null()) {
1201 if (widget_) { 1247 if (widget_) {
1202 const views::NonClientView* non_client_view = widget_->non_client_view(); 1248 const views::NonClientView* non_client_view = widget_->non_client_view();
1203 serial = configure_callback_.Run( 1249 serial = configure_callback_.Run(
1204 non_client_view->frame_view()->GetBoundsForClientView().size(), 1250 non_client_view->frame_view()->GetBoundsForClientView().size(),
1205 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), 1251 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(),
1206 IsResizing(), widget_->IsActive(), origin_); 1252 IsResizing(), widget_->IsActive(), origin_offset);
1207 } else { 1253 } else {
1208 serial = configure_callback_.Run(gfx::Size(), 1254 serial = configure_callback_.Run(gfx::Size(),
1209 ash::wm::WINDOW_STATE_TYPE_NORMAL, false, 1255 ash::wm::WINDOW_STATE_TYPE_NORMAL, false,
1210 false, origin_); 1256 false, origin_offset);
1211 } 1257 }
1212 } 1258 }
1213 1259
1214 if (!serial) { 1260 if (!serial) {
1215 pending_origin_offset_ += origin_offset; 1261 pending_origin_offset_ += origin_offset;
1216 pending_resize_component_ = resize_component; 1262 pending_resize_component_ = resize_component;
1217 return; 1263 return;
1218 } 1264 }
1219 1265
1220 // Apply origin offset and resize component at the first Commit() after this 1266 // Apply origin offset and resize component at the first Commit() after this
1221 // configure request has been acknowledged. 1267 // configure request has been acknowledged.
1222 pending_configs_.push_back({serial, origin_offset, resize_component}); 1268 pending_configs_.push_back({serial, origin_offset, resize_component});
1223 LOG_IF(WARNING, pending_configs_.size() > 100) 1269 LOG_IF(WARNING, pending_configs_.size() > 100)
1224 << "Number of pending configure acks for shell surface has reached: " 1270 << "Number of pending configure acks for shell surface has reached: "
1225 << pending_configs_.size(); 1271 << pending_configs_.size();
1226 } 1272 }
1227 1273
1274 aura::Window* ShellSurface::GetDragWindow() const {
1275 switch (bounds_mode_) {
1276 case BoundsMode::SHELL:
1277 return widget_->GetNativeWindow();
1278
1279 case BoundsMode::CLIENT:
1280 return surface_ ? surface_->window() : nullptr;
1281
1282 case BoundsMode::FIXED:
1283 return nullptr;
1284 }
1285
1286 NOTREACHED();
1287 return nullptr;
1288 }
1289
1228 void ShellSurface::AttemptToStartDrag(int component) { 1290 void ShellSurface::AttemptToStartDrag(int component) {
1229 DCHECK(widget_); 1291 DCHECK(widget_);
1230 1292
1231 // Cannot start another drag if one is already taking place. 1293 // Cannot start another drag if one is already taking place.
1232 if (resizer_) 1294 if (resizer_)
1233 return; 1295 return;
1234 1296
1235 if (widget_->GetNativeWindow()->HasCapture()) 1297 aura::Window* window = GetDragWindow();
1298 if (!window || window->HasCapture())
1236 return; 1299 return;
1237 1300
1238 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow(); 1301 if (bounds_mode_ == BoundsMode::SHELL) {
1239 gfx::Point drag_location = 1302 // Set the cursor before calling CreateWindowResizer(), as that will
1240 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); 1303 // eventually call LockCursor() and prevent the cursor from changing.
1241 aura::Window::ConvertPointToTarget( 1304 aura::client::CursorClient* cursor_client =
1242 root_window, widget_->GetNativeWindow()->parent(), &drag_location); 1305 aura::client::GetCursorClient(window->GetRootWindow());
1306 DCHECK(cursor_client);
1243 1307
1244 // Set the cursor before calling CreateWindowResizer(), as that will 1308 switch (component) {
1245 // eventually call LockCursor() and prevent the cursor from changing. 1309 case HTCAPTION:
1246 aura::client::CursorClient* cursor_client = 1310 cursor_client->SetCursor(ui::kCursorPointer);
1247 aura::client::GetCursorClient(root_window); 1311 break;
1248 DCHECK(cursor_client); 1312 case HTTOP:
1313 cursor_client->SetCursor(ui::kCursorNorthResize);
1314 break;
1315 case HTTOPRIGHT:
1316 cursor_client->SetCursor(ui::kCursorNorthEastResize);
1317 break;
1318 case HTRIGHT:
1319 cursor_client->SetCursor(ui::kCursorEastResize);
1320 break;
1321 case HTBOTTOMRIGHT:
1322 cursor_client->SetCursor(ui::kCursorSouthEastResize);
1323 break;
1324 case HTBOTTOM:
1325 cursor_client->SetCursor(ui::kCursorSouthResize);
1326 break;
1327 case HTBOTTOMLEFT:
1328 cursor_client->SetCursor(ui::kCursorSouthWestResize);
1329 break;
1330 case HTLEFT:
1331 cursor_client->SetCursor(ui::kCursorWestResize);
1332 break;
1333 case HTTOPLEFT:
1334 cursor_client->SetCursor(ui::kCursorNorthWestResize);
1335 break;
1336 default:
1337 NOTREACHED();
1338 break;
1339 }
1249 1340
1250 switch (component) { 1341 resizer_ = ash::CreateWindowResizer(ash::WmWindow::Get(window),
1251 case HTCAPTION: 1342 GetMouseLocation(), component,
1252 cursor_client->SetCursor(ui::kCursorPointer); 1343 aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1253 break; 1344 if (!resizer_)
1254 case HTTOP: 1345 return;
1255 cursor_client->SetCursor(ui::kCursorNorthResize); 1346
1256 break; 1347 // Apply pending origin offsets and resize direction before starting a
1257 case HTTOPRIGHT: 1348 // new resize operation. These can still be pending if the client has
1258 cursor_client->SetCursor(ui::kCursorNorthEastResize); 1349 // acknowledged the configure request but not yet called Commit().
1259 break; 1350 origin_offset_ += pending_origin_offset_;
1260 case HTRIGHT: 1351 pending_origin_offset_ = gfx::Vector2d();
1261 cursor_client->SetCursor(ui::kCursorEastResize); 1352 resize_component_ = pending_resize_component_;
1262 break; 1353 } else {
1263 case HTBOTTOMRIGHT: 1354 DCHECK(bounds_mode_ == BoundsMode::CLIENT);
1264 cursor_client->SetCursor(ui::kCursorSouthEastResize); 1355
1265 break; 1356 ash::wm::WindowState* window_state =
1266 case HTBOTTOM: 1357 ash::wm::GetWindowState(widget_->GetNativeWindow());
1267 cursor_client->SetCursor(ui::kCursorSouthResize); 1358 DCHECK(!window_state->drag_details());
1268 break; 1359 DCHECK(component == HTCAPTION);
1269 case HTBOTTOMLEFT: 1360 window_state->CreateDragDetails(GetMouseLocation(), component,
1270 cursor_client->SetCursor(ui::kCursorSouthWestResize); 1361 aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1271 break; 1362
1272 case HTLEFT: 1363 // Chained with a CustomWindowResizer, DragWindowResizer does not handle
1273 cursor_client->SetCursor(ui::kCursorWestResize); 1364 // dragging. It only renders phantom windows and moves the window to the
1274 break; 1365 // target root window when dragging ends.
1275 case HTTOPLEFT: 1366 resizer_.reset(ash::DragWindowResizer::Create(
1276 cursor_client->SetCursor(ui::kCursorNorthWestResize); 1367 new CustomWindowResizer(window_state), window_state));
1277 break;
1278 default:
1279 NOTREACHED();
1280 break;
1281 } 1368 }
1282 1369
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); 1370 WMHelper::GetInstance()->AddPreTargetHandler(this);
1297 widget_->GetNativeWindow()->SetCapture(); 1371 window->SetCapture();
1298 1372
1299 // Notify client that resizing state has changed. 1373 // Notify client that resizing state has changed.
1300 if (IsResizing()) 1374 if (IsResizing())
1301 Configure(); 1375 Configure();
1302 } 1376 }
1303 1377
1304 void ShellSurface::EndDrag(bool revert) { 1378 void ShellSurface::EndDrag(bool revert) {
1305 DCHECK(widget_); 1379 DCHECK(widget_);
1306 DCHECK(resizer_); 1380 DCHECK(resizer_);
1307 1381
1382 aura::Window* window = GetDragWindow();
1383 DCHECK(window);
1384 DCHECK(window->HasCapture());
1385
1308 bool was_resizing = IsResizing(); 1386 bool was_resizing = IsResizing();
1309 1387
1310 if (revert) 1388 if (revert)
1311 resizer_->RevertDrag(); 1389 resizer_->RevertDrag();
1312 else 1390 else
1313 resizer_->CompleteDrag(); 1391 resizer_->CompleteDrag();
1314 1392
1315 WMHelper::GetInstance()->RemovePreTargetHandler(this); 1393 WMHelper::GetInstance()->RemovePreTargetHandler(this);
1316 widget_->GetNativeWindow()->ReleaseCapture(); 1394 window->ReleaseCapture();
1317 resizer_.reset(); 1395 resizer_.reset();
1318 1396
1319 // Notify client that resizing state has changed. 1397 // Notify client that resizing state has changed.
1320 if (was_resizing) 1398 if (was_resizing)
1321 Configure(); 1399 Configure();
1322 1400
1323 UpdateWidgetBounds(); 1401 UpdateWidgetBounds();
1324 } 1402 }
1325 1403
1326 bool ShellSurface::IsResizing() const { 1404 bool ShellSurface::IsResizing() const {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 new_widget_bounds.set_origin( 1497 new_widget_bounds.set_origin(
1420 widget_->GetWindowBoundsInScreen().origin()); 1498 widget_->GetWindowBoundsInScreen().origin());
1421 } 1499 }
1422 break; 1500 break;
1423 } 1501 }
1424 1502
1425 // Set |ignore_window_bounds_changes_| as this change to window bounds 1503 // Set |ignore_window_bounds_changes_| as this change to window bounds
1426 // should not result in a configure request. 1504 // should not result in a configure request.
1427 DCHECK(!ignore_window_bounds_changes_); 1505 DCHECK(!ignore_window_bounds_changes_);
1428 ignore_window_bounds_changes_ = true; 1506 ignore_window_bounds_changes_ = true;
1429 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) 1507 const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen();
1430 widget_->SetBounds(new_widget_bounds); 1508 if (widget_bounds != new_widget_bounds) {
1509 if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) {
1510 widget_->SetBounds(new_widget_bounds);
1511 UpdateSurfaceBounds();
1512 } else {
1513 // TODO(domlaskowski): Synchronize window state transitions with the
1514 // client, and abort client-side dragging on transition to fullscreen. See
1515 // crbug.com/699746.
1516 DLOG_IF(ERROR, widget_bounds.size() != new_widget_bounds.size())
1517 << "Window size changed during client-driven drag";
1518
1519 // Convert from screen to display coordinates.
1520 gfx::Point origin = new_widget_bounds.origin();
1521 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
1522 new_widget_bounds.set_origin(origin);
1523
1524 // Move the window relative to the current display.
1525 widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
1526 UpdateSurfaceBounds();
1527
1528 // Render phantom windows when beyond the current display.
1529 resizer_->Drag(GetMouseLocation(), 0);
1530 }
1531 }
1532
1431 ignore_window_bounds_changes_ = false; 1533 ignore_window_bounds_changes_ = false;
1432 } 1534 }
1433 1535
1434 void ShellSurface::UpdateSurfaceBounds() { 1536 void ShellSurface::UpdateSurfaceBounds() {
1435 gfx::Rect client_view_bounds = 1537 gfx::Rect client_view_bounds =
1436 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1538 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1437 1539
1438 surface_->window()->SetBounds( 1540 surface_->window()->SetBounds(
1439 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), 1541 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
1440 surface_->window()->layer()->size())); 1542 surface_->window()->layer()->size()));
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 // Surfaces that can't be activated are usually menus and tooltips. Use a 1686 // Surfaces that can't be activated are usually menus and tooltips. Use a
1585 // small style shadow for them. 1687 // small style shadow for them.
1586 if (!activatable_) 1688 if (!activatable_)
1587 shadow->SetElevation(wm::ShadowElevation::SMALL); 1689 shadow->SetElevation(wm::ShadowElevation::SMALL);
1588 // We don't have rounded corners unless frame is enabled. 1690 // We don't have rounded corners unless frame is enabled.
1589 if (!frame_enabled_) 1691 if (!frame_enabled_)
1590 shadow->SetRoundedCornerRadius(0); 1692 shadow->SetRoundedCornerRadius(0);
1591 } 1693 }
1592 } 1694 }
1593 1695
1696 gfx::Point ShellSurface::GetMouseLocation() const {
1697 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
1698 gfx::Point location =
1699 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1700 aura::Window::ConvertPointToTarget(
1701 root_window, widget_->GetNativeWindow()->parent(), &location);
1702 return location;
1703 }
1704
1594 } // namespace exo 1705 } // namespace exo
OLDNEW
« no previous file with comments | « components/exo/shell_surface.h ('k') | components/exo/shell_surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698