diff src/video/quartz/SDL_QuartzWindow.m @ 683:5d2f027b3349

Date: Sat, 9 Aug 2003 20:14:06 -0400 From: Darrell Walisser Subject: Re: Updated projects? >> Did you get a chance to look at my "Custom Cocoa" demo? I have a few >> minor patches that enable SDL/Cocoa integration, and a project >> template. > > I didn't yet, but go ahead and send me the patches. :) > I updated the patch for current CVS. There are a lot of changes, but I don't think I've broken anything. This patch also improves the behavior of window minimize/deminimize.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 10 Aug 2003 07:21:43 +0000
parents 52864d66d168
children c5b2b6d2d1fe
line wrap: on
line diff
--- a/src/video/quartz/SDL_QuartzWindow.m	Sat Aug 09 22:49:28 2003 +0000
+++ b/src/video/quartz/SDL_QuartzWindow.m	Sun Aug 10 07:21:43 2003 +0000
@@ -32,6 +32,7 @@
 - (void)display;
 - (void)setFrame:(NSRect)frameRect display:(BOOL)flag;
 - (void)appDidHide:(NSNotification*)note;
+- (void)appWillUnhide:(NSNotification*)note;
 - (void)appDidUnhide:(NSNotification*)note;
 - (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
 @end
@@ -63,13 +64,27 @@
 - (void)display
 {    
     /* 
-        This method fires just before the window deminaturizes.
-        So, it's just the right place to fixup the alpha channel - which
-        makes the deminiaturize animation look right.
+        This method fires just before the window deminaturizes from the Dock.
+        
+        We'll save the current visible surface, let the window manager redraw any
+        UI elements, and restore the SDL surface. This way, no expose event 
+        is required, and the deminiaturize works perfectly.
     */
-    if ( (SDL_VideoSurface->flags & SDL_OPENGL) == 0)
+     SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+    
+    /* make sure pixels are fully opaque */
+    if (! ( SDL_VideoSurface->flags & SDL_OPENGL ) )
         QZ_SetPortAlphaOpaque ();
-
+    
+    /* save current visible SDL surface */
+    [ self cacheImageInRect:[ window_view frame ] ];
+    
+    /* let the window manager redraw controls, border, etc */
+    [ super display ];
+    
+    /* restore visible SDL surface */
+    [ self restoreCachedImage ];
+    
     /* window is visible again */
     SDL_PrivateAppActive (1, SDL_APPACTIVE);
 }
@@ -81,30 +96,45 @@
         If the video surface is NULL, this originated from QZ_SetVideoMode,
         so don't send the resize event. 
     */
-    if (SDL_VideoSurface == NULL) {
+    SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+    
+    if (this && SDL_VideoSurface == NULL) {
 
         [ super setFrame:frameRect display:flag ];
     }
-    else {
+    else if (this && qz_window) {
 
-        SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+        NSRect newViewFrame;
         
-        NSRect sdlRect = [ NSWindow contentRectForFrameRect:frameRect styleMask:[self styleMask] ];
-
         [ super setFrame:frameRect display:flag ];
-        SDL_PrivateResize (sdlRect.size.width, sdlRect.size.height);
+        
+        newViewFrame = [ window_view frame ];
+        
+        SDL_PrivateResize (newViewFrame.size.width, newViewFrame.size.height);
 
         /* If not OpenGL, we have to update the pixels and pitch */
-        if ( ! this->screen->flags & SDL_OPENGL ) {
+        if ( ! ( SDL_VideoSurface->flags & SDL_OPENGL ) ) {
             
-            LockPortBits ( [ window_view qdPort ] );
+            CGrafPtr thePort = [ window_view qdPort ];
+            LockPortBits ( thePort );
             
-            SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
-            SDL_VideoSurface->pitch  = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
+            SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( thePort ) );
+            SDL_VideoSurface->pitch  = GetPixRowBytes ( GetPortPixMap ( thePort ) );
+                        
+            /* 
+                SDL_VideoSurface->pixels now points to the window's pixels
+                We want it to point to the *view's* pixels 
+            */
+            { 
+                int vOffset = [ qz_window frame ].size.height - 
+                    newViewFrame.size.height - newViewFrame.origin.y;
+                
+                int hOffset = newViewFrame.origin.x;
+                        
+                SDL_VideoSurface->pixels += (vOffset * SDL_VideoSurface->pitch) + hOffset * (device_bpp/8);
+            }
             
-            SDL_VideoSurface->pixels += ((int)[ self frame ].size.height - (int)sdlRect.size.height) * SDL_VideoSurface->pitch;
-    
-            UnlockPortBits ( [ window_view qdPort ] );
+            UnlockPortBits ( thePort );
         }
     }
 }
@@ -114,8 +144,28 @@
     SDL_PrivateAppActive (0, SDL_APPACTIVE);
 }
 
+- (void)appWillUnhide:(NSNotification*)note
+{
+    SDL_VideoDevice *this = (SDL_VideoDevice*)current_video;
+    
+    if ( this ) {
+    
+        /* make sure pixels are fully opaque */
+        if (! ( SDL_VideoSurface->flags & SDL_OPENGL ) )
+            QZ_SetPortAlphaOpaque ();
+          
+        /* save current visible SDL surface */
+        [ self cacheImageInRect:[ window_view frame ] ];
+    }
+}
+
 - (void)appDidUnhide:(NSNotification*)note
 {
+    /* restore cached image, since it may not be current, post expose event too */
+    [ self restoreCachedImage ];
+    
+    //SDL_PrivateExpose ();
+    
     SDL_PrivateAppActive (1, SDL_APPACTIVE);
 }
 
@@ -127,6 +177,9 @@
     
     [ [ NSNotificationCenter defaultCenter ] addObserver:self
         selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
+   
+    [ [ NSNotificationCenter defaultCenter ] addObserver:self
+        selector:@selector(appWillUnhide:) name:NSApplicationWillUnhideNotification object:NSApp ];
         
     return [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ];
 }