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

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

Issue 2645663004: exo: Initial support for multiple displays in ARC (Closed)
Patch Set: Fix bad merge in test 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 349 }
329 } 350 }
330 351
331 //////////////////////////////////////////////////////////////////////////////// 352 ////////////////////////////////////////////////////////////////////////////////
332 // ShellSurface, public: 353 // ShellSurface, public:
333 354
334 DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) 355 DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
335 356
336 ShellSurface::ShellSurface(Surface* surface, 357 ShellSurface::ShellSurface(Surface* surface,
337 ShellSurface* parent, 358 ShellSurface* parent,
338 const gfx::Rect& initial_bounds, 359 BoundsMode bounds_mode,
360 const gfx::Point& origin,
339 bool activatable, 361 bool activatable,
340 bool can_minimize, 362 bool can_minimize,
341 int container) 363 int container)
342 : widget_(nullptr), 364 : widget_(nullptr),
343 surface_(surface), 365 surface_(surface),
344 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), 366 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr),
345 initial_bounds_(initial_bounds), 367 bounds_mode_(bounds_mode),
368 origin_(origin),
346 activatable_(activatable), 369 activatable_(activatable),
347 can_minimize_(can_minimize), 370 can_minimize_(can_minimize),
348 container_(container) { 371 container_(container) {
349 WMHelper::GetInstance()->AddActivationObserver(this); 372 WMHelper::GetInstance()->AddActivationObserver(this);
350 surface_->SetSurfaceDelegate(this); 373 surface_->SetSurfaceDelegate(this);
351 surface_->AddSurfaceObserver(this); 374 surface_->AddSurfaceObserver(this);
352 surface_->window()->Show(); 375 surface_->window()->Show();
353 set_owned_by_client(); 376 set_owned_by_client();
354 if (parent_) 377 if (parent_)
355 parent_->AddObserver(this); 378 parent_->AddObserver(this);
356 } 379 }
357 380
358 ShellSurface::ShellSurface(Surface* surface) 381 ShellSurface::ShellSurface(Surface* surface)
359 : ShellSurface(surface, 382 : ShellSurface(surface,
360 nullptr, 383 nullptr,
361 gfx::Rect(), 384 BoundsMode::SHELL,
385 gfx::Point(),
362 true, 386 true,
363 true, 387 true,
364 ash::kShellWindowId_DefaultContainer) {} 388 ash::kShellWindowId_DefaultContainer) {}
365 389
366 ShellSurface::~ShellSurface() { 390 ShellSurface::~ShellSurface() {
367 DCHECK(!scoped_configure_); 391 DCHECK(!scoped_configure_);
368 if (resizer_) 392 if (resizer_)
369 EndDrag(false /* revert */); 393 EndDrag(false /* revert */);
370 if (widget_) { 394 if (widget_) {
371 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); 395 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this);
372 widget_->GetNativeWindow()->RemoveObserver(this); 396 widget_->GetNativeWindow()->RemoveObserver(this);
373 // Remove transient children so they are not automatically destroyed. 397 // Remove transient children so they are not automatically destroyed.
374 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow())) 398 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow()))
375 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); 399 wm::RemoveTransientChild(widget_->GetNativeWindow(), child);
376 if (widget_->IsVisible()) 400 if (widget_->IsVisible())
377 widget_->Hide(); 401 widget_->Hide();
378 widget_->CloseNow(); 402 widget_->CloseNow();
379 } 403 }
380 WMHelper::GetInstance()->RemoveActivationObserver(this); 404 WMHelper::GetInstance()->RemoveActivationObserver(this);
381 if (parent_) 405 if (parent_)
382 parent_->RemoveObserver(this); 406 parent_->RemoveObserver(this);
383 if (surface_) { 407 if (surface_) {
384 if (scale_ != 1.0) 408 if (scale_ != 1.0)
385 surface_->window()->SetTransform(gfx::Transform()); 409 surface_->window()->SetTransform(gfx::Transform());
386 surface_->SetSurfaceDelegate(nullptr); 410 surface_->SetSurfaceDelegate(nullptr);
387 surface_->RemoveSurfaceObserver(this); 411 surface_->RemoveSurfaceObserver(this);
388 } 412 }
389 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); 413 WMHelper::GetInstance()->RemoveAccessibilityObserver(this);
414
415 if (!destroyed_callback_.is_null())
416 destroyed_callback_.Run();
390 } 417 }
391 418
392 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { 419 void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
393 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); 420 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial);
394 421
395 // 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
396 // 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
397 // change to reflect the acknowledgement of configure request with |serial| 424 // change to reflect the acknowledgement of configure request with |serial|
398 // at the next call to Commit(). 425 // at the next call to Commit().
399 while (!pending_configs_.empty()) { 426 while (!pending_configs_.empty()) {
400 auto config = pending_configs_.front(); 427 auto config = pending_configs_.front();
401 pending_configs_.pop_front(); 428 pending_configs_.pop_front();
402 429
403 // 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
404 // Commit() is called. 431 // Commit() is called.
405 pending_origin_offset_ += config.origin_offset; 432 pending_origin_offset_ += config.origin_offset;
406 433
407 // 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.
408 pending_resize_component_ = config.resize_component; 435 pending_resize_component_ = config.resize_component;
409 436
410 if (config.serial == serial) 437 if (config.serial == serial)
411 break; 438 break;
412 } 439 }
413 440
414 if (widget_) 441 if (widget_) {
415 UpdateWidgetBounds(); 442 UpdateWidgetBounds();
443 UpdateShadow();
444 }
416 } 445 }
417 446
418 void ShellSurface::SetParent(ShellSurface* parent) { 447 void ShellSurface::SetParent(ShellSurface* parent) {
419 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent", 448 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent",
420 parent ? base::UTF16ToASCII(parent->title_) : "null"); 449 parent ? base::UTF16ToASCII(parent->title_) : "null");
421 450
422 if (parent_) { 451 if (parent_) {
423 parent_->RemoveObserver(this); 452 parent_->RemoveObserver(this);
424 if (widget_) 453 if (widget_)
425 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow()); 454 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow());
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 void ShellSurface::SetApplicationId(const std::string& application_id) { 586 void ShellSurface::SetApplicationId(const std::string& application_id) {
558 // 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.
559 application_id_ = application_id; 588 application_id_ = application_id;
560 if (widget_ && widget_->GetNativeWindow()) 589 if (widget_ && widget_->GetNativeWindow())
561 SetApplicationId(widget_->GetNativeWindow(), application_id); 590 SetApplicationId(widget_->GetNativeWindow(), application_id);
562 } 591 }
563 592
564 void ShellSurface::Move() { 593 void ShellSurface::Move() {
565 TRACE_EVENT0("exo", "ShellSurface::Move"); 594 TRACE_EVENT0("exo", "ShellSurface::Move");
566 595
567 if (widget_ && !widget_->movement_disabled()) 596 if (!widget_ || resizer_)
568 AttemptToStartDrag(HTCAPTION); 597 return;
598
599 switch (bounds_mode_) {
600 case BoundsMode::SHELL:
601 AttemptToStartDrag(HTCAPTION);
602 break;
603 case BoundsMode::CLIENT:
604 AttemptToStartClientDrag();
605 break;
606 case BoundsMode::FIXED:
607 NOTREACHED();
608 break;
609 }
569 } 610 }
570 611
571 void ShellSurface::Resize(int component) { 612 void ShellSurface::Resize(int component) {
572 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); 613 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component);
573 614
574 if (widget_ && !widget_->movement_disabled()) 615 if (!widget_ || resizer_)
575 AttemptToStartDrag(component); 616 return;
617
618 switch (bounds_mode_) {
619 case BoundsMode::SHELL:
620 AttemptToStartDrag(component);
621 break;
622 case BoundsMode::CLIENT:
623 case BoundsMode::FIXED:
624 NOTREACHED();
625 break;
626 }
576 } 627 }
577 628
578 void ShellSurface::Close() { 629 void ShellSurface::Close() {
579 if (!close_callback_.is_null()) 630 if (!close_callback_.is_null())
580 close_callback_.Run(); 631 close_callback_.Run();
581 } 632 }
582 633
583 void ShellSurface::SetGeometry(const gfx::Rect& geometry) { 634 void ShellSurface::SetGeometry(const gfx::Rect& geometry) {
584 TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry", 635 TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry",
585 geometry.ToString()); 636 geometry.ToString());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 693
643 void ShellSurface::SetTopInset(int height) { 694 void ShellSurface::SetTopInset(int height) {
644 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); 695 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height);
645 696
646 pending_top_inset_height_ = height; 697 pending_top_inset_height_ = height;
647 } 698 }
648 699
649 void ShellSurface::SetOrigin(const gfx::Point& origin) { 700 void ShellSurface::SetOrigin(const gfx::Point& origin) {
650 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); 701 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString());
651 702
652 initial_bounds_ = gfx::Rect(origin, gfx::Size(1, 1)); 703 const gfx::Point old_origin = origin_;
704 origin_ = origin;
705
706 if (bounds_mode_ != BoundsMode::CLIENT || origin == old_origin)
707 return;
708
709 // If the origin changed, give the client a chance to adjust window positions
710 // before switching to the new coordinate system. Retain the old origin by
711 // reverting the origin delta until the next configure is acknowledged.
712 const gfx::Vector2d delta = origin - old_origin;
713 origin_offset_ -= delta;
714 pending_origin_offset_accumulator_ += delta;
715
716 if (widget_) {
717 UpdateWidgetBounds();
718 UpdateShadow();
719 }
720
721 Configure();
653 } 722 }
654 723
655 void ShellSurface::SetActivatable(bool activatable) { 724 void ShellSurface::SetActivatable(bool activatable) {
656 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", 725 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable",
657 activatable); 726 activatable);
658 727
659 activatable_ = activatable; 728 activatable_ = activatable;
660 } 729 }
661 730
662 void ShellSurface::SetContainer(int container) { 731 void ShellSurface::SetContainer(int container) {
(...skipping 26 matching lines...) Expand all
689 758
690 //////////////////////////////////////////////////////////////////////////////// 759 ////////////////////////////////////////////////////////////////////////////////
691 // SurfaceDelegate overrides: 760 // SurfaceDelegate overrides:
692 761
693 void ShellSurface::OnSurfaceCommit() { 762 void ShellSurface::OnSurfaceCommit() {
694 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); 763 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
695 surface_->CommitSurfaceHierarchy(); 764 surface_->CommitSurfaceHierarchy();
696 765
697 if (enabled() && !widget_) { 766 if (enabled() && !widget_) {
698 // Defer widget creation until surface contains some contents. 767 // Defer widget creation until surface contains some contents.
699 if (surface_->content_size().IsEmpty()) 768 if (surface_->content_size().IsEmpty()) {
700 Configure(); 769 Configure();
701 else 770 return;
702 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); 771 }
772
773 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
703 } 774 }
704 775
705 // Apply the accumulated pending origin offset to reflect acknowledged 776 // Apply the accumulated pending origin offset to reflect acknowledged
706 // configure requests. 777 // configure requests.
707 origin_ += pending_origin_offset_; 778 origin_offset_ += pending_origin_offset_;
708 pending_origin_offset_ = gfx::Vector2d(); 779 pending_origin_offset_ = gfx::Vector2d();
709 780
710 // Update resize direction to reflect acknowledged configure requests. 781 // Update resize direction to reflect acknowledged configure requests.
711 resize_component_ = pending_resize_component_; 782 resize_component_ = pending_resize_component_;
712 783
713 if (widget_) { 784 if (widget_) {
714 // Apply new window geometry. 785 // Apply new window geometry.
715 geometry_ = pending_geometry_; 786 geometry_ = pending_geometry_;
716 787
717 UpdateWidgetBounds(); 788 UpdateWidgetBounds();
(...skipping 18 matching lines...) Expand all
736 if (activatable != CanActivate()) { 807 if (activatable != CanActivate()) {
737 set_can_activate(activatable); 808 set_can_activate(activatable);
738 // Activate or deactivate window if activation state changed. 809 // Activate or deactivate window if activation state changed.
739 if (activatable) 810 if (activatable)
740 wm::ActivateWindow(widget_->GetNativeWindow()); 811 wm::ActivateWindow(widget_->GetNativeWindow());
741 else if (widget_->IsActive()) 812 else if (widget_->IsActive())
742 wm::DeactivateWindow(widget_->GetNativeWindow()); 813 wm::DeactivateWindow(widget_->GetNativeWindow());
743 } 814 }
744 } 815 }
745 816
746 gfx::Rect client_view_bounds = 817 UpdateSurfaceBounds();
747 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
748
749 // Update surface bounds.
750 surface_->window()->SetBounds(
751 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
752 surface_->window()->layer()->size()));
753 818
754 // Update surface scale. 819 // Update surface scale.
755 if (pending_scale_ != scale_) { 820 if (pending_scale_ != scale_) {
756 gfx::Transform transform; 821 gfx::Transform transform;
757 DCHECK_NE(pending_scale_, 0.0); 822 DCHECK_NE(pending_scale_, 0.0);
758 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); 823 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_);
759 surface_->window()->SetTransform(transform); 824 surface_->window()->SetTransform(transform);
760 scale_ = pending_scale_; 825 scale_ = pending_scale_;
761 } 826 }
762 827
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 // destroyed callback may destroy the ShellSurface instance. This call needs 864 // destroyed callback may destroy the ShellSurface instance. This call needs
800 // to be last so that the instance can be destroyed. 865 // to be last so that the instance can be destroyed.
801 if (!surface_destroyed_callback_.is_null()) 866 if (!surface_destroyed_callback_.is_null())
802 surface_destroyed_callback_.Run(); 867 surface_destroyed_callback_.Run();
803 } 868 }
804 869
805 //////////////////////////////////////////////////////////////////////////////// 870 ////////////////////////////////////////////////////////////////////////////////
806 // views::WidgetDelegate overrides: 871 // views::WidgetDelegate overrides:
807 872
808 bool ShellSurface::CanResize() const { 873 bool ShellSurface::CanResize() const {
809 return initial_bounds_.IsEmpty(); 874 return bounds_mode_ == BoundsMode::SHELL;
810 } 875 }
811 876
812 bool ShellSurface::CanMaximize() const { 877 bool ShellSurface::CanMaximize() const {
813 // Shell surfaces in system modal container cannot be maximized. 878 // Shell surfaces in system modal container cannot be maximized.
814 if (container_ == ash::kShellWindowId_SystemModalContainer) 879 if (container_ == ash::kShellWindowId_SystemModalContainer)
815 return false; 880 return false;
816 881
817 // Non-transient shell surfaces can be maximized. 882 // Non-transient shell surfaces can be maximized.
818 return !parent_; 883 return !parent_;
819 } 884 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 ash::wm::WindowState* window_state, 958 ash::wm::WindowState* window_state,
894 ash::wm::WindowStateType old_type) { 959 ash::wm::WindowStateType old_type) {
895 ash::wm::WindowStateType new_type = window_state->GetStateType(); 960 ash::wm::WindowStateType new_type = window_state->GetStateType();
896 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 961 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
897 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 962 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
898 // When transitioning in/out of maximized or fullscreen mode we need to 963 // When transitioning in/out of maximized or fullscreen mode we need to
899 // make sure we have a configure callback before we allow the default 964 // make sure we have a configure callback before we allow the default
900 // cross-fade animations. The configure callback provides a mechanism for 965 // cross-fade animations. The configure callback provides a mechanism for
901 // the client to inform us that a frame has taken the state change into 966 // the client to inform us that a frame has taken the state change into
902 // account and without this cross-fade animations are unreliable. 967 // account and without this cross-fade animations are unreliable.
903 if (configure_callback_.is_null()) 968
969 // TODO(domlaskowski): For shell surfaces whose bounds are controlled by the
970 // client, the configure callback does not yet support window state changes.
971 if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT)
904 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); 972 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
905 } 973 }
906 } 974 }
907 975
908 void ShellSurface::OnPostWindowStateTypeChange( 976 void ShellSurface::OnPostWindowStateTypeChange(
909 ash::wm::WindowState* window_state, 977 ash::wm::WindowState* window_state,
910 ash::wm::WindowStateType old_type) { 978 ash::wm::WindowStateType old_type) {
911 ash::wm::WindowStateType new_type = window_state->GetStateType(); 979 ash::wm::WindowStateType new_type = window_state->GetStateType();
912 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 980 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
913 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 981 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
(...skipping 19 matching lines...) Expand all
933 const gfx::Rect& old_bounds, 1001 const gfx::Rect& old_bounds,
934 const gfx::Rect& new_bounds) { 1002 const gfx::Rect& new_bounds) {
935 if (!widget_ || !surface_ || ignore_window_bounds_changes_) 1003 if (!widget_ || !surface_ || ignore_window_bounds_changes_)
936 return; 1004 return;
937 1005
938 if (window == widget_->GetNativeWindow()) { 1006 if (window == widget_->GetNativeWindow()) {
939 if (new_bounds.size() == old_bounds.size()) 1007 if (new_bounds.size() == old_bounds.size())
940 return; 1008 return;
941 1009
942 // If size changed then give the client a chance to produce new contents 1010 // If size changed then give the client a chance to produce new contents
943 // before origin on screen is changed by adding offset to the next configure 1011 // before origin on screen is changed. Retain the old origin by reverting
944 // request and offset |origin_| by the same distance. 1012 // the origin delta until the next configure is acknowledged.
945 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin(); 1013 const gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin();
946 pending_origin_config_offset_ += origin_offset; 1014 origin_offset_ -= delta;
947 origin_ -= origin_offset; 1015 pending_origin_offset_accumulator_ += delta;
948 1016
949 gfx::Rect client_view_bounds = 1017 UpdateSurfaceBounds();
950 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
951
952 // Update surface bounds.
953 surface_->window()->SetBounds(
954 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
955 surface_->window()->layer()->size()));
956 1018
957 // The shadow size may be updated to match the widget. Change it back 1019 // The shadow size may be updated to match the widget. Change it back
958 // to the shadow content size. 1020 // to the shadow content size.
959 // TODO(oshima): When the arc window reiszing is enabled, we may want to 1021 // TODO(oshima): When the arc window reiszing is enabled, we may want to
960 // implement shadow management here instead of using shadow controller. 1022 // implement shadow management here instead of using shadow controller.
961 UpdateShadow(); 1023 UpdateShadow();
962 1024
963 Configure(); 1025 Configure();
964 } 1026 }
965 } 1027 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 1062
1001 //////////////////////////////////////////////////////////////////////////////// 1063 ////////////////////////////////////////////////////////////////////////////////
1002 // ui::EventHandler overrides: 1064 // ui::EventHandler overrides:
1003 1065
1004 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { 1066 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) {
1005 if (!resizer_) { 1067 if (!resizer_) {
1006 views::View::OnKeyEvent(event); 1068 views::View::OnKeyEvent(event);
1007 return; 1069 return;
1008 } 1070 }
1009 1071
1010 if (event->type() == ui::ET_KEY_PRESSED && 1072 if (bounds_mode_ == BoundsMode::SHELL &&
1073 event->type() == ui::ET_KEY_PRESSED &&
1011 event->key_code() == ui::VKEY_ESCAPE) { 1074 event->key_code() == ui::VKEY_ESCAPE) {
1012 EndDrag(true /* revert */); 1075 EndDrag(true /* revert */);
1013 } 1076 }
1014 } 1077 }
1015 1078
1016 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) { 1079 void ShellSurface::OnMouseEvent(ui::MouseEvent* event) {
1017 if (!resizer_) { 1080 if (!resizer_) {
1018 views::View::OnMouseEvent(event); 1081 views::View::OnMouseEvent(event);
1019 return; 1082 return;
1020 } 1083 }
1021 1084
1022 if (event->handled()) 1085 if (event->handled())
1023 return; 1086 return;
1024 1087
1025 if ((event->flags() & 1088 if ((event->flags() &
1026 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0) 1089 (ui::EF_MIDDLE_MOUSE_BUTTON | ui::EF_RIGHT_MOUSE_BUTTON)) != 0)
1027 return; 1090 return;
1028 1091
1029 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { 1092 if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) {
1030 // We complete the drag instead of reverting it, as reverting it will 1093 // We complete the drag instead of reverting it, as reverting it will
1031 // result in a weird behavior when a client produces a modal dialog 1094 // result in a weird behavior when a client produces a modal dialog
1032 // while the drag is in progress. 1095 // while the drag is in progress.
1033 EndDrag(false /* revert */); 1096 EndDrag(false /* revert */);
1034 return; 1097 return;
1035 } 1098 }
1036 1099
1037 switch (event->type()) { 1100 switch (event->type()) {
1038 case ui::ET_MOUSE_DRAGGED: { 1101 case ui::ET_MOUSE_DRAGGED: {
1102 if (bounds_mode_ == BoundsMode::CLIENT)
1103 break;
1104
1039 gfx::Point location(event->location()); 1105 gfx::Point location(event->location());
1040 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(), 1106 aura::Window::ConvertPointToTarget(widget_->GetNativeWindow(),
1041 widget_->GetNativeWindow()->parent(), 1107 widget_->GetNativeWindow()->parent(),
1042 &location); 1108 &location);
1043 ScopedConfigure scoped_configure(this, false); 1109 ScopedConfigure scoped_configure(this, false);
1044 resizer_->Drag(location, event->flags()); 1110 resizer_->Drag(location, event->flags());
1045 event->StopPropagation(); 1111 event->StopPropagation();
1046 break; 1112 break;
1047 } 1113 }
1048 case ui::ET_MOUSE_RELEASED: { 1114 case ui::ET_MOUSE_RELEASED: {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 views::Widget::InitParams params; 1153 views::Widget::InitParams params;
1088 params.type = views::Widget::InitParams::TYPE_WINDOW; 1154 params.type = views::Widget::InitParams::TYPE_WINDOW;
1089 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; 1155 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
1090 params.delegate = this; 1156 params.delegate = this;
1091 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 1157 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
1092 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 1158 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
1093 params.show_state = show_state; 1159 params.show_state = show_state;
1094 // Make shell surface a transient child if |parent_| has been set. 1160 // Make shell surface a transient child if |parent_| has been set.
1095 params.parent = 1161 params.parent =
1096 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_); 1162 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_);
1097 params.bounds = initial_bounds_; 1163 params.bounds = gfx::Rect(origin_, gfx::Size());
1098 bool activatable = activatable_; 1164 bool activatable = activatable_;
1099 // ShellSurfaces in system modal container are only activatable if input 1165 // ShellSurfaces in system modal container are only activatable if input
1100 // region is non-empty. See OnCommitSurface() for more details. 1166 // region is non-empty. See OnCommitSurface() for more details.
1101 if (container_ == ash::kShellWindowId_SystemModalContainer) 1167 if (container_ == ash::kShellWindowId_SystemModalContainer)
1102 activatable &= !surface_->GetHitTestBounds().IsEmpty(); 1168 activatable &= !surface_->GetHitTestBounds().IsEmpty();
1103 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES 1169 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES
1104 : views::Widget::InitParams::ACTIVATABLE_NO; 1170 : views::Widget::InitParams::ACTIVATABLE_NO;
1105 1171
1106 // Note: NativeWidget owns this widget. 1172 // Note: NativeWidget owns this widget.
1107 widget_ = new ShellSurfaceWidget(this); 1173 widget_ = new ShellSurfaceWidget(this);
1108 widget_->Init(params); 1174 widget_->Init(params);
1109 1175
1110 aura::Window* window = widget_->GetNativeWindow(); 1176 aura::Window* window = widget_->GetNativeWindow();
1111 window->SetName("ExoShellSurface"); 1177 window->SetName("ExoShellSurface");
1112 window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey, 1178 window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey,
1113 false); 1179 false);
1114 window->AddChild(surface_->window()); 1180 window->AddChild(surface_->window());
1115 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_))); 1181 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_)));
1116 SetApplicationId(window, application_id_); 1182 SetApplicationId(window, application_id_);
1117 SetMainSurface(window, surface_); 1183 SetMainSurface(window, surface_);
1118 1184
1185 const bool client_controls_bounds = bounds_mode_ == BoundsMode::CLIENT;
1186
1119 // Start tracking changes to window bounds and window state. 1187 // Start tracking changes to window bounds and window state.
1120 window->AddObserver(this); 1188 if (!client_controls_bounds)
1189 window->AddObserver(this);
1121 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); 1190 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
1122 window_state->AddObserver(this); 1191 window_state->AddObserver(this);
1123 1192
1124 // Absolete positioned shell surfaces may request the bounds that does not 1193 // Allow the client to request bounds that do not fill the entire work area
1125 // fill the entire work area / display in maximized / fullscreen state. 1194 // when maximized, or the entire display when fullscreen.
1126 // Allow such clients to update the bounds in these states. 1195 window_state->set_allow_set_bounds_in_maximized(client_controls_bounds);
1127 if (!initial_bounds_.IsEmpty())
1128 window_state->set_allow_set_bounds_in_maximized(true);
1129 1196
1130 // Notify client of initial state if different than normal. 1197 // Notify client of initial state if different than normal.
1131 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL && 1198 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL &&
1132 !state_changed_callback_.is_null()) { 1199 !state_changed_callback_.is_null()) {
1133 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL, 1200 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL,
1134 window_state->GetStateType()); 1201 window_state->GetStateType());
1135 } 1202 }
1136 1203
1137 // Disable movement if initial bounds were specified. 1204 // Disable movement if bounds are controlled by the client or fixed.
1138 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); 1205 const bool movement_disabled = bounds_mode_ != BoundsMode::SHELL;
1139 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); 1206 widget_->set_movement_disabled(movement_disabled);
1207 window_state->set_ignore_keyboard_bounds_change(movement_disabled);
1140 1208
1141 // AutoHide shelf in fullscreen state. 1209 // AutoHide shelf in fullscreen state.
1142 window_state->set_hide_shelf_when_fullscreen(false); 1210 window_state->set_hide_shelf_when_fullscreen(false);
1143 1211
1144 // Fade visibility animations for non-activatable windows. 1212 // Fade visibility animations for non-activatable windows.
1145 if (!activatable_) { 1213 if (!activatable_) {
1146 wm::SetWindowVisibilityAnimationType( 1214 wm::SetWindowVisibilityAnimationType(
1147 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); 1215 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
1148 } 1216 }
1149 1217
(...skipping 12 matching lines...) Expand all
1162 pending_show_widget_ = true; 1230 pending_show_widget_ = true;
1163 } 1231 }
1164 1232
1165 void ShellSurface::Configure() { 1233 void ShellSurface::Configure() {
1166 // Delay configure callback if |scoped_configure_| is set. 1234 // Delay configure callback if |scoped_configure_| is set.
1167 if (scoped_configure_) { 1235 if (scoped_configure_) {
1168 scoped_configure_->set_needs_configure(); 1236 scoped_configure_->set_needs_configure();
1169 return; 1237 return;
1170 } 1238 }
1171 1239
1172 gfx::Vector2d origin_offset = pending_origin_config_offset_; 1240 const gfx::Vector2d origin_offset = pending_origin_offset_accumulator_;
1173 pending_origin_config_offset_ = gfx::Vector2d(); 1241 pending_origin_offset_accumulator_ = gfx::Vector2d();
1174 1242
1175 int resize_component = HTCAPTION; 1243 int resize_component = HTCAPTION;
1176 if (widget_) { 1244 if (widget_) {
1177 ash::wm::WindowState* window_state = 1245 ash::wm::WindowState* window_state =
1178 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1246 ash::wm::GetWindowState(widget_->GetNativeWindow());
1179 1247
1180 // If surface is being resized, save the resize direction. 1248 // If surface is being resized, save the resize direction.
1181 if (window_state->is_dragged()) 1249 if (window_state->is_dragged())
1182 resize_component = window_state->drag_details()->window_component; 1250 resize_component = window_state->drag_details()->window_component;
1183 } 1251 }
1184 1252
1185 uint32_t serial = 0; 1253 uint32_t serial = 0;
1186 if (!configure_callback_.is_null()) { 1254 if (!configure_callback_.is_null()) {
1187 if (widget_) { 1255 if (widget_) {
1188 const views::NonClientView* non_client_view = widget_->non_client_view(); 1256 const views::NonClientView* non_client_view = widget_->non_client_view();
1189 serial = configure_callback_.Run( 1257 serial = configure_callback_.Run(
1190 non_client_view->frame_view()->GetBoundsForClientView().size(), 1258 non_client_view->frame_view()->GetBoundsForClientView().size(),
1191 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), 1259 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(),
1192 IsResizing(), widget_->IsActive()); 1260 IsResizing(), widget_->IsActive(), origin_);
1193 } else { 1261 } else {
1194 serial = configure_callback_.Run( 1262 serial = configure_callback_.Run(gfx::Size(),
1195 gfx::Size(), ash::wm::WINDOW_STATE_TYPE_NORMAL, false, false); 1263 ash::wm::WINDOW_STATE_TYPE_NORMAL, false,
1264 false, origin_);
1196 } 1265 }
1197 } 1266 }
1198 1267
1199 if (!serial) { 1268 if (!serial) {
1200 pending_origin_offset_ += origin_offset; 1269 pending_origin_offset_ += origin_offset;
1201 pending_resize_component_ = resize_component; 1270 pending_resize_component_ = resize_component;
1202 return; 1271 return;
1203 } 1272 }
1204 1273
1205 // Apply origin offset and resize component at the first Commit() after this 1274 // Apply origin offset and resize component at the first Commit() after this
1206 // configure request has been acknowledged. 1275 // configure request has been acknowledged.
1207 pending_configs_.push_back({serial, origin_offset, resize_component}); 1276 pending_configs_.push_back({serial, origin_offset, resize_component});
1208 LOG_IF(WARNING, pending_configs_.size() > 100) 1277 LOG_IF(WARNING, pending_configs_.size() > 100)
1209 << "Number of pending configure acks for shell surface has reached: " 1278 << "Number of pending configure acks for shell surface has reached: "
1210 << pending_configs_.size(); 1279 << pending_configs_.size();
1211 } 1280 }
1212 1281
1213 void ShellSurface::AttemptToStartDrag(int component) { 1282 void ShellSurface::AttemptToStartDrag(int component) {
1214 DCHECK(widget_); 1283 DCHECK(widget_);
1215 1284
1216 // Cannot start another drag if one is already taking place.
1217 if (resizer_)
1218 return;
1219
1220 if (widget_->GetNativeWindow()->HasCapture()) 1285 if (widget_->GetNativeWindow()->HasCapture())
1221 return; 1286 return;
1222 1287
1223 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow();
1224 gfx::Point drag_location =
1225 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1226 aura::Window::ConvertPointToTarget(
1227 root_window, widget_->GetNativeWindow()->parent(), &drag_location);
1228
1229 // Set the cursor before calling CreateWindowResizer(), as that will 1288 // Set the cursor before calling CreateWindowResizer(), as that will
1230 // eventually call LockCursor() and prevent the cursor from changing. 1289 // eventually call LockCursor() and prevent the cursor from changing.
1231 aura::client::CursorClient* cursor_client = 1290 aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
1232 aura::client::GetCursorClient(root_window); 1291 widget_->GetNativeWindow()->GetRootWindow());
1233 DCHECK(cursor_client); 1292 DCHECK(cursor_client);
1234 1293
1235 switch (component) { 1294 switch (component) {
1236 case HTCAPTION: 1295 case HTCAPTION:
1237 cursor_client->SetCursor(ui::kCursorPointer); 1296 cursor_client->SetCursor(ui::kCursorPointer);
1238 break; 1297 break;
1239 case HTTOP: 1298 case HTTOP:
1240 cursor_client->SetCursor(ui::kCursorNorthResize); 1299 cursor_client->SetCursor(ui::kCursorNorthResize);
1241 break; 1300 break;
1242 case HTTOPRIGHT: 1301 case HTTOPRIGHT:
(...skipping 16 matching lines...) Expand all
1259 break; 1318 break;
1260 case HTTOPLEFT: 1319 case HTTOPLEFT:
1261 cursor_client->SetCursor(ui::kCursorNorthWestResize); 1320 cursor_client->SetCursor(ui::kCursorNorthWestResize);
1262 break; 1321 break;
1263 default: 1322 default:
1264 NOTREACHED(); 1323 NOTREACHED();
1265 break; 1324 break;
1266 } 1325 }
1267 1326
1268 resizer_ = ash::CreateWindowResizer( 1327 resizer_ = ash::CreateWindowResizer(
1269 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, 1328 ash::WmWindow::Get(widget_->GetNativeWindow()), GetMouseLocation(),
1270 aura::client::WINDOW_MOVE_SOURCE_MOUSE); 1329 component, aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1271 if (!resizer_) 1330 if (!resizer_)
1272 return; 1331 return;
1273 1332
1274 // Apply pending origin offsets and resize direction before starting a new 1333 // Apply pending origin offsets and resize direction before starting a new
1275 // resize operation. These can still be pending if the client has acknowledged 1334 // resize operation. These can still be pending if the client has acknowledged
1276 // the configure request but not yet called Commit(). 1335 // the configure request but not yet called Commit().
1277 origin_ += pending_origin_offset_; 1336 origin_offset_ += pending_origin_offset_;
1278 pending_origin_offset_ = gfx::Vector2d(); 1337 pending_origin_offset_ = gfx::Vector2d();
1279 resize_component_ = pending_resize_component_; 1338 resize_component_ = pending_resize_component_;
1280 1339
1281 WMHelper::GetInstance()->AddPreTargetHandler(this); 1340 WMHelper::GetInstance()->AddPreTargetHandler(this);
1282 widget_->GetNativeWindow()->SetCapture(); 1341 widget_->GetNativeWindow()->SetCapture();
1283 1342
1284 // Notify client that resizing state has changed. 1343 // Notify client that resizing state has changed.
1285 if (IsResizing()) 1344 if (IsResizing())
1286 Configure(); 1345 Configure();
1287 } 1346 }
1288 1347
1348 void ShellSurface::AttemptToStartClientDrag() {
1349 DCHECK(widget_);
1350
1351 if (surface_->window()->HasCapture())
1352 return;
1353
1354 ash::wm::WindowState* const window_state =
1355 ash::wm::GetWindowState(widget_->GetNativeWindow());
1356
1357 DCHECK(!window_state->drag_details());
1358 window_state->CreateDragDetails(GetMouseLocation(), HTCAPTION,
1359 aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1360
1361 // The resizer renders phantom windows, but does not control window movement.
1362 resizer_.reset(ash::DragWindowResizer::Create(
1363 new CustomWindowResizer(window_state), window_state));
1364
1365 WMHelper::GetInstance()->AddPreTargetHandler(this);
1366 surface_->window()->SetCapture();
1367 }
1368
1289 void ShellSurface::EndDrag(bool revert) { 1369 void ShellSurface::EndDrag(bool revert) {
1290 DCHECK(widget_); 1370 DCHECK(widget_);
1291 DCHECK(resizer_); 1371 DCHECK(resizer_);
1292 1372
1293 bool was_resizing = IsResizing(); 1373 switch (bounds_mode_) {
1374 case BoundsMode::SHELL: {
1375 bool was_resizing = IsResizing();
1294 1376
1377 EndDrag(widget_->GetNativeWindow(), revert);
1378
1379 // Notify client that resizing state has changed.
1380 if (was_resizing)
1381 Configure();
1382
1383 UpdateWidgetBounds();
1384 break;
1385 }
1386 case BoundsMode::CLIENT:
1387 EndDrag(surface_->window(), revert);
1388 break;
1389 case BoundsMode::FIXED:
1390 NOTREACHED();
1391 break;
1392 }
1393 }
1394
1395 void ShellSurface::EndDrag(aura::Window* window, bool revert) {
1295 if (revert) 1396 if (revert)
1296 resizer_->RevertDrag(); 1397 resizer_->RevertDrag();
1297 else 1398 else
1298 resizer_->CompleteDrag(); 1399 resizer_->CompleteDrag();
1299 1400
1300 WMHelper::GetInstance()->RemovePreTargetHandler(this); 1401 WMHelper::GetInstance()->RemovePreTargetHandler(this);
1301 widget_->GetNativeWindow()->ReleaseCapture(); 1402 window->ReleaseCapture();
1302 resizer_.reset(); 1403 resizer_.reset();
1303
1304 // Notify client that resizing state has changed.
1305 if (was_resizing)
1306 Configure();
1307
1308 UpdateWidgetBounds();
1309 } 1404 }
1310 1405
1311 bool ShellSurface::IsResizing() const { 1406 bool ShellSurface::IsResizing() const {
1312 ash::wm::WindowState* window_state = 1407 ash::wm::WindowState* window_state =
1313 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1408 ash::wm::GetWindowState(widget_->GetNativeWindow());
1314 if (!window_state->is_dragged()) 1409 if (!window_state->is_dragged())
1315 return false; 1410 return false;
1316 1411
1317 return window_state->drag_details()->bounds_change & 1412 return window_state->drag_details()->bounds_change &
1318 ash::WindowResizer::kBoundsChange_Resizes; 1413 ash::WindowResizer::kBoundsChange_Resizes;
1319 } 1414 }
1320 1415
1321 gfx::Rect ShellSurface::GetVisibleBounds() const { 1416 gfx::Rect ShellSurface::GetVisibleBounds() const {
1322 // Use |geometry_| if set, otherwise use the visual bounds of the surface. 1417 // Use |geometry_| if set, otherwise use the visual bounds of the surface.
1323 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) 1418 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size())
1324 : geometry_; 1419 : geometry_;
1325 } 1420 }
1326 1421
1327 gfx::Point ShellSurface::GetSurfaceOrigin() const { 1422 gfx::Point ShellSurface::GetSurfaceOrigin() const {
1328 // If initial bounds were specified then surface origin is always relative 1423 // For client-positioned shell surfaces, the surface origin corresponds to the
1329 // to those bounds. 1424 // widget position relative to the origin specified by the client. Since the
1330 if (!initial_bounds_.IsEmpty()) { 1425 // surface is positioned relative to the widget, negate this vector to align
1331 gfx::Point origin = widget_->GetNativeWindow()->bounds().origin(); 1426 // the surface with the widget. Note that the widget position must have been
1332 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); 1427 // adjusted by the |origin_offset_| prior to this call.
1333 return initial_bounds_.origin() - origin.OffsetFromOrigin(); 1428 if (bounds_mode_ != BoundsMode::SHELL) {
1429 gfx::Point position = widget_->GetNativeWindow()->bounds().origin();
1430 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position);
1431 return origin_ - position.OffsetFromOrigin();
1334 } 1432 }
1335 1433
1336 gfx::Rect visible_bounds = GetVisibleBounds(); 1434 gfx::Rect visible_bounds = GetVisibleBounds();
1337 gfx::Rect client_bounds = 1435 gfx::Rect client_bounds =
1338 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1436 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1339 switch (resize_component_) { 1437 switch (resize_component_) {
1340 case HTCAPTION: 1438 case HTCAPTION:
1341 return origin_ - visible_bounds.OffsetFromOrigin(); 1439 return gfx::Point() + origin_offset_ - visible_bounds.OffsetFromOrigin();
1342 case HTBOTTOM: 1440 case HTBOTTOM:
1343 case HTRIGHT: 1441 case HTRIGHT:
1344 case HTBOTTOMRIGHT: 1442 case HTBOTTOMRIGHT:
1345 return gfx::Point() - visible_bounds.OffsetFromOrigin(); 1443 return gfx::Point() - visible_bounds.OffsetFromOrigin();
1346 case HTTOP: 1444 case HTTOP:
1347 case HTTOPRIGHT: 1445 case HTTOPRIGHT:
1348 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) - 1446 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) -
1349 visible_bounds.OffsetFromOrigin(); 1447 visible_bounds.OffsetFromOrigin();
1350 break;
1351 case HTLEFT: 1448 case HTLEFT:
1352 case HTBOTTOMLEFT: 1449 case HTBOTTOMLEFT:
1353 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) - 1450 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) -
1354 visible_bounds.OffsetFromOrigin(); 1451 visible_bounds.OffsetFromOrigin();
1355 case HTTOPLEFT: 1452 case HTTOPLEFT:
1356 return gfx::Point(client_bounds.width() - visible_bounds.width(), 1453 return gfx::Point(client_bounds.width() - visible_bounds.width(),
1357 client_bounds.height() - visible_bounds.height()) - 1454 client_bounds.height() - visible_bounds.height()) -
1358 visible_bounds.OffsetFromOrigin(); 1455 visible_bounds.OffsetFromOrigin();
1359 default: 1456 default:
1360 NOTREACHED(); 1457 NOTREACHED();
1361 return gfx::Point(); 1458 return gfx::Point();
1362 } 1459 }
1363 } 1460 }
1364 1461
1365 void ShellSurface::UpdateWidgetBounds() { 1462 void ShellSurface::UpdateWidgetBounds() {
1366 DCHECK(widget_); 1463 DCHECK(widget_);
1367 1464
1368 // Return early if the shell is currently managing the bounds of the widget. 1465 // Return early if the shell is currently managing the bounds of the widget.
1369 // 1) When a window is either maximized/fullscreen/pinned, and the bounds 1466 if (bounds_mode_ == BoundsMode::SHELL) {
1370 // isn't controlled by a client. 1467 // 1) When a window is either maximized/fullscreen/pinned.
1371 ash::wm::WindowState* window_state = 1468 ash::wm::WindowState* window_state =
1372 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1469 ash::wm::GetWindowState(widget_->GetNativeWindow());
1373 if (window_state->IsMaximizedOrFullscreenOrPinned() && 1470 if (window_state->IsMaximizedOrFullscreenOrPinned())
1374 !window_state->allow_set_bounds_in_maximized()) { 1471 return;
1375 return; 1472
1473 // 2) When a window is being dragged.
1474 if (IsResizing())
1475 return;
1376 } 1476 }
1377 1477
1378 // 2) When a window is being dragged.
1379 if (IsResizing())
1380 return;
1381
1382 // Return early if there is pending configure requests. 1478 // Return early if there is pending configure requests.
1383 if (!pending_configs_.empty() || scoped_configure_) 1479 if (!pending_configs_.empty() || scoped_configure_)
1384 return; 1480 return;
1385 1481
1386 gfx::Rect visible_bounds = GetVisibleBounds(); 1482 gfx::Rect visible_bounds = GetVisibleBounds();
1387 gfx::Rect new_widget_bounds = 1483 gfx::Rect new_widget_bounds =
1388 widget_->non_client_view()->GetWindowBoundsForClientBounds( 1484 widget_->non_client_view()->GetWindowBoundsForClientBounds(
1389 visible_bounds); 1485 visible_bounds);
1390 1486
1391 // Avoid changing widget origin unless initial bounds were specified and 1487 switch (bounds_mode_) {
1392 // widget origin is always relative to it. 1488 case BoundsMode::CLIENT:
1393 if (initial_bounds_.IsEmpty()) { 1489 // Position is relative to the latest origin acknowledged by the client.
1394 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); 1490 new_widget_bounds -= origin_offset_;
1395 } else { 1491 break;
1396 new_widget_bounds.set_origin(initial_bounds_.origin() + 1492 case BoundsMode::FIXED:
1397 visible_bounds.OffsetFromOrigin()); 1493 // Position is relative to the origin.
1398 } 1494 new_widget_bounds += origin_.OffsetFromOrigin();
1399 1495 break;
1400 // Update widget origin using the surface origin if the current location of 1496 case BoundsMode::SHELL:
1401 // surface is being anchored to one side of the widget as a result of a 1497 // Update widget origin using the surface origin if the current location
1402 // resize operation. 1498 // of surface is being anchored to one side of the widget as a result of a
1403 if (resize_component_ != HTCAPTION) { 1499 // resize operation.
1404 gfx::Point new_widget_origin = 1500 if (resize_component_ != HTCAPTION) {
1405 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); 1501 gfx::Point widget_origin =
1406 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); 1502 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
1407 new_widget_bounds.set_origin(new_widget_origin); 1503 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &widget_origin);
1504 new_widget_bounds.set_origin(widget_origin);
1505 } else {
1506 // Preserve widget position.
1507 new_widget_bounds.set_origin(
1508 widget_->GetWindowBoundsInScreen().origin());
1509 }
1510 break;
1408 } 1511 }
1409 1512
1410 // Set |ignore_window_bounds_changes_| as this change to window bounds 1513 // Set |ignore_window_bounds_changes_| as this change to window bounds
1411 // should not result in a configure request. 1514 // should not result in a configure request.
1412 DCHECK(!ignore_window_bounds_changes_); 1515 DCHECK(!ignore_window_bounds_changes_);
1413 ignore_window_bounds_changes_ = true; 1516 ignore_window_bounds_changes_ = true;
1414 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) 1517 const gfx::Rect widget_bounds = widget_->GetWindowBoundsInScreen();
1415 widget_->SetBounds(new_widget_bounds); 1518 if (widget_bounds != new_widget_bounds) {
1519 if (bounds_mode_ != BoundsMode::CLIENT || !resizer_) {
1520 widget_->SetBounds(new_widget_bounds);
1521 UpdateSurfaceBounds();
1522 } else {
1523 // TODO(domlaskowski): Synchronize window state transitions with the
1524 // client, and abort client-side dragging on transition to fullscreen.
1525 LOG_IF(ERROR, widget_bounds.size() != new_widget_bounds.size())
1526 << "Window size changed during client-driven drag";
1527
1528 // Convert from screen to display coordinates.
1529 gfx::Point origin = new_widget_bounds.origin();
1530 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
1531 new_widget_bounds.set_origin(origin);
1532
1533 // Move the window relative to the current display.
1534 widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
1535 UpdateSurfaceBounds();
1536
1537 // Render phantom windows when beyond the current display.
1538 resizer_->Drag(GetMouseLocation(), 0);
1539 }
1540 }
1541
1416 ignore_window_bounds_changes_ = false; 1542 ignore_window_bounds_changes_ = false;
1543 }
1417 1544
1418 gfx::Rect client_view_bounds = 1545 void ShellSurface::UpdateSurfaceBounds() {
1546 const gfx::Rect client_view_bounds =
1419 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1547 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1420 1548
1421 // A change to the widget size requires surface bounds to be re-adjusted.
1422 surface_->window()->SetBounds( 1549 surface_->window()->SetBounds(
1423 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), 1550 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
1424 surface_->window()->layer()->size())); 1551 surface_->window()->layer()->size()));
1425 } 1552 }
1426 1553
1427 void ShellSurface::UpdateShadow() { 1554 void ShellSurface::UpdateShadow() {
1428 if (!widget_) 1555 if (!widget_)
1429 return; 1556 return;
1430 aura::Window* window = widget_->GetNativeWindow(); 1557 aura::Window* window = widget_->GetNativeWindow();
1431 if (!shadow_enabled_) { 1558 if (!shadow_enabled_) {
1432 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); 1559 wm::SetShadowElevation(window, wm::ShadowElevation::NONE);
1433 if (shadow_underlay_) 1560 if (shadow_underlay_)
1434 shadow_underlay_->Hide(); 1561 shadow_underlay_->Hide();
1435 } else { 1562 } else {
1436 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM); 1563 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM);
1437 gfx::Rect shadow_content_bounds = 1564 gfx::Rect shadow_content_bounds =
1438 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_); 1565 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_);
1439 gfx::Rect shadow_underlay_bounds = shadow_content_bounds_; 1566 gfx::Rect shadow_underlay_bounds = shadow_content_bounds_;
1440 if (shadow_underlay_bounds.IsEmpty()) 1567 if (shadow_underlay_bounds.IsEmpty())
1441 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); 1568 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size());
1442 1569
1443 if (!shadow_underlay_in_surface_) { 1570 if (!shadow_underlay_in_surface_) {
1444 shadow_content_bounds = shadow_content_bounds_; 1571 shadow_content_bounds = shadow_content_bounds_;
1445 if (shadow_content_bounds.IsEmpty()) { 1572 if (shadow_content_bounds.IsEmpty()) {
1446 shadow_content_bounds = window->bounds(); 1573 shadow_content_bounds = window->bounds();
1447 } 1574 }
1448 } 1575 }
1449 1576
1450 // TODO(oshima): Adjust the coordinates from client screen to 1577 gfx::Point shadow_origin = shadow_content_bounds.origin() - origin_offset_;
1451 // chromeos screen when multi displays are supported. 1578 wm::ConvertPointFromScreen(window->parent(), &shadow_origin);
1452 gfx::Point origin = window->bounds().origin(); 1579 shadow_origin -= window->bounds().OffsetFromOrigin();
1453 gfx::Point shadow_origin = shadow_content_bounds.origin();
1454 shadow_origin -= origin.OffsetFromOrigin();
1455 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); 1580 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size());
1456 1581
1457 // Always create and show the underlay, even in maximized/fullscreen. 1582 // Always create and show the underlay, even in maximized/fullscreen.
1458 if (!shadow_underlay_) { 1583 if (!shadow_underlay_) {
1459 shadow_underlay_ = new aura::Window(nullptr); 1584 shadow_underlay_ = new aura::Window(nullptr);
1460 shadow_underlay_event_handler_ = 1585 shadow_underlay_event_handler_ =
1461 base::MakeUnique<ShadowUnderlayEventHandler>(); 1586 base::MakeUnique<ShadowUnderlayEventHandler>();
1462 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); 1587 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
1463 DCHECK(shadow_underlay_->owned_by_parent()); 1588 DCHECK(shadow_underlay_->owned_by_parent());
1464 // Ensure the background area inside the shadow is solid black. 1589 // Ensure the background area inside the shadow is solid black.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 // Surfaces that can't be activated are usually menus and tooltips. Use a 1674 // Surfaces that can't be activated are usually menus and tooltips. Use a
1550 // small style shadow for them. 1675 // small style shadow for them.
1551 if (!activatable_) 1676 if (!activatable_)
1552 shadow->SetElevation(wm::ShadowElevation::SMALL); 1677 shadow->SetElevation(wm::ShadowElevation::SMALL);
1553 // We don't have rounded corners unless frame is enabled. 1678 // We don't have rounded corners unless frame is enabled.
1554 if (!frame_enabled_) 1679 if (!frame_enabled_)
1555 shadow->SetRoundedCornerRadius(0); 1680 shadow->SetRoundedCornerRadius(0);
1556 } 1681 }
1557 } 1682 }
1558 1683
1684 gfx::Point ShellSurface::GetMouseLocation() const {
1685 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
1686 gfx::Point location =
1687 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1688 aura::Window::ConvertPointToTarget(
1689 root_window, widget_->GetNativeWindow()->parent(), &location);
1690 return location;
1691 }
1692
1559 } // namespace exo 1693 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698