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. 4 5 #include "ui/aura/root_window_host_mac.h" 6 7 #import <Cocoa/Cocoa.h> 8 9 #include "base/compiler_specific.h" 10 #include "base/mac/bundle_locations.h" 11 #include "base/mac/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" 19 20 namespace aura { 21 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 { 29 public: 30 explicit RootWindowHostMac(const gfx::Rect& bounds); 31 virtual ~RootWindowHostMac(); 32 33 // RootWindowHost: 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 // RootWindowHostMacDelegate: 53 virtual void SendEvent(const base::NativeEvent& native_event) OVERRIDE; 54 55 // Set the initial location of the root window. The origin of |bounds| is 56 // top-left. This gets converted to bottom-left to match Mac coordinates on 57 // the main screen. 58 void SetLocation(const gfx::Rect& bounds); 59 60 private: 61 // Weak reference. 62 RootWindow* root_window_; 63 64 // The bounds of the Aura desktop. Relative to Aura's coordinate system. 65 // This is currently used only for size information, not location. 66 gfx::Rect bounds_; 67 68 // An NSWindowController for the root window. Controls the actual Cocoa 69 // window on Mac. 70 base::scoped_nsobject<NSWindowController> controller_; 71 72 DISALLOW_COPY_AND_ASSIGN(RootWindowHostMac); 73 }; 74 75 RootWindowHostMacDelegate::RootWindowHostMacDelegate() { 76 } 77 78 RootWindowHostMacDelegate::~RootWindowHostMacDelegate() { 79 } 80 81 RootWindowHostMac::RootWindowHostMac(const gfx::Rect& bounds) 82 : root_window_(NULL), bounds_(bounds) { 83 NSString* nibpath = [base::mac::FrameworkBundle() 84 pathForResource:@"RootWindow" 85 ofType:@"nib"]; 86 NSWindowController* controller = [NSWindowController alloc]; 87 controller_.reset([controller initWithWindowNibPath:nibpath 88 owner:controller]); 89 SetSize(bounds.size()); 90 SetLocation(bounds); 91 } 92 93 RootWindowHostMac::~RootWindowHostMac() { 94 RootWindowView* view = [[controller_ window] contentView]; 95 [view setCompositor:NULL]; 96 [controller_ close]; 97 } 98 99 // static 100 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { 101 return new RootWindowHostMac(bounds); 102 } 103 104 // static 105 gfx::Size RootWindowHost::GetNativeScreenSize() { 106 NSRect screen = [[NSScreen mainScreen] visibleFrame]; 107 return gfx::Size(NSSizeToCGSize(screen.size)); 108 } 109 110 void RootWindowHostMac::SetRootWindow(RootWindow* root_window) { 111 root_window_ = root_window; 112 113 RootWindowView* view = [[controller_ window] contentView]; 114 DCHECK([view respondsToSelector:@selector(setCompositor:)]); 115 [view setCompositor:root_window->compositor()]; 116 117 RootWindowMac* window = static_cast<RootWindowMac*>([controller_ window]); 118 DCHECK([window respondsToSelector:@selector(setHostDelegate:)]); 119 [window setHostDelegate:this]; 120 } 121 122 gfx::AcceleratedWidget RootWindowHostMac::GetAcceleratedWidget() { 123 return [[controller_ window] contentView]; 124 } 125 126 void RootWindowHostMac::Show() { 127 [controller_ showWindow:controller_]; 128 } 129 130 void RootWindowHostMac::ToggleFullScreen() { 131 } 132 133 gfx::Size RootWindowHostMac::GetSize() const { 134 NSSize size = [[[controller_ window] contentView] bounds].size; 135 return gfx::Size(NSSizeToCGSize(size)); 136 } 137 138 void RootWindowHostMac::SetSize(const gfx::Size& size) { 139 NSSize nssize = NSSizeFromCGSize(size.ToCGSize()); 140 [[controller_ window] setContentSize:nssize]; 141 [[controller_ window] setContentMaxSize:nssize]; 142 [[controller_ window] setContentMinSize:nssize]; 143 } 144 145 gfx::Point RootWindowHostMac::GetLocationOnNativeScreen() const { 146 return gfx::Point(); 147 } 148 149 void RootWindowHostMac::SetCapture() { 150 } 151 152 void RootWindowHostMac::ReleaseCapture() { 153 } 154 155 void RootWindowHostMac::SetCursor(gfx::NativeCursor cursor) { 156 } 157 158 void RootWindowHostMac::ShowCursor(bool show) { 159 } 160 161 bool RootWindowHostMac::QueryMouseLocation(gfx::Point* location_return) { 162 *location_return = gfx::Point(); 163 return true; 164 } 165 166 void RootWindowHostMac::MoveCursorTo(const gfx::Point& location) { 167 } 168 169 bool RootWindowHostMac::ConfineCursorToRootWindow() { 170 return false; 171 } 172 173 void RootWindowHostMac::UnConfineCursor() { 174 } 175 176 void RootWindowHostMac::SendEvent(const base::NativeEvent& native_event) { 177 ui::EventType type = ui::EventTypeFromNative(native_event); 178 switch (type) { 179 case ui::ET_MOUSE_PRESSED: 180 case ui::ET_MOUSE_DRAGGED: 181 case ui::ET_MOUSE_RELEASED: 182 case ui::ET_MOUSE_MOVED: 183 case ui::ET_MOUSE_ENTERED: 184 case ui::ET_MOUSE_EXITED: { 185 MouseEvent mouse_event(native_event); 186 root_window_->DispatchMouseEvent(&mouse_event); 187 break; 188 } 189 case ui::ET_KEY_PRESSED: 190 case ui::ET_KEY_RELEASED: { 191 KeyEvent key_event(native_event, false); 192 root_window_->DispatchKeyEvent(&key_event); 193 break; 194 } 195 case ui::ET_MOUSEWHEEL: 196 case ui::ET_TOUCH_RELEASED: 197 case ui::ET_TOUCH_PRESSED: 198 case ui::ET_TOUCH_MOVED: 199 case ui::ET_TOUCH_STATIONARY: 200 case ui::ET_TOUCH_CANCELLED: 201 case ui::ET_DROP_TARGET_EVENT: 202 case ui::ET_FOCUS_CHANGE: 203 case ui::ET_SCROLL: 204 case ui::ET_UNKNOWN: 205 default: 206 break; 207 } 208 } 209 210 void RootWindowHostMac::SetLocation(const gfx::Rect& bounds) { 211 NSRect screen = [[NSScreen mainScreen] visibleFrame]; 212 NSPoint origin = NSMakePoint(screen.origin.x + bounds.x(), 213 screen.origin.y + screen.size.height - 214 bounds.y() - bounds.height()); 215 [[controller_ window] setFrameOrigin:origin]; 216 } 217 218 } // namespace aura 219