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

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

Issue 2645663004: exo: Initial support for multiple displays in ARC (Closed)
Patch Set: Rebase 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 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
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
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
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
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