1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/aura/root_window_host_mac.h"
7 #import <Cocoa/Cocoa.h>
9 #include "base/compiler_specific.h"
10 #include "base/mac/bundle_locations.h"
11 #include "base/memory/scoped_nsobject.h"
12 #include "ui/aura/event.h"
13 #include "ui/aura/root_window.h"
14 #include "ui/aura/root_window_host.h"
15 #include "ui/aura/root_window_mac.h"
16 #include "ui/aura/root_window_view_mac.h"
17 #include "ui/base/events/event_utils.h"
18 #include "ui/gfx/point.h"
22 // The Mac-specific implementation of the RootWindowHost interface. This class
23 // acts at an intermediary between the Aura shell and an NSWindow. The
24 // association between the Aura compositor and the native window's view is
25 // established with this class as is the association between the native window's
26 // event dispatch and the Aura event processing.
27 class RootWindowHostMac : public RootWindowHost,
28 public RootWindowHostMacDelegate {
30 explicit RootWindowHostMac(const gfx::Rect& bounds);
31 virtual ~RootWindowHostMac();
34 virtual void SetRootWindow(RootWindow* root_window) OVERRIDE;
35 virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE;
36 virtual void Show() OVERRIDE;
37 virtual void ToggleFullScreen() OVERRIDE;
38 virtual gfx::Size GetSize() const OVERRIDE;
39 virtual void SetSize(const gfx::Size& size) OVERRIDE;
40 virtual gfx::Point GetLocationOnNativeScreen() const OVERRIDE;
41 virtual void SetCapture() OVERRIDE;
42 virtual void ReleaseCapture() OVERRIDE;
43 virtual void SetCursor(gfx::NativeCursor cursor) OVERRIDE;
44 virtual void ShowCursor(bool show) OVERRIDE;
45 virtual bool QueryMouseLocation(gfx::Point* location_return) OVERRIDE;
46 virtual void MoveCursorTo(const gfx::Point& location) OVERRIDE;
47 virtual bool ConfineCursorToRootWindow() OVERRIDE;
48 virtual void UnConfineCursor() OVERRIDE;
49 virtual bool CopyAreaToSkCanvas(const gfx::Rect& source_bounds,
50 const gfx::Point& dest_offset,
51 SkCanvas* canvas) OVERRIDE;
52 virtual bool GrabSnapshot(
53 const gfx::Rect& snapshot_bounds,
54 std::vector<unsigned char>* png_representation) OVERRIDE;
56 // RootWindowHostMacDelegate:
57 virtual void SendEvent(const base::NativeEvent& native_event) OVERRIDE;
59 // Set the initial location of the root window. The origin of |bounds| is
60 // top-left. This gets converted to bottom-left to match Mac coordinates on
62 void SetLocation(const gfx::Rect& bounds);
66 RootWindow* root_window_;
68 // The bounds of the Aura desktop. Relative to Aura's coordinate system.
69 // This is currently used only for size information, not location.
72 // An NSWindowController for the root window. Controls the actual Cocoa
74 scoped_nsobject<NSWindowController> controller_;
76 DISALLOW_COPY_AND_ASSIGN(RootWindowHostMac);
79 RootWindowHostMacDelegate::RootWindowHostMacDelegate() {
82 RootWindowHostMacDelegate::~RootWindowHostMacDelegate() {
85 RootWindowHostMac::RootWindowHostMac(const gfx::Rect& bounds)
86 : root_window_(NULL), bounds_(bounds) {
87 NSString* nibpath = [base::mac::FrameworkBundle()
88 pathForResource:@"RootWindow"
90 NSWindowController* controller = [NSWindowController alloc];
91 controller_.reset([controller initWithWindowNibPath:nibpath
93 SetSize(bounds.size());
97 RootWindowHostMac::~RootWindowHostMac() {
98 RootWindowView* view = [[controller_ window] contentView];
99 [view setCompositor:NULL];
104 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
105 return new RootWindowHostMac(bounds);
109 gfx::Size RootWindowHost::GetNativeScreenSize() {
110 NSRect screen = [[NSScreen mainScreen] visibleFrame];
111 return gfx::Size(NSSizeToCGSize(screen.size));
114 void RootWindowHostMac::SetRootWindow(RootWindow* root_window) {
115 root_window_ = root_window;
117 RootWindowView* view = [[controller_ window] contentView];
118 DCHECK([view respondsToSelector:@selector(setCompositor:)]);
119 [view setCompositor:root_window->compositor()];
121 RootWindowMac* window = static_cast<RootWindowMac*>([controller_ window]);
122 DCHECK([window respondsToSelector:@selector(setHostDelegate:)]);
123 [window setHostDelegate:this];
126 gfx::AcceleratedWidget RootWindowHostMac::GetAcceleratedWidget() {
127 return [[controller_ window] contentView];
130 void RootWindowHostMac::Show() {
131 [controller_ showWindow:controller_];
134 void RootWindowHostMac::ToggleFullScreen() {
137 gfx::Size RootWindowHostMac::GetSize() const {
138 NSSize size = [[[controller_ window] contentView] bounds].size;
139 return gfx::Size(NSSizeToCGSize(size));
142 void RootWindowHostMac::SetSize(const gfx::Size& size) {
143 NSSize nssize = NSSizeFromCGSize(size.ToCGSize());
144 [[controller_ window] setContentSize:nssize];
145 [[controller_ window] setContentMaxSize:nssize];
146 [[controller_ window] setContentMinSize:nssize];
149 gfx::Point RootWindowHostMac::GetLocationOnNativeScreen() const {
153 void RootWindowHostMac::SetCapture() {
156 void RootWindowHostMac::ReleaseCapture() {
159 void RootWindowHostMac::SetCursor(gfx::NativeCursor cursor) {
162 void RootWindowHostMac::ShowCursor(bool show) {
165 bool RootWindowHostMac::QueryMouseLocation(gfx::Point* location_return) {
166 *location_return = gfx::Point();
170 void RootWindowHostMac::MoveCursorTo(const gfx::Point& location) {
173 bool RootWindowHostMac::ConfineCursorToRootWindow() {
177 void RootWindowHostMac::UnConfineCursor() {
180 bool RootWindowHostMac::GrabSnapshot(
181 const gfx::Rect& snapshot_bounds,
182 std::vector<unsigned char>* png_representation) {
187 void RootWindowHostMac::SendEvent(const base::NativeEvent& native_event) {
188 ui::EventType type = ui::EventTypeFromNative(native_event);
190 case ui::ET_MOUSE_PRESSED:
191 case ui::ET_MOUSE_DRAGGED:
192 case ui::ET_MOUSE_RELEASED:
193 case ui::ET_MOUSE_MOVED:
194 case ui::ET_MOUSE_ENTERED:
195 case ui::ET_MOUSE_EXITED: {
196 MouseEvent mouse_event(native_event);
197 root_window_->DispatchMouseEvent(&mouse_event);
200 case ui::ET_KEY_PRESSED:
201 case ui::ET_KEY_RELEASED: {
202 KeyEvent key_event(native_event, false);
203 root_window_->DispatchKeyEvent(&key_event);
206 case ui::ET_MOUSEWHEEL:
207 case ui::ET_TOUCH_RELEASED:
208 case ui::ET_TOUCH_PRESSED:
209 case ui::ET_TOUCH_MOVED:
210 case ui::ET_TOUCH_STATIONARY:
211 case ui::ET_TOUCH_CANCELLED:
212 case ui::ET_DROP_TARGET_EVENT:
213 case ui::ET_FOCUS_CHANGE:
221 void RootWindowHostMac::SetLocation(const gfx::Rect& bounds) {
222 NSRect screen = [[NSScreen mainScreen] visibleFrame];
223 NSPoint origin = NSMakePoint(screen.origin.x + bounds.x(),
224 screen.origin.y + screen.size.height -
225 bounds.y() - bounds.height());
226 [[controller_ window] setFrameOrigin:origin];