macosx: add new controller which handles multiple vout windows

refs #6814
This commit is contained in:
David Fuhrmann 2012-10-02 19:26:37 +02:00
parent e0d96420fe
commit 0b3c20521a
8 changed files with 210 additions and 81 deletions

View File

@ -986,6 +986,8 @@
E0382C01160BA09E0031D7FF /* ControlsBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ControlsBar.m; path = ../../../modules/gui/macosx/ControlsBar.m; sourceTree = SOURCE_ROOT; };
E06CF7F416020F6200C698B7 /* Windows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Windows.h; path = ../../../modules/gui/macosx/Windows.h; sourceTree = SOURCE_ROOT; };
E06CF7F516020F6200C698B7 /* Windows.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Windows.m; path = ../../../modules/gui/macosx/Windows.m; sourceTree = SOURCE_ROOT; };
E0C2583E161B593D00185AAD /* VLCVoutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCVoutWindowController.h; path = ../../../modules/gui/macosx/VLCVoutWindowController.h; sourceTree = SOURCE_ROOT; };
E0C2583F161B593D00185AAD /* VLCVoutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCVoutWindowController.m; path = ../../../modules/gui/macosx/VLCVoutWindowController.m; sourceTree = SOURCE_ROOT; };
E0FB95CD1615B6DF0005069A /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Resources/English.lproj/DetachedVideoWindow.xib; sourceTree = "<group>"; };
F69B0CA702E24F6401A80112 /* English */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.plist.strings; name = English; path = Resources/English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -1066,6 +1068,8 @@
CC448A6313B68A0B009F72E0 /* MainWindow.m */,
E0382C00160BA09E0031D7FF /* ControlsBar.h */,
E0382C01160BA09E0031D7FF /* ControlsBar.m */,
E0C2583E161B593D00185AAD /* VLCVoutWindowController.h */,
E0C2583F161B593D00185AAD /* VLCVoutWindowController.m */,
CC4A33220F8CB017000FC4A7 /* coredialogs.h */,
CC4A33210F8CB017000FC4A7 /* coredialogs.m */,
5CCED71014C0D4A90057F8D1 /* ExtensionsDialogProvider.h */,

View File

@ -60,8 +60,6 @@
IBOutlet VLCFSPanel *o_fspanel;
VLCDetachedVideoWindow *o_detached_video_window;
IBOutlet id o_podcast_view;
IBOutlet id o_podcast_add_btn;
IBOutlet id o_podcast_remove_btn;
@ -107,7 +105,6 @@
VLCColorView * o_color_backdrop;
NSInteger i_originalLevel;
VLCVideoWindowCommon *o_extra_video_window;
id o_current_video_window;
NSRect frameBeforePlayback;

View File

@ -44,6 +44,7 @@
#import "ControlsBar.h"
#import "VideoView.h"
#import "VLCVoutWindowController.h"
@interface VLCMainWindow ()
@ -53,9 +54,10 @@
@end
@implementation VLCMainWindow
static const float f_min_video_height = 70.0;
@implementation VLCMainWindow
static VLCMainWindow *_o_sharedInstance = nil;
+ (VLCMainWindow *)sharedInstance
@ -138,16 +140,6 @@ static VLCMainWindow *_o_sharedInstance = nil;
[[NSNotificationCenter defaultCenter] removeObserver: self];
[o_sidebaritems release];
if (o_extra_video_window) {
[o_extra_video_window release];
o_extra_video_window = nil;
}
if (o_detached_video_window) {
[o_detached_video_window release];
o_detached_video_window = nil;
}
[super dealloc];
}
@ -529,7 +521,9 @@ static VLCMainWindow *_o_sharedInstance = nil;
- (void)someWindowWillClose:(NSNotification *)notification
{
id obj = [notification object];
if (obj == o_detached_video_window || obj == o_extra_video_window || (obj == self && !b_nonembedded)) {
BOOL b_is_mainwindow = [NSStringFromClass([obj class]) isEqualToString:@"VLCMainWindow"];
if (!b_is_mainwindow || (b_is_mainwindow && !b_nonembedded)) {
if ([[VLCMain sharedInstance] activeVideoPlayback])
[[VLCCoreInteraction sharedInstance] stop];
}
@ -539,7 +533,9 @@ static VLCMainWindow *_o_sharedInstance = nil;
{
if (config_GetInt(VLCIntf, "macosx-pause-minimized")) {
id obj = [notification object];
if (obj == o_detached_video_window || obj == o_extra_video_window || (obj == self && !b_nonembedded)) {
BOOL b_is_mainwindow = [NSStringFromClass([obj class]) isEqualToString:@"VLCMainWindow"];
if (!b_is_mainwindow || (b_is_mainwindow && !b_nonembedded)) {
if ([[VLCMain sharedInstance] activeVideoPlayback])
[[VLCCoreInteraction sharedInstance] pause];
}
@ -631,8 +627,8 @@ static VLCMainWindow *_o_sharedInstance = nil;
{
[o_controls_bar updateTimeSlider];
[[self controlsBar] updatePosAndTimeInFSPanel:o_fspanel];
if (o_detached_video_window)
[[o_detached_video_window controlsBar] updateTimeSlider];
[[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(updateTimeSlider)];
}
- (void)updateName
@ -652,12 +648,14 @@ static VLCMainWindow *_o_sharedInstance = nil;
NSURL * o_url = [NSURL URLWithString: [NSString stringWithUTF8String: uri]];
if ([o_url isFileURL]) {
[self setRepresentedURL: o_url];
if (o_detached_video_window)
[o_detached_video_window setRepresentedURL: o_url];
[[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *o_window) {
[o_window setRepresentedURL:o_url];
}];
} else {
[self setRepresentedURL: nil];
if (o_detached_video_window)
[o_detached_video_window setRepresentedURL: nil];
[[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *o_window) {
[o_window setRepresentedURL:nil];
}];
}
free(uri);
@ -669,8 +667,9 @@ static VLCMainWindow *_o_sharedInstance = nil;
}
[self setTitle: aString];
if (b_nonembedded && o_detached_video_window && [[VLCMain sharedInstance] activeVideoPlayback])
[o_detached_video_window setTitle: aString];
[[[VLCMain sharedInstance] voutController] updateWindowsUsingBlock:^(VLCVideoWindowCommon *o_window) {
[o_window setTitle:aString];
}];
[o_fspanel setStreamTitle: aString];
vlc_object_release(p_input);
@ -683,8 +682,7 @@ static VLCMainWindow *_o_sharedInstance = nil;
- (void)updateWindow
{
[o_controls_bar updateControls];
if (o_detached_video_window)
[[o_detached_video_window controlsBar] updateControls];
[[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(updateControls)];
bool b_seekable = false;
@ -713,17 +711,18 @@ static VLCMainWindow *_o_sharedInstance = nil;
- (void)setPause
{
[o_controls_bar setPause];
if (o_detached_video_window)
[[o_detached_video_window controlsBar] setPause];
[o_fspanel setPause];
[[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(setPause)];
}
- (void)setPlay
{
[o_controls_bar setPlay];
if (o_detached_video_window)
[[o_detached_video_window controlsBar] setPlay];
[o_fspanel setPlay];
[[[VLCMain sharedInstance] voutController] updateWindowsControlsBarWithSelector:@selector(setPlay)];
}
- (void)updateVolumeSlider
@ -757,40 +756,36 @@ static VLCMainWindow *_o_sharedInstance = nil;
else
window_rect = [self frame];
if (o_extra_video_window)
[o_extra_video_window release];
NSUInteger mask = NSBorderlessWindowMask;
if (!OSX_SNOW_LEOPARD && !b_video_deco)
mask |= NSResizableWindowMask;
BOOL b_no_video_deco_only = !b_video_wallpaper;
o_extra_video_window = [[VLCVideoWindowCommon alloc] initWithContentRect:window_rect styleMask:mask backing:NSBackingStoreBuffered defer:YES];
[o_extra_video_window setDelegate:self];
o_new_video_window = [[VLCVideoWindowCommon alloc] initWithContentRect:window_rect styleMask:mask backing:NSBackingStoreBuffered defer:YES];
[o_new_video_window setDelegate:self];
if (b_video_wallpaper)
[o_extra_video_window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey) + 1];
[o_new_video_window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey) + 1];
[o_extra_video_window setBackgroundColor: [NSColor blackColor]];
[o_extra_video_window setCanBecomeKeyWindow: !b_video_wallpaper];
[o_extra_video_window setCanBecomeMainWindow: !b_video_wallpaper];
[o_extra_video_window setAcceptsMouseMovedEvents: !b_video_wallpaper];
[o_extra_video_window setMovableByWindowBackground: !b_video_wallpaper];
[o_extra_video_window useOptimizedDrawing: YES];
[o_new_video_window setBackgroundColor: [NSColor blackColor]];
[o_new_video_window setCanBecomeKeyWindow: !b_video_wallpaper];
[o_new_video_window setCanBecomeMainWindow: !b_video_wallpaper];
[o_new_video_window setAcceptsMouseMovedEvents: !b_video_wallpaper];
[o_new_video_window setMovableByWindowBackground: !b_video_wallpaper];
[o_new_video_window useOptimizedDrawing: YES];
o_vout_view = [[VLCVoutView alloc] initWithFrame:[[o_extra_video_window contentView] bounds]];
o_vout_view = [[VLCVoutView alloc] initWithFrame:[[o_new_video_window contentView] bounds]];
[o_vout_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[[o_extra_video_window contentView] addSubview:o_vout_view positioned:NSWindowAbove relativeTo:nil];
[o_extra_video_window setVideoView:o_vout_view];
[[o_new_video_window contentView] addSubview:o_vout_view positioned:NSWindowAbove relativeTo:nil];
[o_new_video_window setVideoView:o_vout_view];
o_new_video_window = o_extra_video_window;
if (b_video_wallpaper)
[o_extra_video_window orderBack:nil];
[o_new_video_window orderBack:nil];
else {
[o_extra_video_window center];
[o_extra_video_window setFrameAutosaveName:@"extra-videowindow"];
[o_extra_video_window setContentMinSize: NSMakeSize(f_min_video_height, f_min_video_height)];
[o_new_video_window center];
[o_new_video_window setFrameAutosaveName:@"extra-videowindow"];
[o_new_video_window setContentMinSize: NSMakeSize(f_min_video_height, f_min_video_height)];
}
b_nonembedded = YES;
@ -800,28 +795,15 @@ static VLCMainWindow *_o_sharedInstance = nil;
o_new_video_window = self;
b_nonembedded = NO;
} else {
if (!o_detached_video_window) {
NSWindowController *o_controller = [[NSWindowController alloc] initWithWindowNibName:@"DetachedVideoWindow"];
[o_controller loadWindow];
o_detached_video_window = [(VLCDetachedVideoWindow *)[o_controller window] retain];
[o_controller release];
NSWindowController *o_controller = [[NSWindowController alloc] initWithWindowNibName:@"DetachedVideoWindow"];
[o_controller loadWindow];
o_new_video_window = [(VLCDetachedVideoWindow *)[o_controller window] retain];
[o_controller release];
// event occurs before window is created, so call again
[[VLCMain sharedInstance] playbackStatusUpdated];
}
[o_detached_video_window setDelegate: self];
if (b_dark_interface) {
[o_detached_video_window setContentMinSize: NSMakeSize(363., f_min_video_height + [[[o_detached_video_window controlsBar] bottomBarView] frame].size.height + [o_titlebar_view frame].size.height)];
} else {
[o_detached_video_window setContentMinSize: NSMakeSize(363., f_min_video_height + [[[o_detached_video_window controlsBar] bottomBarView] frame].size.height)];
}
[o_detached_video_window setLevel:NSNormalWindowLevel];
[o_detached_video_window useOptimizedDrawing: YES];
o_vout_view = [[o_detached_video_window videoView] retain];
o_new_video_window = o_detached_video_window;
[o_new_video_window setDelegate: self];
[o_new_video_window setLevel:NSNormalWindowLevel];
[o_new_video_window useOptimizedDrawing: YES];
o_vout_view = [[o_new_video_window videoView] retain];
b_nonembedded = YES;
}
}
@ -840,6 +822,12 @@ static VLCMainWindow *_o_sharedInstance = nil;
}
[o_new_video_window setAlphaValue: config_GetFloat(VLCIntf, "macosx-opaqueness")];
[[[VLCMain sharedInstance] voutController] addVout:o_new_video_window forDisplay:p_wnd];
if(b_nonembedded) {
// event occurs before window is created, so call again
[[VLCMain sharedInstance] playbackStatusUpdated];
}
return [o_vout_view autorelease];
}
@ -858,15 +846,9 @@ static VLCMainWindow *_o_sharedInstance = nil;
[[self animator] setFrame:frameBeforePlayback display:YES];
[self makeFirstResponder: nil];
if (o_detached_video_window)
[o_detached_video_window orderOut: nil];
if (o_extra_video_window)
[o_extra_video_window orderOut: nil];
if ([self level] != NSNormalWindowLevel)
[self setLevel: NSNormalWindowLevel];
if (o_detached_video_window && [o_detached_video_window level] != NSNormalWindowLevel)
[o_detached_video_window setLevel: NSNormalWindowLevel];
// restore alpha value to 1 for the case that macosx-opaqueness is set to < 1
[self setAlphaValue:1.0];
@ -1020,8 +1002,8 @@ static VLCMainWindow *_o_sharedInstance = nil;
screen_rect = [screen frame];
[o_controls_bar setFullscreenState:YES];
if (o_detached_video_window)
[[o_detached_video_window controlsBar] setFullscreenState:YES];
//if (o_detached_video_window)
// [[o_detached_video_window controlsBar] setFullscreenState:YES];
[self recreateHideMouseTimer];
@ -1178,8 +1160,8 @@ static VLCMainWindow *_o_sharedInstance = nil;
[self lockFullscreenAnimation];
[o_controls_bar setFullscreenState:NO];
if (o_detached_video_window)
[[o_detached_video_window controlsBar] setFullscreenState:NO];
//if (o_detached_video_window)
// [[o_detached_video_window controlsBar] setFullscreenState:NO];
/* We always try to do so */
[NSScreen unblackoutScreens];
@ -1886,6 +1868,12 @@ static VLCMainWindow *_o_sharedInstance = nil;
videoViewRect.size.height -= f_bottomBarHeight;
videoViewRect.origin.y = f_bottomBarHeight;
[o_video_view setFrame: videoViewRect];
if (b_dark_interface) {
[self setContentMinSize: NSMakeSize(363., f_min_video_height + [[[self controlsBar] bottomBarView] frame].size.height + [o_titlebar_view frame].size.height)];
} else {
[self setContentMinSize: NSMakeSize(363., f_min_video_height + [[[self controlsBar] bottomBarView] frame].size.height)];
}
}
@end

View File

@ -84,4 +84,6 @@ SOURCES_macosx = \
Windows.m \
ControlsBar.m \
ControlsBar.h \
VLCVoutWindowController.m \
VLCVoutWindowController.h \
$(NULL)

View File

@ -0,0 +1,43 @@
/*****************************************************************************
* VLCVoutWindowController.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2012 VLC authors and VideoLAN
* $Id$
*
* Authors: 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "CompatibilityFixes.h"
#import <vlc_vout_window.h>
@class VLCVideoWindowCommon;
@interface VLCVoutWindowController : NSObject
{
NSMutableDictionary *o_vout_dict;
}
- (void)addVout:(VLCVideoWindowCommon *)o_window forDisplay:(vout_window_t *)p_wnd;
- (void)removeVoutforDisplay:(NSValue *)o_key;
- (void)updateWindowsControlsBarWithSelector:(SEL)aSel;
- (void)updateWindowsUsingBlock:(void (^)(VLCVideoWindowCommon *o_window))windowUpdater;
@end

View File

@ -0,0 +1,75 @@
/*****************************************************************************
* VLCVoutWindowController.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2012 VLC authors and VideoLAN
* $Id$
*
* Authors: 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCVoutWindowController.h"
#import "Windows.h"
@implementation VLCVoutWindowController
- (id)init
{
self = [super init];
o_vout_dict = [[NSMutableDictionary alloc] init];
return self;
}
- (void)dealloc
{
[o_vout_dict release];
[super dealloc];
}
- (void)addVout:(VLCVideoWindowCommon *)o_window forDisplay:(vout_window_t *)p_wnd
{
[o_vout_dict setObject:o_window forKey:[NSValue valueWithPointer:p_wnd]];
}
- (void)removeVoutforDisplay:(NSValue *)o_key
{
VLCVideoWindowCommon *o_window = [o_vout_dict objectForKey:o_key];
if (![NSStringFromClass([o_window class]) isEqualToString:@"VLCMainWindow"]) {
[o_window orderOut:self];
}
[o_vout_dict removeObjectForKey:o_key];
}
- (void)updateWindowsControlsBarWithSelector:(SEL)aSel
{
[o_vout_dict enumerateKeysAndObjectsUsingBlock:^(id key, VLCVideoWindowCommon *o_window, BOOL *stop) {
id o_controlsBar = [o_window controlsBar];
if (o_controlsBar)
[o_controlsBar performSelector:aSel];
}];
}
- (void)updateWindowsUsingBlock:(void (^)(VLCVideoWindowCommon *o_window))windowUpdater
{
[o_vout_dict enumerateKeysAndObjectsUsingBlock:^(id key, VLCVideoWindowCommon *o_window, BOOL *stop) {
windowUpdater(o_window);
}];
}
@end

View File

@ -77,6 +77,8 @@ struct intf_sys_t
@class VLCEmbeddedWindow;
@class VLCControls;
@class VLCPlaylist;
@class VLCVoutWindowController;
@interface VLCMain : NSObject <NSWindowDelegate, NSApplicationDelegate>
{
intf_thread_t *p_intf; /* The main intf object */
@ -141,8 +143,12 @@ struct intf_sys_t
/* sleep management */
IOPMAssertionID systemSleepAssertionID;
VLCVoutWindowController *o_vout_controller;
}
@property (readonly) VLCVoutWindowController* voutController;
+ (VLCMain *)sharedInstance;
- (intf_thread_t *)intf;

View File

@ -62,6 +62,7 @@
#import "simple_prefs.h"
#import "CoreInteraction.h"
#import "TrackSynchronization.h"
#import "VLCVoutWindowController.h"
#import <AddressBook/AddressBook.h> /* for crashlog send mechanism */
#import <Sparkle/Sparkle.h> /* we're the update delegate */
@ -141,6 +142,7 @@ int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
int i_y = cfg->y;
unsigned i_width = cfg->width;
unsigned i_height = cfg->height;
NSLog(@"window open with x%i, y %i, wi %i, hei %i", i_x, i_y, i_width, i_height);
p_wnd->handle.nsobject = [[VLCMain sharedInstance] getVideoViewAtPositionX: &i_x Y: &i_y withWidth: &i_width andHeight: &i_height forWindow: p_wnd];
if (!p_wnd->handle.nsobject) {
@ -192,6 +194,8 @@ void WindowClose(vout_window_t *p_wnd)
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
[[VLCMain sharedInstance] setActiveVideoPlayback:NO];
[[[VLCMain sharedInstance] voutController] performSelectorOnMainThread:@selector(removeVoutforDisplay:) withObject:[NSValue valueWithPointer:p_wnd] waitUntilDone:NO];
[o_pool release];
}
@ -498,6 +502,8 @@ audio_output_t *getAout(void)
*****************************************************************************/
@implementation VLCMain
@synthesize voutController=o_vout_controller;
#pragma mark -
#pragma mark Initialization
@ -540,9 +546,17 @@ static VLCMain *_o_sharedMainInstance = nil;
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"LiveUpdateTheMessagesPanel"];
[defaults registerDefaults:appDefaults];
o_vout_controller = [[VLCVoutWindowController alloc] init];
return _o_sharedMainInstance;
}
- (void)dealloc
{
[o_vout_controller release];
[super dealloc];
}
- (void)setIntf: (intf_thread_t *)p_mainintf
{
p_intf = p_mainintf;