Index: services/ui/public/cpp/window.cc |
diff --git a/services/ui/public/cpp/window.cc b/services/ui/public/cpp/window.cc |
deleted file mode 100644 |
index e1cbe88d177c9e367b173a27fb5ebac65e55c590..0000000000000000000000000000000000000000 |
--- a/services/ui/public/cpp/window.cc |
+++ /dev/null |
@@ -1,965 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "services/ui/public/cpp/window.h" |
- |
-#include <stddef.h> |
-#include <stdint.h> |
- |
-#include <set> |
-#include <string> |
- |
-#include "base/bind.h" |
-#include "base/macros.h" |
-#include "services/ui/common/transient_window_utils.h" |
-#include "services/ui/public/cpp/property_type_converters.h" |
-#include "services/ui/public/cpp/window_compositor_frame_sink.h" |
-#include "services/ui/public/cpp/window_observer.h" |
-#include "services/ui/public/cpp/window_private.h" |
-#include "services/ui/public/cpp/window_property.h" |
-#include "services/ui/public/cpp/window_tracker.h" |
-#include "services/ui/public/cpp/window_tree_client.h" |
-#include "services/ui/public/interfaces/window_manager.mojom.h" |
-#include "ui/display/display.h" |
-#include "ui/display/types/display_constants.h" |
-#include "ui/gfx/geometry/rect.h" |
-#include "ui/gfx/geometry/size.h" |
- |
-namespace ui { |
- |
-namespace { |
- |
-void NotifyWindowTreeChangeAtReceiver( |
- Window* receiver, |
- const WindowObserver::TreeChangeParams& params, |
- bool change_applied) { |
- WindowObserver::TreeChangeParams local_params = params; |
- local_params.receiver = receiver; |
- if (change_applied) { |
- for (auto& observer : *WindowPrivate(receiver).observers()) |
- observer.OnTreeChanged(local_params); |
- } else { |
- for (auto& observer : *WindowPrivate(receiver).observers()) |
- observer.OnTreeChanging(local_params); |
- } |
-} |
- |
-void NotifyWindowTreeChangeUp(Window* start_at, |
- const WindowObserver::TreeChangeParams& params, |
- bool change_applied) { |
- for (Window* current = start_at; current; current = current->parent()) |
- NotifyWindowTreeChangeAtReceiver(current, params, change_applied); |
-} |
- |
-void NotifyWindowTreeChangeDown(Window* start_at, |
- const WindowObserver::TreeChangeParams& params, |
- bool change_applied) { |
- NotifyWindowTreeChangeAtReceiver(start_at, params, change_applied); |
- Window::Children::const_iterator it = start_at->children().begin(); |
- for (; it != start_at->children().end(); ++it) |
- NotifyWindowTreeChangeDown(*it, params, change_applied); |
-} |
- |
-void NotifyWindowTreeChange(const WindowObserver::TreeChangeParams& params, |
- bool change_applied) { |
- NotifyWindowTreeChangeDown(params.target, params, change_applied); |
- if (params.old_parent) |
- NotifyWindowTreeChangeUp(params.old_parent, params, change_applied); |
- if (params.new_parent) |
- NotifyWindowTreeChangeUp(params.new_parent, params, change_applied); |
-} |
- |
-class ScopedTreeNotifier { |
- public: |
- ScopedTreeNotifier(Window* target, Window* old_parent, Window* new_parent) { |
- params_.target = target; |
- params_.old_parent = old_parent; |
- params_.new_parent = new_parent; |
- NotifyWindowTreeChange(params_, false); |
- } |
- ~ScopedTreeNotifier() { NotifyWindowTreeChange(params_, true); } |
- |
- private: |
- WindowObserver::TreeChangeParams params_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ScopedTreeNotifier); |
-}; |
- |
-void RemoveChildImpl(Window* child, Window::Children* children) { |
- Window::Children::iterator it = |
- std::find(children->begin(), children->end(), child); |
- if (it != children->end()) { |
- children->erase(it); |
- WindowPrivate(child).ClearParent(); |
- } |
-} |
- |
-class OrderChangedNotifier { |
- public: |
- OrderChangedNotifier(Window* window, |
- Window* relative_window, |
- mojom::OrderDirection direction) |
- : window_(window), |
- relative_window_(relative_window), |
- direction_(direction) {} |
- |
- ~OrderChangedNotifier() {} |
- |
- void NotifyWindowReordering() { |
- for (auto& observer : *WindowPrivate(window_).observers()) |
- observer.OnWindowReordering(window_, relative_window_, direction_); |
- } |
- |
- void NotifyWindowReordered() { |
- for (auto& observer : *WindowPrivate(window_).observers()) |
- observer.OnWindowReordered(window_, relative_window_, direction_); |
- } |
- |
- private: |
- Window* window_; |
- Window* relative_window_; |
- mojom::OrderDirection direction_; |
- |
- DISALLOW_COPY_AND_ASSIGN(OrderChangedNotifier); |
-}; |
- |
-class ScopedSetBoundsNotifier { |
- public: |
- ScopedSetBoundsNotifier(Window* window, |
- const gfx::Rect& old_bounds, |
- const gfx::Rect& new_bounds) |
- : window_(window), old_bounds_(old_bounds), new_bounds_(new_bounds) { |
- for (auto& observer : *WindowPrivate(window_).observers()) |
- observer.OnWindowBoundsChanging(window_, old_bounds_, new_bounds_); |
- } |
- ~ScopedSetBoundsNotifier() { |
- for (auto& observer : *WindowPrivate(window_).observers()) |
- observer.OnWindowBoundsChanged(window_, old_bounds_, new_bounds_); |
- } |
- |
- private: |
- Window* window_; |
- const gfx::Rect old_bounds_; |
- const gfx::Rect new_bounds_; |
- |
- DISALLOW_COPY_AND_ASSIGN(ScopedSetBoundsNotifier); |
-}; |
- |
-bool IsClientRoot(Window* window) { |
- return window->window_tree() && |
- window->window_tree()->GetRoots().count(window) > 0; |
-} |
- |
-bool WasCreatedByThisClientOrIsRoot(Window* window) { |
- return window->WasCreatedByThisClient() || IsClientRoot(window); |
-} |
- |
-void EmptyEmbedCallback(bool result) {} |
- |
-} // namespace |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// Window, public: |
- |
-void Window::Destroy() { |
- if (!WasCreatedByThisClientOrIsRoot(this)) |
- return; |
- |
- if (client_) |
- client_->DestroyWindow(this); |
- while (!children_.empty()) { |
- Window* child = children_.front(); |
- if (!child->WasCreatedByThisClient()) { |
- WindowPrivate(child).ClearParent(); |
- children_.erase(children_.begin()); |
- } else { |
- child->Destroy(); |
- DCHECK(std::find(children_.begin(), children_.end(), child) == |
- children_.end()); |
- } |
- } |
- LocalDestroy(); |
-} |
- |
-bool Window::WasCreatedByThisClient() const { |
- return !client_ || client_->WasCreatedByThisClient(this); |
-} |
- |
-void Window::SetBounds(const gfx::Rect& bounds) { |
- if (!WasCreatedByThisClientOrIsRoot(this)) |
- return; |
- if (bounds_ == bounds) |
- return; |
- if (client_) |
- client_->SetBounds(this, bounds_, bounds); |
- LocalSetBounds(bounds_, bounds); |
-} |
- |
-gfx::Rect Window::GetBoundsInRoot() const { |
- gfx::Vector2d offset; |
- for (const Window* w = parent(); w != nullptr; w = w->parent()) |
- offset += w->bounds().OffsetFromOrigin(); |
- return bounds() + offset; |
-} |
- |
-void Window::SetClientArea( |
- const gfx::Insets& client_area, |
- const std::vector<gfx::Rect>& additional_client_areas) { |
- if (!WasCreatedByThisClientOrIsRoot(this)) |
- return; |
- |
- if (client_) |
- client_->SetClientArea(server_id_, client_area, |
- additional_client_areas); |
- LocalSetClientArea(client_area, additional_client_areas); |
-} |
- |
-void Window::SetHitTestMask(const gfx::Rect& mask) { |
- if (!WasCreatedByThisClientOrIsRoot(this)) |
- return; |
- |
- if (hit_test_mask_ && *hit_test_mask_ == mask) |
- return; |
- |
- if (client_) |
- client_->SetHitTestMask(server_id_, mask); |
- hit_test_mask_.reset(new gfx::Rect(mask)); |
-} |
- |
-void Window::ClearHitTestMask() { |
- if (!WasCreatedByThisClientOrIsRoot(this)) |
- return; |
- |
- if (!hit_test_mask_) |
- return; |
- |
- if (client_) |
- client_->ClearHitTestMask(server_id_); |
- hit_test_mask_.reset(); |
-} |
- |
-void Window::SetVisible(bool value) { |
- if (visible_ == value) |
- return; |
- |
- if (client_) |
- client_->SetVisible(this, value); |
- LocalSetVisible(value); |
-} |
- |
-void Window::SetOpacity(float opacity) { |
- if (client_) |
- client_->SetOpacity(this, opacity); |
- LocalSetOpacity(opacity); |
-} |
- |
-void Window::SetPredefinedCursor(ui::mojom::Cursor cursor_id) { |
- if (cursor_id_ == cursor_id) |
- return; |
- |
- if (client_) |
- client_->SetPredefinedCursor(server_id_, cursor_id); |
- LocalSetPredefinedCursor(cursor_id); |
-} |
- |
-bool Window::IsDrawn() const { |
- if (!visible_) |
- return false; |
- return parent_ ? parent_->IsDrawn() : parent_drawn_; |
-} |
- |
-std::unique_ptr<WindowCompositorFrameSink> Window::RequestCompositorFrameSink( |
- scoped_refptr<cc::ContextProvider> context_provider, |
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) { |
- std::unique_ptr<WindowCompositorFrameSinkBinding> |
- compositor_frame_sink_binding; |
- std::unique_ptr<WindowCompositorFrameSink> compositor_frame_sink = |
- WindowCompositorFrameSink::Create( |
- cc::FrameSinkId(server_id(), 0), std::move(context_provider), |
- gpu_memory_buffer_manager, &compositor_frame_sink_binding); |
- AttachCompositorFrameSink(std::move(compositor_frame_sink_binding)); |
- return compositor_frame_sink; |
-} |
- |
-void Window::AttachCompositorFrameSink( |
- std::unique_ptr<WindowCompositorFrameSinkBinding> |
- compositor_frame_sink_binding) { |
- window_tree()->AttachCompositorFrameSink( |
- server_id_, |
- std::move(compositor_frame_sink_binding->compositor_frame_sink_request_), |
- mojo::MakeProxy(std::move( |
- compositor_frame_sink_binding->compositor_frame_sink_client_))); |
-} |
- |
-void Window::ClearSharedProperty(const std::string& name) { |
- SetSharedPropertyInternal(name, nullptr); |
-} |
- |
-bool Window::HasSharedProperty(const std::string& name) const { |
- return properties_.count(name) > 0; |
-} |
- |
-void Window::AddObserver(WindowObserver* observer) { |
- observers_.AddObserver(observer); |
-} |
- |
-void Window::RemoveObserver(WindowObserver* observer) { |
- observers_.RemoveObserver(observer); |
-} |
- |
-const Window* Window::GetRoot() const { |
- const Window* root = this; |
- for (const Window* parent = this; parent; parent = parent->parent()) |
- root = parent; |
- return root; |
-} |
- |
-void Window::AddChild(Window* child) { |
- // TODO(beng): not necessarily valid to all clients, but possibly to the |
- // embeddee in an embedder-embeddee relationship. |
- if (client_) |
- CHECK_EQ(child->client_, client_); |
- // Roots can not be added as children of other windows. |
- if (window_tree() && window_tree()->IsRoot(child)) |
- return; |
- LocalAddChild(child); |
- if (client_) |
- client_->AddChild(this, child->server_id()); |
-} |
- |
-void Window::RemoveChild(Window* child) { |
- // TODO(beng): not necessarily valid to all clients, but possibly to the |
- // embeddee in an embedder-embeddee relationship. |
- if (client_) |
- CHECK_EQ(child->client_, client_); |
- LocalRemoveChild(child); |
- if (client_) |
- client_->RemoveChild(this, child->server_id()); |
-} |
- |
-void Window::Reorder(Window* relative, mojom::OrderDirection direction) { |
- if (!LocalReorder(relative, direction)) |
- return; |
- if (client_) |
- client_->Reorder(this, relative->server_id(), direction); |
-} |
- |
-void Window::MoveToFront() { |
- if (!parent_ || parent_->children_.back() == this) |
- return; |
- Reorder(parent_->children_.back(), mojom::OrderDirection::ABOVE); |
-} |
- |
-void Window::MoveToBack() { |
- if (!parent_ || parent_->children_.front() == this) |
- return; |
- Reorder(parent_->children_.front(), mojom::OrderDirection::BELOW); |
-} |
- |
-bool Window::Contains(const Window* child) const { |
- if (!child) |
- return false; |
- if (child == this) |
- return true; |
- if (client_) |
- CHECK_EQ(child->client_, client_); |
- for (const Window* p = child->parent(); p; p = p->parent()) { |
- if (p == this) |
- return true; |
- } |
- return false; |
-} |
- |
-void Window::AddTransientWindow(Window* transient_window) { |
- // A system modal window cannot become a transient child. |
- DCHECK(!transient_window->is_modal() || transient_window->transient_parent()); |
- |
- if (client_) |
- CHECK_EQ(transient_window->client_, client_); |
- LocalAddTransientWindow(transient_window); |
- if (client_) |
- client_->AddTransientWindow(this, transient_window->server_id()); |
-} |
- |
-void Window::RemoveTransientWindow(Window* transient_window) { |
- if (client_) |
- CHECK_EQ(transient_window->window_tree(), client_); |
- LocalRemoveTransientWindow(transient_window); |
- if (client_) |
- client_->RemoveTransientWindowFromParent(transient_window); |
-} |
- |
-void Window::SetModal() { |
- if (is_modal_) |
- return; |
- |
- LocalSetModal(); |
- if (client_) |
- client_->SetModal(this); |
-} |
- |
-Window* Window::GetChildByLocalId(int id) { |
- if (id == local_id_) |
- return this; |
- // TODO(beng): this could be improved depending on how we decide to own |
- // windows. |
- for (Window* child : children_) { |
- Window* matching_child = child->GetChildByLocalId(id); |
- if (matching_child) |
- return matching_child; |
- } |
- return nullptr; |
-} |
- |
-void Window::SetTextInputState(mojo::TextInputStatePtr state) { |
- if (client_) |
- client_->SetWindowTextInputState(server_id_, std::move(state)); |
-} |
- |
-void Window::SetImeVisibility(bool visible, mojo::TextInputStatePtr state) { |
- // SetImeVisibility() shouldn't be used if the window is not editable. |
- DCHECK(state.is_null() || state->type != mojo::TextInputType::NONE); |
- if (client_) |
- client_->SetImeVisibility(server_id_, visible, std::move(state)); |
-} |
- |
-bool Window::HasCapture() const { |
- return client_ && client_->GetCaptureWindow() == this; |
-} |
- |
-void Window::SetCapture() { |
- if (client_) |
- client_->SetCapture(this); |
-} |
- |
-void Window::ReleaseCapture() { |
- if (client_) |
- client_->ReleaseCapture(this); |
-} |
- |
-void Window::SetFocus() { |
- if (client_ && IsDrawn()) |
- client_->SetFocus(this); |
-} |
- |
-bool Window::HasFocus() const { |
- return client_ && client_->GetFocusedWindow() == this; |
-} |
- |
-void Window::SetCanFocus(bool can_focus) { |
- if (client_) |
- client_->SetCanFocus(server_id_, can_focus); |
-} |
- |
-void Window::SetCanAcceptDrops(WindowDropTarget* drop_target) { |
- if (drop_target_ == drop_target) |
- return; |
- drop_target_ = drop_target; |
- if (client_) |
- client_->SetCanAcceptDrops(server_id_, !!drop_target_); |
-} |
- |
-void Window::SetCanAcceptEvents(bool can_accept_events) { |
- if (can_accept_events_ == can_accept_events) |
- return; |
- can_accept_events_ = can_accept_events; |
- if (client_) |
- client_->SetCanAcceptEvents(server_id_, can_accept_events_); |
-} |
- |
-void Window::Embed(ui::mojom::WindowTreeClientPtr client, uint32_t flags) { |
- Embed(std::move(client), base::Bind(&EmptyEmbedCallback), flags); |
-} |
- |
-void Window::Embed(ui::mojom::WindowTreeClientPtr client, |
- const EmbedCallback& callback, |
- uint32_t flags) { |
- if (PrepareForEmbed()) |
- client_->Embed(server_id_, std::move(client), flags, callback); |
- else |
- callback.Run(false); |
-} |
- |
-void Window::RequestClose() { |
- if (client_) |
- client_->RequestClose(this); |
-} |
- |
-void Window::PerformDragDrop( |
- const std::map<std::string, std::vector<uint8_t>>& drag_data, |
- int drag_operation, |
- const gfx::Point& cursor_location, |
- const SkBitmap& bitmap, |
- const base::Callback<void(bool, uint32_t)>& callback) { |
- client_->PerformDragDrop(this, drag_data, drag_operation, cursor_location, |
- bitmap, callback); |
-} |
- |
-void Window::CancelDragDrop() { |
- client_->CancelDragDrop(this); |
-} |
- |
-void Window::PerformWindowMove(mojom::MoveLoopSource source, |
- const gfx::Point& cursor_location, |
- const base::Callback<void(bool)>& callback) { |
- client_->PerformWindowMove(this, source, cursor_location, callback); |
-} |
- |
-void Window::CancelWindowMove() { |
- client_->CancelWindowMove(this); |
-} |
- |
-std::string Window::GetName() const { |
- if (HasSharedProperty(mojom::WindowManager::kName_Property)) |
- return GetSharedProperty<std::string>(mojom::WindowManager::kName_Property); |
- |
- return std::string(); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// Window, protected: |
- |
-Window::Window() : Window(nullptr, static_cast<Id>(-1)) {} |
- |
-Window::~Window() { |
- for (auto& observer : observers_) |
- observer.OnWindowDestroying(this); |
- if (client_) |
- client_->OnWindowDestroying(this); |
- |
- if (HasFocus()) { |
- // The focused window is being removed. When this happens the server |
- // advances focus. We don't want to randomly pick a Window to get focus, so |
- // we update local state only, and wait for the next focus change from the |
- // server. |
- client_->LocalSetFocus(nullptr); |
- } |
- |
- // Remove from transient parent. |
- if (transient_parent_) |
- transient_parent_->LocalRemoveTransientWindow(this); |
- |
- // Return the surface reference if there is one. |
- if (surface_info_.id().is_valid()) |
- LocalSetSurfaceInfo(cc::SurfaceInfo()); |
- |
- // Remove transient children. |
- while (!transient_children_.empty()) { |
- Window* transient_child = transient_children_.front(); |
- LocalRemoveTransientWindow(transient_child); |
- transient_child->LocalDestroy(); |
- DCHECK(transient_children_.empty() || |
- transient_children_.front() != transient_child); |
- } |
- |
- if (parent_) |
- parent_->LocalRemoveChild(this); |
- |
- // We may still have children. This can happen if the embedder destroys the |
- // root while we're still alive. |
- while (!children_.empty()) { |
- Window* child = children_.front(); |
- LocalRemoveChild(child); |
- DCHECK(children_.empty() || children_.front() != child); |
- } |
- |
- // Notify observers before clearing properties (order matches aura::Window). |
- for (auto& observer : observers_) |
- observer.OnWindowDestroyed(this); |
- |
- // Clear properties. |
- for (auto& pair : prop_map_) { |
- if (pair.second.deallocator) |
- (*pair.second.deallocator)(pair.second.value); |
- } |
- prop_map_.clear(); |
- |
- // Invoke after observers so that can clean up any internal state observers |
- // may have changed. |
- if (window_tree()) |
- window_tree()->OnWindowDestroyed(this); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-// Window, private: |
- |
-Window::Window(WindowTreeClient* client, Id id) |
- : client_(client), |
- server_id_(id), |
- parent_(nullptr), |
- stacking_target_(nullptr), |
- transient_parent_(nullptr), |
- is_modal_(false), |
- // Matches aura, see aura::Window for details. |
- observers_(base::ObserverList<WindowObserver>::NOTIFY_EXISTING_ONLY), |
- input_event_handler_(nullptr), |
- visible_(false), |
- opacity_(1.0f), |
- display_id_(display::kInvalidDisplayId), |
- cursor_id_(mojom::Cursor::CURSOR_NULL), |
- parent_drawn_(false) {} |
- |
-void Window::SetSharedPropertyInternal(const std::string& name, |
- const std::vector<uint8_t>* value) { |
- if (!WasCreatedByThisClientOrIsRoot(this)) |
- return; |
- |
- if (client_) { |
- base::Optional<std::vector<uint8_t>> transport_value; |
- if (value) { |
- transport_value.emplace(value->size()); |
- if (value->size()) |
- memcpy(&transport_value.value().front(), &(value->front()), |
- value->size()); |
- } |
- // TODO: add test coverage of this (450303). |
- client_->SetProperty(this, name, std::move(transport_value)); |
- } |
- LocalSetSharedProperty(name, value); |
-} |
- |
-int64_t Window::SetLocalPropertyInternal(const void* key, |
- const char* name, |
- PropertyDeallocator deallocator, |
- int64_t value, |
- int64_t default_value) { |
- int64_t old = GetLocalPropertyInternal(key, default_value); |
- if (value == default_value) { |
- prop_map_.erase(key); |
- } else { |
- Value prop_value; |
- prop_value.name = name; |
- prop_value.value = value; |
- prop_value.deallocator = deallocator; |
- prop_map_[key] = prop_value; |
- } |
- for (auto& observer : observers_) |
- observer.OnWindowLocalPropertyChanged(this, key, old); |
- return old; |
-} |
- |
-int64_t Window::GetLocalPropertyInternal(const void* key, |
- int64_t default_value) const { |
- std::map<const void*, Value>::const_iterator iter = prop_map_.find(key); |
- if (iter == prop_map_.end()) |
- return default_value; |
- return iter->second.value; |
-} |
- |
-void Window::LocalDestroy() { |
- delete this; |
-} |
- |
-void Window::LocalAddChild(Window* child) { |
- ScopedTreeNotifier notifier(child, child->parent(), this); |
- if (child->parent()) |
- RemoveChildImpl(child, &child->parent_->children_); |
- children_.push_back(child); |
- child->parent_ = this; |
- child->display_id_ = display_id_; |
-} |
- |
-void Window::LocalRemoveChild(Window* child) { |
- DCHECK_EQ(this, child->parent()); |
- ScopedTreeNotifier notifier(child, this, nullptr); |
- RemoveChildImpl(child, &children_); |
-} |
- |
-void Window::LocalAddTransientWindow(Window* transient_window) { |
- if (transient_window->transient_parent()) |
- RemoveTransientWindowImpl(transient_window); |
- transient_children_.push_back(transient_window); |
- transient_window->transient_parent_ = this; |
- |
- // Restack |transient_window| properly above its transient parent, if they |
- // share the same parent. |
- if (transient_window->parent() == parent()) |
- RestackTransientDescendants(this, &GetStackingTarget, |
- &ReorderWithoutNotification); |
- |
- for (auto& observer : observers_) |
- observer.OnTransientChildAdded(this, transient_window); |
-} |
- |
-void Window::LocalRemoveTransientWindow(Window* transient_window) { |
- DCHECK_EQ(this, transient_window->transient_parent()); |
- RemoveTransientWindowImpl(transient_window); |
- for (auto& observer : observers_) |
- observer.OnTransientChildRemoved(this, transient_window); |
-} |
- |
-void Window::LocalSetModal() { |
- is_modal_ = true; |
-} |
- |
-bool Window::LocalReorder(Window* relative, mojom::OrderDirection direction) { |
- OrderChangedNotifier notifier(this, relative, direction); |
- return ReorderImpl(this, relative, direction, ¬ifier); |
-} |
- |
-void Window::LocalSetBounds(const gfx::Rect& old_bounds, |
- const gfx::Rect& new_bounds) { |
- // If this client owns the window, then it should be the only one to change |
- // the bounds. |
- DCHECK(!WasCreatedByThisClient() || old_bounds == bounds_); |
- ScopedSetBoundsNotifier notifier(this, old_bounds, new_bounds); |
- bounds_ = new_bounds; |
-} |
- |
-void Window::LocalSetClientArea( |
- const gfx::Insets& new_client_area, |
- const std::vector<gfx::Rect>& additional_client_areas) { |
- const std::vector<gfx::Rect> old_additional_client_areas = |
- additional_client_areas_; |
- const gfx::Insets old_client_area = client_area_; |
- client_area_ = new_client_area; |
- additional_client_areas_ = additional_client_areas; |
- for (auto& observer : observers_) { |
- observer.OnWindowClientAreaChanged(this, old_client_area, |
- old_additional_client_areas); |
- } |
-} |
- |
-void Window::LocalSetDisplay(int64_t display_id) { |
- display_id_ = display_id; |
- // TODO(sad): Notify observers (of this window, and of the descendant windows) |
- // when a window moves from one display into another. https://crbug.com/614887 |
-} |
- |
-void Window::LocalSetParentDrawn(bool value) { |
- if (parent_drawn_ == value) |
- return; |
- |
- // As IsDrawn() is derived from |visible_| and |parent_drawn_|, only send |
- // drawn notification is the value of IsDrawn() is really changing. |
- if (IsDrawn() == value) { |
- parent_drawn_ = value; |
- return; |
- } |
- for (auto& observer : observers_) |
- observer.OnWindowDrawnChanging(this); |
- parent_drawn_ = value; |
- for (auto& observer : observers_) |
- observer.OnWindowDrawnChanged(this); |
-} |
- |
-void Window::LocalSetVisible(bool visible) { |
- if (visible_ == visible) |
- return; |
- |
- for (auto& observer : observers_) |
- observer.OnWindowVisibilityChanging(this, visible); |
- visible_ = visible; |
- if (parent_) { |
- for (auto& observer : parent_->observers_) |
- observer.OnChildWindowVisibilityChanged(this, visible); |
- } |
- |
- NotifyWindowVisibilityChanged(this, visible); |
-} |
- |
-void Window::LocalSetOpacity(float opacity) { |
- if (opacity_ == opacity) |
- return; |
- |
- float old_opacity = opacity_; |
- opacity_ = opacity; |
- for (auto& observer : observers_) |
- observer.OnWindowOpacityChanged(this, old_opacity, opacity_); |
-} |
- |
-void Window::LocalSetPredefinedCursor(mojom::Cursor cursor_id) { |
- if (cursor_id_ == cursor_id) |
- return; |
- |
- cursor_id_ = cursor_id; |
- for (auto& observer : observers_) |
- observer.OnWindowPredefinedCursorChanged(this, cursor_id); |
-} |
- |
-void Window::LocalSetSharedProperty(const std::string& name, |
- const std::vector<uint8_t>* value) { |
- std::vector<uint8_t> old_value; |
- std::vector<uint8_t>* old_value_ptr = nullptr; |
- auto it = properties_.find(name); |
- if (it != properties_.end()) { |
- old_value = it->second; |
- old_value_ptr = &old_value; |
- |
- if (value && old_value == *value) |
- return; |
- } else if (!value) { |
- // This property isn't set in |properties_| and |value| is nullptr, so |
- // there's no change. |
- return; |
- } |
- |
- if (value) { |
- properties_[name] = *value; |
- } else if (it != properties_.end()) { |
- properties_.erase(it); |
- } |
- |
- for (auto& observer : observers_) |
- observer.OnWindowSharedPropertyChanged(this, name, old_value_ptr, value); |
-} |
- |
-void Window::LocalSetSurfaceInfo(const cc::SurfaceInfo& surface_info) { |
- if (surface_info_.id().is_valid()) { |
- const cc::SurfaceId& existing_surface_id = surface_info_.id(); |
- const cc::SurfaceId& new_surface_id = surface_info.id(); |
- if (existing_surface_id.is_valid() && |
- existing_surface_id != new_surface_id) { |
- // TODO(kylechar): Start return reference here? |
- } |
- } |
- surface_info_ = surface_info; |
-} |
- |
-void Window::NotifyWindowStackingChanged() { |
- if (stacking_target_) { |
- Children::const_iterator window_i = std::find( |
- parent()->children().begin(), parent()->children().end(), this); |
- DCHECK(window_i != parent()->children().end()); |
- if (window_i != parent()->children().begin() && |
- (*(window_i - 1) == stacking_target_)) |
- return; |
- } |
- RestackTransientDescendants(this, &GetStackingTarget, |
- &ReorderWithoutNotification); |
-} |
- |
-void Window::NotifyWindowVisibilityChanged(Window* target, bool visible) { |
- if (!NotifyWindowVisibilityChangedDown(target, visible)) |
- return; // |this| has been deleted. |
- |
- NotifyWindowVisibilityChangedUp(target, visible); |
-} |
- |
-bool Window::NotifyWindowVisibilityChangedAtReceiver(Window* target, |
- bool visible) { |
- // |this| may be deleted during a call to OnWindowVisibilityChanged() on one |
- // of the observers. We create an local observer for that. In that case we |
- // exit without further access to any members. |
- WindowTracker tracker; |
- tracker.Add(this); |
- for (auto& observer : observers_) |
- observer.OnWindowVisibilityChanged(target, visible); |
- return tracker.Contains(this); |
-} |
- |
-bool Window::NotifyWindowVisibilityChangedDown(Window* target, bool visible) { |
- if (!NotifyWindowVisibilityChangedAtReceiver(target, visible)) |
- return false; // |this| was deleted. |
- std::set<const Window*> child_already_processed; |
- bool child_destroyed = false; |
- do { |
- child_destroyed = false; |
- for (Window::Children::const_iterator it = children_.begin(); |
- it != children_.end(); ++it) { |
- if (!child_already_processed.insert(*it).second) |
- continue; |
- if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) { |
- // |*it| was deleted, |it| is invalid and |children_| has changed. We |
- // exit the current for-loop and enter a new one. |
- child_destroyed = true; |
- break; |
- } |
- } |
- } while (child_destroyed); |
- return true; |
-} |
- |
-void Window::NotifyWindowVisibilityChangedUp(Window* target, bool visible) { |
- // Start with the parent as we already notified |this| |
- // in NotifyWindowVisibilityChangedDown. |
- for (Window* window = parent(); window; window = window->parent()) { |
- bool ret = window->NotifyWindowVisibilityChangedAtReceiver(target, visible); |
- DCHECK(ret); |
- } |
-} |
- |
-bool Window::PrepareForEmbed() { |
- if (!WasCreatedByThisClient()) |
- return false; |
- |
- while (!children_.empty()) |
- RemoveChild(children_[0]); |
- return true; |
-} |
- |
-void Window::RemoveTransientWindowImpl(Window* transient_window) { |
- Window::Children::iterator it = std::find( |
- transient_children_.begin(), transient_children_.end(), transient_window); |
- if (it != transient_children_.end()) { |
- transient_children_.erase(it); |
- transient_window->transient_parent_ = nullptr; |
- } |
- // If |transient_window| and its former transient parent share the same |
- // parent, |transient_window| should be restacked properly so it is not among |
- // transient children of its former parent, anymore. |
- if (parent() == transient_window->parent()) |
- RestackTransientDescendants(this, &GetStackingTarget, |
- &ReorderWithoutNotification); |
- |
- // TOOD(fsamuel): We might want to notify observers here. |
-} |
- |
-// static |
-void Window::ReorderWithoutNotification(Window* window, |
- Window* relative, |
- mojom::OrderDirection direction) { |
- ReorderImpl(window, relative, direction, nullptr); |
-} |
- |
-// static |
-bool Window::ReorderImpl(Window* window, |
- Window* relative, |
- mojom::OrderDirection direction, |
- OrderChangedNotifier* notifier) { |
- DCHECK(relative); |
- DCHECK_NE(window, relative); |
- DCHECK_EQ(window->parent(), relative->parent()); |
- DCHECK(window->parent()); |
- |
- if (!AdjustStackingForTransientWindows(&window, &relative, &direction, |
- window->stacking_target_)) |
- return false; |
- |
- const size_t child_i = std::find(window->parent_->children_.begin(), |
- window->parent_->children_.end(), window) - |
- window->parent_->children_.begin(); |
- const size_t target_i = |
- std::find(window->parent_->children_.begin(), |
- window->parent_->children_.end(), relative) - |
- window->parent_->children_.begin(); |
- if ((direction == mojom::OrderDirection::ABOVE && child_i == target_i + 1) || |
- (direction == mojom::OrderDirection::BELOW && child_i + 1 == target_i)) { |
- return false; |
- } |
- |
- if (notifier) |
- notifier->NotifyWindowReordering(); |
- |
- const size_t dest_i = direction == mojom::OrderDirection::ABOVE |
- ? (child_i < target_i ? target_i : target_i + 1) |
- : (child_i < target_i ? target_i - 1 : target_i); |
- window->parent_->children_.erase(window->parent_->children_.begin() + |
- child_i); |
- window->parent_->children_.insert(window->parent_->children_.begin() + dest_i, |
- window); |
- |
- window->NotifyWindowStackingChanged(); |
- |
- if (notifier) |
- notifier->NotifyWindowReordered(); |
- |
- return true; |
-} |
- |
-// static |
-Window** Window::GetStackingTarget(Window* window) { |
- return &window->stacking_target_; |
-} |
-} // namespace ui |