Home | History | Annotate | Download | only in aura
      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