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

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

Issue 2645663004: exo: Initial support for multiple displays in ARC (Closed)
Patch Set: Fix race and refactor 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"
reveman 2017/02/06 19:49:34 please remove from this patch
Dominik Laskowski 2017/02/08 18:07:40 See comment below.
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 {
reveman 2017/02/06 19:49:34 please remove from this patch
Dominik Laskowski 2017/02/08 18:07:40 Dragging and multi-display positioning are interde
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 EndDragOrMove(false /* revert */);
369 EndDrag(false /* revert */);
370 if (widget_) { 393 if (widget_) {
371 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); 394 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this);
372 widget_->GetNativeWindow()->RemoveObserver(this); 395 widget_->GetNativeWindow()->RemoveObserver(this);
373 // Remove transient children so they are not automatically destroyed. 396 // Remove transient children so they are not automatically destroyed.
374 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow())) 397 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow()))
375 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); 398 wm::RemoveTransientChild(widget_->GetNativeWindow(), child);
376 if (widget_->IsVisible()) 399 if (widget_->IsVisible())
377 widget_->Hide(); 400 widget_->Hide();
378 widget_->CloseNow(); 401 widget_->CloseNow();
379 } 402 }
380 WMHelper::GetInstance()->RemoveActivationObserver(this); 403 WMHelper::GetInstance()->RemoveActivationObserver(this);
381 if (parent_) 404 if (parent_)
382 parent_->RemoveObserver(this); 405 parent_->RemoveObserver(this);
383 if (surface_) { 406 if (surface_) {
384 if (scale_ != 1.0) 407 if (scale_ != 1.0)
385 surface_->window()->SetTransform(gfx::Transform()); 408 surface_->window()->SetTransform(gfx::Transform());
386 surface_->SetSurfaceDelegate(nullptr); 409 surface_->SetSurfaceDelegate(nullptr);
387 surface_->RemoveSurfaceObserver(this); 410 surface_->RemoveSurfaceObserver(this);
388 } 411 }
389 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); 412 WMHelper::GetInstance()->RemoveAccessibilityObserver(this);
413
414 if (!destroyed_callback_.is_null())
415 destroyed_callback_.Run();
390 } 416 }
391 417
392 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { 418 void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
393 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); 419 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial);
394 420
395 // Apply all configs that are older or equal to |serial|. The result is that 421 // 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 422 // the origin of the main surface will move and the resize direction will
397 // change to reflect the acknowledgement of configure request with |serial| 423 // change to reflect the acknowledgement of configure request with |serial|
398 // at the next call to Commit(). 424 // at the next call to Commit().
399 while (!pending_configs_.empty()) { 425 while (!pending_configs_.empty()) {
400 auto config = pending_configs_.front(); 426 auto config = pending_configs_.front();
401 pending_configs_.pop_front(); 427 pending_configs_.pop_front();
402 428
403 // Add the config offset to the accumulated offset that will be applied when 429 // Add the config offset to the accumulated offset that will be applied when
404 // Commit() is called. 430 // Commit() is called.
405 pending_origin_offset_ += config.origin_offset; 431 pending_origin_offset_ += config.origin_offset;
406 432
407 // Set the resize direction that will be applied when Commit() is called. 433 // Set the resize direction that will be applied when Commit() is called.
408 pending_resize_component_ = config.resize_component; 434 pending_resize_component_ = config.resize_component;
409 435
410 if (config.serial == serial) 436 if (config.serial == serial)
411 break; 437 break;
412 } 438 }
413 439
414 if (widget_) 440 if (widget_) {
415 UpdateWidgetBounds(); 441 UpdateWidgetBounds();
442 UpdateShadow();
443 }
416 } 444 }
417 445
418 void ShellSurface::SetParent(ShellSurface* parent) { 446 void ShellSurface::SetParent(ShellSurface* parent) {
419 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent", 447 TRACE_EVENT1("exo", "ShellSurface::SetParent", "parent",
420 parent ? base::UTF16ToASCII(parent->title_) : "null"); 448 parent ? base::UTF16ToASCII(parent->title_) : "null");
421 449
422 if (parent_) { 450 if (parent_) {
423 parent_->RemoveObserver(this); 451 parent_->RemoveObserver(this);
424 if (widget_) 452 if (widget_)
425 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow()); 453 wm::RemoveTransientChild(parent_, widget_->GetNativeWindow());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 502
475 if (!widget_) 503 if (!widget_)
476 return; 504 return;
477 505
478 // Note: This will ask client to configure its surface even if not already 506 // Note: This will ask client to configure its surface even if not already
479 // maximized or minimized. 507 // maximized or minimized.
480 ScopedConfigure scoped_configure(this, true); 508 ScopedConfigure scoped_configure(this, true);
481 widget_->Restore(); 509 widget_->Restore();
482 } 510 }
483 511
512 void ShellSurface::SetMoving() {
513 TRACE_EVENT0("exo", "ShellSurface::SetMoving");
514
515 if (move_resizer_)
516 return;
517
518 ash::wm::WindowState* const window_state =
519 ash::wm::GetWindowState(widget_->GetNativeWindow());
520
521 DCHECK(!window_state->drag_details());
522 window_state->CreateDragDetails(GetMouseLocation(), HTCAPTION,
523 aura::client::WINDOW_MOVE_SOURCE_MOUSE);
524
525 // The resizer renders phantom windows, but does not control window movement.
526 move_resizer_.reset(ash::DragWindowResizer::Create(
527 new CustomWindowResizer(window_state), window_state));
528
529 surface_->window()->SetCapture();
530 }
531
532 void ShellSurface::UnsetMoving(bool revert) {
533 TRACE_EVENT1("exo", "ShellSurface::UnsetMoving", "revert", revert);
534
535 if (!move_resizer_)
536 return;
537
538 if (revert)
539 move_resizer_->RevertDrag();
540 else
541 move_resizer_->CompleteDrag();
542
543 move_resizer_.reset();
544 surface_->window()->ReleaseCapture();
545 }
546
484 void ShellSurface::SetFullscreen(bool fullscreen) { 547 void ShellSurface::SetFullscreen(bool fullscreen) {
485 TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen); 548 TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen);
486 549
487 if (!widget_) 550 if (!widget_)
488 CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN); 551 CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN);
489 552
490 // Note: This will ask client to configure its surface even if fullscreen 553 // Note: This will ask client to configure its surface even if fullscreen
491 // state doesn't change. 554 // state doesn't change.
492 ScopedConfigure scoped_configure(this, true); 555 ScopedConfigure scoped_configure(this, true);
493 widget_->SetFullscreen(fullscreen); 556 widget_->SetFullscreen(fullscreen);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 695
633 void ShellSurface::SetTopInset(int height) { 696 void ShellSurface::SetTopInset(int height) {
634 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); 697 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height);
635 698
636 pending_top_inset_height_ = height; 699 pending_top_inset_height_ = height;
637 } 700 }
638 701
639 void ShellSurface::SetOrigin(const gfx::Point& origin) { 702 void ShellSurface::SetOrigin(const gfx::Point& origin) {
640 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); 703 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString());
641 704
642 initial_bounds_ = gfx::Rect(origin, gfx::Size(1, 1)); 705 const gfx::Point old_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();
643 } 724 }
644 725
645 void ShellSurface::SetActivatable(bool activatable) { 726 void ShellSurface::SetActivatable(bool activatable) {
646 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", 727 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable",
647 activatable); 728 activatable);
648 729
649 activatable_ = activatable; 730 activatable_ = activatable;
650 } 731 }
651 732
652 void ShellSurface::SetContainer(int container) { 733 void ShellSurface::SetContainer(int container) {
(...skipping 26 matching lines...) Expand all
679 760
680 //////////////////////////////////////////////////////////////////////////////// 761 ////////////////////////////////////////////////////////////////////////////////
681 // SurfaceDelegate overrides: 762 // SurfaceDelegate overrides:
682 763
683 void ShellSurface::OnSurfaceCommit() { 764 void ShellSurface::OnSurfaceCommit() {
684 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); 765 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
685 surface_->CommitSurfaceHierarchy(); 766 surface_->CommitSurfaceHierarchy();
686 767
687 if (enabled() && !widget_) { 768 if (enabled() && !widget_) {
688 // Defer widget creation until surface contains some contents. 769 // Defer widget creation until surface contains some contents.
689 if (surface_->content_size().IsEmpty()) 770 if (surface_->content_size().IsEmpty()) {
690 Configure(); 771 Configure();
691 else 772 return;
692 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); 773 }
774
775 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
693 } 776 }
694 777
695 // Apply the accumulated pending origin offset to reflect acknowledged 778 // Apply the accumulated pending origin offset to reflect acknowledged
696 // configure requests. 779 // configure requests.
697 origin_ += pending_origin_offset_; 780 origin_offset_ += pending_origin_offset_;
698 pending_origin_offset_ = gfx::Vector2d(); 781 pending_origin_offset_ = gfx::Vector2d();
699 782
700 // Update resize direction to reflect acknowledged configure requests. 783 // Update resize direction to reflect acknowledged configure requests.
701 resize_component_ = pending_resize_component_; 784 resize_component_ = pending_resize_component_;
702 785
703 if (widget_) { 786 if (widget_) {
704 // Apply new window geometry. 787 // Apply new window geometry.
705 geometry_ = pending_geometry_; 788 geometry_ = pending_geometry_;
706 789
707 UpdateWidgetBounds(); 790 UpdateWidgetBounds();
(...skipping 18 matching lines...) Expand all
726 if (activatable != CanActivate()) { 809 if (activatable != CanActivate()) {
727 set_can_activate(activatable); 810 set_can_activate(activatable);
728 // Activate or deactivate window if activation state changed. 811 // Activate or deactivate window if activation state changed.
729 if (activatable) 812 if (activatable)
730 wm::ActivateWindow(widget_->GetNativeWindow()); 813 wm::ActivateWindow(widget_->GetNativeWindow());
731 else if (widget_->IsActive()) 814 else if (widget_->IsActive())
732 wm::DeactivateWindow(widget_->GetNativeWindow()); 815 wm::DeactivateWindow(widget_->GetNativeWindow());
733 } 816 }
734 } 817 }
735 818
736 gfx::Rect client_view_bounds = 819 UpdateSurfaceBounds();
737 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
738
739 // Update surface bounds.
740 surface_->window()->SetBounds(
741 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
742 surface_->window()->layer()->size()));
743 820
744 // Update surface scale. 821 // Update surface scale.
745 if (pending_scale_ != scale_) { 822 if (pending_scale_ != scale_) {
746 gfx::Transform transform; 823 gfx::Transform transform;
747 DCHECK_NE(pending_scale_, 0.0); 824 DCHECK_NE(pending_scale_, 0.0);
748 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); 825 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_);
749 surface_->window()->SetTransform(transform); 826 surface_->window()->SetTransform(transform);
750 scale_ = pending_scale_; 827 scale_ = pending_scale_;
751 } 828 }
752 829
753 // Show widget if needed. 830 // Show widget if needed.
754 if (pending_show_widget_) { 831 if (pending_show_widget_) {
755 DCHECK(!widget_->IsClosed()); 832 DCHECK(!widget_->IsClosed());
756 DCHECK(!widget_->IsVisible()); 833 DCHECK(!widget_->IsVisible());
757 pending_show_widget_ = false; 834 pending_show_widget_ = false;
758 widget_->Show(); 835 widget_->Show();
759 } 836 }
760 } 837 }
761 } 838 }
762 839
763 bool ShellSurface::IsSurfaceSynchronized() const { 840 bool ShellSurface::IsSurfaceSynchronized() const {
764 // A shell surface is always desynchronized. 841 // A shell surface is always desynchronized.
765 return false; 842 return false;
766 } 843 }
767 844
768 //////////////////////////////////////////////////////////////////////////////// 845 ////////////////////////////////////////////////////////////////////////////////
769 // SurfaceObserver overrides: 846 // SurfaceObserver overrides:
770 847
771 void ShellSurface::OnSurfaceDestroying(Surface* surface) { 848 void ShellSurface::OnSurfaceDestroying(Surface* surface) {
772 if (resizer_) 849 EndDragOrMove(false /* revert */);
773 EndDrag(false /* revert */);
774 if (widget_) 850 if (widget_)
775 SetMainSurface(widget_->GetNativeWindow(), nullptr); 851 SetMainSurface(widget_->GetNativeWindow(), nullptr);
776 surface->RemoveSurfaceObserver(this); 852 surface->RemoveSurfaceObserver(this);
777 surface_ = nullptr; 853 surface_ = nullptr;
778 854
779 // Hide widget before surface is destroyed. This allows hide animations to 855 // Hide widget before surface is destroyed. This allows hide animations to
780 // run using the current surface contents. 856 // run using the current surface contents.
781 if (widget_) { 857 if (widget_) {
782 // Remove transient children so they are not automatically hidden. 858 // Remove transient children so they are not automatically hidden.
783 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow())) 859 for (auto child : wm::GetTransientChildren(widget_->GetNativeWindow()))
784 wm::RemoveTransientChild(widget_->GetNativeWindow(), child); 860 wm::RemoveTransientChild(widget_->GetNativeWindow(), child);
785 widget_->Hide(); 861 widget_->Hide();
786 } 862 }
787 863
788 // Note: In its use in the Wayland server implementation, the surface 864 // Note: In its use in the Wayland server implementation, the surface
789 // destroyed callback may destroy the ShellSurface instance. This call needs 865 // destroyed callback may destroy the ShellSurface instance. This call needs
790 // to be last so that the instance can be destroyed. 866 // to be last so that the instance can be destroyed.
791 if (!surface_destroyed_callback_.is_null()) 867 if (!surface_destroyed_callback_.is_null())
792 surface_destroyed_callback_.Run(); 868 surface_destroyed_callback_.Run();
793 } 869 }
794 870
795 //////////////////////////////////////////////////////////////////////////////// 871 ////////////////////////////////////////////////////////////////////////////////
796 // views::WidgetDelegate overrides: 872 // views::WidgetDelegate overrides:
797 873
798 bool ShellSurface::CanResize() const { 874 bool ShellSurface::CanResize() const {
799 return initial_bounds_.IsEmpty(); 875 return bounds_mode_ == BoundsMode::SHELL;
800 } 876 }
801 877
802 bool ShellSurface::CanMaximize() const { 878 bool ShellSurface::CanMaximize() const {
803 // Shell surfaces in system modal container cannot be maximized. 879 // Shell surfaces in system modal container cannot be maximized.
804 if (container_ == ash::kShellWindowId_SystemModalContainer) 880 if (container_ == ash::kShellWindowId_SystemModalContainer)
805 return false; 881 return false;
806 882
807 // Non-transient shell surfaces can be maximized. 883 // Non-transient shell surfaces can be maximized.
808 return !parent_; 884 return !parent_;
809 } 885 }
810 886
811 bool ShellSurface::CanMinimize() const { 887 bool ShellSurface::CanMinimize() const {
812 return can_minimize_; 888 return can_minimize_;
813 } 889 }
814 890
815 base::string16 ShellSurface::GetWindowTitle() const { 891 base::string16 ShellSurface::GetWindowTitle() const {
816 return title_; 892 return title_;
817 } 893 }
818 894
819 void ShellSurface::WindowClosing() { 895 void ShellSurface::WindowClosing() {
820 if (resizer_) 896 EndDragOrMove(true /* revert */);
821 EndDrag(true /* revert */);
822 SetEnabled(false); 897 SetEnabled(false);
823 widget_ = nullptr; 898 widget_ = nullptr;
824 shadow_overlay_ = nullptr; 899 shadow_overlay_ = nullptr;
825 shadow_underlay_ = nullptr; 900 shadow_underlay_ = nullptr;
826 } 901 }
827 902
828 views::Widget* ShellSurface::GetWidget() { 903 views::Widget* ShellSurface::GetWidget() {
829 return widget_; 904 return widget_;
830 } 905 }
831 906
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 ash::wm::WindowState* window_state, 958 ash::wm::WindowState* window_state,
884 ash::wm::WindowStateType old_type) { 959 ash::wm::WindowStateType old_type) {
885 ash::wm::WindowStateType new_type = window_state->GetStateType(); 960 ash::wm::WindowStateType new_type = window_state->GetStateType();
886 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 961 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
887 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 962 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
888 // 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
889 // 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
890 // cross-fade animations. The configure callback provides a mechanism for 965 // cross-fade animations. The configure callback provides a mechanism for
891 // 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
892 // account and without this cross-fade animations are unreliable. 967 // account and without this cross-fade animations are unreliable.
893 if (configure_callback_.is_null()) 968
969 // TODO(domlaskowski): For shell surfaces whose bounds are controlled by the
reveman 2017/02/06 19:49:34 Please remove this as it shouldn't hurt to trigger
Dominik Laskowski 2017/02/08 18:07:40 The TODO alludes to the above comment, i.e. animat
970 // client, the configure callback does not yet support window state changes.
971 if (configure_callback_.is_null() || bounds_mode_ == BoundsMode::CLIENT)
894 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); 972 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
895 } 973 }
896 } 974 }
897 975
898 void ShellSurface::OnPostWindowStateTypeChange( 976 void ShellSurface::OnPostWindowStateTypeChange(
899 ash::wm::WindowState* window_state, 977 ash::wm::WindowState* window_state,
900 ash::wm::WindowStateType old_type) { 978 ash::wm::WindowStateType old_type) {
901 ash::wm::WindowStateType new_type = window_state->GetStateType(); 979 ash::wm::WindowStateType new_type = window_state->GetStateType();
902 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 980 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
903 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 981 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
(...skipping 11 matching lines...) Expand all
915 // Re-enable animations if they were disabled in pre state change handler. 993 // Re-enable animations if they were disabled in pre state change handler.
916 scoped_animations_disabled_.reset(); 994 scoped_animations_disabled_.reset();
917 } 995 }
918 996
919 //////////////////////////////////////////////////////////////////////////////// 997 ////////////////////////////////////////////////////////////////////////////////
920 // aura::WindowObserver overrides: 998 // aura::WindowObserver overrides:
921 999
922 void ShellSurface::OnWindowBoundsChanged(aura::Window* window, 1000 void ShellSurface::OnWindowBoundsChanged(aura::Window* window,
923 const gfx::Rect& old_bounds, 1001 const gfx::Rect& old_bounds,
924 const gfx::Rect& new_bounds) { 1002 const gfx::Rect& new_bounds) {
925 if (!widget_ || !surface_ || ignore_window_bounds_changes_) 1003 if (bounds_mode_ != BoundsMode::SHELL || !widget_ || !surface_ ||
reveman 2017/02/06 19:49:34 why is this needed. should ignore_window_bounds_ch
Dominik Laskowski 2017/02/08 18:07:40 The origin offset should not be modified for size
1004 ignore_window_bounds_changes_)
926 return; 1005 return;
927 1006
928 if (window == widget_->GetNativeWindow()) { 1007 if (window == widget_->GetNativeWindow()) {
929 if (new_bounds.size() == old_bounds.size()) 1008 if (new_bounds.size() == old_bounds.size())
930 return; 1009 return;
931 1010
932 // If size changed then give the client a chance to produce new contents 1011 // If size changed then give the client a chance to produce new contents
933 // before origin on screen is changed by adding offset to the next configure 1012 // before origin on screen is changed. Retain the old origin by reverting
934 // request and offset |origin_| by the same distance. 1013 // the origin delta until the next configure is acknowledged.
935 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin(); 1014 const gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin();
936 pending_origin_config_offset_ += origin_offset; 1015 origin_offset_ -= delta;
937 origin_ -= origin_offset; 1016 pending_origin_offset_accumulator_ += delta;
938 1017
939 gfx::Rect client_view_bounds = 1018 UpdateSurfaceBounds();
reveman 2017/02/06 19:49:33 is this change needed?
Dominik Laskowski 2017/02/08 18:07:40 Yes, UpdateSurfaceBounds is called from several pl
940 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
941
942 // Update surface bounds.
943 surface_->window()->SetBounds(
944 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
945 surface_->window()->layer()->size()));
946 1019
947 // The shadow size may be updated to match the widget. Change it back 1020 // The shadow size may be updated to match the widget. Change it back
948 // to the shadow content size. 1021 // to the shadow content size.
949 // TODO(oshima): When the arc window reiszing is enabled, we may want to 1022 // TODO(oshima): When the arc window reiszing is enabled, we may want to
950 // implement shadow management here instead of using shadow controller. 1023 // implement shadow management here instead of using shadow controller.
951 UpdateShadow(); 1024 UpdateShadow();
952 1025
953 Configure(); 1026 Configure();
954 } 1027 }
955 } 1028 }
(...skipping 10 matching lines...) Expand all
966 1039
967 //////////////////////////////////////////////////////////////////////////////// 1040 ////////////////////////////////////////////////////////////////////////////////
968 // WMHelper::ActivationObserver overrides: 1041 // WMHelper::ActivationObserver overrides:
969 1042
970 void ShellSurface::OnWindowActivated( 1043 void ShellSurface::OnWindowActivated(
971 aura::Window* gained_active, 1044 aura::Window* gained_active,
972 aura::Window* lost_active) { 1045 aura::Window* lost_active) {
973 if (!widget_) 1046 if (!widget_)
974 return; 1047 return;
975 1048
1049 if (lost_active == widget_->GetNativeWindow())
1050 UnsetMoving(false /* revert */);
1051
976 if (gained_active == widget_->GetNativeWindow() || 1052 if (gained_active == widget_->GetNativeWindow() ||
977 lost_active == widget_->GetNativeWindow()) { 1053 lost_active == widget_->GetNativeWindow()) {
978 DCHECK(activatable_); 1054 DCHECK(activatable_);
979 Configure(); 1055 Configure();
980 UpdateShadow(); 1056 UpdateShadow();
981 } 1057 }
982 } 1058 }
983 1059
984 //////////////////////////////////////////////////////////////////////////////// 1060 ////////////////////////////////////////////////////////////////////////////////
985 // WMHelper::AccessibilityObserver overrides: 1061 // WMHelper::AccessibilityObserver overrides:
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 views::Widget::InitParams params; 1153 views::Widget::InitParams params;
1078 params.type = views::Widget::InitParams::TYPE_WINDOW; 1154 params.type = views::Widget::InitParams::TYPE_WINDOW;
1079 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; 1155 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
1080 params.delegate = this; 1156 params.delegate = this;
1081 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 1157 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
1082 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 1158 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
1083 params.show_state = show_state; 1159 params.show_state = show_state;
1084 // Make shell surface a transient child if |parent_| has been set. 1160 // Make shell surface a transient child if |parent_| has been set.
1085 params.parent = 1161 params.parent =
1086 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_); 1162 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_);
1087 params.bounds = initial_bounds_; 1163 params.bounds = gfx::Rect(origin_, gfx::Size());
1088 bool activatable = activatable_; 1164 bool activatable = activatable_;
1089 // ShellSurfaces in system modal container are only activatable if input 1165 // ShellSurfaces in system modal container are only activatable if input
1090 // region is non-empty. See OnCommitSurface() for more details. 1166 // region is non-empty. See OnCommitSurface() for more details.
1091 if (container_ == ash::kShellWindowId_SystemModalContainer) 1167 if (container_ == ash::kShellWindowId_SystemModalContainer)
1092 activatable &= !surface_->GetHitTestBounds().IsEmpty(); 1168 activatable &= !surface_->GetHitTestBounds().IsEmpty();
1093 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES 1169 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES
1094 : views::Widget::InitParams::ACTIVATABLE_NO; 1170 : views::Widget::InitParams::ACTIVATABLE_NO;
1095 1171
1096 // Note: NativeWidget owns this widget. 1172 // Note: NativeWidget owns this widget.
1097 widget_ = new ShellSurfaceWidget(this); 1173 widget_ = new ShellSurfaceWidget(this);
1098 widget_->Init(params); 1174 widget_->Init(params);
1099 1175
1100 aura::Window* window = widget_->GetNativeWindow(); 1176 aura::Window* window = widget_->GetNativeWindow();
1101 window->SetName("ExoShellSurface"); 1177 window->SetName("ExoShellSurface");
1102 window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey, 1178 window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey,
1103 false); 1179 false);
1104 window->AddChild(surface_->window()); 1180 window->AddChild(surface_->window());
1105 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_))); 1181 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_)));
1106 SetApplicationId(window, application_id_); 1182 SetApplicationId(window, application_id_);
1107 SetMainSurface(window, surface_); 1183 SetMainSurface(window, surface_);
1108 1184
1109 // Start tracking changes to window bounds and window state. 1185 // Start tracking changes to window bounds and window state.
1110 window->AddObserver(this); 1186 window->AddObserver(this);
1111 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); 1187 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window);
1112 window_state->AddObserver(this); 1188 window_state->AddObserver(this);
1113 1189
1114 // Absolete positioned shell surfaces may request the bounds that does not 1190 // Allow the client to request bounds that do not fill the entire work area
1115 // fill the entire work area / display in maximized / fullscreen state. 1191 // when maximized, or the entire display when fullscreen.
1116 // Allow such clients to update the bounds in these states. 1192 window_state->set_allow_set_bounds_in_maximized(bounds_mode_ ==
1117 if (!initial_bounds_.IsEmpty()) 1193 BoundsMode::CLIENT);
1118 window_state->set_allow_set_bounds_in_maximized(true);
1119 1194
1120 // Notify client of initial state if different than normal. 1195 // Notify client of initial state if different than normal.
1121 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL && 1196 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL &&
1122 !state_changed_callback_.is_null()) { 1197 !state_changed_callback_.is_null()) {
1123 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL, 1198 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL,
1124 window_state->GetStateType()); 1199 window_state->GetStateType());
1125 } 1200 }
1126 1201
1127 // Disable movement if initial bounds were specified. 1202 // Disable movement if bounds are controlled by the client or fixed.
1128 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); 1203 widget_->set_movement_disabled(bounds_mode_ != BoundsMode::SHELL);
reveman 2017/02/06 19:49:33 nit: consider "bool shell_controls_bounds = bounds
Dominik Laskowski 2017/02/08 18:07:40 Done.
1129 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); 1204 window_state->set_ignore_keyboard_bounds_change(bounds_mode_ !=
1205 BoundsMode::SHELL);
1130 1206
1131 // AutoHide shelf in fullscreen state. 1207 // AutoHide shelf in fullscreen state.
1132 window_state->set_hide_shelf_when_fullscreen(false); 1208 window_state->set_hide_shelf_when_fullscreen(false);
1133 1209
1134 // Fade visibility animations for non-activatable windows. 1210 // Fade visibility animations for non-activatable windows.
1135 if (!activatable_) { 1211 if (!activatable_) {
1136 wm::SetWindowVisibilityAnimationType( 1212 wm::SetWindowVisibilityAnimationType(
1137 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); 1213 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
1138 } 1214 }
1139 1215
(...skipping 12 matching lines...) Expand all
1152 pending_show_widget_ = true; 1228 pending_show_widget_ = true;
1153 } 1229 }
1154 1230
1155 void ShellSurface::Configure() { 1231 void ShellSurface::Configure() {
1156 // Delay configure callback if |scoped_configure_| is set. 1232 // Delay configure callback if |scoped_configure_| is set.
1157 if (scoped_configure_) { 1233 if (scoped_configure_) {
1158 scoped_configure_->set_needs_configure(); 1234 scoped_configure_->set_needs_configure();
1159 return; 1235 return;
1160 } 1236 }
1161 1237
1162 gfx::Vector2d origin_offset = pending_origin_config_offset_; 1238 const gfx::Vector2d origin_offset = pending_origin_offset_accumulator_;
1163 pending_origin_config_offset_ = gfx::Vector2d(); 1239 pending_origin_offset_accumulator_ = gfx::Vector2d();
1164 1240
1165 int resize_component = HTCAPTION; 1241 int resize_component = HTCAPTION;
1166 if (widget_) { 1242 if (widget_) {
1167 ash::wm::WindowState* window_state = 1243 ash::wm::WindowState* window_state =
1168 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1244 ash::wm::GetWindowState(widget_->GetNativeWindow());
1169 1245
1170 // If surface is being resized, save the resize direction. 1246 // If surface is being resized, save the resize direction.
1171 if (window_state->is_dragged()) 1247 if (window_state->is_dragged())
1172 resize_component = window_state->drag_details()->window_component; 1248 resize_component = window_state->drag_details()->window_component;
1173 } 1249 }
1174 1250
1175 uint32_t serial = 0; 1251 uint32_t serial = 0;
1176 if (!configure_callback_.is_null()) { 1252 if (!configure_callback_.is_null()) {
1177 if (widget_) { 1253 if (widget_) {
1178 const views::NonClientView* non_client_view = widget_->non_client_view(); 1254 const views::NonClientView* non_client_view = widget_->non_client_view();
1179 serial = configure_callback_.Run( 1255 serial = configure_callback_.Run(
1180 non_client_view->frame_view()->GetBoundsForClientView().size(), 1256 non_client_view->frame_view()->GetBoundsForClientView().size(),
1181 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), 1257 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(),
1182 IsResizing(), widget_->IsActive()); 1258 IsResizing(), widget_->IsActive(), origin_);
1183 } else { 1259 } else {
1184 serial = configure_callback_.Run( 1260 serial = configure_callback_.Run(gfx::Size(),
1185 gfx::Size(), ash::wm::WINDOW_STATE_TYPE_NORMAL, false, false); 1261 ash::wm::WINDOW_STATE_TYPE_NORMAL, false,
1262 false, origin_);
1186 } 1263 }
1187 } 1264 }
1188 1265
1189 if (!serial) { 1266 if (!serial) {
1190 pending_origin_offset_ += origin_offset; 1267 pending_origin_offset_ += origin_offset;
1191 pending_resize_component_ = resize_component; 1268 pending_resize_component_ = resize_component;
1192 return; 1269 return;
1193 } 1270 }
1194 1271
1195 // Apply origin offset and resize component at the first Commit() after this 1272 // Apply origin offset and resize component at the first Commit() after this
1196 // configure request has been acknowledged. 1273 // configure request has been acknowledged.
1197 pending_configs_.push_back({serial, origin_offset, resize_component}); 1274 pending_configs_.push_back({serial, origin_offset, resize_component});
1198 LOG_IF(WARNING, pending_configs_.size() > 100) 1275 LOG_IF(WARNING, pending_configs_.size() > 100)
1199 << "Number of pending configure acks for shell surface has reached: " 1276 << "Number of pending configure acks for shell surface has reached: "
1200 << pending_configs_.size(); 1277 << pending_configs_.size();
1201 } 1278 }
1202 1279
1203 void ShellSurface::AttemptToStartDrag(int component) { 1280 void ShellSurface::AttemptToStartDrag(int component) {
1204 DCHECK(widget_); 1281 DCHECK(widget_);
1205 1282
1206 // Cannot start another drag if one is already taking place. 1283 // Cannot start another drag if one is already taking place.
1207 if (resizer_) 1284 if (resizer_)
1208 return; 1285 return;
1209 1286
1210 if (widget_->GetNativeWindow()->HasCapture()) 1287 if (widget_->GetNativeWindow()->HasCapture())
1211 return; 1288 return;
1212 1289
1213 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow();
1214 gfx::Point drag_location =
1215 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1216 aura::Window::ConvertPointToTarget(
1217 root_window, widget_->GetNativeWindow()->parent(), &drag_location);
1218
1219 // Set the cursor before calling CreateWindowResizer(), as that will 1290 // Set the cursor before calling CreateWindowResizer(), as that will
1220 // eventually call LockCursor() and prevent the cursor from changing. 1291 // eventually call LockCursor() and prevent the cursor from changing.
1221 aura::client::CursorClient* cursor_client = 1292 aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
1222 aura::client::GetCursorClient(root_window); 1293 widget_->GetNativeWindow()->GetRootWindow());
1223 DCHECK(cursor_client); 1294 DCHECK(cursor_client);
1224 1295
1225 switch (component) { 1296 switch (component) {
1226 case HTCAPTION: 1297 case HTCAPTION:
1227 cursor_client->SetCursor(ui::kCursorPointer); 1298 cursor_client->SetCursor(ui::kCursorPointer);
1228 break; 1299 break;
1229 case HTTOP: 1300 case HTTOP:
1230 cursor_client->SetCursor(ui::kCursorNorthResize); 1301 cursor_client->SetCursor(ui::kCursorNorthResize);
1231 break; 1302 break;
1232 case HTTOPRIGHT: 1303 case HTTOPRIGHT:
(...skipping 16 matching lines...) Expand all
1249 break; 1320 break;
1250 case HTTOPLEFT: 1321 case HTTOPLEFT:
1251 cursor_client->SetCursor(ui::kCursorNorthWestResize); 1322 cursor_client->SetCursor(ui::kCursorNorthWestResize);
1252 break; 1323 break;
1253 default: 1324 default:
1254 NOTREACHED(); 1325 NOTREACHED();
1255 break; 1326 break;
1256 } 1327 }
1257 1328
1258 resizer_ = ash::CreateWindowResizer( 1329 resizer_ = ash::CreateWindowResizer(
1259 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, 1330 ash::WmWindow::Get(widget_->GetNativeWindow()), GetMouseLocation(),
1260 aura::client::WINDOW_MOVE_SOURCE_MOUSE); 1331 component, aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1261 if (!resizer_) 1332 if (!resizer_)
1262 return; 1333 return;
1263 1334
1264 // Apply pending origin offsets and resize direction before starting a new 1335 // Apply pending origin offsets and resize direction before starting a new
1265 // resize operation. These can still be pending if the client has acknowledged 1336 // resize operation. These can still be pending if the client has acknowledged
1266 // the configure request but not yet called Commit(). 1337 // the configure request but not yet called Commit().
1267 origin_ += pending_origin_offset_; 1338 origin_offset_ += pending_origin_offset_;
1268 pending_origin_offset_ = gfx::Vector2d(); 1339 pending_origin_offset_ = gfx::Vector2d();
1269 resize_component_ = pending_resize_component_; 1340 resize_component_ = pending_resize_component_;
1270 1341
1271 WMHelper::GetInstance()->AddPreTargetHandler(this); 1342 WMHelper::GetInstance()->AddPreTargetHandler(this);
1272 widget_->GetNativeWindow()->SetCapture(); 1343 widget_->GetNativeWindow()->SetCapture();
1273 1344
1274 // Notify client that resizing state has changed. 1345 // Notify client that resizing state has changed.
1275 if (IsResizing()) 1346 if (IsResizing())
1276 Configure(); 1347 Configure();
1277 } 1348 }
(...skipping 13 matching lines...) Expand all
1291 widget_->GetNativeWindow()->ReleaseCapture(); 1362 widget_->GetNativeWindow()->ReleaseCapture();
1292 resizer_.reset(); 1363 resizer_.reset();
1293 1364
1294 // Notify client that resizing state has changed. 1365 // Notify client that resizing state has changed.
1295 if (was_resizing) 1366 if (was_resizing)
1296 Configure(); 1367 Configure();
1297 1368
1298 UpdateWidgetBounds(); 1369 UpdateWidgetBounds();
1299 } 1370 }
1300 1371
1372 void ShellSurface::EndDragOrMove(bool revert) {
1373 if (resizer_)
1374 EndDrag(revert);
1375 else
1376 UnsetMoving(revert);
1377 }
1378
1301 bool ShellSurface::IsResizing() const { 1379 bool ShellSurface::IsResizing() const {
1302 ash::wm::WindowState* window_state = 1380 ash::wm::WindowState* window_state =
1303 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1381 ash::wm::GetWindowState(widget_->GetNativeWindow());
1304 if (!window_state->is_dragged()) 1382 if (!window_state->is_dragged())
1305 return false; 1383 return false;
1306 1384
1307 return window_state->drag_details()->bounds_change & 1385 return window_state->drag_details()->bounds_change &
1308 ash::WindowResizer::kBoundsChange_Resizes; 1386 ash::WindowResizer::kBoundsChange_Resizes;
1309 } 1387 }
1310 1388
1311 gfx::Rect ShellSurface::GetVisibleBounds() const { 1389 gfx::Rect ShellSurface::GetVisibleBounds() const {
1312 // Use |geometry_| if set, otherwise use the visual bounds of the surface. 1390 // Use |geometry_| if set, otherwise use the visual bounds of the surface.
1313 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) 1391 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size())
1314 : geometry_; 1392 : geometry_;
1315 } 1393 }
1316 1394
1317 gfx::Point ShellSurface::GetSurfaceOrigin() const { 1395 gfx::Point ShellSurface::GetSurfaceOrigin() const {
1318 // If initial bounds were specified then surface origin is always relative 1396 // For client-positioned shell surfaces, the surface origin corresponds to the
1319 // to those bounds. 1397 // widget position relative to the origin specified by the client. Since the
1320 if (!initial_bounds_.IsEmpty()) { 1398 // surface is positioned relative to the widget, negate this vector to align
1321 gfx::Point origin = widget_->GetNativeWindow()->bounds().origin(); 1399 // the surface with the widget. Note that the widget position must have been
1322 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); 1400 // adjusted by the |origin_offset_| prior to this call.
1323 return initial_bounds_.origin() - origin.OffsetFromOrigin(); 1401 if (bounds_mode_ != BoundsMode::SHELL) {
1402 gfx::Point position = widget_->GetNativeWindow()->bounds().origin();
1403 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position);
1404 return origin_ - position.OffsetFromOrigin();
1324 } 1405 }
1325 1406
1326 gfx::Rect visible_bounds = GetVisibleBounds(); 1407 gfx::Rect visible_bounds = GetVisibleBounds();
1327 gfx::Rect client_bounds = 1408 gfx::Rect client_bounds =
1328 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1409 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1329 switch (resize_component_) { 1410 switch (resize_component_) {
1330 case HTCAPTION: 1411 case HTCAPTION:
1331 return origin_ - visible_bounds.OffsetFromOrigin(); 1412 return gfx::Point() + origin_offset_ - visible_bounds.OffsetFromOrigin();
1332 case HTBOTTOM: 1413 case HTBOTTOM:
1333 case HTRIGHT: 1414 case HTRIGHT:
1334 case HTBOTTOMRIGHT: 1415 case HTBOTTOMRIGHT:
1335 return gfx::Point() - visible_bounds.OffsetFromOrigin(); 1416 return gfx::Point() - visible_bounds.OffsetFromOrigin();
1336 case HTTOP: 1417 case HTTOP:
1337 case HTTOPRIGHT: 1418 case HTTOPRIGHT:
1338 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) - 1419 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) -
1339 visible_bounds.OffsetFromOrigin(); 1420 visible_bounds.OffsetFromOrigin();
1340 break; 1421 break;
1341 case HTLEFT: 1422 case HTLEFT:
1342 case HTBOTTOMLEFT: 1423 case HTBOTTOMLEFT:
1343 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) - 1424 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) -
1344 visible_bounds.OffsetFromOrigin(); 1425 visible_bounds.OffsetFromOrigin();
1345 case HTTOPLEFT: 1426 case HTTOPLEFT:
1346 return gfx::Point(client_bounds.width() - visible_bounds.width(), 1427 return gfx::Point(client_bounds.width() - visible_bounds.width(),
1347 client_bounds.height() - visible_bounds.height()) - 1428 client_bounds.height() - visible_bounds.height()) -
1348 visible_bounds.OffsetFromOrigin(); 1429 visible_bounds.OffsetFromOrigin();
1349 default: 1430 default:
1350 NOTREACHED(); 1431 NOTREACHED();
1351 return gfx::Point(); 1432 return gfx::Point();
1352 } 1433 }
1353 } 1434 }
1354 1435
1355 void ShellSurface::UpdateWidgetBounds() { 1436 void ShellSurface::UpdateWidgetBounds() {
1356 DCHECK(widget_); 1437 DCHECK(widget_);
1357 1438
1358 // Return early if the shell is currently managing the bounds of the widget. 1439 // Return early if the shell is currently managing the bounds of the widget,
1359 // 1) When a window is either maximized/fullscreen/pinned, and the bounds 1440 // and the window is maximized/fullscreen/pinned or being dragged.
1360 // isn't controlled by a client. 1441 if (bounds_mode_ == BoundsMode::SHELL &&
reveman 2017/02/06 19:49:33 please split this into multiple lines as before. t
Dominik Laskowski 2017/02/08 18:07:40 Done, but it's "&&" so there's no third case.
1361 ash::wm::WindowState* window_state = 1442 (ash::wm::GetWindowState(widget_->GetNativeWindow())
1362 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1443 ->IsMaximizedOrFullscreenOrPinned() ||
1363 if (window_state->IsMaximizedOrFullscreenOrPinned() && 1444 IsResizing()))
1364 !window_state->allow_set_bounds_in_maximized()) {
1365 return;
1366 }
1367
1368 // 2) When a window is being dragged.
1369 if (IsResizing())
1370 return; 1445 return;
1371 1446
1372 // Return early if there is pending configure requests. 1447 // Return early if there is pending configure requests.
1373 if (!pending_configs_.empty() || scoped_configure_) 1448 if (!pending_configs_.empty() || scoped_configure_)
1374 return; 1449 return;
1375 1450
1376 gfx::Rect visible_bounds = GetVisibleBounds(); 1451 gfx::Rect visible_bounds = GetVisibleBounds();
1377 gfx::Rect new_widget_bounds = 1452 gfx::Rect new_widget_bounds =
1378 widget_->non_client_view()->GetWindowBoundsForClientBounds( 1453 widget_->non_client_view()->GetWindowBoundsForClientBounds(
1379 visible_bounds); 1454 visible_bounds);
1380 1455
1381 // Avoid changing widget origin unless initial bounds were specified and 1456 if (bounds_mode_ == BoundsMode::CLIENT) {
reveman 2017/02/06 19:49:33 nit: use a switch statement
Dominik Laskowski 2017/02/08 18:07:40 Done. I've also merged the case below so it's clea
1382 // widget origin is always relative to it. 1457 // Position is relative to the latest origin acknowledged by the client.
1383 if (initial_bounds_.IsEmpty()) { 1458 new_widget_bounds -= origin_offset_;
1459 } else if (bounds_mode_ == BoundsMode::FIXED) {
1460 // Position is relative to the origin.
1461 new_widget_bounds += origin_.OffsetFromOrigin();
1462 } else {
1463 // Preserve widget position.
1384 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); 1464 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin());
1385 } else {
1386 new_widget_bounds.set_origin(initial_bounds_.origin() +
1387 visible_bounds.OffsetFromOrigin());
1388 } 1465 }
1389 1466
1390 // Update widget origin using the surface origin if the current location of 1467 // Update widget origin using the surface origin if the current location of
1391 // surface is being anchored to one side of the widget as a result of a 1468 // surface is being anchored to one side of the widget as a result of a
1392 // resize operation. 1469 // resize operation.
1393 if (resize_component_ != HTCAPTION) { 1470 if (resize_component_ != HTCAPTION) {
1394 gfx::Point new_widget_origin = 1471 gfx::Point new_widget_origin =
1395 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); 1472 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
1396 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); 1473 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin);
1397 new_widget_bounds.set_origin(new_widget_origin); 1474 new_widget_bounds.set_origin(new_widget_origin);
1398 } 1475 }
1399 1476
1400 // Set |ignore_window_bounds_changes_| as this change to window bounds 1477 // Set |ignore_window_bounds_changes_| as this change to window bounds
1401 // should not result in a configure request. 1478 // should not result in a configure request.
1402 DCHECK(!ignore_window_bounds_changes_); 1479 DCHECK(!ignore_window_bounds_changes_);
1403 ignore_window_bounds_changes_ = true; 1480 ignore_window_bounds_changes_ = true;
1404 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) 1481 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) {
1405 widget_->SetBounds(new_widget_bounds); 1482 if (!move_resizer_) {
1483 widget_->SetBounds(new_widget_bounds);
1484 UpdateSurfaceBounds();
1485 } else {
1486 // Convert from screen to display coordinates.
1487 gfx::Point origin = new_widget_bounds.origin();
1488 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
1489 new_widget_bounds.set_origin(origin);
1490
1491 // Move the window relative to the current display.
1492 widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
1493 UpdateSurfaceBounds();
1494
1495 // Render phantom windows when beyond the current display.
1496 move_resizer_->Drag(GetMouseLocation(), 0);
1497 }
1498 }
1499
1406 ignore_window_bounds_changes_ = false; 1500 ignore_window_bounds_changes_ = false;
1501 }
1407 1502
1408 gfx::Rect client_view_bounds = 1503 void ShellSurface::UpdateSurfaceBounds() {
1504 const gfx::Rect client_view_bounds =
1409 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); 1505 widget_->non_client_view()->frame_view()->GetBoundsForClientView();
1410 1506
1411 // A change to the widget size requires surface bounds to be re-adjusted.
1412 surface_->window()->SetBounds( 1507 surface_->window()->SetBounds(
1413 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), 1508 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(),
1414 surface_->window()->layer()->size())); 1509 surface_->window()->layer()->size()));
1415 } 1510 }
1416 1511
1417 void ShellSurface::UpdateShadow() { 1512 void ShellSurface::UpdateShadow() {
1418 if (!widget_) 1513 if (!widget_)
1419 return; 1514 return;
1420 aura::Window* window = widget_->GetNativeWindow(); 1515 aura::Window* window = widget_->GetNativeWindow();
1421 if (!shadow_enabled_) { 1516 if (!shadow_enabled_) {
1422 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); 1517 wm::SetShadowElevation(window, wm::ShadowElevation::NONE);
1423 if (shadow_underlay_) 1518 if (shadow_underlay_)
1424 shadow_underlay_->Hide(); 1519 shadow_underlay_->Hide();
1425 } else { 1520 } else {
1426 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM); 1521 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM);
1427 1522
1428 gfx::Rect shadow_content_bounds = shadow_content_bounds_; 1523 gfx::Rect shadow_content_bounds = shadow_content_bounds_;
1429 if (shadow_content_bounds.IsEmpty()) 1524 if (shadow_content_bounds.IsEmpty())
1430 shadow_content_bounds = window->bounds(); 1525 shadow_content_bounds = window->bounds();
1431 1526
1432 // TODO(oshima): Adjust the coordinates from client screen to 1527 gfx::Point shadow_origin = shadow_content_bounds.origin() - origin_offset_;
1433 // chromeos screen when multi displays are supported. 1528 wm::ConvertPointFromScreen(window->parent(), &shadow_origin);
1434 gfx::Point origin = window->bounds().origin(); 1529 shadow_origin -= window->bounds().OffsetFromOrigin();
1435 gfx::Point shadow_origin = shadow_content_bounds.origin();
1436 shadow_origin -= origin.OffsetFromOrigin();
1437 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); 1530 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size());
1438 1531
1439 // Always create and show the underlay, even in maximized/fullscreen. 1532 // Always create and show the underlay, even in maximized/fullscreen.
1440 if (!shadow_underlay_) { 1533 if (!shadow_underlay_) {
1441 shadow_underlay_ = new aura::Window(nullptr); 1534 shadow_underlay_ = new aura::Window(nullptr);
1442 shadow_underlay_event_handler_ = 1535 shadow_underlay_event_handler_ =
1443 base::MakeUnique<ShadowUnderlayEventHandler>(); 1536 base::MakeUnique<ShadowUnderlayEventHandler>();
1444 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); 1537 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
1445 DCHECK(shadow_underlay_->owned_by_parent()); 1538 DCHECK(shadow_underlay_->owned_by_parent());
1446 // Ensure the background area inside the shadow is solid black. 1539 // Ensure the background area inside the shadow is solid black.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 // Surfaces that can't be activated are usually menus and tooltips. Use a 1609 // Surfaces that can't be activated are usually menus and tooltips. Use a
1517 // small style shadow for them. 1610 // small style shadow for them.
1518 if (!activatable_) 1611 if (!activatable_)
1519 shadow->SetElevation(wm::ShadowElevation::SMALL); 1612 shadow->SetElevation(wm::ShadowElevation::SMALL);
1520 // We don't have rounded corners unless frame is enabled. 1613 // We don't have rounded corners unless frame is enabled.
1521 if (!frame_enabled_) 1614 if (!frame_enabled_)
1522 shadow->SetRoundedCornerRadius(0); 1615 shadow->SetRoundedCornerRadius(0);
1523 } 1616 }
1524 } 1617 }
1525 1618
1619 gfx::Point ShellSurface::GetMouseLocation() const {
1620 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
1621 gfx::Point location =
1622 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1623 aura::Window::ConvertPointToTarget(
1624 root_window, widget_->GetNativeWindow()->parent(), &location);
1625 return location;
1626 }
1627
1526 } // namespace exo 1628 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698