OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "services/ui/public/cpp/window.h" | 5 #include "services/ui/public/cpp/window.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <set> | 10 #include <set> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/containers/adapters.h" |
14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "cc/output/compositor_frame.h" |
| 17 #include "cc/quads/render_pass.h" |
| 18 #include "cc/quads/render_pass_draw_quad.h" |
| 19 #include "cc/quads/shared_quad_state.h" |
| 20 #include "cc/quads/surface_draw_quad.h" |
15 #include "services/ui/common/transient_window_utils.h" | 21 #include "services/ui/common/transient_window_utils.h" |
16 #include "services/ui/public/cpp/property_type_converters.h" | 22 #include "services/ui/public/cpp/property_type_converters.h" |
17 #include "services/ui/public/cpp/window_observer.h" | 23 #include "services/ui/public/cpp/window_observer.h" |
18 #include "services/ui/public/cpp/window_private.h" | 24 #include "services/ui/public/cpp/window_private.h" |
19 #include "services/ui/public/cpp/window_property.h" | 25 #include "services/ui/public/cpp/window_property.h" |
20 #include "services/ui/public/cpp/window_surface.h" | 26 #include "services/ui/public/cpp/window_surface.h" |
21 #include "services/ui/public/cpp/window_tracker.h" | 27 #include "services/ui/public/cpp/window_tracker.h" |
22 #include "services/ui/public/cpp/window_tree_client.h" | 28 #include "services/ui/public/cpp/window_tree_client.h" |
23 #include "services/ui/public/interfaces/window_manager.mojom.h" | 29 #include "services/ui/public/interfaces/window_manager.mojom.h" |
24 #include "ui/display/display.h" | 30 #include "ui/display/display.h" |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 std::string Window::GetName() const { | 514 std::string Window::GetName() const { |
509 if (HasSharedProperty(mojom::WindowManager::kName_Property)) | 515 if (HasSharedProperty(mojom::WindowManager::kName_Property)) |
510 return GetSharedProperty<std::string>(mojom::WindowManager::kName_Property); | 516 return GetSharedProperty<std::string>(mojom::WindowManager::kName_Property); |
511 | 517 |
512 return std::string(); | 518 return std::string(); |
513 } | 519 } |
514 | 520 |
515 //////////////////////////////////////////////////////////////////////////////// | 521 //////////////////////////////////////////////////////////////////////////////// |
516 // Window, protected: | 522 // Window, protected: |
517 | 523 |
518 Window::Window() : Window(nullptr, static_cast<Id>(-1)) {} | 524 Window::Window(bool container) |
| 525 : Window(nullptr, static_cast<Id>(-1), container) {} |
519 | 526 |
520 Window::~Window() { | 527 Window::~Window() { |
521 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); | 528 FOR_EACH_OBSERVER(WindowObserver, observers_, OnWindowDestroying(this)); |
| 529 if (!surface_info_.surface_id.is_null()) { |
| 530 // If the existing surface ID is non-null, then we should return the |
| 531 // existing SurfaceSequence. |
| 532 if (client_) { |
| 533 client_->SatisfySurfaceSequence( |
| 534 server_id_, surface_info_.surface_sequence); |
| 535 } |
| 536 } |
| 537 |
522 if (client_) | 538 if (client_) |
523 client_->OnWindowDestroying(this); | 539 client_->OnWindowDestroying(this); |
524 | 540 |
525 if (HasFocus()) { | 541 if (HasFocus()) { |
526 // The focused window is being removed. When this happens the server | 542 // The focused window is being removed. When this happens the server |
527 // advances focus. We don't want to randomly pick a Window to get focus, so | 543 // advances focus. We don't want to randomly pick a Window to get focus, so |
528 // we update local state only, and wait for the next focus change from the | 544 // we update local state only, and wait for the next focus change from the |
529 // server. | 545 // server. |
530 client_->LocalSetFocus(nullptr); | 546 client_->LocalSetFocus(nullptr); |
531 } | 547 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 | 581 |
566 // Invoke after observers so that can clean up any internal state observers | 582 // Invoke after observers so that can clean up any internal state observers |
567 // may have changed. | 583 // may have changed. |
568 if (window_tree()) | 584 if (window_tree()) |
569 window_tree()->OnWindowDestroyed(this); | 585 window_tree()->OnWindowDestroyed(this); |
570 } | 586 } |
571 | 587 |
572 //////////////////////////////////////////////////////////////////////////////// | 588 //////////////////////////////////////////////////////////////////////////////// |
573 // Window, private: | 589 // Window, private: |
574 | 590 |
575 Window::Window(WindowTreeClient* client, Id id) | 591 Window::Window(WindowTreeClient* client, Id id, bool container) |
576 : client_(client), | 592 : client_(client), |
| 593 container_(container), |
577 server_id_(id), | 594 server_id_(id), |
578 parent_(nullptr), | 595 parent_(nullptr), |
579 stacking_target_(nullptr), | 596 stacking_target_(nullptr), |
580 transient_parent_(nullptr), | 597 transient_parent_(nullptr), |
581 is_modal_(false), | 598 is_modal_(false), |
582 // Matches aura, see aura::Window for details. | 599 // Matches aura, see aura::Window for details. |
583 observers_(base::ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY), | 600 observers_(base::ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY), |
584 input_event_handler_(nullptr), | 601 input_event_handler_(nullptr), |
585 visible_(false), | 602 visible_(false), |
586 opacity_(1.0f), | 603 opacity_(1.0f), |
587 display_id_(display::Display::kInvalidDisplayID), | 604 display_id_(display::Display::kInvalidDisplayID), |
588 cursor_id_(mojom::Cursor::CURSOR_NULL), | 605 cursor_id_(mojom::Cursor::CURSOR_NULL), |
589 parent_drawn_(false) {} | 606 parent_drawn_(false), |
| 607 draw_timer_(false, false), |
| 608 weak_factory_(this) { |
| 609 if (container) { |
| 610 WantToDraw(); |
| 611 } |
| 612 } |
| 613 |
| 614 void Window::WantToDraw() { |
| 615 if (draw_timer_.IsRunning()) |
| 616 return; |
| 617 |
| 618 // TODO(rjkroege): Use vblank to kick off Draw. |
| 619 draw_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(16), |
| 620 base::Bind(&Window::Draw, weak_factory_.GetWeakPtr())); |
| 621 } |
| 622 |
| 623 void Window::Draw() { |
| 624 if (!visible_) |
| 625 return; |
| 626 |
| 627 const cc::RenderPassId render_pass_id(1, 1); |
| 628 std::unique_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create(); |
| 629 render_pass->SetNew(render_pass_id, bounds_, bounds_, gfx::Transform()); |
| 630 |
| 631 uint32_t children_drawn = 0; |
| 632 for (Window* child : base::Reversed(children_)) { |
| 633 if (child->surface_info_.surface_id.is_null()) |
| 634 continue; |
| 635 children_drawn++; |
| 636 gfx::Transform quad_to_target_transform; |
| 637 quad_to_target_transform.Translate(child->bounds().x(), |
| 638 child->bounds().y()); |
| 639 cc::SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); |
| 640 const gfx::Rect bounds_at_origin(child->bounds().size()); |
| 641 // TODO(fsamuel): These clipping and visible rects are incorrect. They need |
| 642 // to be populated from CompositorFrame structs. |
| 643 sqs->SetAll(quad_to_target_transform, |
| 644 bounds_at_origin.size() /* layer_bounds */, |
| 645 bounds_at_origin /* visible_layer_bounds */, |
| 646 bounds_at_origin /* clip_rect */, false /* is_clipped */, |
| 647 1.f /* opacity */, SkXfermode::kSrcOver_Mode, |
| 648 0 /* sorting-context_id */); |
| 649 auto* quad = render_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); |
| 650 quad->SetAll(sqs, child->bounds() /* rect */, gfx::Rect() /* opaque_rect */, |
| 651 bounds_at_origin /* visible_rect */, true /* needs_blending*/, |
| 652 child->surface_info_.surface_id); |
| 653 } |
| 654 if (children_drawn) { |
| 655 std::unique_ptr<cc::DelegatedFrameData> frame_data( |
| 656 new cc::DelegatedFrameData); |
| 657 frame_data->render_pass_list.push_back(std::move(render_pass)); |
| 658 cc::CompositorFrame frame; |
| 659 frame.delegated_frame_data = std::move(frame_data); |
| 660 if (!container_surface_) { |
| 661 SetSharedProperty<bool>( |
| 662 ui::mojom::WindowManager::kContainer_Property, true); |
| 663 container_surface_ = RequestSurface(mojom::SurfaceType::DEFAULT); |
| 664 container_surface_->BindToThread(); |
| 665 } |
| 666 container_surface_->SubmitCompositorFrame( |
| 667 std::move(frame), base::Bind(&base::DoNothing)); |
| 668 } |
| 669 |
| 670 WantToDraw(); |
| 671 } |
| 672 |
| 673 void Window::SetIsContainer() { |
| 674 if (!container_) { |
| 675 container_ = true; |
| 676 WantToDraw(); |
| 677 } |
| 678 } |
590 | 679 |
591 void Window::SetSharedPropertyInternal(const std::string& name, | 680 void Window::SetSharedPropertyInternal(const std::string& name, |
592 const std::vector<uint8_t>* value) { | 681 const std::vector<uint8_t>* value) { |
593 if (!WasCreatedByThisClientOrIsRoot(this)) | 682 if (!WasCreatedByThisClientOrIsRoot(this)) |
594 return; | 683 return; |
595 | 684 |
596 if (client_) { | 685 if (client_) { |
597 mojo::Array<uint8_t> transport_value(nullptr); | 686 mojo::Array<uint8_t> transport_value(nullptr); |
598 if (value) { | 687 if (value) { |
599 transport_value.resize(value->size()); | 688 transport_value.resize(value->size()); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 | 776 |
688 void Window::LocalSetBounds(const gfx::Rect& old_bounds, | 777 void Window::LocalSetBounds(const gfx::Rect& old_bounds, |
689 const gfx::Rect& new_bounds) { | 778 const gfx::Rect& new_bounds) { |
690 // If this client owns the window, then it should be the only one to change | 779 // If this client owns the window, then it should be the only one to change |
691 // the bounds. | 780 // the bounds. |
692 DCHECK(!WasCreatedByThisClient() || old_bounds == bounds_); | 781 DCHECK(!WasCreatedByThisClient() || old_bounds == bounds_); |
693 ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds); | 782 ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds); |
694 bounds_ = new_bounds; | 783 bounds_ = new_bounds; |
695 } | 784 } |
696 | 785 |
| 786 void Window::LocalSetSurfaceId(const gfx::Size& size, |
| 787 float device_scale_factor, |
| 788 const cc::SurfaceId& surface_id, |
| 789 const cc::SurfaceSequence& surface_sequence) { |
| 790 const cc::SurfaceId& existing_surface_id = surface_info_.surface_id; |
| 791 if (!existing_surface_id.is_null() && existing_surface_id != surface_id) { |
| 792 // If the existing surface ID is non-null, then we should return the |
| 793 // existing SurfaceSequence. |
| 794 if (client_) { |
| 795 client_->SatisfySurfaceSequence( |
| 796 server_id_, surface_info_.surface_sequence); |
| 797 } |
| 798 } |
| 799 surface_info_ = {size, device_scale_factor, surface_id, surface_sequence}; |
| 800 if (parent_) { |
| 801 FOR_EACH_OBSERVER( |
| 802 WindowObserver, observers_, |
| 803 OnChildWindowSurfaceCreated(this, size, device_scale_factor, surface_id, |
| 804 surface_sequence)); |
| 805 } |
| 806 } |
| 807 |
697 void Window::LocalSetClientArea( | 808 void Window::LocalSetClientArea( |
698 const gfx::Insets& new_client_area, | 809 const gfx::Insets& new_client_area, |
699 const std::vector<gfx::Rect>& additional_client_areas) { | 810 const std::vector<gfx::Rect>& additional_client_areas) { |
700 const std::vector<gfx::Rect> old_additional_client_areas = | 811 const std::vector<gfx::Rect> old_additional_client_areas = |
701 additional_client_areas_; | 812 additional_client_areas_; |
702 const gfx::Insets old_client_area = client_area_; | 813 const gfx::Insets old_client_area = client_area_; |
703 client_area_ = new_client_area; | 814 client_area_ = new_client_area; |
704 additional_client_areas_ = additional_client_areas; | 815 additional_client_areas_ = additional_client_areas; |
705 FOR_EACH_OBSERVER(WindowObserver, observers_, | 816 FOR_EACH_OBSERVER(WindowObserver, observers_, |
706 OnWindowClientAreaChanged(this, old_client_area, | 817 OnWindowClientAreaChanged(this, old_client_area, |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 notifier->NotifyWindowReordered(); | 1035 notifier->NotifyWindowReordered(); |
925 | 1036 |
926 return true; | 1037 return true; |
927 } | 1038 } |
928 | 1039 |
929 // static | 1040 // static |
930 Window** Window::GetStackingTarget(Window* window) { | 1041 Window** Window::GetStackingTarget(Window* window) { |
931 return &window->stacking_target_; | 1042 return &window->stacking_target_; |
932 } | 1043 } |
933 } // namespace ui | 1044 } // namespace ui |
OLD | NEW |