]> git.sesse.net Git - vlc/commitdiff
macosx: fix and improve window level handling
authorDavid Fuhrmann <david.fuhrmann@googlemail.com>
Sat, 12 Jan 2013 15:29:26 +0000 (16:29 +0100)
committerDavid Fuhrmann <david.fuhrmann@googlemail.com>
Sat, 12 Jan 2013 15:30:12 +0000 (16:30 +0100)
    - fix behavior of video-on-top by adapting to vout windows handling changes
    - set all windows to status level if one vout window has this level:
    This avoids that video effects panel, audio efffects panel etc. pp. are opened behind
    a vout window. Now they can be used as usual.

    Please note, that due to the type of these panels they do not remain visible
    when VLC gets inactive.

18 files changed:
modules/gui/macosx/AudioEffects.h
modules/gui/macosx/AudioEffects.m
modules/gui/macosx/MainMenu.m
modules/gui/macosx/MainWindow.m
modules/gui/macosx/TrackSynchronization.h
modules/gui/macosx/TrackSynchronization.m
modules/gui/macosx/VLCVoutWindowController.h
modules/gui/macosx/VLCVoutWindowController.m
modules/gui/macosx/VideoEffects.h
modules/gui/macosx/VideoEffects.m
modules/gui/macosx/Windows.h
modules/gui/macosx/Windows.m
modules/gui/macosx/bookmarks.h
modules/gui/macosx/bookmarks.m
modules/gui/macosx/intf.h
modules/gui/macosx/intf.m
modules/gui/macosx/playlistinfo.h
modules/gui/macosx/playlistinfo.m

index 0c84b90eaea2c7da4abe5edf6fc2f6644cf804a2..d0df51e265e9bf17c0fa854a097a6c5fc4f5b233 100644 (file)
 
 /* generic */
 + (VLCAudioEffects *)sharedInstance;
+
+- (void)updateCocoaWindowLevel:(NSInteger)i_level;
 - (IBAction)toggleWindow:(id)sender;
 - (void)setAudioFilter: (char *)psz_name on:(BOOL)b_on;
 - (IBAction)profileSelectorAction:(id)sender;
index 84763872a13b597d42cc751e2f29353f75f3d27e..38a32c9c730811a6075d7a00f78a5bf7962a79bd 100644 (file)
@@ -216,12 +216,20 @@ static VLCAudioEffects *_o_sharedInstance = nil;
 
 #pragma mark -
 #pragma mark generic code
+- (void)updateCocoaWindowLevel:(NSInteger)i_level
+{
+    if (o_window && [o_window isVisible] && [o_window level] != i_level)
+        [o_window setLevel: i_level];
+}
+
 - (IBAction)toggleWindow:(id)sender
 {
     if ([o_window isVisible])
         [o_window orderOut:sender];
-    else
+    else {
+        [o_window setLevel: [[[VLCMain sharedInstance] voutController] currentWindowLevel]];
         [o_window makeKeyAndOrderFront:sender];
+    }
 }
 
 - (NSString *)generateProfileString
index 13d644f6946ae1389ffe58b085887e89cbcd5ea4..e9c6546c9eebfd20c9549320e8258d58b21babbe 100644 (file)
@@ -870,10 +870,7 @@ static VLCMainMenu *_o_sharedInstance = nil;
 
 - (IBAction)viewPreferences:(id)sender
 {
-    NSInteger i_level = NSNormalWindowLevel;
-    NSInteger i_video_window_level = [[[[VLCMainWindow sharedInstance] videoView] window] level];
-    if (i_video_window_level == NSStatusWindowLevel)
-        i_level = NSStatusWindowLevel;
+    NSInteger i_level = [[[VLCMain sharedInstance] voutController] currentWindowLevel];
     [[[VLCMain sharedInstance] simplePreferences] showSimplePrefsWithLevel:i_level];
 }
 
index 3550610a5a9e878733d409309b180b7f99ebb827..f0c69cd35747e928523392db195e22b109304a82 100644 (file)
@@ -742,9 +742,7 @@ static VLCMainWindow *_o_sharedInstance = nil;
         }
 
         [self makeFirstResponder: nil];
-
-        if ([self level] != NSNormalWindowLevel)
-            [self setLevel: NSNormalWindowLevel];
+        [[[VLCMain sharedInstance] voutController] updateWindowLevelForHelperWindows: NSNormalWindowLevel];
 
         // restore alpha value to 1 for the case that macosx-opaqueness is set to < 1
         [self setAlphaValue:1.0];
@@ -856,6 +854,7 @@ static VLCMainWindow *_o_sharedInstance = nil;
 
     [self recreateHideMouseTimer];
     i_originalLevel = [self level];
+    [[[VLCMain sharedInstance] voutController] updateWindowLevelForHelperWindows: NSNormalWindowLevel];
     [self setLevel:NSNormalWindowLevel];
 
     if (b_dark_interface) {
@@ -899,7 +898,6 @@ static VLCMainWindow *_o_sharedInstance = nil;
 
 - (void)windowWillExitFullScreen:(NSNotification *)notification
 {
-
     var_SetBool(pl_Get(VLCIntf), "fullscreen", false);
 
     vout_thread_t *p_vout = getVout();
@@ -911,7 +909,9 @@ static VLCMainWindow *_o_sharedInstance = nil;
     [o_video_view setFrame: [o_split_view frame]];
     [NSCursor setHiddenUntilMouseMoves: NO];
     [o_fspanel setNonActive: nil];
+    [[[VLCMain sharedInstance] voutController] updateWindowLevelForHelperWindows: i_originalLevel];
     [self setLevel:i_originalLevel];
+
     b_fullscreen = NO;
 
     if (b_dark_interface) {
index d74371dda9e2853935825fe3359c53105ed78f56..9599a5250afcde8b2ede9a9723a344a08da7e928 100644 (file)
@@ -52,6 +52,8 @@
 
 /* generic */
 + (VLCTrackSynchronization *)sharedInstance;
+
+- (void)updateCocoaWindowLevel:(NSInteger)i_level;
 - (IBAction)toggleWindow:(id)sender;
 - (IBAction)resetValues:(id)sender;
 - (void)updateValues;
index 687ab8bc275701d35f1e893263b18880aae3c2d6..61e6138eb0fc81cec8b88adb66d5a1f04565e8b3 100644 (file)
@@ -98,12 +98,20 @@ static VLCTrackSynchronization *_o_sharedInstance = nil;
     [self resetValues:self];
 }
 
+- (void)updateCocoaWindowLevel:(NSInteger)i_level
+{
+    if (o_window && [o_window isVisible] && [o_window level] != i_level)
+        [o_window setLevel: i_level];
+}
+
 - (IBAction)toggleWindow:(id)sender
 {
     if ([o_window isVisible])
         [o_window orderOut:sender];
-    else
+    else {
+        [o_window setLevel: [[[VLCMain sharedInstance] voutController] currentWindowLevel]];
         [o_window makeKeyAndOrderFront:sender];
+    }
 }
 
 - (IBAction)resetValues:(id)sender
index 69577fcf8a9b82a177aedb394d4d0f46d7655895..3480914b25196071046497cb0002eb8a9186f624 100644 (file)
     NSMutableDictionary *o_vout_dict;
 
     NSPoint top_left_point;
+
+    // save the status level if at least one video window is on status level
+    NSUInteger i_statusLevelWindowCounter;
+    NSInteger i_currentWindowLevel;
 }
 
+@property (readonly, nonatomic) NSInteger currentWindowLevel;
+
 - (VLCVoutView *)setupVoutForWindow:(vout_window_t *)p_wnd withProposedVideoViewPosition:(NSRect)videoViewPosition;
 - (void)removeVoutforDisplay:(NSValue *)o_key;
 
@@ -46,5 +52,8 @@
 - (void)updateWindow:(vout_window_t *)p_wnd withSelector:(SEL)aSel;
 
 - (void)setNativeVideoSize:(NSSize)size forWindow:(vout_window_t *)p_wnd;
+- (void)setWindowLevel:(NSInteger)i_level forWindow:(vout_window_t *)p_wnd;
+
+- (void)updateWindowLevelForHelperWindows:(NSInteger)i_level;
 
 @end
index 93b7d8966dde8ef866323fc5d259999509f9da91..a3df4f02fe29d536e4b8384696b079e78a002228 100644 (file)
 #import "MainWindow.h"
 #import "VideoView.h"
 
+#import "VideoEffects.h"
+#import "AudioEffects.h"
+#import "playlistinfo.h"
+#import "bookmarks.h"
+#import "TrackSynchronization.h"
+
 @implementation VLCVoutWindowController
 
 - (id)init
 {
     self = [super init];
     o_vout_dict = [[NSMutableDictionary alloc] init];
+    i_currentWindowLevel = NSNormalWindowLevel;
     return self;
 }
 
         [o_new_video_window setNativeVideoSize:videoViewSize];
 
         [o_new_video_window makeKeyAndOrderFront: self];
-
-        vout_thread_t *p_vout = getVout();
-        if (p_vout) {
-            if (var_GetBool(p_vout, "video-on-top"))
-                [o_new_video_window setLevel: NSStatusWindowLevel];
-            else
-                [o_new_video_window setLevel: NSNormalWindowLevel];
-            vlc_object_release(p_vout);
-        }
     }
 
     [o_new_video_window setAlphaValue: config_GetFloat(VLCIntf, "macosx-opaqueness")];
     [o_window setNativeVideoSize:size];
 }
 
+- (void)setWindowLevel:(NSInteger)i_level forWindow:(vout_window_t *)p_wnd
+{
+    // only set level for helper windows to normal if no status vout window exist anymore
+    if(i_level == NSStatusWindowLevel) {
+        i_statusLevelWindowCounter++;
+        [self updateWindowLevelForHelperWindows:i_level];
+    } else {
+        i_statusLevelWindowCounter--;
+        if (i_statusLevelWindowCounter == 0) {
+            [self updateWindowLevelForHelperWindows:i_level];
+        }
+    }
+
+    VLCVideoWindowCommon *o_window = [o_vout_dict objectForKey:[NSValue valueWithPointer:p_wnd]];
+    if (!o_window) {
+        msg_Err(VLCIntf, "Cannot set size for nonexisting window");
+        return;
+    }
+
+    [o_window setWindowLevel:i_level];
+}
+
+- (void)updateWindowLevelForHelperWindows:(NSInteger)i_level
+{
+    if (var_InheritBool(VLCIntf, "video-wallpaper"))
+        return;
+
+    i_currentWindowLevel = i_level;
+
+    [[VLCMainWindow sharedInstance] setWindowLevel:i_level];
+    [[VLCVideoEffects sharedInstance] updateCocoaWindowLevel:i_level];
+    [[VLCAudioEffects sharedInstance] updateCocoaWindowLevel:i_level];
+    [[[VLCMain sharedInstance] info] updateCocoaWindowLevel:i_level];
+    [[VLCBookmarks sharedInstance] updateCocoaWindowLevel:i_level];
+    [[VLCTrackSynchronization sharedInstance] updateCocoaWindowLevel:i_level];
+}
+
+@synthesize currentWindowLevel=i_currentWindowLevel;
+
+
 @end
index 7679fe22a8ff55b4eea2b682a24b42063a207af1..1355cff94381465447ef0c8cee1c374dbb44dee6 100644 (file)
 
 /* generic */
 + (VLCVideoEffects *)sharedInstance;
+- (void)updateCocoaWindowLevel:(NSInteger)i_level;
+
 - (void)resetValues;
 - (void)setVideoFilter: (char *)psz_name on:(BOOL)b_on;
 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char*)psz_filter integer: (int)i_value;
index 5194c3dcd58edd6f4e9c326c3ac8ebc947e2fd30..f8263261fc07b881d173c22c2da1f84977f6be44 100644 (file)
@@ -212,6 +212,12 @@ static VLCVideoEffects *_o_sharedInstance = nil;
     [self resetValues];
 }
 
+- (void)updateCocoaWindowLevel:(NSInteger)i_level
+{
+    if (o_window && [o_window isVisible] && [o_window level] != i_level)
+        [o_window setLevel: i_level];
+}
+
 #pragma mark -
 #pragma mark internal functions
 - (void)resetProfileSelector
@@ -730,8 +736,10 @@ static VLCVideoEffects *_o_sharedInstance = nil;
 {
     if ([o_window isVisible])
         [o_window orderOut:sender];
-    else
+    else {
+        [o_window setLevel: [[[VLCMain sharedInstance] voutController] currentWindowLevel]];
         [o_window makeKeyAndOrderFront:sender];
+    }
 }
 
 - (IBAction)profileSelectorAction:(id)sender
index ed3677df82782a93ee977b02ad39935447ac7fd1..47faa847d1c62111887d19aad2fb36d691850d78 100644 (file)
@@ -101,6 +101,8 @@ static const float f_min_video_height = 70.0;
 @property (nonatomic, assign) VLCVoutView* videoView;
 @property (readonly) VLCControlsBarCommon* controlsBar;
 
+- (void)setWindowLevel:(NSInteger)i_state;
+
 - (void)resizeWindow;
 - (void)setNativeVideoSize:(NSSize)size;
 - (NSRect)getWindowRectForProposedVideoViewSize:(NSSize)size;
index 4155f72f6a3505f84bd286cdbbb7a76e239a391b..957265bdc5cab12f5e2803a6c0d6382020e9ea1b 100644 (file)
 #pragma mark -
 #pragma mark Video window resizing logic
 
+- (void)setWindowLevel:(NSInteger)i_state
+{
+    if (var_InheritBool(VLCIntf, "video-wallpaper") || [self level] < NSNormalWindowLevel)
+        return;
+
+    [self setLevel: i_state];
+
+}
+
 - (NSRect)getWindowRectForProposedVideoViewSize:(NSSize)size
 {
     NSSize windowMinSize = [self minSize];
 
     /* Make sure we don't see the window flashes in float-on-top mode */
     i_originalLevel = [self level];
+    [[[VLCMain sharedInstance] voutController] updateWindowLevelForHelperWindows: NSNormalWindowLevel];
     [self setLevel:NSNormalWindowLevel];
 
+
     /* Only create the o_fullscreen_window if we are not in the middle of the zooming animation */
     if (!o_fullscreen_window) {
         /* We can't change the styleMask of an already created NSWindow, so we create another window, and do eye catching stuff */
     /* We always try to do so */
     [NSScreen unblackoutScreens];
 
-    vout_thread_t *p_vout = getVoutForActiveWindow();
-    if (p_vout) {
-        if (var_GetBool(p_vout, "video-on-top"))
-            [[o_video_view window] setLevel: NSStatusWindowLevel];
-        else
-            [[o_video_view window] setLevel: NSNormalWindowLevel];
-        vlc_object_release(p_vout);
-    }
     [[o_video_view window] makeKeyAndOrderFront: nil];
 
     /* Don't do anything if o_fullscreen_window is already closed */
 
     [o_fullscreen_window release];
     o_fullscreen_window = nil;
+    
+    [[[VLCMain sharedInstance] voutController] updateWindowLevelForHelperWindows: i_originalLevel];
     [self setLevel:i_originalLevel];
     [self setAlphaValue: config_GetFloat(VLCIntf, "macosx-opaqueness")];
 
index accd5a3f81146d762e51c5ccb0fe5860d325a8e5..809c112bf913356571398e576efad8faaa8f4d54 100644 (file)
@@ -51,6 +51,8 @@
 }
 + (VLCBookmarks *)sharedInstance;
 
+- (void)updateCocoaWindowLevel:(NSInteger)i_level;
+
 - (IBAction)add:(id)sender;
 - (IBAction)clear:(id)sender;
 - (IBAction)edit:(id)sender;
index 3a64d146444316054cbd549918d8940c1c7a0bf2..e8ef385551643b8a7e44827ec1949440a380d1af 100644 (file)
@@ -108,10 +108,17 @@ static VLCBookmarks *_o_sharedInstance = nil;
     [o_edit_lbl_bytes setStringValue: _NS("Position")];
 }
 
+- (void)updateCocoaWindowLevel:(NSInteger)i_level
+{
+    if (o_bookmarks_window && [o_bookmarks_window isVisible] && [o_bookmarks_window level] != i_level)
+        [o_bookmarks_window setLevel: i_level];
+}
+
 - (void)showBookmarks
 {
     /* show the window, called from intf.m */
     [o_bookmarks_window displayIfNeeded];
+    [o_bookmarks_window setLevel: [[[VLCMain sharedInstance] voutController] currentWindowLevel]];
     [o_bookmarks_window makeKeyAndOrderFront:nil];
 }
 
index 5fa2490f25ff33fcd2ccbf606ce10215b6975820..873279a03d2842c8568d25028b7ae2ca5490d3fe 100644 (file)
@@ -8,6 +8,7 @@
  *          Christophe Massiot <massiot@via.ecp.fr>
  *          Derk-Jan Hartman <hartman at videolan dot org>
  *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +42,7 @@
 #import "SPMediaKeyTap.h"                   /* for the media key support */
 #import "misc.h"
 #import "MainWindow.h"
+#import "VLCVoutWindowController.h"
 #import "StringUtility.h"
 
 #import <IOKit/pwr_mgt/IOPMLib.h>           /* for sleep prevention */
@@ -78,7 +80,6 @@ struct intf_sys_t
 @class VLCEmbeddedWindow;
 @class VLCControls;
 @class VLCPlaylist;
-@class VLCVoutWindowController;
 
 @interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
 {
index 3aa9f6679e2a60283693df29283b678823f20d04..bc4547d45df9a636164143b423ddd9846b889b48 100644 (file)
@@ -8,6 +8,7 @@
  *          Christophe Massiot <massiot@via.ecp.fr>
  *          Derk-Jan Hartman <hartman at videolan.org>
  *          Felix Paul Kühne <fkuehne at videolan dot org>
+ *          David Fuhrmann <david dot fuhrmann at googlemail dot com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -140,7 +141,6 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
         msg_Err(p_wnd, "Mac OS X interface not found");
         return VLC_EGENERIC;
     }
-
     NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
 
     VLCVoutWindowController *o_vout_controller = [[VLCMain sharedInstance] voutController];
@@ -194,7 +194,20 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
         case VOUT_WINDOW_SET_STATE:
         {
             unsigned i_state = va_arg(args, unsigned);
-            [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(setWindowLevel:) withObject:[NSNumber numberWithUnsignedInt:i_state] waitUntilDone:NO];
+
+            NSInteger i_cooca_level = NSNormalWindowLevel;
+            if (i_state & VOUT_WINDOW_STATE_ABOVE)
+                i_cooca_level = NSStatusWindowLevel;
+
+            SEL sel = @selector(setWindowLevel:forWindow:);
+            NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[[VLCMain sharedInstance] voutController] methodSignatureForSelector:sel]];
+            [inv setTarget:[[VLCMain sharedInstance] voutController]];
+            [inv setSelector:sel];
+            [inv setArgument:&i_cooca_level atIndex:2]; // starting at 2!
+            [inv setArgument:&p_wnd atIndex:3];
+            [inv performSelectorOnMainThread:@selector(invoke) withObject:nil
+                               waitUntilDone:NO];
+
             return VLC_SUCCESS;
         }
         case VOUT_WINDOW_SET_SIZE:
@@ -850,6 +863,10 @@ static VLCMain *_o_sharedMainInstance = nil;
     /* remove global observer watching for vout device changes correctly */
     [[NSNotificationCenter defaultCenter] removeObserver: self];
 
+    // release before o_info!
+    [o_vout_controller release];
+    o_vout_controller = nil;
+
     /* release some other objects here, because it isn't sure whether dealloc
      * will be called later on */
     if (o_sprefs)
@@ -886,10 +903,8 @@ static VLCMain *_o_sharedMainInstance = nil;
     /* write cached user defaults to disk */
     [[NSUserDefaults standardUserDefaults] synchronize];
 
-    [o_mainmenu release];
 
-    [o_vout_controller release];
-    o_vout_controller = nil;
+    [o_mainmenu release];
 
     libvlc_Quit(p_intf->p_libvlc);
 
@@ -1475,16 +1490,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 #pragma mark -
 #pragma mark Window updater
 
-- (void)setWindowLevel:(NSNumber*)state
-{
-    if (var_InheritBool(p_intf, "video-wallpaper") || [[[[VLCMainWindow sharedInstance] videoView] window] level] < NSNormalWindowLevel)
-        return;
 
-    if ([state unsignedIntValue] & VOUT_WINDOW_STATE_ABOVE)
-        [[[[VLCMainWindow sharedInstance] videoView] window] setLevel: NSStatusWindowLevel];
-    else
-        [[[[VLCMainWindow sharedInstance] videoView] window] setLevel: NSNormalWindowLevel];
-}
 
 - (void)setActiveVideoPlayback:(BOOL)b_value
 {
index d4936418df17c2fdc54d0e6921c2b1ca8f75056d..8deb36f75994b6d53c0811ac30e588b8a7c385a5 100644 (file)
 }
 @property (readonly) input_item_t * item;
 
+- (void)updateCocoaWindowLevel:(NSInteger)i_level;
 - (void)initPanel;
 
 - (IBAction)metaFieldChanged:(id)sender;
index ff3cefc529d8b82a4a3c5666b8d1993b34702b4b..fd3ffc46f3de870dcba83f6258b04b9a68a080d0 100644 (file)
@@ -135,6 +135,12 @@ static VLCInfo *_o_sharedInstance = nil;
     [super dealloc];
 }
 
+- (void)updateCocoaWindowLevel:(NSInteger)i_level
+{
+    if (o_info_window && [o_info_window isVisible] && [o_info_window level] != i_level)
+        [o_info_window setLevel: i_level];
+}
+
 - (void)initPanel
 {
     b_stats = config_GetInt(VLCIntf, "stats");
@@ -145,6 +151,8 @@ static VLCInfo *_o_sharedInstance = nil;
     else
         [self initMediaPanelStats];
 
+    NSInteger i_level = [[[VLCMain sharedInstance] voutController] currentWindowLevel];
+    [o_info_window setLevel: i_level];
     [o_info_window makeKeyAndOrderFront: self];
 }