Close the embedded window only when playlist stop. Have the window to animate smoothl...
authorPierre d'Herbemont <pdherbemont@videolan.org>
Sat, 3 Mar 2007 00:25:05 +0000 (00:25 +0000)
committerPierre d'Herbemont <pdherbemont@videolan.org>
Sat, 3 Mar 2007 00:25:05 +0000 (00:25 +0000)
modules/gui/macosx/embeddedwindow.h
modules/gui/macosx/embeddedwindow.m
modules/gui/macosx/vout.m

index e9964b8..0c24268 100644 (file)
     NSViewAnimation * o_fullscreen_anim1;
     NSViewAnimation * o_fullscreen_anim2;
     NSView          * o_temp_view;
+    /* set to yes if we are fullscreen and all animations are over */
+    BOOL              b_fullscreen;
 }
 
 - (void)setTime:(NSString *)o_arg_ime position:(float)f_position;
 - (void)playStatusUpdated:(int)i_status;
 - (void)setSeekable:(BOOL)b_seekable;
 
+- (NSView *)mainView;
+
+- (BOOL)isFullscreen;
+
 - (void)enterFullscreen;
 - (void)leaveFullscreen;
 
 /* private */
 - (void)hasEndedFullscreen;
 - (void)hasBecomeFullscreen;
+
+- (void)setFrameOnMainThread:(NSData*)packedargs;
 @end
 
index c466a93..7510e78 100644 (file)
@@ -66,6 +66,7 @@
 
     /* Not fullscreen when we wake up */
     [o_btn_fullscreen setState: NO];
+    b_fullscreen = NO;
 }
 
 - (void)setTime:(NSString *)o_arg_time position:(float)f_position
     return YES;
 }
 
+- (NSView *)mainView
+{
+    if (o_fullscreen_window)
+        return o_temp_view;
+    else
+        return o_view;
+}
+
 /*****************************************************************************
  * Fullscreen support
  */
+
+- (BOOL)isFullscreen
+{
+    return b_fullscreen;
+}
+
 - (void)enterFullscreen
 {
     NSMutableDictionary *dict1, *dict2;
         return;
     }
 
+    /* We are in fullscreen (and no animation is running) */
+    if (b_fullscreen)
+        return;
+
     if (o_fullscreen_anim1)
     {
         [o_fullscreen_anim1 stopAnimation];
     [[[[VLCMain sharedInstance] getControls] getFSPanel] setVoutWasUpdated: (int)[[o_fullscreen_window screen] displayID]];
     
     [[[[VLCMain sharedInstance] getControls] getFSPanel] setActive: nil];
+    b_fullscreen = YES;
 }
 
 - (void)leaveFullscreen
     NSMutableDictionary *dict1, *dict2;
     NSRect frame;
     
+    b_fullscreen = NO;
     [o_btn_fullscreen setState: NO];
 
     /* We always try to do so */
     if (!o_fullscreen_window)
         return;
 
-    if (MACOS_VERSION < 10.4f)
+    if (![self isVisible] || MACOS_VERSION < 10.4f)
     {
         /* We don't animate if we are not visible or if we are running on
         * Mac OS X <10.4 which doesn't support NSAnimation, instead we
         [[[[VLCMain sharedInstance] getControls] getFSPanel] setNonActive: nil];
         SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
 
-        [self makeKeyAndOrderFront:self];
         [self hasEndedFullscreen];
 
         CGDisplayFade( token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, NO );
     [[self contentView] replaceSubview:o_temp_view with:o_view];
     [o_view release];
     [o_view setFrame:[o_temp_view frame]];
-    [self makeKeyAndOrderFront:self];
+    if ([self isVisible])
+        [self makeKeyAndOrderFront:self];
     [o_fullscreen_window orderOut: self];
     EnableScreenUpdates();
 
     }
 }
 
+- (void)orderOut: (id)sender
+{
+    [super orderOut: sender];
+    /* Make sure we leave fullscreen */
+    [self leaveFullscreen];
+}
+
+/* Make sure setFrame gets executed on main thread especially if we are animating.
+ * (Thus we won't block the video output thread) */
+- (void)setFrame:(NSRect)frame display:(BOOL)display animate:(BOOL)animate
+{
+    struct { NSRect frame; BOOL display; BOOL animate;} args;
+    NSData *packedargs;
+
+    args.frame = frame;
+    args.display = display;
+    args.animate = animate;
+
+    packedargs = [NSData dataWithBytes:&args length:sizeof(args)];
+
+    [self performSelectorOnMainThread:@selector(setFrameOnMainThread:)
+                    withObject: packedargs waitUntilDone: YES];
+}
+
+- (void)setFrameOnMainThread:(NSData*)packedargs
+{
+    struct args { NSRect frame; BOOL display; BOOL animate; } * args = (struct args*)[packedargs bytes];
+
+    [super setFrame: args->frame display: args->display animate:args->animate];
+}
 @end
index c9671c1..7815331 100644 (file)
@@ -245,10 +245,21 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
     [o_view setFrameSize: [self frame].size];
 }
 
+- (void)drawRect:(NSRect)rect
+{
+    /* When there is no subview we draw a black background */
+    [self lockFocus];
+    [[NSColor blackColor] set];
+    NSRectFill(rect);
+    [self unlockFocus];
+}
+
 - (void)closeVout
 {
     [[[[VLCMain sharedInstance] getControls] getFSPanel] fadeOut];
 
+    /* Make sure we don't see a white flash */
+    [[self window] disableScreenUpdatesUntilFlush];
     [o_view removeFromSuperview];
     o_view = nil;
     p_vout = NULL;
@@ -334,6 +345,7 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
 
     if ( !p_vout->b_fullscreen )
     {
+        NSView *mainView;
         NSRect new_frame;
         topleftbase.x = 0;
         topleftbase.y = [o_window frame].size.height;
@@ -355,11 +367,18 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
             newsize.height = (int) ( i_corrected_height * factor );
         }
 
+        /* In fullscreen mode we need to use a view that is different from
+         * ourselves, with the VLCEmbeddedWindow */
+        if([o_window isKindOfClass:[VLCEmbeddedWindow class]])
+            mainView = [o_window mainView];
+        else
+            mainView = self;
+
         /* Calculate the window's new size */
         new_frame.size.width = [o_window frame].size.width -
-                                    [self frame].size.width + newsize.width;
+                                    [mainView frame].size.width + newsize.width;
         new_frame.size.height = [o_window frame].size.height -
-                                    [self frame].size.height + newsize.height;
+                                    [mainView frame].size.height + newsize.height;
 
         new_frame.origin.x = topleftscreen.x;
         new_frame.origin.y = topleftscreen.y - new_frame.size.height;
@@ -894,19 +913,34 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
 {
     BOOL b_return = [super setVout: p_arg_vout subView: view frame: s_arg_frame];
 
+    /* o_window needs to point to our o_embeddedwindow, super might have set it
+     * to the fullscreen window that o_embeddedwindow setups during fullscreen */
+    o_window = o_embeddedwindow;
+    
     if( b_return )
     {
         [o_window setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
         [self updateTitle];
-        [self scaleWindowWithFactor: 1.0 animate: NO];
-        [o_window makeKeyAndOrderFront: self];
+
+        if(!([o_window isFullscreen]))
+            [o_window makeKeyAndOrderFront: self];
+
+        NSLog(@"We are %s animating (%s)",  [o_window isVisible] && (![o_window isFullscreen]) ? "" :"not", [o_window isFullscreen] ? "fullscreen" : "");
+
+        [self scaleWindowWithFactor: 1.0 animate: [o_window isVisible] && (![o_window isFullscreen])];
     }
     return b_return;
 }
 
 - (void)closeVout
 {
-    [o_window orderOut: self];
+    playlist_t * p_playlist = pl_Yield( VLCIntf );
+
+    if(!playlist_IsPlaying( p_playlist ))
+        [o_window performSelectorOnMainThread: @selector(orderOut:) withObject: self waitUntilDone: YES];
+    
+    vlc_object_release( p_playlist );
+
     [super closeVout];
 }