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

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, 10 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
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/window_state_delegate.h" 13 #include "ash/common/wm/window_state_delegate.h"
14 #include "ash/common/wm_shell.h" 14 #include "ash/common/wm_shell.h"
15 #include "ash/common/wm_window.h" 15 #include "ash/common/wm_window.h"
16 #include "ash/public/cpp/shell_window_ids.h" 16 #include "ash/public/cpp/shell_window_ids.h"
17 #include "ash/wm/drag_window_resizer.h"
17 #include "ash/wm/window_state_aura.h" 18 #include "ash/wm/window_state_aura.h"
18 #include "ash/wm/window_util.h" 19 #include "ash/wm/window_util.h"
19 #include "base/logging.h" 20 #include "base/logging.h"
20 #include "base/macros.h" 21 #include "base/macros.h"
21 #include "base/memory/ptr_util.h" 22 #include "base/memory/ptr_util.h"
22 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
23 #include "base/trace_event/trace_event.h" 24 #include "base/trace_event/trace_event.h"
24 #include "base/trace_event/trace_event_argument.h" 25 #include "base/trace_event/trace_event_argument.h"
25 #include "components/exo/surface.h" 26 #include "components/exo/surface.h"
26 #include "ui/aura/client/aura_constants.h" 27 #include "ui/aura/client/aura_constants.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 widget_->RemoveObserver(this); 182 widget_->RemoveObserver(this);
182 widget_ = nullptr; 183 widget_ = nullptr;
183 } 184 }
184 185
185 private: 186 private:
186 views::Widget* widget_; 187 views::Widget* widget_;
187 188
188 DISALLOW_COPY_AND_ASSIGN(CustomWindowStateDelegate); 189 DISALLOW_COPY_AND_ASSIGN(CustomWindowStateDelegate);
189 }; 190 };
190 191
192 class CustomWindowResizer : public ash::WindowResizer {
193 public:
194 explicit CustomWindowResizer(ash::wm::WindowState* window_state)
195 : WindowResizer(window_state), shell_(GetTarget()->GetShell()) {
196 shell_->LockCursor();
197 }
198
199 ~CustomWindowResizer() override { shell_->UnlockCursor(); }
200
201 // ash::WindowResizer:
202 void Drag(const gfx::Point& location, int event_flags) override {}
203 void CompleteDrag() override {}
204 void RevertDrag() override {}
205
206 private:
207 ash::WmShell* const shell_;
208
209 DISALLOW_COPY_AND_ASSIGN(CustomWindowResizer);
210 };
211
191 class ShellSurfaceWidget : public views::Widget { 212 class ShellSurfaceWidget : public views::Widget {
192 public: 213 public:
193 explicit ShellSurfaceWidget(ShellSurface* shell_surface) 214 explicit ShellSurfaceWidget(ShellSurface* shell_surface)
194 : shell_surface_(shell_surface) {} 215 : shell_surface_(shell_surface) {}
195 216
196 // Overridden from views::Widget 217 // Overridden from views::Widget
197 void Close() override { shell_surface_->Close(); } 218 void Close() override { shell_surface_->Close(); }
198 void OnKeyEvent(ui::KeyEvent* event) override { 219 void OnKeyEvent(ui::KeyEvent* event) override {
199 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key 220 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key
200 // to escape pinned mode. 221 // to escape pinned mode.
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 WMHelper::GetInstance()->RemoveActivationObserver(this); 404 WMHelper::GetInstance()->RemoveActivationObserver(this);
384 if (parent_) 405 if (parent_)
385 parent_->RemoveObserver(this); 406 parent_->RemoveObserver(this);
386 if (surface_) { 407 if (surface_) {
387 if (scale_ != 1.0) 408 if (scale_ != 1.0)
388 surface_->window()->SetTransform(gfx::Transform()); 409 surface_->window()->SetTransform(gfx::Transform());
389 surface_->SetSurfaceDelegate(nullptr); 410 surface_->SetSurfaceDelegate(nullptr);
390 surface_->RemoveSurfaceObserver(this); 411 surface_->RemoveSurfaceObserver(this);
391 } 412 }
392 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); 413 WMHelper::GetInstance()->RemoveAccessibilityObserver(this);
414
415 if (!destroyed_callback_.is_null())
416 destroyed_callback_.Run();
393 } 417 }
394 418
395 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { 419 void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
396 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); 420 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial);
397 421
398 // Apply all configs that are older or equal to |serial|. The result is that 422 // Apply all configs that are older or equal to |serial|. The result is that
399 // the origin of the main surface will move and the resize direction will 423 // the origin of the main surface will move and the resize direction will
400 // change to reflect the acknowledgement of configure request with |serial| 424 // change to reflect the acknowledgement of configure request with |serial|
401 // at the next call to Commit(). 425 // at the next call to Commit().
402 while (!pending_configs_.empty()) { 426 while (!pending_configs_.empty()) {
403 auto config = pending_configs_.front(); 427 auto config = pending_configs_.front();
404 pending_configs_.pop_front(); 428 pending_configs_.pop_front();
405 429
406 // Add the config offset to the accumulated offset that will be applied when 430 // Add the config offset to the accumulated offset that will be applied when
407 // Commit() is called. 431 // Commit() is called.
408 pending_origin_offset_ += config.origin_offset; 432 pending_origin_offset_ += config.origin_offset;
409 433
410 // Set the resize direction that will be applied when Commit() is called. 434 // Set the resize direction that will be applied when Commit() is called.
411 pending_resize_component_ = config.resize_component; 435 pending_resize_component_ = config.resize_component;
412 436
413 if (config.serial == serial) 437 if (config.serial == serial)
414 break; 438 break;
415 } 439 }
416 440
417 if (widget_) 441 if (widget_) {
418 UpdateWidgetBounds(); 442 UpdateWidgetBounds();
443 UpdateShadow();
444 }
419 } 445 }
420 446
421 void ShellSurface::SetParent(ShellSurface* parent) { 447 void ShellSurface::SetParent(ShellSurface* parent) {
422 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent", 448 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent",
423 parent ? base::UTF16ToASCII(parent->title_) : "null"); 449 parent ? base::UTF16ToASCII(parent->title_) : "null");
424 450
425 if (parent_) { 451 if (parent_) {
426 parent_->RemoveObserver(this); 452 parent_->RemoveObserver(this);
427 if (widget_) 453 if (widget_)
428 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow()); 454 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 void ShellSurface::SetApplicationId(const std::string& application_id) { 586 void ShellSurface::SetApplicationId(const std::string& application_id) {
561 // Store the value in |application_id_| in case the window does not exist yet. 587 // Store the value in |application_id_| in case the window does not exist yet.
562 application_id_ = application_id; 588 application_id_ = application_id;
563 if (widget_ && widget_->GetNativeWindow()) 589 if (widget_ && widget_->GetNativeWindow())
564 SetApplicationId(widget_->GetNativeWindow(), application_id); 590 SetApplicationId(widget_->GetNativeWindow(), application_id);
565 } 591 }
566 592
567 void ShellSurface::Move() { 593 void ShellSurface::Move() {
568 TRACE_EVENT0("exo", "ShellSurface::Move"); 594 TRACE_EVENT0("exo", "ShellSurface::Move");
569 595
570 if (!widget_) 596 if (!widget_ || resizer_)
571 return; 597 return;
572 598
573 switch (bounds_mode_) { 599 switch (bounds_mode_) {
574 case BoundsMode::SHELL: 600 case BoundsMode::SHELL:
575 AttemptToStartDrag(HTCAPTION); 601 AttemptToStartDrag(HTCAPTION);
576 return; 602 return;
577 case BoundsMode::CLIENT: 603 case BoundsMode::CLIENT:
604 AttemptToStartClientDrag();
605 return;
578 case BoundsMode::FIXED: 606 case BoundsMode::FIXED:
579 return; 607 return;
580 } 608 }
581 609
582 NOTREACHED(); 610 NOTREACHED();
583 } 611 }
584 612
585 void ShellSurface::Resize(int component) { 613 void ShellSurface::Resize(int component) {
586 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); 614 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component);
587 615
588 if (!widget_) 616 if (!widget_ || resizer_)
589 return; 617 return;
590 618
591 switch (bounds_mode_) { 619 switch (bounds_mode_) {
592 case BoundsMode::SHELL: 620 case BoundsMode::SHELL:
593 AttemptToStartDrag(component); 621 AttemptToStartDrag(component);
594 return; 622 return;
595 case BoundsMode::CLIENT: 623 case BoundsMode::CLIENT:
596 case BoundsMode::FIXED: 624 case BoundsMode::FIXED:
597 return; 625 return;
598 } 626 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 695
668 void ShellSurface::SetTopInset(int height) { 696 void ShellSurface::SetTopInset(int height) {
669 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); 697 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height);
670 698
671 pending_top_inset_height_ = height; 699 pending_top_inset_height_ = height;
672 } 700 }
673 701
674 void ShellSurface::SetOrigin(const gfx::Point& origin) { 702 void ShellSurface::SetOrigin(const gfx::Point& origin) {
675 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); 703 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString());
676 704
705 const gfx::Point old_origin = origin_;
677 origin_ = origin; 706 origin_ = origin;
707
708 if (bounds_mode_ != BoundsMode::CLIENT || origin == old_origin)
709 return;
710
711 // If the origin changed, give the client a chance to adjust window positions
712 // before switching to the new coordinate system. Retain the old origin by
713 // reverting the origin delta until the next configure is acknowledged.
714 const gfx::Vector2d delta = origin - old_origin;
715 origin_offset_ -= delta;
716 pending_origin_offset_accumulator_ += delta;
717
718 if (widget_) {
719 UpdateWidgetBounds();
720 UpdateShadow();
721 }
722
723 Configure();
678 } 724 }
679 725
680 void ShellSurface::SetActivatable(bool activatable) { 726 void ShellSurface::SetActivatable(bool activatable) {
681 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", 727 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable",
682 activatable); 728 activatable);
683 729
684 activatable_ = activatable; 730 activatable_ = activatable;
685 } 731 }
686 732
687 void ShellSurface::SetContainer(int container) { 733 void ShellSurface::SetContainer(int container) {
(...skipping 26 matching lines...) Expand all
714 760
715 //////////////////////////////////////////////////////////////////////////////// 761 ////////////////////////////////////////////////////////////////////////////////
716 // SurfaceDelegate overrides: 762 // SurfaceDelegate overrides:
717 763
718 void ShellSurface::OnSurfaceCommit() { 764 void ShellSurface::OnSurfaceCommit() {
719 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); 765 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
720 surface_->CommitSurfaceHierarchy(); 766 surface_->CommitSurfaceHierarchy();
721 767
722 if (enabled() && !widget_) { 768 if (enabled() && !widget_) {
723 // Defer widget creation until surface contains some contents. 769 // Defer widget creation until surface contains some contents.
724 if (surface_->content_size().IsEmpty()) 770 if (surface_->content_size().IsEmpty()) {
725 Configure(); 771 Configure();
726 else 772 return;
727 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); 773 }
774
775 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
728 } 776 }
729 777
730 // Apply the accumulated pending origin offset to reflect acknowledged 778 // Apply the accumulated pending origin offset to reflect acknowledged
731 // configure requests. 779 // configure requests.
732 origin_offset_ += pending_origin_offset_; 780 origin_offset_ += pending_origin_offset_;
733 pending_origin_offset_ = gfx::Vector2d(); 781 pending_origin_offset_ = gfx::Vector2d();
734 782
735 // Update resize direction to reflect acknowledged configure requests. 783 // Update resize direction to reflect acknowledged configure requests.
736 resize_component_ = pending_resize_component_; 784 resize_component_ = pending_resize_component_;
737 785
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 ash::wm::WindowState* window_state, 960 ash::wm::WindowState* window_state,
913 ash::wm::WindowStateType old_type) { 961 ash::wm::WindowStateType old_type) {
914 ash::wm::WindowStateType new_type = window_state->GetStateType(); 962 ash::wm::WindowStateType new_type = window_state->GetStateType();
915 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 963 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
916 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 964 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
917 // When transitioning in/out of maximized or fullscreen mode we need to 965 // When transitioning in/out of maximized or fullscreen mode we need to
918 // make sure we have a configure callback before we allow the default 966 // make sure we have a configure callback before we allow the default
919 // cross-fade animations. The configure callback provides a mechanism for 967 // cross-fade animations. The configure callback provides a mechanism for
920 // the client to inform us that a frame has taken the state change into 968 // the client to inform us that a frame has taken the state change into
921 // account and without this cross-fade animations are unreliable. 969 // account and without this cross-fade animations are unreliable.
922 if (configure_callback_.is_null()) 970
971 // TODO(domlaskowski): For shell surfaces whose bounds are controlled by the
972 // client, the configure callback does not yet support window state changes.
973 if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT)
923 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); 974 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
924 } 975 }
925 } 976 }
926 977
927 void ShellSurface::OnPostWindowStateTypeChange( 978 void ShellSurface::OnPostWindowStateTypeChange(
928 ash::wm::WindowState* window_state, 979 ash::wm::WindowState* window_state,
929 ash::wm::WindowStateType old_type) { 980 ash::wm::WindowStateType old_type) {
930 ash::wm::WindowStateType new_type = window_state->GetStateType(); 981 ash::wm::WindowStateType new_type = window_state->GetStateType();
931 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 982 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
932 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 983 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
(...skipping 11 matching lines...) Expand all
944 // Re-enable animations if they were disabled in pre state change handler. 995 // Re-enable animations if they were disabled in pre state change handler.
945 scoped_animations_disabled_.reset(); 996 scoped_animations_disabled_.reset();
946 } 997 }
947 998
948 //////////////////////////////////////////////////////////////////////////////// 999 ////////////////////////////////////////////////////////////////////////////////
949 // aura::WindowObserver overrides: 1000 // aura::WindowObserver overrides:
950 1001
951 void ShellSurface::OnWindowBoundsChanged(aura::Window* window, 1002 void ShellSurface::OnWindowBoundsChanged(aura::Window* window,
952 const gfx::Rect& old_bounds, 1003 const gfx::Rect& old_bounds,
953 const gfx::Rect& new_bounds) { 1004 const gfx::Rect& new_bounds) {
954 if (!widget_ || !surface_ || ignore_window_bounds_changes_) 1005 if (bounds_mode_ == BoundsMode::CLIENT || !widget_ || !surface_ ||
1006 ignore_window_bounds_changes_)
955 return; 1007 return;
956 1008
957 if (window == widget_->GetNativeWindow()) { 1009 if (window == widget_->GetNativeWindow()) {
958 if (new_bounds.size() == old_bounds.size()) 1010 if (new_bounds.size() == old_bounds.size())
959 return; 1011 return;
960 1012
961 // If size changed then give the client a chance to produce new contents 1013 // If size changed then give the client a chance to produce new contents
962 // before origin on screen is changed. Retain the old origin by reverting 1014 // before origin on screen is changed. Retain the old origin by reverting
963 // the origin delta until the next configure is acknowledged. 1015 // the origin delta until the next configure is acknowledged.
964 gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin(); 1016 gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 1065
1014 //////////////////////////////////////////////////////////////////////////////// 1066 ////////////////////////////////////////////////////////////////////////////////
1015 // ui::EventHandler overrides: 1067 // ui::EventHandler overrides:
1016 1068
1017 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { 1069 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) {
1018 if (!resizer_) { 1070 if (!resizer_) {
1019 views::View::OnKeyEvent(event); 1071 views::View::OnKeyEvent(event);
1020 return; 1072 return;
1021 } 1073 }
1022 1074
1023 if (event->type() == ui::ET_KEY_PRESSED && 1075 if (bounds_mode_ == BoundsMode::SHELL &&
1076 event->type() == ui::ET_KEY_PRESSED &&
1024 event->key_code() == ui::VKEY_ESCAPE) { 1077 event->key_code() == ui::VKEY_ESCAPE) {
1025 EndDrag(true /* revert */); 1078 EndDrag(true /* revert */);
1026 } 1079 }
1027 } 1080 }
1028 1081
1029 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { 1082 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) {
1030 if (!resizer_) { 1083 if (!resizer_) {
1031 views::View::OnMouseEvent(event); 1084 views::View::OnMouseEvent(event);
1032 return; 1085 return;
1033 } 1086 }
1034 1087
1035 if (event->handled()) 1088 if (event->handled())
1036 return; 1089 return;
1037 1090
1038 if ((event->flags() & 1091 if ((event->flags() &
1039 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) 1092 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0)
1040 return; 1093 return;
1041 1094
1042 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { 1095 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) {
1043 // We complete the drag instead of reverting it, as reverting it will 1096 // We complete the drag instead of reverting it, as reverting it will
1044 // result in a weird behavior when a client produces a modal dialog 1097 // result in a weird behavior when a client produces a modal dialog
1045 // while the drag is in progress. 1098 // while the drag is in progress.
1046 EndDrag(false /* revert */); 1099 EndDrag(false /* revert */);
1047 return; 1100 return;
1048 } 1101 }
1049 1102
1050 switch (event->type()) { 1103 switch (event->type()) {
1051 case ui::ET_MOUSE_DRAGGED: { 1104 case ui::ET_MOUSE_DRAGGED: {
1105 if (bounds_mode_ == BoundsMode::CLIENT)
1106 break;
1107
1052 gfx::Point location(event->location()); 1108 gfx::Point location(event->location());
1053 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), 1109 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(),
1054 widget_->GetNativeWindow()->parent(), 1110 widget_->GetNativeWindow()->parent(),
1055 &location); 1111 &location);
1056 ScopedConfigure scoped_configure(this, false); 1112 ScopedConfigure scoped_configure(this, false);
1057 resizer_->Drag(location, event->flags()); 1113 resizer_->Drag(location, event->flags());
1058 event->StopPropagation(); 1114 event->StopPropagation();
1059 break; 1115 break;
1060 } 1116 }
1061 case ui::ET_MOUSE_RELEASED: { 1117 case ui::ET_MOUSE_RELEASED: {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 resize_component = window_state->drag_details()->window_component; 1251 resize_component = window_state->drag_details()->window_component;
1196 } 1252 }
1197 1253
1198 uint32_t serial = 0; 1254 uint32_t serial = 0;
1199 if (!configure_callback_.is_null()) { 1255 if (!configure_callback_.is_null()) {
1200 if (widget_) { 1256 if (widget_) {
1201 const views::NonClientView* non_client_view = widget_->non_client_view(); 1257 const views::NonClientView* non_client_view = widget_->non_client_view();
1202 serial = configure_callback_.Run( 1258 serial = configure_callback_.Run(
1203 non_client_view->frame_view()->GetBoundsForClientView().size(), 1259 non_client_view->frame_view()->GetBoundsForClientView().size(),
1204 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), 1260 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(),
1205 IsResizing(), widget_->IsActive()); 1261 IsResizing(), widget_->IsActive(), origin_);
1206 } else { 1262 } else {
1207 serial = configure_callback_.Run( 1263 serial = configure_callback_.Run(gfx::Size(),
1208 gfx::Size(), ash::wm::WINDOW_STATE_TYPE_NORMAL, false, false); 1264 ash::wm::WINDOW_STATE_TYPE_NORMAL, false,
1265 false, origin_);
1209 } 1266 }
1210 } 1267 }
1211 1268
1212 if (!serial) { 1269 if (!serial) {
1213 pending_origin_offset_ += origin_offset; 1270 pending_origin_offset_ += origin_offset;
1214 pending_resize_component_ = resize_component; 1271 pending_resize_component_ = resize_component;
1215 return; 1272 return;
1216 } 1273 }
1217 1274
1218 // Apply origin offset and resize component at the first Commit() after this 1275 // Apply origin offset and resize component at the first Commit() after this
1219 // configure request has been acknowledged. 1276 // configure request has been acknowledged.
1220 pending_configs_.push_back({serial, origin_offset, resize_component}); 1277 pending_configs_.push_back({serial, origin_offset, resize_component});
1221 LOG_IF(WARNING, pending_configs_.size() > 100) 1278 LOG_IF(WARNING, pending_configs_.size() > 100)
1222 << "Number of pending configure acks for shell surface has reached: " 1279 << "Number of pending configure acks for shell surface has reached: "
1223 << pending_configs_.size(); 1280 << pending_configs_.size();
1224 } 1281 }
1225 1282
1226 void ShellSurface::AttemptToStartDrag(int component) { 1283 void ShellSurface::AttemptToStartDrag(int component) {
1227 DCHECK(widget_); 1284 DCHECK(widget_);
1228 1285
1229 // Cannot start another drag if one is already taking place.
1230 if (resizer_)
1231 return;
1232
1233 if (widget_->GetNativeWindow()->HasCapture()) 1286 if (widget_->GetNativeWindow()->HasCapture())
1234 return; 1287 return;
1235 1288
1236 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow();
1237 gfx::Point drag_location =
1238 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1239 aura::Window::ConvertPointToTarget(
1240 root_window, widget_->GetNativeWindow()->parent(), &drag_location);
1241
1242 // Set the cursor before calling CreateWindowResizer(), as that will 1289 // Set the cursor before calling CreateWindowResizer(), as that will
1243 // eventually call LockCursor() and prevent the cursor from changing. 1290 // eventually call LockCursor() and prevent the cursor from changing.
1244 aura::client::CursorClient* cursor_client = 1291 aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
1245 aura::client::GetCursorClient(root_window); 1292 widget_->GetNativeWindow()->GetRootWindow());
1246 DCHECK(cursor_client); 1293 DCHECK(cursor_client);
1247 1294
1248 switch (component) { 1295 switch (component) {
1249 case HTCAPTION: 1296 case HTCAPTION:
1250 cursor_client->SetCursor(ui::kCursorPointer); 1297 cursor_client->SetCursor(ui::kCursorPointer);
1251 break; 1298 break;
1252 case HTTOP: 1299 case HTTOP:
1253 cursor_client->SetCursor(ui::kCursorNorthResize); 1300 cursor_client->SetCursor(ui::kCursorNorthResize);
1254 break; 1301 break;
1255 case HTTOPRIGHT: 1302 case HTTOPRIGHT:
(...skipping 16 matching lines...) Expand all
1272 break; 1319 break;
1273 case HTTOPLEFT: 1320 case HTTOPLEFT:
1274 cursor_client->SetCursor(ui::kCursorNorthWestResize); 1321 cursor_client->SetCursor(ui::kCursorNorthWestResize);
1275 break; 1322 break;
1276 default: 1323 default:
1277 NOTREACHED(); 1324 NOTREACHED();
1278 break; 1325 break;
1279 } 1326 }
1280 1327
1281 resizer_ = ash::CreateWindowResizer( 1328 resizer_ = ash::CreateWindowResizer(
1282 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, 1329 ash::WmWindow::Get(widget_->GetNativeWindow()), GetMouseLocation(),
1283 aura::client::WINDOW_MOVE_SOURCE_MOUSE); 1330 component, aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1284 if (!resizer_) 1331 if (!resizer_)
1285 return; 1332 return;
1286 1333
1287 // Apply pending origin offsets and resize direction before starting a new 1334 // Apply pending origin offsets and resize direction before starting a new
1288 // resize operation. These can still be pending if the client has acknowledged 1335 // resize operation. These can still be pending if the client has acknowledged
1289 // the configure request but not yet called Commit(). 1336 // the configure request but not yet called Commit().
1290 origin_offset_ += pending_origin_offset_; 1337 origin_offset_ += pending_origin_offset_;
1291 pending_origin_offset_ = gfx::Vector2d(); 1338 pending_origin_offset_ = gfx::Vector2d();
1292 resize_component_ = pending_resize_component_; 1339 resize_component_ = pending_resize_component_;
1293 1340
1294 WMHelper::GetInstance()->AddPreTargetHandler(this); 1341 WMHelper::GetInstance()->AddPreTargetHandler(this);
1295 widget_->GetNativeWindow()->SetCapture(); 1342 widget_->GetNativeWindow()->SetCapture();
1296 1343
1297 // Notify client that resizing state has changed. 1344 // Notify client that resizing state has changed.
1298 if (IsResizing()) 1345 if (IsResizing())
1299 Configure(); 1346 Configure();
1300 } 1347 }
1301 1348
1349 void ShellSurface::AttemptToStartClientDrag() {
1350 DCHECK(widget_);
1351
1352 if (surface_->window()->HasCapture())
1353 return;
1354
1355 ash::wm::WindowState* const window_state =
1356 ash::wm::GetWindowState(widget_->GetNativeWindow());
1357
1358 DCHECK(!window_state->drag_details());
1359 window_state->CreateDragDetails(GetMouseLocation(), HTCAPTION,
1360 aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1361
1362 // The resizer renders phantom windows, but does not control window movement.
1363 resizer_.reset(ash::DragWindowResizer::Create(
1364 new CustomWindowResizer(window_state), window_state));
1365
1366 WMHelper::GetInstance()->AddPreTargetHandler(this);
1367 surface_->window()->SetCapture();
1368 }
1369
1302 void ShellSurface::EndDrag(bool revert) { 1370 void ShellSurface::EndDrag(bool revert) {
1303 DCHECK(widget_); 1371 DCHECK(widget_);
1304 DCHECK(resizer_); 1372 DCHECK(resizer_);
1305 1373
1306 bool was_resizing = IsResizing(); 1374 switch (bounds_mode_) {
1375 case BoundsMode::SHELL: {
1376 bool was_resizing = IsResizing();
1307 1377
1378 EndDrag(widget_->GetNativeWindow(), revert);
1379
1380 // Notify client that resizing state has changed.
1381 if (was_resizing)
1382 Configure();
1383
1384 UpdateWidgetBounds();
1385 return;
1386 }
1387 case BoundsMode::CLIENT:
1388 EndDrag(surface_->window(), revert);
1389 return;
1390 case BoundsMode::FIXED:
1391 break;
1392 }
1393
1394 NOTREACHED();
1395 }
1396
1397 void ShellSurface::EndDrag(aura::Window* window, bool revert) {
1308 if (revert) 1398 if (revert)
1309 resizer_->RevertDrag(); 1399 resizer_->RevertDrag();
1310 else 1400 else
1311 resizer_->CompleteDrag(); 1401 resizer_->CompleteDrag();
1312 1402
1313 WMHelper::GetInstance()->RemovePreTargetHandler(this); 1403 WMHelper::GetInstance()->RemovePreTargetHandler(this);
1314 widget_->GetNativeWindow()->ReleaseCapture(); 1404 window->ReleaseCapture();
1315 resizer_.reset(); 1405 resizer_.reset();
1316
1317 // Notify client that resizing state has changed.
1318 if (was_resizing)
1319 Configure();
1320
1321 UpdateWidgetBounds();
1322 } 1406 }
1323 1407
1324 bool ShellSurface::IsResizing() const { 1408 bool ShellSurface::IsResizing() const {
1325 ash::wm::WindowState* window_state = 1409 ash::wm::WindowState* window_state =
1326 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1410 ash::wm::GetWindowState(widget_->GetNativeWindow());
1327 if (!window_state->is_dragged()) 1411 if (!window_state->is_dragged())
1328 return false; 1412 return false;
1329 1413
1330 return window_state->drag_details()->bounds_change & 1414 return window_state->drag_details()->bounds_change &
1331 ash::WindowResizer::kBoundsChange_Resizes; 1415 ash::WindowResizer::kBoundsChange_Resizes;
1332 } 1416 }
1333 1417
1334 gfx::Rect ShellSurface::GetVisibleBounds() const { 1418 gfx::Rect ShellSurface::GetVisibleBounds() const {
1335 // Use |geometry_| if set, otherwise use the visual bounds of the surface. 1419 // Use |geometry_| if set, otherwise use the visual bounds of the surface.
1336 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) 1420 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size())
1337 : geometry_; 1421 : geometry_;
1338 } 1422 }
1339 1423
1340 gfx::Point ShellSurface::GetSurfaceOrigin() const { 1424 gfx::Point ShellSurface::GetSurfaceOrigin() const {
1341 // For client-positioned shell surfaces, the surface origin corresponds to the 1425 // For client-positioned shell surfaces, the surface origin corresponds to the
1342 // widget position relative to the origin specified by the client. Since the 1426 // widget position relative to the origin specified by the client. Since the
1343 // surface is positioned relative to the widget, negate this vector to align 1427 // surface is positioned relative to the widget, negate this vector to align
1344 // the surface with the widget. 1428 // the surface with the widget. Note that the widget position must have been
1429 // adjusted by the |origin_offset_| prior to this call.
1345 if (bounds_mode_ != BoundsMode::SHELL) { 1430 if (bounds_mode_ != BoundsMode::SHELL) {
1346 gfx::Point position = widget_->GetNativeWindow()->bounds().origin(); 1431 gfx::Point position = widget_->GetNativeWindow()->bounds().origin();
1347 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position); 1432 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position);
1348 return origin_ - position.OffsetFromOrigin(); 1433 return origin_ - position.OffsetFromOrigin();
1349 } 1434 }
1350 1435
1351 gfx::Rect visible_bounds = GetVisibleBounds(); 1436 gfx::Rect visible_bounds = GetVisibleBounds();
1352 gfx::Rect client_bounds = 1437 gfx::Rect client_bounds =
1353 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1438 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1354 switch (resize_component_) { 1439 switch (resize_component_) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 if (!pending_configs_.empty() || scoped_configure_) 1482 if (!pending_configs_.empty() || scoped_configure_)
1398 return; 1483 return;
1399 1484
1400 gfx::Rect visible_bounds = GetVisibleBounds(); 1485 gfx::Rect visible_bounds = GetVisibleBounds();
1401 gfx::Rect new_widget_bounds = 1486 gfx::Rect new_widget_bounds =
1402 widget_->non_client_view()->GetWindowBoundsForClientBounds( 1487 widget_->non_client_view()->GetWindowBoundsForClientBounds(
1403 visible_bounds); 1488 visible_bounds);
1404 1489
1405 switch (bounds_mode_) { 1490 switch (bounds_mode_) {
1406 case BoundsMode::CLIENT: 1491 case BoundsMode::CLIENT:
1492 // Position is relative to the latest origin acknowledged by the client.
1493 new_widget_bounds -= origin_offset_;
1494 break;
1407 case BoundsMode::FIXED: 1495 case BoundsMode::FIXED:
1408 // Position is relative to the origin. 1496 // Position is relative to the origin.
1409 new_widget_bounds += origin_.OffsetFromOrigin(); 1497 new_widget_bounds += origin_.OffsetFromOrigin();
1410 break; 1498 break;
1411 case BoundsMode::SHELL: 1499 case BoundsMode::SHELL:
1412 // Update widget origin using the surface origin if the current location 1500 // Update widget origin using the surface origin if the current location
1413 // of surface is being anchored to one side of the widget as a result of a 1501 // of surface is being anchored to one side of the widget as a result of a
1414 // resize operation. 1502 // resize operation.
1415 if (resize_component_ != HTCAPTION) { 1503 if (resize_component_ != HTCAPTION) {
1416 gfx::Point widget_origin = 1504 gfx::Point widget_origin =
1417 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); 1505 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
1418 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &widget_origin); 1506 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &widget_origin);
1419 new_widget_bounds.set_origin(widget_origin); 1507 new_widget_bounds.set_origin(widget_origin);
1420 } else { 1508 } else {
1421 // Preserve widget position. 1509 // Preserve widget position.
1422 new_widget_bounds.set_origin( 1510 new_widget_bounds.set_origin(
1423 widget_->GetWindowBoundsInScreen().origin()); 1511 widget_->GetWindowBoundsInScreen().origin());
1424 } 1512 }
1425 break; 1513 break;
1426 } 1514 }
1427 1515
1428 // Set |ignore_window_bounds_changes_| as this change to window bounds 1516 // Set |ignore_window_bounds_changes_| as this change to window bounds
1429 // should not result in a configure request. 1517 // should not result in a configure request.
1430 DCHECK(!ignore_window_bounds_changes_); 1518 DCHECK(!ignore_window_bounds_changes_);
1431 ignore_window_bounds_changes_ = true; 1519 ignore_window_bounds_changes_ = true;
1432 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) 1520 const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen();
1433 widget_->SetBounds(new_widget_bounds); 1521 if (widget_bounds != new_widget_bounds) {
1522 if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) {
1523 widget_->SetBounds(new_widget_bounds);
1524 UpdateSurfaceBounds();
1525 } else {
1526 // TODO(domlaskowski): Synchronize window state transitions with the
1527 // client, and abort client-side dragging on transition to fullscreen.
1528 LOG_IF(ERROR, widget_bounds.size() != new_widget_bounds.size())
1529 << "Window size changed during client-driven drag";
1530
1531 // Convert from screen to display coordinates.
1532 gfx::Point origin = new_widget_bounds.origin();
1533 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
1534 new_widget_bounds.set_origin(origin);
1535
1536 // Move the window relative to the current display.
1537 widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
1538 UpdateSurfaceBounds();
1539
1540 // Render phantom windows when beyond the current display.
1541 resizer_->Drag(GetMouseLocation(), 0);
1542 }
1543 }
1544
1434 ignore_window_bounds_changes_ = false; 1545 ignore_window_bounds_changes_ = false;
1435 } 1546 }
1436 1547
1437 void ShellSurface::UpdateSurfaceBounds() { 1548 void ShellSurface::UpdateSurfaceBounds() {
1438 gfx::Rect client_view_bounds = 1549 gfx::Rect client_view_bounds =
1439 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1550 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1440 1551
1441 surface_->window()->SetBounds( 1552 surface_->window()->SetBounds(
1442 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), 1553 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
1443 surface_->window()->layer()->size())); 1554 surface_->window()->layer()->size()));
(...skipping 15 matching lines...) Expand all
1459 if (shadow_underlay_bounds.IsEmpty()) 1570 if (shadow_underlay_bounds.IsEmpty())
1460 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); 1571 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size());
1461 1572
1462 if (!shadow_underlay_in_surface_) { 1573 if (!shadow_underlay_in_surface_) {
1463 shadow_content_bounds = shadow_content_bounds_; 1574 shadow_content_bounds = shadow_content_bounds_;
1464 if (shadow_content_bounds.IsEmpty()) { 1575 if (shadow_content_bounds.IsEmpty()) {
1465 shadow_content_bounds = window->bounds(); 1576 shadow_content_bounds = window->bounds();
1466 } 1577 }
1467 } 1578 }
1468 1579
1469 // TODO(oshima): Adjust the coordinates from client screen to 1580 gfx::Point shadow_origin = shadow_content_bounds.origin() - origin_offset_;
1470 // chromeos screen when multi displays are supported. 1581 wm::ConvertPointFromScreen(window->parent(), &shadow_origin);
1471 gfx::Point origin = window->bounds().origin(); 1582 shadow_origin -= window->bounds().OffsetFromOrigin();
1472 gfx::Point shadow_origin = shadow_content_bounds.origin();
1473 shadow_origin -= origin.OffsetFromOrigin();
1474 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); 1583 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size());
1475 1584
1476 // Always create and show the underlay, even in maximized/fullscreen. 1585 // Always create and show the underlay, even in maximized/fullscreen.
1477 if (!shadow_underlay_) { 1586 if (!shadow_underlay_) {
1478 shadow_underlay_ = new aura::Window(nullptr); 1587 shadow_underlay_ = new aura::Window(nullptr);
1479 shadow_underlay_event_handler_ = 1588 shadow_underlay_event_handler_ =
1480 base::MakeUnique<ShadowUnderlayEventHandler>(); 1589 base::MakeUnique<ShadowUnderlayEventHandler>();
1481 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); 1590 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
1482 DCHECK(shadow_underlay_->owned_by_parent()); 1591 DCHECK(shadow_underlay_->owned_by_parent());
1483 // Ensure the background area inside the shadow is solid black. 1592 // Ensure the background area inside the shadow is solid black.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 // Surfaces that can't be activated are usually menus and tooltips. Use a 1677 // Surfaces that can't be activated are usually menus and tooltips. Use a
1569 // small style shadow for them. 1678 // small style shadow for them.
1570 if (!activatable_) 1679 if (!activatable_)
1571 shadow->SetElevation(wm::ShadowElevation::SMALL); 1680 shadow->SetElevation(wm::ShadowElevation::SMALL);
1572 // We don't have rounded corners unless frame is enabled. 1681 // We don't have rounded corners unless frame is enabled.
1573 if (!frame_enabled_) 1682 if (!frame_enabled_)
1574 shadow->SetRoundedCornerRadius(0); 1683 shadow->SetRoundedCornerRadius(0);
1575 } 1684 }
1576 } 1685 }
1577 1686
1687 gfx::Point ShellSurface::GetMouseLocation() const {
1688 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
1689 gfx::Point location =
1690 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1691 aura::Window::ConvertPointToTarget(
1692 root_window, widget_->GetNativeWindow()->parent(), &location);
1693 return location;
1694 }
1695
1578 } // namespace exo 1696 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698