Cocoa port :
authorDamien Plisson <damien.plisson@yahoo.fr>
Fri, 9 Oct 2009 12:48:28 +0000 (12:48 +0000)
committerDamien Plisson <damien.plisson@yahoo.fr>
Fri, 9 Oct 2009 12:48:28 +0000 (12:48 +0000)
- Fullscreen mode is back!
- Cleaner fix for tablet events handling

intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_WindowCocoa.h
intern/ghost/intern/GHOST_WindowCocoa.mm

index eab5a5b28aaa07aba8cb2d35ac2f34876b43e919..ee7f9d8ed37dbe302c48d9f981edf71b3754921d 100644 (file)
@@ -210,9 +210,10 @@ protected:
     /**
      * Handles a tablet event.
      * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+        * @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event
      * @return Indication whether the event was handled. 
      */
-    GHOST_TSuccess handleTabletEvent(void *eventPtr);
+    GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType);
     
        /**
      * Handles a mouse event.
index 7f98f67a1ba597ba6af851ee7571729fd2c7f8f1..481dd7052656a7c43cf0db5e13fa6676bce20159 100644 (file)
 
 #pragma mark KeyMap, mouse converters
 
-//TODO: remove (kept as reminder to implement window events)
-/*
-const EventTypeSpec    kEvents[] =
-{
-       { kEventClassAppleEvent, kEventAppleEvent },
-
-//     { kEventClassApplication, kEventAppActivated },
-//     { kEventClassApplication, kEventAppDeactivated },
-       
-       { kEventClassKeyboard, kEventRawKeyDown },
-       { kEventClassKeyboard, kEventRawKeyRepeat },
-       { kEventClassKeyboard, kEventRawKeyUp },
-       { kEventClassKeyboard, kEventRawKeyModifiersChanged },
-       
-       { kEventClassMouse, kEventMouseDown },
-       { kEventClassMouse, kEventMouseUp },
-       { kEventClassMouse, kEventMouseMoved },
-       { kEventClassMouse, kEventMouseDragged },
-       { kEventClassMouse, kEventMouseWheelMoved },
-       
-       { kEventClassWindow, kEventWindowClickZoomRgn } ,  // for new zoom behaviour  
-       { kEventClassWindow, kEventWindowZoom },  // for new zoom behaviour  
-       { kEventClassWindow, kEventWindowExpand } ,  // for new zoom behaviour 
-       { kEventClassWindow, kEventWindowExpandAll },  // for new zoom behaviour 
-
-       { kEventClassWindow, kEventWindowClose },
-       { kEventClassWindow, kEventWindowActivated },
-       { kEventClassWindow, kEventWindowDeactivated },
-       { kEventClassWindow, kEventWindowUpdate },
-       { kEventClassWindow, kEventWindowBoundsChanged },
-       
-       { kEventClassBlender, kEventBlenderNdofAxis },
-       { kEventClassBlender, kEventBlenderNdofButtons }
-       
-       
-       
-};*/
 
 /* Keycodes from Carbon include file */
 /*  
@@ -701,25 +664,6 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
                }
                                
                [pool drain];
-               
-               /*
-         * Initialize the cursor to the standard arrow shape (so that we can change it later on).
-         * This initializes the cursor's visibility counter to 0.
-         */
-        /*::InitCursor();
-               
-               MenuRef windMenu;
-               ::CreateStandardWindowMenu(0, &windMenu);
-               ::InsertMenu(windMenu, 0);
-               ::DrawMenuBar();
-               
-        ::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler);
-               
-               ::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false);
-               ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false);
-               ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false);
-               ::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false);
-               */
     }
     return success;
 }
@@ -789,6 +733,13 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        GHOST_IWindow* window = 0;
        
+       //First check if we are in fullscreen mode
+       //If so, exit it before creating a new window
+       window = m_windowManager->getActiveWindow();
+       if (window && (window->getState() == GHOST_kWindowStateFullScreen))
+               window->setState(GHOST_kWindowStateNormal);
+       window = NULL;
+       
        //Get the available rect for including window contents
        NSRect frame = [[NSScreen mainScreen] visibleFrame];
        NSRect contentRect = [NSWindow contentRectForFrameRect:frame
@@ -826,27 +777,18 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
 
 GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual)
 {      
-       GHOST_TSuccess success = GHOST_kFailure;
+       GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow();
 
-       //TODO: update this method
-       // need yo make this Carbon all on 10.5 for fullscreen to work correctly
-       CGCaptureAllDisplays();
-       
-       success = GHOST_System::beginFullScreen( setting, window, stereoVisual);
+       *window = currentWindow;
        
-       if( success != GHOST_kSuccess ) {
-                       // fullscreen failed for other reasons, release
-                       CGReleaseAllDisplays(); 
-       }
-
-       return success;
+       return currentWindow->setState(GHOST_kWindowStateFullScreen);
 }
 
 GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)
 {      
-       //TODO: update this method
-       CGReleaseAllDisplays();
-       return GHOST_System::endFullScreen();
+       GHOST_IWindow* currentWindow = m_windowManager->getActiveWindow();
+       
+       return currentWindow->setState(GHOST_kWindowStateNormal);
 }
 
 
@@ -936,8 +878,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
                 anyProcessed = true;
                 }
                 
-                //TODO: check fullscreen redrawing issues
-                if (getFullScreen()) {
+                        if (getFullScreen()) {
                 // Check if the full-screen window is dirty
                 GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
                 if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {
@@ -987,7 +928,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
                                        
                                case NSTabletPoint:
                                case NSTabletProximity:
-                                       handleTabletEvent(event);
+                                       handleTabletEvent(event,[event type]);
                                        break;
                                        
                                        /* Trackpad features, will need OS X 10.6 for implementation
@@ -1028,8 +969,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
        if (!validWindow(window)) {
                return GHOST_kFailure;
        }
-
-       //if (!getFullScreen()) {
                switch(eventType) 
                {
                        case GHOST_kEventWindowClose:
@@ -1045,7 +984,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
                                pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
                                break;
                        case GHOST_kEventWindowUpdate:
-                               //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n");
                                pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
                                break;
                        case GHOST_kEventWindowSize:
@@ -1059,12 +997,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
                                return GHOST_kFailure;
                                break;
                }
-//     }
-       //else {
-               //window = (GHOST_WindowCarbon*) m_windowManager->getFullScreenWindow();
-               //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n");
-               //::RemoveEventFromQueue(::GetMainEventQueue(), event);
-       //}
        return GHOST_kSuccess;
 }
 
@@ -1073,6 +1005,13 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
        //Check open windows if some changes are not saved
        if (m_windowManager->getAnyModifiedState())
        {
+               //First check if we are in fullscreen mode
+               //If so, exit it before creating a new window
+               GHOST_IWindow *window = m_windowManager->getActiveWindow();
+               if (window && (window->getState() == GHOST_kWindowStateFullScreen))
+                       window->setState(GHOST_kWindowStateNormal);
+               window = NULL;          
+               
                int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?",
                                                                                 @"Cancel", @"Quit anyway", nil);
                if (shouldQuit == NSAlertAlternateReturn)
@@ -1090,35 +1029,13 @@ GHOST_TUns8 GHOST_SystemCocoa::handleQuitRequest()
 }
 
 
-GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
+GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType)
 {
        NSEvent *event = (NSEvent *)eventPtr;
        GHOST_IWindow* window = m_windowManager->getActiveWindow();
        GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
-       NSUInteger tabletEvent;
-       
-       //Handle tablet events combined with mouse events
-       @try {
-               switch ([event subtype]) {
-               case NX_SUBTYPE_TABLET_POINT:
-                       tabletEvent = NSTabletPoint;
-                       break;
-               case NX_SUBTYPE_TABLET_PROXIMITY:
-                       tabletEvent = NSTabletProximity;
-                       break;
-
-               default:
-                       tabletEvent = [event type];
-                       break;
-               }
-       }
-       @catch (NSException * e) {
-               //FIXME: check why we get such exceptions when using a tablet
-               return GHOST_kFailure;
-       }
        
-       
-       switch (tabletEvent) {
+       switch (eventType) {
                case NSTabletPoint:
                        ct.Pressure = [event tangentialPressure];
                        ct.Xtilt = [event tilt].x;
@@ -1175,20 +1092,53 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
                case NSRightMouseDown:
                case NSOtherMouseDown:
                        pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
-                       handleTabletEvent(eventPtr);
+                       //Handle tablet events combined with mouse events
+                       switch ([event subtype]) {
+                               case NX_SUBTYPE_TABLET_POINT:
+                                       handleTabletEvent(eventPtr, NSTabletPoint);
+                                       break;
+                               case NX_SUBTYPE_TABLET_PROXIMITY:
+                                       handleTabletEvent(eventPtr, NSTabletProximity);
+                                       break;
+                               default:
+                                       //No tablet event included : do nothing
+                                       break;
+                       }
                        break;
                                                
                case NSLeftMouseUp:
                case NSRightMouseUp:
                case NSOtherMouseUp:
                        pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
-                       handleTabletEvent(eventPtr);
+                       //Handle tablet events combined with mouse events
+                       switch ([event subtype]) {
+                               case NX_SUBTYPE_TABLET_POINT:
+                                       handleTabletEvent(eventPtr, NSTabletPoint);
+                                       break;
+                               case NX_SUBTYPE_TABLET_PROXIMITY:
+                                       handleTabletEvent(eventPtr, NSTabletProximity);
+                                       break;
+                               default:
+                                       //No tablet event included : do nothing
+                                       break;
+                       }
                        break;
                        
                case NSLeftMouseDragged:
                case NSRightMouseDragged:
                case NSOtherMouseDragged:                               
-                       handleTabletEvent(eventPtr);
+                       //Handle tablet events combined with mouse events
+                       switch ([event subtype]) {
+                               case NX_SUBTYPE_TABLET_POINT:
+                                       handleTabletEvent(eventPtr, NSTabletPoint);
+                                       break;
+                               case NX_SUBTYPE_TABLET_PROXIMITY:
+                                       handleTabletEvent(eventPtr, NSTabletProximity);
+                                       break;
+                               default:
+                                       //No tablet event included : do nothing
+                                       break;
+                       }
                case NSMouseMoved:
                        {
                                NSPoint mousePos = [event locationInWindow];
@@ -1227,6 +1177,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
         * the window go away and we still get an HKey up. 
         */
        if (!window) {
+               printf("\nW failure");
                return GHOST_kFailure;
        }
        
@@ -1246,7 +1197,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
                        
                        if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
                                break; //Cmd-Q is directly handled by Cocoa
-                       
+
                        if ([event type] == NSKeyDown) {
                                pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, keyCode, ascii) );
                                //printf("\nKey pressed keyCode=%u ascii=%i %c",keyCode,ascii,ascii);
@@ -1282,143 +1233,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
 }
 
 
-/* System wide mouse clicks are handled directly through systematic event forwarding to Cocoa
-bool GHOST_SystemCarbon::handleMouseDown(void *eventPtr)
-{
-       NSEvent *event = (NSEvent *)eventPtr;
-       WindowPtr                       window;
-       short                           part;
-       BitMap                          screenBits;
-    bool                               handled = true;
-    GHOST_WindowCarbon* ghostWindow;
-    Point                              mousePos = {0 , 0};
-       
-       ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
-       
-       part = ::FindWindow(mousePos, &window);
-       ghostWindow = (GHOST_WindowCarbon*) ::GetWRefCon(window);
-       
-       switch (part) {
-               case inMenuBar:
-                       handleMenuCommand(::MenuSelect(mousePos));
-                       break;
-                       
-               case inDrag:
-                       // *
-                       // * The DragWindow() routine creates a lot of kEventWindowBoundsChanged
-                       // * events. By setting m_ignoreWindowSizedMessages these are suppressed.
-                       // * @see GHOST_SystemCarbon::handleWindowEvent(EventRef event)
-                       // *
-                       // even worse: scale window also generates a load of events, and nothing 
-                        //  is handled (read: client's event proc called) until you release mouse (ton) 
-                       
-                       GHOST_ASSERT(validWindow(ghostWindow), "GHOST_SystemCarbon::handleMouseDown: invalid window");
-                       m_ignoreWindowSizedMessages = true;
-                       ::DragWindow(window, mousePos, &GetQDGlobalsScreenBits(&screenBits)->bounds);
-                       m_ignoreWindowSizedMessages = false;
-                       
-                       pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, ghostWindow) );
-
-                       break;
-               
-               case inContent:
-                       if (window != ::FrontWindow()) {
-                               ::SelectWindow(window);
-                               //
-                               // * We add a mouse down event on the newly actived window
-                               // *            
-                               //GHOST_PRINT("GHOST_SystemCarbon::handleMouseDown(): adding mouse down event, " << ghostWindow << "\n");
-                               EventMouseButton button;
-                               ::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
-                               pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonDown, ghostWindow, convertButton(button)));
-                       } else {
-                               handled = false;
-                       }
-                       break;
-                       
-               case inGoAway:
-                       GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
-                       if (::TrackGoAway(window, mousePos))
-                       {
-                               // todo: add option-close, because itÿs in the HIG
-                               // if (event.modifiers & optionKey) {
-                                       // Close the clean documents, others will be confirmed one by one.
-                               //}
-                               // else {
-                               pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, ghostWindow));
-                               //}
-                       }
-                       break;
-                       
-               case inGrow:
-                       GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
-                       ::ResizeWindow(window, mousePos, NULL, NULL);
-                       break;
-                       
-               case inZoomIn:
-               case inZoomOut:
-                       GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
-                       if (::TrackBox(window, mousePos, part)) {
-                               int macState;
-                               
-                               macState = ghostWindow->getMac_windowState();
-                               if ( macState== 0)
-                                       ::ZoomWindow(window, part, true);
-                               else 
-                                       if (macState == 2) { // always ok
-                                                       ::ZoomWindow(window, part, true);
-                                                       ghostWindow->setMac_windowState(1);
-                                       } else { // need to force size again
-                                       //      GHOST_TUns32 scr_x,scr_y; //unused
-                                               Rect outAvailableRect;
-                                               
-                                               ghostWindow->setMac_windowState(2);
-                                               ::GetAvailableWindowPositioningBounds ( GetMainDevice(), &outAvailableRect);
-                                               
-                                               //this->getMainDisplayDimensions(scr_x,scr_y);
-                                               ::SizeWindow (window, outAvailableRect.right-outAvailableRect.left,outAvailableRect.bottom-outAvailableRect.top-1,false);
-                                               ::MoveWindow (window, outAvailableRect.left, outAvailableRect.top,true);
-                                       }
-                               
-                       }
-                       break;
-
-               default:
-                       handled = false;
-                       break;
-       }
-       
-       return handled;
-}
-
-
-bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult)
-{
-       short           menuID;
-       short           menuItem;
-       UInt32          command;
-       bool            handled;
-       OSErr           err;
-       
-       menuID = HiWord(menuResult);
-       menuItem = LoWord(menuResult);
-
-       err = ::GetMenuItemCommandID(::GetMenuHandle(menuID), menuItem, &command);
-
-       handled = false;
-       
-       if (err || command == 0) {
-       }
-       else {
-               switch(command) {
-               }
-       }
-
-       ::HiliteMenu(0);
-    return handled;
-}*/
-
-
 
 #pragma mark Clipboard get/set
 
index 5ff205d964fe95b52ee6f49b1883bf75eb9a7f14..8c2919d1ce2d61e56c01fa67767df7db9440fad7 100644 (file)
@@ -70,7 +70,7 @@ public:
         * @param stereoVisual  Stereo visual for quad buffered stereo.
         */
        GHOST_WindowCocoa(
-               const GHOST_SystemCocoa *systemCocoa,
+               GHOST_SystemCocoa *systemCocoa,
                const STR_String& title,
                GHOST_TInt32 left,
                GHOST_TInt32 top,
@@ -204,16 +204,6 @@ public:
 
        virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
     
-    /**
-     * Returns the dirty state of the window when in full-screen mode.
-     * @return Whether it is dirty.
-     */
-    virtual bool getFullScreenDirty();
-
-               /* accessor for fullscreen window */
-       /*virtual void setMac_windowState(short value);
-       virtual short getMac_windowState();*/
-
 
        const GHOST_TabletData* GetTabletData()
        { return &m_tablet; }
@@ -270,19 +260,13 @@ protected:
        /** The opgnGL drawing context */
        NSOpenGLContext *m_openGLContext;
        
-       //CGrafPtr m_grafPtr;
-    //AGLContext m_aglCtx;
-
-       /** The first created OpenGL context (for sharing display lists) */
-       //static AGLContext s_firstaglCtx;
-               
+       /** The mother SystemCocoa class to send events */
+       GHOST_SystemCocoa *m_systemCocoa;
+                       
        NSCursor*       m_customCursor;
 
        GHOST_TabletData m_tablet;
     
-    /** When running in full-screen this tells whether to refresh the window. */
-    bool m_fullScreenDirty;
-                        
     /**
      * The width/height of the size rectangle in the lower right corner of a 
      * Mac/Carbon window. This is also the height of the gutter area.
index a185aa036b1533d37d5b72354d5e04c3a06c72c4..f4c9172c6684404c87424c6e2b4d19a14b1e40a5 100644 (file)
 #include "GHOST_WindowCocoa.h"
 #include "GHOST_SystemCocoa.h"
 #include "GHOST_Debug.h"
-/*
-AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL;
-#ifdef GHOST_DRAW_CARBON_GUTTER
-const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16;
-#endif //GHOST_DRAW_CARBON_GUTTER
-
-static const GLint sPreferredFormatWindow[8] = {
-AGL_RGBA,
-AGL_DOUBLEBUFFER,      
-AGL_ACCELERATED,
-AGL_DEPTH_SIZE,                32,
-AGL_NONE,
-};
-
-static const GLint sPreferredFormatFullScreen[9] = {
-AGL_RGBA,
-AGL_DOUBLEBUFFER,
-AGL_ACCELERATED,
-AGL_FULLSCREEN,
-AGL_DEPTH_SIZE,                32,
-AGL_NONE,
-};
 
 
-
-WindowRef ugly_hack=NULL;
-
-const EventTypeSpec    kWEvents[] = {
-       { kEventClassWindow, kEventWindowZoom },  // for new zoom behaviour  
+// Pixel Format Attributes for the windowed NSOpenGLContext
+static const NSOpenGLPixelFormatAttribute pixelFormatAttrsWindow[] =
+{
+       NSOpenGLPFADoubleBuffer,
+       NSOpenGLPFAAccelerated,
+       NSOpenGLPFAAllowOfflineRenderers,   // NOTE: Needed to connect to secondary GPUs
+       NSOpenGLPFADepthSize, 32,
+       0
 };
 
-static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
-       WindowRef mywindow;
-       GHOST_WindowCocoa *ghost_window;
-       OSStatus err;
-       int theState;
-       
-       if (::GetEventKind(event) == kEventWindowZoom) {
-               err =  ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow);
-               ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow);
-               theState = ghost_window->getMac_windowState();
-               if (theState == 1) 
-                       ghost_window->setMac_windowState(2);
-               else if (theState == 2)
-                       ghost_window->setMac_windowState(1);
-
-       }
-       return eventNotHandledErr;
-}*/
-
 #pragma mark Cocoa delegate object
+
 @interface CocoaWindowDelegate : NSObject
 {
        GHOST_SystemCocoa *systemCocoa;
@@ -116,7 +79,10 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event,
 
 - (void)windowDidResignKey:(NSNotification *)notification
 {
-       systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
+       //The window is no more key when its own view becomes fullscreen
+       //but ghost doesn't know the view/window difference, so hide this fact
+       if (associatedWindow->getState() != GHOST_kWindowStateFullScreen)
+               systemCocoa->handleWindowEvent(GHOST_kEventWindowDeactivate, associatedWindow);
 }
 
 - (void)windowDidUpdate:(NSNotification *)notification
@@ -159,7 +125,7 @@ static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event,
 #pragma mark initialization / finalization
 
 GHOST_WindowCocoa::GHOST_WindowCocoa(
-       const GHOST_SystemCocoa *systemCocoa,
+       GHOST_SystemCocoa *systemCocoa,
        const STR_String& title,
        GHOST_TInt32 left,
        GHOST_TInt32 top,
@@ -170,136 +136,55 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
        const bool stereoVisual
 ) :
        GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
-       m_customCursor(0),
-       m_fullScreenDirty(false)
+       m_customCursor(0)
 {
+       m_systemCocoa = systemCocoa;
+       m_fullScreen = false;
+       
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        
-       //fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width);
-       /*
-       if (state >= GHOST_kWindowState8Normal ) {
-               if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal;
-               else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized;
-               else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized;
-               else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen;
-               
-               // state = state - 8;   this was the simple version of above code, doesnt work in gcc 4.0
-               
-               setMac_windowState(1);
-       } else 
-               setMac_windowState(0);
-*/
-       if (state != GHOST_kWindowStateFullScreen) {
-               
-               //Creates the window
-               NSRect rect;
-               
-               rect.origin.x = left;
-               rect.origin.y = top;
-               rect.size.width = width;
-               rect.size.height = height;
-               
-               m_window = [[NSWindow alloc] initWithContentRect:rect
-                                                                                          styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
-                                                                                                backing:NSBackingStoreBuffered defer:NO];
-               if (m_window == nil) {
-                       [pool drain];
-                       return;
-               }
-               
-               [m_window setTitle:[NSString stringWithUTF8String:title]];
-               
-                               
-               //Creates the OpenGL View inside the window
-               NSOpenGLPixelFormatAttribute attributes[] =
-               {
-                       NSOpenGLPFADoubleBuffer,
-                       NSOpenGLPFAAccelerated,
-                       NSOpenGLPFAAllowOfflineRenderers,   // NOTE: Needed to connect to secondary GPUs
-                       NSOpenGLPFADepthSize, 32,
-                       0
-               };
-               
-               NSOpenGLPixelFormat *pixelFormat =
-        [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
-               
-               m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect
-                                                                                                        pixelFormat:pixelFormat];
-               
-               [pixelFormat release];
-               
-               m_openGLContext = [m_openGLView openGLContext];
-               
-               [m_window setContentView:m_openGLView];
-               [m_window setInitialFirstResponder:m_openGLView];
-               
-               [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window
-               
-               [m_window makeKeyAndOrderFront:nil];
-               
-               setDrawingContextType(type);
-               updateDrawingContext();
-               activateDrawingContext();
-               
-               // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/
-        /*gen2mac(title, title255);
-        
-               
-               err =  ::CreateNewWindow( kDocumentWindowClass,
-                                                                kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute,
-                                                                &bnds,
-                                                                &m_windowRef);
-               
-               if ( err != noErr) {
-                       fprintf(stderr," error creating window %i \n",(int)err);
-               } else {
+
+       //Creates the window
+       NSRect rect;
+       
+       rect.origin.x = left;
+       rect.origin.y = top;
+       rect.size.width = width;
+       rect.size.height = height;
+       
+       m_window = [[NSWindow alloc] initWithContentRect:rect
+                                                                                  styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
+                                                                                        backing:NSBackingStoreBuffered defer:NO];
+       if (m_window == nil) {
+               [pool drain];
+               return;
+       }
+       
+       [m_window setTitle:[NSString stringWithUTF8String:title]];
+       
                        
-                       ::SetWRefCon(m_windowRef,(SInt32)this);
-                       setTitle(title);
-                       err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL); 
-                       if ( err != noErr) {
-                               fprintf(stderr," error creating handler %i \n",(int)err);
-                       } else {
-                               //      ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
-                               ::ShowWindow(m_windowRef);
-                               ::MoveWindow (m_windowRef, left, top,true);
-                               
-                       }
-               }
-        if (m_windowRef) {
-            m_grafPtr = ::GetWindowPort(m_windowRef);
-            setDrawingContextType(type);
-            updateDrawingContext();
-            activateDrawingContext();
-        }
-               if(ugly_hack==NULL) {
-                       ugly_hack= m_windowRef;
-                       // when started from commandline, window remains in the back... also for play anim
-                       ProcessSerialNumber psn;
-                       GetCurrentProcess(&psn);
-                       SetFrontProcess(&psn);
-               }*/
-    }
-    else {
-    /*
-        Rect bnds = { top, left, top+height, left+width };
-        gen2mac("", title255);
-        m_windowRef = ::NewCWindow(
-            nil,                                                       // Storage 
-            &bnds,                                                     // Bounding rectangle of the window
-            title255,                                          // Title of the window
-            0,                                                         // Window initially visible
-            plainDBox,                                                 // procID
-            (WindowRef)-1L,                                    // Put window before all other windows
-            0,                                                         // Window has minimize box
-            (SInt32)this);                                     // Store a pointer to the class in the refCon
-    */
-        //GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n");
-        setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);
-               installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
-        updateDrawingContext();
-        activateDrawingContext();
-    }
+       //Creates the OpenGL View inside the window
+       NSOpenGLPixelFormat *pixelFormat =
+       [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttrsWindow];
+       
+       m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect
+                                                                                                pixelFormat:pixelFormat];
+       
+       [pixelFormat release];
+       
+       m_openGLContext = [m_openGLView openGLContext];
+       
+       [m_window setContentView:m_openGLView];
+       [m_window setInitialFirstResponder:m_openGLView];
+       
+       [m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window
+       
+       [m_window makeKeyAndOrderFront:nil];
+       
+       setDrawingContextType(type);
+       updateDrawingContext();
+       activateDrawingContext();
+       
        m_tablet.Active = GHOST_kTabletModeNone;
        
        CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init];
@@ -308,6 +193,9 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
        
        [m_window setAcceptsMouseMovedEvents:YES];
        
+       if (state == GHOST_kWindowStateFullScreen)
+               setState(GHOST_kWindowStateFullScreen);
+               
        [pool drain];
 }
 
@@ -401,19 +289,30 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
        
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-       NSRect screenSize = [[m_window screen] visibleFrame];
+       
+       if (!m_fullScreen)
+       {
+               NSRect screenSize = [[m_window screen] visibleFrame];
 
-       //Max window contents as screen size (excluding title bar...)
-       NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize
-                                                                                                styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
+               //Max window contents as screen size (excluding title bar...)
+               NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize
+                                                                                                        styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
 
-       rect = [m_window contentRectForFrameRect:[m_window frame]];
-       
-       bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y);
-       bounds.m_l = rect.origin.x -contentRect.origin.x;
-       bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width;
-       bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y);
-       
+               rect = [m_window contentRectForFrameRect:[m_window frame]];
+               
+               bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y);
+               bounds.m_l = rect.origin.x -contentRect.origin.x;
+               bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width;
+               bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y);
+       }
+       else {
+               NSRect screenSize = [[m_window screen] frame];
+               
+               bounds.m_b = screenSize.origin.y + screenSize.size.height;
+               bounds.m_l = screenSize.origin.x;
+               bounds.m_r = screenSize.origin.x + screenSize.size.width;
+               bounds.m_t = screenSize.origin.y;
+       }
        [pool drain];
 }
 
@@ -469,7 +368,10 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        GHOST_TWindowState state;
-       if ([m_window isMiniaturized]) {
+       if (m_fullScreen) {
+               state = GHOST_kWindowStateFullScreen;
+       } 
+       else if ([m_window isMiniaturized]) {
                state = GHOST_kWindowStateMinimized;
        }
        else if ([m_window isZoomed]) {
@@ -521,15 +423,50 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
 {
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
     switch (state) {
-       case GHOST_kWindowStateMinimized:
+               case GHOST_kWindowStateMinimized:
             [m_window miniaturize:nil];
             break;
-       case GHOST_kWindowStateMaximized:
+               case GHOST_kWindowStateMaximized:
                        [m_window zoom:nil];
                        break;
-       case GHOST_kWindowStateNormal:
+               
+               case GHOST_kWindowStateFullScreen:
+                       if (!m_fullScreen)
+                       {
+                               NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+                       
+                               //This status change needs to be done before Cocoa call to enter fullscreen mode
+                               //to give window delegate hint not to forward its deactivation to ghost wm that doesn't know view/window difference
+                               m_fullScreen = true;
+
+                               //Only 10.6 API will enable to manage several display in fullscreen mode, and topmenu autoshow
+                               [m_openGLView enterFullScreenMode:[m_window screen] withOptions:nil];
+                               
+                               //Tell WM of view new size
+                               m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
+                               
+                               [pool drain];
+                               }
+                       break;
+               case GHOST_kWindowStateNormal:
         default:
-            if ([m_window isMiniaturized])
+                       if (m_fullScreen)
+                       {
+                               NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+                               m_fullScreen = false;
+
+                               //Exit fullscreen
+                               [m_openGLView exitFullScreenModeWithOptions:nil];
+                               
+                               [m_window makeKeyAndOrderFront:nil];
+                               [m_window makeFirstResponder:m_openGLView];
+                               
+                               //Tell WM of view new size
+                               m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
+                               
+                               [pool drain];
+                       }
+            else if ([m_window isMiniaturized])
                                [m_window deminiaturize:nil];
                        else if ([m_window isZoomed])
                                [m_window zoom:nil];
@@ -540,8 +477,11 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
 
 GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges)
 {
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       
        [m_window setDocumentEdited:isUnsavedChanges];
        
+       [pool drain];
        return GHOST_Window::setModifiedState(isUnsavedChanges);
 }
 
@@ -631,12 +571,11 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
                case GHOST_kDrawingContextTypeOpenGL:
                        if (!getValid()) break;
                                        
-                       if(!m_fullScreen)
-                       {
                                pixelFormat = [m_openGLView pixelFormat];
                                tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
                                                                                                                          shareContext:m_openGLContext];
                                if (tmpOpenGLContext == nil)
+                                       success = GHOST_kFailure;
                                        break;
 #ifdef WAIT_FOR_VSYNC
                                /* wait for vsync, to avoid tearing artifacts */
@@ -645,37 +584,8 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
                                [m_openGLView setOpenGLContext:tmpOpenGLContext];
                                [tmpOpenGLContext setView:m_openGLView];
                                
-                               //[m_openGLContext release];
+                               [m_openGLContext release];
                                m_openGLContext = tmpOpenGLContext;
-                       }
-                       /*      
-            AGLPixelFormat pixelFormat;
-            if (!m_fullScreen) {
-                pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
-                m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx);
-                if (!m_aglCtx) break;
-                               if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
-                 success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
-            }
-            else {
-                //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n");
-GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen);
-                m_aglCtx = ::aglCreateContext(pixelFormat, 0);
-                if (!m_aglCtx) break;
-                               if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
-                //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n");
-                //::CGGetActiveDisplayList(0, NULL, &m_numDisplays)
-                success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
-                
-                if (success == GHOST_kSuccess) {
-                    GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n");
-                }
-                else {
-                    GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n");
-                }
-                
-            }
-            ::aglDestroyPixelFormat(pixelFormat);*/
                        break;
                
                case GHOST_kDrawingContextTypeNone:
@@ -696,14 +606,16 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
        switch (m_drawingContextType) {
                case GHOST_kDrawingContextTypeOpenGL:
                        [m_openGLView clearGLContext];
+                       [pool drain];
                        return GHOST_kSuccess;
                case GHOST_kDrawingContextTypeNone:
+                       [pool drain];
                        return GHOST_kSuccess;
                        break;
                default:
+                       [pool drain];
                        return GHOST_kFailure;
        }
-       [pool drain];
 }
 
 
@@ -711,20 +623,7 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate()
 {
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    if (!m_fullScreen) {
-               [m_openGLView setNeedsDisplay:YES];
-    }
-    else {
-        //EventRef event;
-        //OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event);
-        //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n");
-        //status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this);
-        //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n");
-        //status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard);
-        //status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget());
-        //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n");
-        m_fullScreenDirty = true;
-    }
+       [m_openGLView setNeedsDisplay:YES];
        [pool drain];
        return GHOST_kSuccess;
 }
@@ -803,11 +702,6 @@ void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) c
 }
 
 
-bool GHOST_WindowCocoa::getFullScreenDirty()
-{
-    return m_fullScreen && m_fullScreenDirty;
-}
-
 
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
 {