blob: 30be6c5b3584e281d121abcb85eeabdcaadd82d5 [file] [log] [blame]
// 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.
#ifndef SERVICES_UI_PUBLIC_CPP_WINDOW_H_
#define SERVICES_UI_PUBLIC_CPP_WINDOW_H_
#include <stdint.h>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "cc/surfaces/surface_info.h"
#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
#include "services/ui/common/types.h"
#include "services/ui/public/cpp/window_compositor_frame_sink.h"
#include "services/ui/public/interfaces/mus_constants.mojom.h"
#include "services/ui/public/interfaces/window_tree.mojom.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
namespace gpu {
class GpuMemoryBufferManager;
}
namespace ui {
class InputEventHandler;
class WindowCompositorFrameSinkBinding;
class WindowObserver;
class WindowDropTarget;
class WindowTreeClient;
class WindowTreeClientPrivate;
namespace {
class OrderChangedNotifier;
}
// Defined in window_property.h (which we do not include)
template <typename T>
struct WindowProperty;
// Windows are owned by the WindowTreeClient. See WindowTreeClientDelegate for
// details on ownership.
//
// TODO(beng): Right now, you'll have to implement a WindowObserver to track
// destruction and NULL any pointers you have.
// Investigate some kind of smart pointer or weak pointer for these.
class Window {
public:
using Children = std::vector<Window*>;
using EmbedCallback = base::Callback<void(bool)>;
using PropertyDeallocator = void (*)(int64_t value);
using SharedProperties = std::map<std::string, std::vector<uint8_t>>;
// Destroys this window and all its children. Destruction is allowed for
// windows that were created by this connection, or the roots. For windows
// from other connections (except the roots), Destroy() does nothing. If the
// destruction is allowed observers are notified and the Window is
// immediately deleted.
void Destroy();
// Returns true if this client created and owns this window.
bool WasCreatedByThisClient() const;
WindowTreeClient* window_tree() { return client_; }
// The local_id is provided for client code. The local_id is not set or
// manipulated by mus. The default value is -1.
void set_local_id(int id) { local_id_ = id; }
int local_id() const { return local_id_; }
int64_t display_id() const { return display_id_; }
// Geometric disposition relative to parent window.
const gfx::Rect& bounds() const { return bounds_; }
void SetBounds(const gfx::Rect& bounds);
// Geometric disposition relative to root window.
gfx::Rect GetBoundsInRoot() const;
const gfx::Insets& client_area() const { return client_area_; }
const std::vector<gfx::Rect>& additional_client_areas() {
return additional_client_areas_;
}
void SetClientArea(const gfx::Insets& new_client_area) {
SetClientArea(new_client_area, std::vector<gfx::Rect>());
}
void SetClientArea(const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& additional_client_areas);
// Mouse events outside the hit test mask do not hit the window. Returns null
// if there is no mask.
const gfx::Rect* hit_test_mask() const { return hit_test_mask_.get(); }
void SetHitTestMask(const gfx::Rect& mask_rect);
void ClearHitTestMask();
// Visibility (also see IsDrawn()). When created windows are hidden.
bool visible() const { return visible_; }
void SetVisible(bool value);
float opacity() const { return opacity_; }
void SetOpacity(float opacity);
// Cursors
mojom::Cursor predefined_cursor() const { return cursor_id_; }
void SetPredefinedCursor(ui::mojom::Cursor cursor_id);
// A Window is drawn if the Window and all its ancestors are visible and the
// Window is attached to the root.
bool IsDrawn() const;
std::unique_ptr<WindowCompositorFrameSink> RequestCompositorFrameSink(
scoped_refptr<cc::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
void AttachCompositorFrameSink(
std::unique_ptr<WindowCompositorFrameSinkBinding>
compositor_frame_sink_binding);
// The template-ized versions of the following methods rely on the presence
// of a mojo::TypeConverter<const std::vector<uint8_t>, T>.
// Sets a shared property on the window which is sent to the window server and
// shared with other clients that can view this window.
template <typename T>
void SetSharedProperty(const std::string& name, const T& data);
// Gets a shared property set on the window. The property must exist. Call
// HasSharedProperty() before calling.
template <typename T>
T GetSharedProperty(const std::string& name) const;
// Removes the shared property.
void ClearSharedProperty(const std::string& name);
bool HasSharedProperty(const std::string& name) const;
// TODO(beng): Test only, should move to a helper.
const SharedProperties& shared_properties() { return properties_; }
// Sets the |value| of the given window |property|. Setting to the default
// value (e.g., NULL) removes the property. The caller is responsible for the
// lifetime of any object set as a property on the Window.
//
// These properties are not visible to the window server.
template <typename T>
void SetLocalProperty(const WindowProperty<T>* property, T value);
// Returns the value of the given window |property|. Returns the
// property-specific default value if the property was not previously set.
//
// These properties are only visible in the current process and are not
// shared with other mojo services.
template <typename T>
T GetLocalProperty(const WindowProperty<T>* property) const;
// Sets the |property| to its default value. Useful for avoiding a cast when
// setting to NULL.
//
// These properties are only visible in the current process and are not
// shared with other mojo services.
template <typename T>
void ClearLocalProperty(const WindowProperty<T>* property);
void set_input_event_handler(InputEventHandler* input_event_handler) {
input_event_handler_ = input_event_handler;
}
// Observation.
void AddObserver(WindowObserver* observer);
void RemoveObserver(WindowObserver* observer);
// Tree.
Window* parent() { return parent_; }
const Window* parent() const { return parent_; }
Window* GetRoot() {
return const_cast<Window*>(const_cast<const Window*>(this)->GetRoot());
}
const Window* GetRoot() const;
void AddChild(Window* child);
void RemoveChild(Window* child);
const Children& children() const { return children_; }
void Reorder(Window* relative, mojom::OrderDirection direction);
void MoveToFront();
void MoveToBack();
// Returns true if |child| is this or a descendant of this.
bool Contains(const Window* child) const;
void AddTransientWindow(Window* transient_window);
void RemoveTransientWindow(Window* transient_window);
// TODO(fsamuel): Figure out if we want to refactor transient window
// management into a separate class.
// Transient tree.
Window* transient_parent() { return transient_parent_; }
const Window* transient_parent() const { return transient_parent_; }
const Children& transient_children() const { return transient_children_; }
void SetModal();
bool is_modal() const { return is_modal_; }
Window* GetChildByLocalId(int id);
void SetTextInputState(mojo::TextInputStatePtr state);
void SetImeVisibility(bool visible, mojo::TextInputStatePtr state);
bool HasCapture() const;
void SetCapture();
void ReleaseCapture();
// Focus. See WindowTreeClient::ClearFocus() to reset focus.
void SetFocus();
bool HasFocus() const;
void SetCanFocus(bool can_focus);
// Sets whether this window accepts drags. Passing a non-null |drop_target|
// will enable acceptance of drops. Passing null will disable it.
void SetCanAcceptDrops(WindowDropTarget* drop_target);
WindowDropTarget* drop_target() { return drop_target_; }
// Sets whether this window accepts events.
void SetCanAcceptEvents(bool can_accept_events);
// Embedding. See window_tree.mojom for details.
void Embed(ui::mojom::WindowTreeClientPtr client, uint32_t flags = 0);
// NOTE: callback is run synchronously if Embed() is not allowed on this
// Window.
void Embed(ui::mojom::WindowTreeClientPtr client,
const EmbedCallback& callback,
uint32_t flags = 0);
// TODO(sky): this API is only applicable to the WindowManager. Move it
// to a better place.
void RequestClose();
// Starts an inter-process drag and drop operation. When this finishes, will
// return the tuple [success, action_taken] to |callback|, where action_taken
// is one of the ui::mojom::kDropEffect constants in
// window_tree_constants.mojom.
void 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);
// Cancels the in progress drag started with PerformDragDrop().
void CancelDragDrop();
// Tells the window manager to take control of moving the window. Returns
// true if the move wasn't canceled.
void PerformWindowMove(mojom::MoveLoopSource source,
const gfx::Point& cursor_location,
const base::Callback<void(bool)>& callback);
// Tells the window manager to abort any current move initiated by
// PerformWindowMove().
void CancelWindowMove();
// Returns an internal name, set by a client app when it creates a window.
std::string GetName() const;
protected:
// This class is subclassed only by test classes that provide a public ctor.
Window();
~Window();
private:
friend class WindowPrivate;
friend class WindowTreeClient;
friend class WindowTreeClientPrivate;
Window(WindowTreeClient* client, Id id);
// Used to identify this Window on the server. Clients can not change this
// value.
Id server_id() const { return server_id_; }
// Applies a shared property change locally and forwards to the server. If
// |data| is null, this property is deleted.
void SetSharedPropertyInternal(const std::string& name,
const std::vector<uint8_t>* data);
// Called by the public {Set,Get,Clear}Property functions.
int64_t SetLocalPropertyInternal(const void* key,
const char* name,
PropertyDeallocator deallocator,
int64_t value,
int64_t default_value);
int64_t GetLocalPropertyInternal(const void* key,
int64_t default_value) const;
void LocalDestroy();
void LocalAddChild(Window* child);
void LocalRemoveChild(Window* child);
void LocalAddTransientWindow(Window* transient_window);
void LocalRemoveTransientWindow(Window* transient_window);
void LocalSetModal();
// Returns true if the order actually changed.
bool LocalReorder(Window* relative, mojom::OrderDirection direction);
void LocalSetBounds(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds);
void LocalSetClientArea(
const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& additional_client_areas);
void LocalSetParentDrawn(bool drawn);
void LocalSetDisplay(int64_t display_id);
void LocalSetVisible(bool visible);
void LocalSetOpacity(float opacity);
void LocalSetPredefinedCursor(mojom::Cursor cursor_id);
void LocalSetSharedProperty(const std::string& name,
const std::vector<uint8_t>* data);
void LocalSetSurfaceInfo(const cc::SurfaceInfo& surface_info);
// Notifies this winodw that its stacking position has changed.
void NotifyWindowStackingChanged();
// Methods implementing visibility change notifications. See WindowObserver
// for more details.
void NotifyWindowVisibilityChanged(Window* target, bool visible);
// Notifies this window's observers. Returns false if |this| was deleted
// during the call (by an observer), otherwise true.
bool NotifyWindowVisibilityChangedAtReceiver(Window* target, bool visible);
// Notifies this window and its child hierarchy. Returns false if |this| was
// deleted during the call (by an observer), otherwise true.
bool NotifyWindowVisibilityChangedDown(Window* target, bool visible);
// Notifies this window and its parent hierarchy.
void NotifyWindowVisibilityChangedUp(Window* target, bool visible);
// Returns true if embed is allowed for this node. If embedding is allowed all
// the children are removed.
bool PrepareForEmbed();
void RemoveTransientWindowImpl(Window* child);
static void ReorderWithoutNotification(Window* window,
Window* relative,
mojom::OrderDirection direction);
// Returns true if the order actually changed.
static bool ReorderImpl(Window* window,
Window* relative,
mojom::OrderDirection direction,
OrderChangedNotifier* notifier);
// Returns a pointer to the stacking target that can be used by
// RestackTransientDescendants.
static Window** GetStackingTarget(Window* window);
WindowTreeClient* client_;
Id server_id_;
int local_id_ = -1;
Window* parent_;
Children children_;
Window* stacking_target_;
Window* transient_parent_;
Children transient_children_;
bool is_modal_;
base::ObserverList<WindowObserver> observers_;
InputEventHandler* input_event_handler_;
gfx::Rect bounds_;
gfx::Insets client_area_;
std::vector<gfx::Rect> additional_client_areas_;
std::unique_ptr<gfx::Rect> hit_test_mask_;
bool visible_;
float opacity_;
int64_t display_id_;
// The client supplied delegate that receives drag events for this
// window (weak ptr).
WindowDropTarget* drop_target_ = nullptr;
// Whether this window can accept events. Initialized to true to
// match ServerWindow.
bool can_accept_events_ = true;
mojom::Cursor cursor_id_;
SharedProperties properties_;
// Drawn state of our parent. This is only meaningful for root Windows, in
// which the parent Window isn't exposed to the client.
bool parent_drawn_;
// Value struct to keep the name and deallocator for this property.
// Key cannot be used for this purpose because it can be char* or
// WindowProperty<>.
struct Value {
const char* name;
int64_t value;
PropertyDeallocator deallocator;
};
std::map<const void*, Value> prop_map_;
cc::SurfaceInfo surface_info_;
DISALLOW_COPY_AND_ASSIGN(Window);
};
} // namespace ui
#endif // SERVICES_UI_PUBLIC_CPP_WINDOW_H_