1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
|
// 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 UI_VIEWS_COCOA_BRIDGED_NATIVE_WIDGET_H_
#define UI_VIEWS_COCOA_BRIDGED_NATIVE_WIDGET_H_
#import <Cocoa/Cocoa.h>
#include <vector>
#import "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "ui/compositor/layer_owner.h"
#import "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#import "ui/views/cocoa/cocoa_mouse_capture_delegate.h"
#import "ui/views/focus/focus_manager.h"
#include "ui/views/ime/input_method_delegate.h"
#include "ui/views/views_export.h"
#include "ui/views/widget/widget.h"
@class BridgedContentView;
@class ViewsNSWindowDelegate;
namespace ui {
class InputMethod;
}
namespace views {
class CocoaMouseCapture;
class InputMethod;
class NativeWidgetMac;
class View;
// A bridge to an NSWindow managed by an instance of NativeWidgetMac or
// DesktopNativeWidgetMac. Serves as a helper class to bridge requests from the
// NativeWidgetMac to the Cocoa window. Behaves a bit like an aura::Window.
class VIEWS_EXPORT BridgedNativeWidget : public ui::LayerDelegate,
public ui::LayerOwner,
public internal::InputMethodDelegate,
public CocoaMouseCaptureDelegate,
public FocusChangeListener,
public ui::AcceleratedWidgetMacNSView {
public:
// Ways of changing the visibility of the bridged NSWindow.
enum WindowVisibilityState {
HIDE_WINDOW, // Hides with -[NSWindow orderOut:].
SHOW_AND_ACTIVATE_WINDOW, // Shows with -[NSWindow makeKeyAndOrderFront:].
SHOW_INACTIVE, // Shows with -[NSWindow orderWindow:..]. Orders
// the window above its parent if it has one.
};
// Creates one side of the bridge. |parent| must not be NULL.
explicit BridgedNativeWidget(NativeWidgetMac* parent);
virtual ~BridgedNativeWidget();
// Initialize the bridge, "retains" ownership of |window|.
void Init(base::scoped_nsobject<NSWindow> window,
const Widget::InitParams& params);
// Sets or clears the focus manager to use for tracking focused views.
// This does NOT take ownership of |focus_manager|.
void SetFocusManager(FocusManager* focus_manager);
// Changes the bounds of the window and the hosted layer if present.
void SetBounds(const gfx::Rect& new_bounds);
// Set or clears the views::View bridged by the content view. This does NOT
// take ownership of |view|.
void SetRootView(views::View* view);
// Sets the desired visibility of the window and updates the visibility of
// descendant windows where necessary.
void SetVisibilityState(WindowVisibilityState new_state);
// Acquiring mouse capture first steals capture from any existing
// CocoaMouseCaptureDelegate, then captures all mouse events until released.
void AcquireCapture();
void ReleaseCapture();
bool HasCapture();
// See views::Widget.
void SetNativeWindowProperty(const char* key, void* value);
void* GetNativeWindowProperty(const char* key) const;
// Called internally by the NSWindowDelegate when the window is closing.
void OnWindowWillClose();
// Called by the NSWindowDelegate when a fullscreen operation begins. If
// |target_fullscreen_state| is true, the target state is fullscreen.
// Otherwise, a transition has begun to come out of fullscreen.
void OnFullscreenTransitionStart(bool target_fullscreen_state);
// Called when a fullscreen transition completes. If target_fullscreen_state()
// does not match |actual_fullscreen_state|, a new transition will begin.
void OnFullscreenTransitionComplete(bool actual_fullscreen_state);
// Transition the window into or out of fullscreen. This will immediately
// invert the value of target_fullscreen_state().
void ToggleDesiredFullscreenState();
// Called by the NSWindowDelegate when the size of the window changes.
void OnSizeChanged();
// Called by the NSWindowDelegate when the visibility of the window may have
// changed. For example, due to a (de)miniaturize operation, or the window
// being reordered in (or out of) the screen list.
void OnVisibilityChanged();
// Explicitly set the visibility. This is called when Cocoa requests a draw,
// but hasn't updated the value of -[NSWindow isVisible] yet.
void OnVisibilityChangedTo(bool new_visibility);
// Called by the NSWindowDelegate on a scale factor or color space change.
void OnBackingPropertiesChanged();
// See widget.h for documentation.
InputMethod* CreateInputMethod();
ui::InputMethod* GetHostInputMethod();
// The restored bounds will be derived from the current NSWindow frame unless
// fullscreen or transitioning between fullscreen states.
gfx::Rect GetRestoredBounds() const;
// Creates a ui::Compositor which becomes responsible for drawing the window.
void CreateLayer(ui::LayerType layer_type, bool translucent);
NativeWidgetMac* native_widget_mac() { return native_widget_mac_; }
BridgedContentView* ns_view() { return bridged_view_; }
NSWindow* ns_window() { return window_; }
// The parent widget specified in Widget::InitParams::parent. If non-null, the
// parent will close children before the parent closes, and children will be
// raised above their parent when window z-order changes.
BridgedNativeWidget* parent() { return parent_; }
const std::vector<BridgedNativeWidget*>& child_windows() {
return child_windows_;
}
bool target_fullscreen_state() const { return target_fullscreen_state_; }
bool window_visible() { return window_visible_; }
// Overridden from internal::InputMethodDelegate:
virtual void DispatchKeyEventPostIME(const ui::KeyEvent& key) override;
private:
// Closes all child windows. BridgedNativeWidget children will be destroyed.
void RemoveOrDestroyChildren();
// Remove the given |child| from |child_windows_|.
void RemoveChildWindow(BridgedNativeWidget* child);
// Notify descendants of a visibility change.
void NotifyVisibilityChangeDown();
// Essentially NativeWidgetMac::GetClientAreaBoundsInScreen().size(), but no
// coordinate transformations are required from AppKit coordinates.
gfx::Size GetClientAreaSize() const;
// Creates an owned ui::Compositor. For consistency, these functions reflect
// those in aura::WindowTreeHost.
void CreateCompositor();
void InitCompositor();
void DestroyCompositor();
// Installs the NSView for hosting the composited layer. It is later provided
// to |compositor_widget_| via AcceleratedWidgetGetNSView().
void AddCompositorSuperview();
// Size the layer to match the client area bounds, taking into account display
// scale factor.
void UpdateLayerProperties();
// Overridden from CocoaMouseCaptureDelegate:
void PostCapturedEvent(NSEvent* event) override;
void OnMouseCaptureLost() override;
// Returns a properties dictionary associated with the NSWindow.
// Creates and attaches a new instance if not found.
NSMutableDictionary* GetWindowProperties() const;
// Overridden from FocusChangeListener:
void OnWillChangeFocus(View* focused_before,
View* focused_now) override;
void OnDidChangeFocus(View* focused_before,
View* focused_now) override;
// Overridden from ui::LayerDelegate:
void OnPaintLayer(gfx::Canvas* canvas) override;
void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override;
void OnDeviceScaleFactorChanged(float device_scale_factor) override;
base::Closure PrepareForLayerBoundsChange() override;
// Overridden from ui::AcceleratedWidgetMac:
NSView* AcceleratedWidgetGetNSView() const override;
bool AcceleratedWidgetShouldIgnoreBackpressure() const override;
void AcceleratedWidgetSwapCompleted(
const std::vector<ui::LatencyInfo>& latency_info) override;
void AcceleratedWidgetHitError() override;
views::NativeWidgetMac* native_widget_mac_; // Weak. Owns this.
base::scoped_nsobject<NSWindow> window_;
base::scoped_nsobject<ViewsNSWindowDelegate> window_delegate_;
base::scoped_nsobject<BridgedContentView> bridged_view_;
scoped_ptr<ui::InputMethod> input_method_;
scoped_ptr<CocoaMouseCapture> mouse_capture_;
FocusManager* focus_manager_; // Weak. Owned by our Widget.
BridgedNativeWidget* parent_; // Weak. If non-null, owns this.
std::vector<BridgedNativeWidget*> child_windows_;
base::scoped_nsobject<NSView> compositor_superview_;
scoped_ptr<ui::AcceleratedWidgetMac> compositor_widget_;
scoped_ptr<ui::Compositor> compositor_;
// Tracks the bounds when the window last started entering fullscreen. Used to
// provide an answer for GetRestoredBounds(), but not ever sent to Cocoa (it
// has its own copy, but doesn't provide access to it).
gfx::Rect bounds_before_fullscreen_;
// Whether this window wants to be fullscreen. If a fullscreen animation is in
// progress then it might not be actually fullscreen.
bool target_fullscreen_state_;
// Whether this window is in a fullscreen transition, and the fullscreen state
// can not currently be changed.
bool in_fullscreen_transition_;
// Stores the value last read from -[NSWindow isVisible], to detect visibility
// changes.
bool window_visible_;
// If true, the window is either visible, or wants to be visible but is
// currently hidden due to having a hidden parent.
bool wants_to_be_visible_;
DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidget);
};
} // namespace views
#endif // UI_VIEWS_COCOA_BRIDGED_NATIVE_WIDGET_H_
|