WebKit Bugzilla
Attachment 359550 Details for
Bug 193586
: Revert r238815, it broke WK1 video fullscreen on Mac
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Rabased patch for landing
bug-193586-20190118155544.patch (text/plain), 62.37 KB, created by
Eric Carlson
on 2019-01-18 15:55:48 PST
(
hide
)
Description:
Rabased patch for landing
Filename:
MIME Type:
Creator:
Eric Carlson
Created:
2019-01-18 15:55:48 PST
Size:
62.37 KB
patch
obsolete
>Subversion Revision: 240185 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index c3a928c7b7959c3f21a0ebfe4ca39d5bf86dbcd0..46f0fc79bcd196edf081994f59e7fafad4d060e7 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,15 @@ >+2019-01-18 Eric Carlson <eric.carlson@apple.com> >+ >+ Revert r238815, it broke WK1 video fullscreen on Mac >+ https://bugs.webkit.org/show_bug.cgi?id=193586 >+ <rdar://problem/47358941> >+ >+ Reviewed by Jer Noble. >+ >+ * PlatformMac.cmake: >+ * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp: >+ (WebCore::MediaPlayerPrivateAVFoundation::supportsFullscreen const): >+ > 2019-01-18 Daniel Bates <dabates@apple.com> > > Another attempt to fix the iOS build following <https://trac.webkit.org/changeset/240174> >diff --git a/Source/WebKitLegacy/ChangeLog b/Source/WebKitLegacy/ChangeLog >index 0256b9cde3d9ab5a2aedde27a224dae709395b7f..1b4bbf75863c3607a0234e8e4fec0fa11c94aced 100644 >--- a/Source/WebKitLegacy/ChangeLog >+++ b/Source/WebKitLegacy/ChangeLog >@@ -1,3 +1,13 @@ >+2019-01-18 Eric Carlson <eric.carlson@apple.com> >+ >+ Revert r238815, it broke WK1 video fullscreen on Mac >+ https://bugs.webkit.org/show_bug.cgi?id=193586 >+ <rdar://problem/47358941> >+ >+ Reviewed by Jer Noble. >+ >+ * WebKitLegacy.xcodeproj/project.pbxproj: >+ > 2019-01-17 Alex Christensen <achristensen@webkit.org> > > Stop using NetworkStorageSession::storageSession in WebCore >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index 282261cb8858360a34a6ff2ffc31df4b01c452b9..1e064fec7bcb0dab0743c3d52cabf1fe3c923b43 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,107 @@ >+2019-01-18 Eric Carlson <eric.carlson@apple.com> >+ >+ Revert r238815, it broke WK1 video fullscreen on Mac >+ https://bugs.webkit.org/show_bug.cgi?id=193586 >+ <rdar://problem/47358941> >+ >+ Reviewed by Jer Noble. >+ >+ * WebView/WebVideoFullscreenController.h: Added. >+ * WebView/WebVideoFullscreenController.mm: Added. >+ (SOFT_LINK_CLASS): >+ (-[WebVideoFullscreenController init]): >+ (-[WebVideoFullscreenController dealloc]): >+ (-[WebVideoFullscreenController fullscreenWindow]): >+ (-[WebVideoFullscreenController windowDidLoad]): >+ (-[WebVideoFullscreenController videoElement]): >+ (-[WebVideoFullscreenController setVideoElement:]): >+ (-[WebVideoFullscreenController clearFadeAnimation]): >+ (-[WebVideoFullscreenController windowDidExitFullscreen]): >+ (-[WebVideoFullscreenController windowDidEnterFullscreen]): >+ (-[WebVideoFullscreenController videoElementRect]): >+ (-[WebVideoFullscreenController applicationDidResignActive:]): >+ (frameExpandedToRatioOfFrame): >+ (createBackgroundFullscreenWindow): >+ (-[WebVideoFullscreenController setupFadeAnimationIfNeededAndFadeIn:]): >+ (-[WebVideoFullscreenController enterFullscreen:]): >+ (-[WebVideoFullscreenController exitFullscreen]): >+ (-[WebVideoFullscreenController applicationDidChangeScreenParameters:]): >+ (-[WebVideoFullscreenController updateMenuAndDockForFullscreen]): >+ (-[WebVideoFullscreenController _requestExit]): >+ (-[WebVideoFullscreenController requestExitFullscreenWithAnimation:]): >+ (-[WebVideoFullscreenController requestExitFullscreen]): >+ (-[WebVideoFullscreenController fadeHUDIn]): >+ (-[WebVideoFullscreenController observeValueForKeyPath:ofObject:change:context:]): >+ (-[WebVideoFullscreenController rateChanged:]): >+ (-[WebVideoFullscreenWindow initWithContentRect:styleMask:backing:defer:]): >+ (-[WebVideoFullscreenWindow dealloc]): >+ (-[WebVideoFullscreenWindow resignFirstResponder]): >+ (-[WebVideoFullscreenWindow canBecomeKeyWindow]): >+ (-[WebVideoFullscreenWindow mouseDown:]): >+ (-[WebVideoFullscreenWindow cancelOperation:]): >+ (-[WebVideoFullscreenWindow animatedResizeDidEnd]): >+ (-[WebVideoFullscreenWindow animateFromRect:toRect:withSubAnimation:controllerAction:]): >+ (-[WebVideoFullscreenWindow animationDidEnd:]): >+ (-[WebVideoFullscreenWindow mouseMoved:]): >+ * WebView/WebVideoFullscreenHUDWindowController.h: Added. >+ * WebView/WebVideoFullscreenHUDWindowController.mm: Added. >+ (-[WebVideoFullscreenHUDWindow initWithContentRect:styleMask:backing:defer:]): >+ (-[WebVideoFullscreenHUDWindow canBecomeKeyWindow]): >+ (-[WebVideoFullscreenHUDWindow cancelOperation:]): >+ (-[WebVideoFullscreenHUDWindow center]): >+ (-[WebVideoFullscreenHUDWindow keyDown:]): >+ (-[WebVideoFullscreenHUDWindow resignFirstResponder]): >+ (-[WebVideoFullscreenHUDWindow performKeyEquivalent:]): >+ (-[WebVideoFullscreenHUDWindowController init]): >+ (-[WebVideoFullscreenHUDWindowController dealloc]): >+ (-[WebVideoFullscreenHUDWindowController setArea:]): >+ (-[WebVideoFullscreenHUDWindowController keyDown:]): >+ (-[WebVideoFullscreenHUDWindowController delegate]): >+ (-[WebVideoFullscreenHUDWindowController setDelegate:]): >+ (-[WebVideoFullscreenHUDWindowController scheduleTimeUpdate]): >+ (-[WebVideoFullscreenHUDWindowController unscheduleTimeUpdate]): >+ (-[WebVideoFullscreenHUDWindowController fadeWindowIn]): >+ (-[WebVideoFullscreenHUDWindowController fadeWindowOut]): >+ (-[WebVideoFullscreenHUDWindowController closeWindow]): >+ (createMediaUIControl): >+ (createControlWithMediaUIControlType): >+ (createTimeTextField): >+ (createMediaUIBackgroundView): >+ (-[WebVideoFullscreenHUDWindowController windowDidLoad]): >+ (-[WebVideoFullscreenHUDWindowController updateVolume]): >+ (-[WebVideoFullscreenHUDWindowController updateTime]): >+ (-[WebVideoFullscreenHUDWindowController endScrubbing]): >+ (-[WebVideoFullscreenHUDWindowController timelinePositionChanged:]): >+ (-[WebVideoFullscreenHUDWindowController currentTime]): >+ (-[WebVideoFullscreenHUDWindowController setCurrentTime:]): >+ (-[WebVideoFullscreenHUDWindowController duration]): >+ (-[WebVideoFullscreenHUDWindowController maxVolume]): >+ (-[WebVideoFullscreenHUDWindowController volumeChanged:]): >+ (-[WebVideoFullscreenHUDWindowController setVolumeToZero:]): >+ (-[WebVideoFullscreenHUDWindowController setVolumeToMaximum:]): >+ (-[WebVideoFullscreenHUDWindowController decrementVolume]): >+ (-[WebVideoFullscreenHUDWindowController incrementVolume]): >+ (-[WebVideoFullscreenHUDWindowController volume]): >+ (-[WebVideoFullscreenHUDWindowController setVolume:]): >+ (-[WebVideoFullscreenHUDWindowController updatePlayButton]): >+ (-[WebVideoFullscreenHUDWindowController updateRate]): >+ (-[WebVideoFullscreenHUDWindowController togglePlaying:]): >+ (-[WebVideoFullscreenHUDWindowController playing]): >+ (-[WebVideoFullscreenHUDWindowController setPlaying:]): >+ (timeToString): >+ (-[WebVideoFullscreenHUDWindowController remainingTimeText]): >+ (-[WebVideoFullscreenHUDWindowController elapsedTimeText]): >+ (-[WebVideoFullscreenHUDWindowController mouseEntered:]): >+ (-[WebVideoFullscreenHUDWindowController mouseExited:]): >+ (-[WebVideoFullscreenHUDWindowController rewind:]): >+ (-[WebVideoFullscreenHUDWindowController fastForward:]): >+ (-[WebVideoFullscreenHUDWindowController exitFullscreen:]): >+ (-[WebVideoFullscreenHUDWindowController windowDidExpose:]): >+ (-[WebVideoFullscreenHUDWindowController windowDidClose:]): >+ * WebView/WebView.mm: >+ (-[WebView _enterVideoFullscreenForVideoElement:mode:]): >+ (-[WebView _exitVideoFullscreen]): >+ > 2019-01-18 Tim Horton <timothy_horton@apple.com> > > Get rid of ADVANCED_SPELL_CHECKING >diff --git a/Source/WebCore/PlatformMac.cmake b/Source/WebCore/PlatformMac.cmake >index 8dd999e2081f97b334236f3f30d085bb5d05d484..866ea6a54b9a42f878d4e19b650a2c3c3ba209a9 100644 >--- a/Source/WebCore/PlatformMac.cmake >+++ b/Source/WebCore/PlatformMac.cmake >@@ -381,6 +381,8 @@ list(APPEND WebCore_SOURCES > platform/mac/WebCoreObjCExtras.mm > platform/mac/WebGLBlacklist.mm > platform/mac/WebNSAttributedStringExtras.mm >+ platform/mac/WebVideoFullscreenController.mm >+ platform/mac/WebVideoFullscreenHUDWindowController.mm > platform/mac/WidgetMac.mm > > platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >diff --git a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp >index 31030737bbfaccdca67f9c5d98f459b9a86d0db3..28992314ec9c90edf8c5333ab106cadc46f6a455 100644 >--- a/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp >+++ b/Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp >@@ -458,11 +458,14 @@ bool MediaPlayerPrivateAVFoundation::supportsFullscreen() const > { > #if ENABLE(FULLSCREEN_API) > return true; >-#elif PLATFORM(IOS_FAMILY) >+#else >+ // FIXME: WebVideoFullscreenController assumes a QTKit/QuickTime media engine >+#if PLATFORM(IOS_FAMILY) > if (DeprecatedGlobalSettings::avKitEnabled()) > return true; > #endif > return false; >+#endif > } > > bool MediaPlayerPrivateAVFoundation::hasSingleSecurityOrigin() const >diff --git a/Source/WebKitLegacy/WebKitLegacy.xcodeproj/project.pbxproj b/Source/WebKitLegacy/WebKitLegacy.xcodeproj/project.pbxproj >index f2090044fc47994a5b6d41c7e5aa7c3d7ac05edf..b3ca2f81973fd42665facbde62115fa7aef1d5d3 100644 >--- a/Source/WebKitLegacy/WebKitLegacy.xcodeproj/project.pbxproj >+++ b/Source/WebKitLegacy/WebKitLegacy.xcodeproj/project.pbxproj >@@ -775,6 +775,8 @@ > C0C5B3EF1177A4A0002B0AEF /* WebUserContentURLPattern.mm in Sources */ = {isa = PBXBuildFile; fileRef = C0C5B3ED1177A4A0002B0AEF /* WebUserContentURLPattern.mm */; }; > C11EBF4121419CCE00D659E7 /* WebSwitchingGPUClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C11EBF3F21419CCE00D659E7 /* WebSwitchingGPUClient.cpp */; }; > C11EBF4221419CCE00D659E7 /* WebSwitchingGPUClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C11EBF4021419CCE00D659E7 /* WebSwitchingGPUClient.h */; }; >+ C1D81128202CD80000EE74F9 /* WebVideoFullscreenController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C1D81127202CD80000EE74F9 /* WebVideoFullscreenController.mm */; }; >+ C1D8112B202CDCC400EE74F9 /* WebVideoFullscreenHUDWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = C1D81129202CDCC200EE74F9 /* WebVideoFullscreenHUDWindowController.mm */; }; > C1D8112E202CED0800EE74F9 /* WebWindowAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = C1D8112D202CED0700EE74F9 /* WebWindowAnimation.mm */; }; > CD8BFCE715531224005AFB25 /* WebKitFullScreenListener.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD8BFCE515531224005AFB25 /* WebKitFullScreenListener.mm */; }; > CD8BFCE815531224005AFB25 /* WebKitFullScreenListener.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8BFCE615531224005AFB25 /* WebKitFullScreenListener.h */; }; >@@ -1530,6 +1532,10 @@ > C0C5B3ED1177A4A0002B0AEF /* WebUserContentURLPattern.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebUserContentURLPattern.mm; sourceTree = "<group>"; }; > C11EBF3F21419CCE00D659E7 /* WebSwitchingGPUClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebSwitchingGPUClient.cpp; sourceTree = "<group>"; }; > C11EBF4021419CCE00D659E7 /* WebSwitchingGPUClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebSwitchingGPUClient.h; sourceTree = "<group>"; }; >+ C1D81126202CD7FE00EE74F9 /* WebVideoFullscreenController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVideoFullscreenController.h; sourceTree = "<group>"; }; >+ C1D81127202CD80000EE74F9 /* WebVideoFullscreenController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebVideoFullscreenController.mm; sourceTree = "<group>"; }; >+ C1D81129202CDCC200EE74F9 /* WebVideoFullscreenHUDWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebVideoFullscreenHUDWindowController.mm; sourceTree = "<group>"; }; >+ C1D8112A202CDCC300EE74F9 /* WebVideoFullscreenHUDWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVideoFullscreenHUDWindowController.h; sourceTree = "<group>"; }; > C1D8112C202CED0600EE74F9 /* WebWindowAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebWindowAnimation.h; sourceTree = "<group>"; }; > C1D8112D202CED0700EE74F9 /* WebWindowAnimation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebWindowAnimation.mm; sourceTree = "<group>"; }; > CD8BFCE515531224005AFB25 /* WebKitFullScreenListener.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebKitFullScreenListener.mm; sourceTree = "<group>"; }; >@@ -2079,6 +2085,10 @@ > F834AAD60E64B1C700E2737C /* WebTextIterator.mm */, > 515E27CC0458C86500CA2D3A /* WebUIDelegate.h */, > 65A7D44A0568AB2600E70EF6 /* WebUIDelegatePrivate.h */, >+ C1D81126202CD7FE00EE74F9 /* WebVideoFullscreenController.h */, >+ C1D81127202CD80000EE74F9 /* WebVideoFullscreenController.mm */, >+ C1D8112A202CDCC300EE74F9 /* WebVideoFullscreenHUDWindowController.h */, >+ C1D81129202CDCC200EE74F9 /* WebVideoFullscreenHUDWindowController.mm */, > 51A8B579042834F700CA2D3A /* WebView.h */, > 51A8B57A042834F700CA2D3A /* WebView.mm */, > BC2E464B0FD8A96800A9D9DE /* WebViewData.h */, >@@ -3234,6 +3244,7 @@ > Spanish, > Dutch, > Italian, >+ en, > ); > mainGroup = 0867D691FE84028FC02AAC07 /* WebKit */; > productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; >@@ -3683,6 +3694,8 @@ > 939810BE0824BF01008DF038 /* WebURLsWithTitles.m in Sources */, > C0C5B3EF1177A4A0002B0AEF /* WebUserContentURLPattern.mm in Sources */, > 4618DFF91DEF760A0033C3AA /* WebValidationMessageClient.mm in Sources */, >+ C1D81128202CD80000EE74F9 /* WebVideoFullscreenController.mm in Sources */, >+ C1D8112B202CDCC400EE74F9 /* WebVideoFullscreenHUDWindowController.mm in Sources */, > 939811070824BF01008DF038 /* WebView.mm in Sources */, > BC2E464E0FD8A96800A9D9DE /* WebViewData.mm in Sources */, > 1430C12C1B2C5DF700DEA01D /* WebViewGroup.cpp in Sources */, >diff --git a/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.h b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f57578bfc00264e4f41b5ee9f688a26c28ad44a2 >--- /dev/null >+++ b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.h >@@ -0,0 +1,58 @@ >+/* >+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#if PLATFORM(MAC) && ENABLE(VIDEO) >+ >+#import <AppKit/NSWindowController.h> >+#import <wtf/RefPtr.h> >+ >+namespace WebCore { >+class HTMLVideoElement; >+} >+ >+@class WebVideoFullscreenHUDWindowController; >+@class WebWindowFadeAnimation; >+ >+@interface WebVideoFullscreenController : NSWindowController { >+ RefPtr<WebCore::HTMLVideoElement> _videoElement; >+ >+ NSWindow *_backgroundFullscreenWindow; // (retain) >+ WebVideoFullscreenHUDWindowController *_hudController; // (retain) >+ >+ WebWindowFadeAnimation *_fadeAnimation; // (retain) >+ >+ BOOL _isEndingFullscreen; >+ BOOL _forceDisableAnimation; >+} >+ >+- (void)setVideoElement:(WebCore::HTMLVideoElement *)videoElement; >+- (WebCore::HTMLVideoElement *)videoElement; >+ >+- (void)enterFullscreen:(NSScreen *)screen; >+- (void)exitFullscreen; >+ >+@end >+ >+#endif >diff --git a/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.mm b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..c6e07164caf05ca4819e30a786dcc8ad83d60533 >--- /dev/null >+++ b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.mm >@@ -0,0 +1,513 @@ >+/* >+ * Copyright (C) 2009-2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#import "WebVideoFullscreenController.h" >+ >+#if ENABLE(VIDEO) && PLATFORM(MAC) >+ >+#import "WebVideoFullscreenHUDWindowController.h" >+#import "WebWindowAnimation.h" >+#import <AVFoundation/AVPlayer.h> >+#import <AVFoundation/AVPlayerLayer.h> >+#import <Carbon/Carbon.h> >+#import <WebCore/HTMLVideoElement.h> >+#import <objc/runtime.h> >+#import <pal/system/SleepDisabler.h> >+#import <wtf/RetainPtr.h> >+#import <wtf/SoftLinking.h> >+ >+ALLOW_DEPRECATED_DECLARATIONS_BEGIN >+ >+SOFT_LINK_FRAMEWORK(AVFoundation) >+SOFT_LINK_CLASS(AVFoundation, AVPlayerLayer) >+ >+@interface WebVideoFullscreenWindow : NSWindow<NSAnimationDelegate> { >+ SEL _controllerActionOnAnimationEnd; >+ WebWindowScaleAnimation *_fullscreenAnimation; // (retain) >+} >+- (void)animateFromRect:(NSRect)startRect toRect:(NSRect)endRect withSubAnimation:(NSAnimation *)subAnimation controllerAction:(SEL)controllerAction; >+@end >+ >+@interface WebVideoFullscreenController () <WebVideoFullscreenHUDWindowControllerDelegate> >+@end >+ >+@implementation WebVideoFullscreenController >+ >+- (id)init >+{ >+ // Do not defer window creation, to make sure -windowNumber is created (needed by WebWindowScaleAnimation). >+ NSWindow *window = [[WebVideoFullscreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; >+ self = [super initWithWindow:window]; >+ [window release]; >+ if (!self) >+ return nil; >+ [self windowDidLoad]; >+ return self; >+ >+} >+- (void)dealloc >+{ >+ ASSERT(!_backgroundFullscreenWindow); >+ ASSERT(!_fadeAnimation); >+ [[NSNotificationCenter defaultCenter] removeObserver:self]; >+ [super dealloc]; >+} >+ >+- (WebVideoFullscreenWindow *)fullscreenWindow >+{ >+ return (WebVideoFullscreenWindow *)[super window]; >+} >+ >+- (void)windowDidLoad >+{ >+ auto window = [self fullscreenWindow]; >+ auto contentView = [window contentView]; >+ >+ [window setHasShadow:YES]; // This is nicer with a shadow. >+ [window setLevel:NSPopUpMenuWindowLevel-1]; >+ >+ [contentView setLayer:[CALayer layer]]; >+ [contentView setWantsLayer:YES]; >+ >+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:NSApp]; >+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeScreenParameters:) name:NSApplicationDidChangeScreenParametersNotification object:NSApp]; >+} >+ >+- (WebCore::HTMLVideoElement *)videoElement >+{ >+ return _videoElement.get(); >+} >+ >+// FIXME: This method is not really a setter. The caller relies on its side effects, and it's >+// called once each time we enter full screen. So it should have a different name. >+- (void)setVideoElement:(WebCore::HTMLVideoElement *)videoElement >+{ >+ ASSERT(videoElement); >+ _videoElement = videoElement; >+ >+ if (![self isWindowLoaded]) >+ return; >+ auto corePlayer = videoElement->player(); >+ if (!corePlayer) >+ return; >+ auto player = corePlayer->objCAVFoundationAVPlayer(); >+ if (!player) >+ return; >+ >+ auto contentView = [[self fullscreenWindow] contentView]; >+ >+ auto layer = adoptNS([allocAVPlayerLayerInstance() init]); >+ [layer setPlayer:player]; >+ >+ [contentView setLayer:layer.get()]; >+ >+ // FIXME: The windowDidLoad method already called this, so it should >+ // not be necessary to do it again here. >+ [contentView setWantsLayer:YES]; >+ >+ // FIXME: This can be called multiple times, and won't necessarily be >+ // balanced by calls to windowDidExitFullscreen in some cases, so it >+ // would be better to change things so the observer is reliably added >+ // only once and guaranteed removed even in unusual edge cases. >+ [player addObserver:self forKeyPath:@"rate" options:0 context:nullptr]; >+} >+ >+- (CGFloat)clearFadeAnimation >+{ >+ [_fadeAnimation stopAnimation]; >+ CGFloat previousAlpha = [_fadeAnimation currentAlpha]; >+ [_fadeAnimation setWindow:nil]; >+ [_fadeAnimation release]; >+ _fadeAnimation = nil; >+ return previousAlpha; >+} >+ >+- (void)windowDidExitFullscreen >+{ >+ CALayer *layer = [[[self window] contentView] layer]; >+ if ([layer isKindOfClass:getAVPlayerLayerClass()]) >+ [[(AVPlayerLayer *)layer player] removeObserver:self forKeyPath:@"rate"]; >+ >+ [self clearFadeAnimation]; >+ [[self window] close]; >+ [self setWindow:nil]; >+ [self updateMenuAndDockForFullscreen]; >+ [_hudController setDelegate:nil]; >+ [_hudController release]; >+ _hudController = nil; >+ [_backgroundFullscreenWindow close]; >+ [_backgroundFullscreenWindow release]; >+ _backgroundFullscreenWindow = nil; >+ >+ [self autorelease]; // Associated -retain is in -exitFullscreen. >+ _isEndingFullscreen = NO; >+} >+ >+- (void)windowDidEnterFullscreen >+{ >+ [self clearFadeAnimation]; >+ >+ ASSERT(!_hudController); >+ _hudController = [[WebVideoFullscreenHUDWindowController alloc] init]; >+ [_hudController setDelegate:self]; >+ >+ [self updateMenuAndDockForFullscreen]; >+ [NSCursor setHiddenUntilMouseMoves:YES]; >+ >+ // Give the HUD keyboard focus initially >+ [_hudController fadeWindowIn]; >+} >+ >+- (NSRect)videoElementRect >+{ >+ return _videoElement->screenRect(); >+} >+ >+- (void)applicationDidResignActive:(NSNotification*)notification >+{ >+ UNUSED_PARAM(notification); >+ NSWindow* fullscreenWindow = [self fullscreenWindow]; >+ >+ // Replicate the QuickTime Player (X) behavior when losing active application status: >+ // Is the fullscreen screen the main screen? (Note: this covers the case where only a >+ // single screen is available.) Is the fullscreen screen on the current space? IFF so, >+ // then exit fullscreen mode. >+ if (fullscreenWindow.screen == [NSScreen screens][0] && fullscreenWindow.onActiveSpace) >+ [self requestExitFullscreenWithAnimation:NO]; >+} >+ >+ >+// MARK: - >+// MARK: Exposed Interface >+ >+static NSRect frameExpandedToRatioOfFrame(NSRect frameToExpand, NSRect frame) >+{ >+ // Keep a constrained aspect ratio for the destination window >+ NSRect result = frameToExpand; >+ CGFloat newRatio = frame.size.width / frame.size.height; >+ CGFloat originalRatio = frameToExpand.size.width / frameToExpand.size.height; >+ if (newRatio > originalRatio) { >+ CGFloat newWidth = newRatio * frameToExpand.size.height; >+ CGFloat diff = newWidth - frameToExpand.size.width; >+ result.size.width = newWidth; >+ result.origin.x -= diff / 2; >+ } else { >+ CGFloat newHeight = frameToExpand.size.width / newRatio; >+ CGFloat diff = newHeight - frameToExpand.size.height; >+ result.size.height = newHeight; >+ result.origin.y -= diff / 2; >+ } >+ return result; >+} >+ >+static NSWindow *createBackgroundFullscreenWindow(NSRect frame, int level) >+{ >+ NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; >+ [window setOpaque:YES]; >+ [window setBackgroundColor:[NSColor blackColor]]; >+ [window setLevel:level]; >+ [window setReleasedWhenClosed:NO]; >+ return window; >+} >+ >+- (void)setupFadeAnimationIfNeededAndFadeIn:(BOOL)fadeIn >+{ >+ CGFloat initialAlpha = fadeIn ? 0 : 1; >+ if (_fadeAnimation) { >+ // Make sure we support queuing animation if the previous one isn't over yet >+ initialAlpha = [self clearFadeAnimation]; >+ } >+ if (!_forceDisableAnimation) >+ _fadeAnimation = [[WebWindowFadeAnimation alloc] initWithDuration:0.2 window:_backgroundFullscreenWindow initialAlpha:initialAlpha finalAlpha:fadeIn ? 1 : 0]; >+} >+ >+- (void)enterFullscreen:(NSScreen *)screen >+{ >+ if (!screen) >+ screen = [NSScreen mainScreen]; >+ >+ NSRect endFrame = [screen frame]; >+ NSRect frame = frameExpandedToRatioOfFrame([self videoElementRect], endFrame); >+ >+ // Create a black window if needed >+ if (!_backgroundFullscreenWindow) >+ _backgroundFullscreenWindow = createBackgroundFullscreenWindow([screen frame], [[self window] level]-1); >+ else >+ [_backgroundFullscreenWindow setFrame:[screen frame] display:NO]; >+ >+ [self setupFadeAnimationIfNeededAndFadeIn:YES]; >+ if (_forceDisableAnimation) { >+ // This will disable scale animation >+ frame = NSZeroRect; >+ } >+ [[self fullscreenWindow] animateFromRect:frame toRect:endFrame withSubAnimation:_fadeAnimation controllerAction:@selector(windowDidEnterFullscreen)]; >+ >+ [_backgroundFullscreenWindow orderWindow:NSWindowBelow relativeTo:[[self fullscreenWindow] windowNumber]]; >+} >+ >+- (void)exitFullscreen >+{ >+ if (_isEndingFullscreen) >+ return; >+ _isEndingFullscreen = YES; >+ [_hudController closeWindow]; >+ >+ NSRect endFrame = [self videoElementRect]; >+ >+ [self setupFadeAnimationIfNeededAndFadeIn:NO]; >+ if (_forceDisableAnimation) { >+ // This will disable scale animation >+ endFrame = NSZeroRect; >+ } >+ >+ // We have to retain ourselves because we want to be alive for the end of the animation. >+ // If our owner releases us we could crash if this is not the case. >+ // Balanced in windowDidExitFullscreen >+ [self retain]; >+ >+ NSRect startFrame = [[self window] frame]; >+ endFrame = frameExpandedToRatioOfFrame(endFrame, startFrame); >+ >+ [[self fullscreenWindow] animateFromRect:startFrame toRect:endFrame withSubAnimation:_fadeAnimation controllerAction:@selector(windowDidExitFullscreen)]; >+} >+ >+- (void)applicationDidChangeScreenParameters:(NSNotification*)notification >+{ >+ UNUSED_PARAM(notification); >+ // The user may have changed the main screen by moving the menu bar, or they may have changed >+ // the Dock's size or location, or they may have changed the fullscreen screen's dimensions. >+ // Update our presentation parameters, and ensure that the full screen window occupies the >+ // entire screen: >+ [self updateMenuAndDockForFullscreen]; >+ [[self window] setFrame:[[[self window] screen] frame] display:YES]; >+} >+ >+- (void)updateMenuAndDockForFullscreen >+{ >+ // NSApplicationPresentationOptions is available on > 10.6 only: >+ NSApplicationPresentationOptions options = NSApplicationPresentationDefault; >+ NSScreen* fullscreenScreen = [[self window] screen]; >+ >+ if (!_isEndingFullscreen) { >+ // Auto-hide the menu bar if the fullscreenScreen contains the menu bar: >+ // NOTE: if the fullscreenScreen contains the menu bar but not the dock, we must still >+ // auto-hide the dock, or an exception will be thrown. >+ if ([[NSScreen screens] objectAtIndex:0] == fullscreenScreen) >+ options |= (NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock); >+ // Check if the current screen contains the dock by comparing the screen's frame to its >+ // visibleFrame; if a dock is present, the visibleFrame will differ. If the current screen >+ // contains the dock, hide it. >+ else if (!NSEqualRects([fullscreenScreen frame], [fullscreenScreen visibleFrame])) >+ options |= NSApplicationPresentationAutoHideDock; >+ } >+ >+ NSApp.presentationOptions = options; >+} >+ >+// MARK: - >+// MARK: Window callback >+ >+- (void)_requestExit >+{ >+ if (_videoElement) >+ _videoElement->exitFullscreen(); >+ _forceDisableAnimation = NO; >+} >+ >+- (void)requestExitFullscreenWithAnimation:(BOOL)animation >+{ >+ if (_isEndingFullscreen) >+ return; >+ >+ _forceDisableAnimation = !animation; >+ [self performSelector:@selector(_requestExit) withObject:nil afterDelay:0]; >+ >+} >+ >+- (void)requestExitFullscreen >+{ >+ [self requestExitFullscreenWithAnimation:YES]; >+} >+ >+- (void)fadeHUDIn >+{ >+ [_hudController fadeWindowIn]; >+} >+ >+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context >+{ >+ UNUSED_PARAM(object); >+ UNUSED_PARAM(change); >+ UNUSED_PARAM(context); >+ >+ if ([keyPath isEqualTo:@"rate"]) >+ [self rateChanged:nil]; >+} >+ >+- (void)rateChanged:(NSNotification *)unusedNotification >+{ >+ UNUSED_PARAM(unusedNotification); >+ [_hudController updateRate]; >+} >+ >+@end >+ >+@implementation WebVideoFullscreenWindow >+ >+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag >+{ >+ UNUSED_PARAM(aStyle); >+ self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag]; >+ if (!self) >+ return nil; >+ [self setOpaque:NO]; >+ [self setBackgroundColor:[NSColor clearColor]]; >+ [self setIgnoresMouseEvents:NO]; >+ [self setAcceptsMouseMovedEvents:YES]; >+ return self; >+} >+ >+- (void)dealloc >+{ >+ ASSERT(!_fullscreenAnimation); >+ [super dealloc]; >+} >+ >+- (BOOL)resignFirstResponder >+{ >+ return NO; >+} >+ >+- (BOOL)canBecomeKeyWindow >+{ >+ return NO; >+} >+ >+- (void)mouseDown:(NSEvent *)event >+{ >+ UNUSED_PARAM(event); >+} >+ >+- (void)cancelOperation:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [[self windowController] requestExitFullscreen]; >+} >+ >+- (void)animatedResizeDidEnd >+{ >+ if (_controllerActionOnAnimationEnd) >+ [[self windowController] performSelector:_controllerActionOnAnimationEnd]; >+ _controllerActionOnAnimationEnd = NULL; >+} >+ >+// >+// This function will animate a change of frame rectangle >+// We support queuing animation, that means that we'll correctly >+// interrupt the running animation, and queue the next one. >+// >+- (void)animateFromRect:(NSRect)startRect toRect:(NSRect)endRect withSubAnimation:(NSAnimation *)subAnimation controllerAction:(SEL)controllerAction >+{ >+ _controllerActionOnAnimationEnd = controllerAction; >+ >+ BOOL wasAnimating = NO; >+ if (_fullscreenAnimation) { >+ wasAnimating = YES; >+ >+ // Interrupt any running animation. >+ [_fullscreenAnimation stopAnimation]; >+ >+ // Save the current rect to ensure a smooth transition. >+ startRect = [_fullscreenAnimation currentFrame]; >+ [_fullscreenAnimation release]; >+ _fullscreenAnimation = nil; >+ } >+ >+ if (NSIsEmptyRect(startRect) || NSIsEmptyRect(endRect)) { >+ // Fakely end the subanimation. >+ [subAnimation setCurrentProgress:1]; >+ // And remove the weak link to the window. >+ [subAnimation stopAnimation]; >+ >+ [self setFrame:endRect display:NO]; >+ [self makeKeyAndOrderFront:self]; >+ [self animatedResizeDidEnd]; >+ return; >+ } >+ >+ if (!wasAnimating) { >+ // We'll downscale the window during the animation based on the higher resolution rect >+ BOOL higherResolutionIsEndRect = startRect.size.width < endRect.size.width && startRect.size.height < endRect.size.height; >+ [self setFrame:higherResolutionIsEndRect ? endRect : startRect display:NO]; >+ } >+ >+ ASSERT(!_fullscreenAnimation); >+ _fullscreenAnimation = [[WebWindowScaleAnimation alloc] initWithHintedDuration:0.2 window:self initalFrame:startRect finalFrame:endRect]; >+ [_fullscreenAnimation setSubAnimation:subAnimation]; >+ [_fullscreenAnimation setDelegate:self]; >+ >+ // Make sure the animation has scaled the window before showing it. >+ [_fullscreenAnimation setCurrentProgress:0]; >+ [self makeKeyAndOrderFront:self]; >+ >+ [_fullscreenAnimation startAnimation]; >+} >+ >+- (void)animationDidEnd:(NSAnimation *)animation >+{ >+ if (![NSThread isMainThread]) { >+ [self performSelectorOnMainThread:@selector(animationDidEnd:) withObject:animation waitUntilDone:NO]; >+ return; >+ } >+ if (animation != _fullscreenAnimation) >+ return; >+ >+ // The animation is not really over and was interrupted >+ // Don't send completion events. >+ if ([animation currentProgress] < 1.0) >+ return; >+ >+ // Ensure that animation (and subanimation) don't keep >+ // the weak reference to the window ivar that may be destroyed from >+ // now on. >+ [_fullscreenAnimation setWindow:nil]; >+ >+ [_fullscreenAnimation autorelease]; >+ _fullscreenAnimation = nil; >+ >+ [self animatedResizeDidEnd]; >+} >+ >+- (void)mouseMoved:(NSEvent *)event >+{ >+ UNUSED_PARAM(event); >+ [[self windowController] fadeHUDIn]; >+} >+ >+@end >+ >+ALLOW_DEPRECATED_DECLARATIONS_END >+ >+#endif >diff --git a/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.h b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f67feae1342e6a977c56fb1f5c504421200dd219 >--- /dev/null >+++ b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.h >@@ -0,0 +1,70 @@ >+/* >+ * Copyright (C) 2009 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#if ENABLE(VIDEO) >+ >+#import <AppKit/NSButton.h> >+#import <AppKit/NSControl.h> >+#import <AppKit/NSTextField.h> >+#import <AppKit/NSTrackingArea.h> >+#import <AppKit/NSWindow.h> >+#import <AppKit/NSWindowController.h> >+ >+namespace WebCore { >+class HTMLVideoElement; >+} >+ >+@protocol WebVideoFullscreenHUDWindowControllerDelegate; >+ >+@interface WebVideoFullscreenHUDWindowController : NSWindowController { >+ id <WebVideoFullscreenHUDWindowControllerDelegate> _delegate; >+ NSTimer *_timelineUpdateTimer; >+ NSTrackingArea *_area; >+ BOOL _mouseIsInHUD; >+ BOOL _isEndingFullscreen; >+ BOOL _isScrubbing; >+ >+ NSControl *_timeline; >+ NSTextField *_remainingTimeText; >+ NSTextField *_elapsedTimeText; >+ NSControl *_volumeSlider; >+ NSButton *_playButton; >+} >+ >+- (id <WebVideoFullscreenHUDWindowControllerDelegate>)delegate; >+- (void)setDelegate:(id <WebVideoFullscreenHUDWindowControllerDelegate>)delegate; >+- (void)fadeWindowIn; >+- (void)fadeWindowOut; >+- (void)closeWindow; >+- (void)updateRate; >+ >+@end >+ >+@protocol WebVideoFullscreenHUDWindowControllerDelegate <NSObject> >+- (void)requestExitFullscreen; >+- (WebCore::HTMLVideoElement*)videoElement; >+@end >+ >+#endif >diff --git a/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.mm b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..7c3f506e06d97bfde8ea4cb09560a8c70b123f12 >--- /dev/null >+++ b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.mm >@@ -0,0 +1,730 @@ >+/* >+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#if ENABLE(VIDEO) && PLATFORM(MAC) >+ >+#import "WebVideoFullscreenHUDWindowController.h" >+ >+#import <WebCore/FloatConversion.h> >+#import <WebCore/HTMLVideoElement.h> >+#import <pal/spi/cg/CoreGraphicsSPI.h> >+#import <pal/spi/mac/QTKitSPI.h> >+#import <wtf/SoftLinking.h> >+ >+SOFT_LINK_FRAMEWORK(QTKit) >+ >+SOFT_LINK_CLASS(QTKit, QTHUDBackgroundView) >+SOFT_LINK_CLASS(QTKit, QTHUDButton) >+SOFT_LINK_CLASS(QTKit, QTHUDSlider) >+SOFT_LINK_CLASS(QTKit, QTHUDTimeline) >+ >+#define QTHUDBackgroundView getQTHUDBackgroundViewClass() >+#define QTHUDButton getQTHUDButtonClass() >+#define QTHUDSlider getQTHUDSliderClass() >+#define QTHUDTimeline getQTHUDTimelineClass() >+ >+enum class MediaUIControl { >+ Timeline, >+ Slider, >+ PlayPauseButton, >+ ExitFullscreenButton, >+ RewindButton, >+ FastForwardButton, >+ VolumeUpButton, >+ VolumeDownButton, >+}; >+ >+using WebCore::HTMLVideoElement; >+using WebCore::narrowPrecisionToFloat; >+ >+@interface WebVideoFullscreenHUDWindowController (Private) <NSWindowDelegate> >+ >+- (void)updateTime; >+- (void)timelinePositionChanged:(id)sender; >+- (float)currentTime; >+- (void)setCurrentTime:(float)currentTime; >+- (double)duration; >+ >+- (void)volumeChanged:(id)sender; >+- (float)maxVolume; >+- (float)volume; >+- (void)setVolume:(float)volume; >+- (void)decrementVolume; >+- (void)incrementVolume; >+ >+- (void)updatePlayButton; >+- (void)togglePlaying:(id)sender; >+- (BOOL)playing; >+- (void)setPlaying:(BOOL)playing; >+ >+- (void)rewind:(id)sender; >+- (void)fastForward:(id)sender; >+ >+- (NSString *)remainingTimeText; >+- (NSString *)elapsedTimeText; >+ >+- (void)exitFullscreen:(id)sender; >+@end >+ >+@interface WebVideoFullscreenHUDWindow : NSWindow >+@end >+ >+@implementation WebVideoFullscreenHUDWindow >+ >+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag >+{ >+ UNUSED_PARAM(aStyle); >+ self = [super initWithContentRect:contentRect styleMask:NSWindowStyleMaskBorderless backing:bufferingType defer:flag]; >+ if (!self) >+ return nil; >+ >+ [self setOpaque:NO]; >+ [self setBackgroundColor:[NSColor clearColor]]; >+ [self setLevel:NSPopUpMenuWindowLevel]; >+ [self setAcceptsMouseMovedEvents:YES]; >+ [self setIgnoresMouseEvents:NO]; >+ [self setMovableByWindowBackground:YES]; >+ >+ return self; >+} >+ >+- (BOOL)canBecomeKeyWindow >+{ >+ return YES; >+} >+ >+- (void)cancelOperation:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [[self windowController] exitFullscreen:self]; >+} >+ >+- (void)center >+{ >+ NSRect hudFrame = [self frame]; >+ NSRect screenFrame = [[NSScreen mainScreen] frame]; >+ [self setFrameTopLeftPoint:NSMakePoint(screenFrame.origin.x + (screenFrame.size.width - hudFrame.size.width) / 2, screenFrame.origin.y + (screenFrame.size.height - hudFrame.size.height) / 6)]; >+} >+ >+- (void)keyDown:(NSEvent *)event >+{ >+ [super keyDown:event]; >+ [[self windowController] fadeWindowIn]; >+} >+ >+- (BOOL)resignFirstResponder >+{ >+ return NO; >+} >+ >+- (BOOL)performKeyEquivalent:(NSEvent *)event >+{ >+ // Block all command key events while the fullscreen window is up. >+ if ([event type] != NSEventTypeKeyDown) >+ return NO; >+ >+ if (!([event modifierFlags] & NSEventModifierFlagCommand)) >+ return NO; >+ return YES; >+} >+ >+@end >+ >+static const CGFloat windowHeight = 59; >+static const CGFloat windowWidth = 438; >+ >+static const NSTimeInterval HUDWindowFadeOutDelay = 3; >+ >+@implementation WebVideoFullscreenHUDWindowController >+ >+- (id)init >+{ >+ NSWindow *window = [[WebVideoFullscreenHUDWindow alloc] initWithContentRect:NSMakeRect(0, 0, windowWidth, windowHeight) styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO]; >+ self = [super initWithWindow:window]; >+ [window setDelegate:self]; >+ [window release]; >+ if (!self) >+ return nil; >+ [self windowDidLoad]; >+ return self; >+} >+ >+- (void)dealloc >+{ >+ ASSERT(!_timelineUpdateTimer); >+ ASSERT(!_area); >+ ASSERT(!_isScrubbing); >+ [_timeline release]; >+ [_remainingTimeText release]; >+ [_elapsedTimeText release]; >+ [_volumeSlider release]; >+ [_playButton release]; >+ [super dealloc]; >+} >+ >+- (void)setArea:(NSTrackingArea *)area >+{ >+ if (area == _area) >+ return; >+ [_area release]; >+ _area = [area retain]; >+} >+ >+- (void)keyDown:(NSEvent *)event >+{ >+ NSString *charactersIgnoringModifiers = [event charactersIgnoringModifiers]; >+ if ([charactersIgnoringModifiers length] == 1) { >+ switch ([charactersIgnoringModifiers characterAtIndex:0]) { >+ case ' ': >+ [self togglePlaying:nil]; >+ return; >+ case NSUpArrowFunctionKey: >+ if ([event modifierFlags] & NSEventModifierFlagOption) >+ [self setVolume:[self maxVolume]]; >+ else >+ [self incrementVolume]; >+ return; >+ case NSDownArrowFunctionKey: >+ if ([event modifierFlags] & NSEventModifierFlagOption) >+ [self setVolume:0]; >+ else >+ [self decrementVolume]; >+ return; >+ default: >+ break; >+ } >+ } >+ >+ [super keyDown:event]; >+} >+ >+- (id <WebVideoFullscreenHUDWindowControllerDelegate>)delegate >+{ >+ return _delegate; >+} >+ >+- (void)setDelegate:(id <WebVideoFullscreenHUDWindowControllerDelegate>)delegate >+{ >+ _delegate = delegate; >+} >+ >+- (void)scheduleTimeUpdate >+{ >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(unscheduleTimeUpdate) object:self]; >+ >+ // First, update right away, then schedule future update >+ [self updateTime]; >+ [self updatePlayButton]; >+ >+ [_timelineUpdateTimer invalidate]; >+ [_timelineUpdateTimer release]; >+ >+ // Note that this creates a retain cycle between the window and us. >+ _timelineUpdateTimer = [[NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(updateTime) userInfo:nil repeats:YES] retain]; >+ [[NSRunLoop currentRunLoop] addTimer:_timelineUpdateTimer forMode:NSRunLoopCommonModes]; >+} >+ >+- (void)unscheduleTimeUpdate >+{ >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(unscheduleTimeUpdate) object:nil]; >+ >+ [_timelineUpdateTimer invalidate]; >+ [_timelineUpdateTimer release]; >+ _timelineUpdateTimer = nil; >+} >+ >+- (void)fadeWindowIn >+{ >+ NSWindow *window = [self window]; >+ if (![window isVisible]) >+ [window setAlphaValue:0]; >+ >+ [window makeKeyAndOrderFront:self]; >+ [[window animator] setAlphaValue:1]; >+ [self scheduleTimeUpdate]; >+ >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fadeWindowOut) object:nil]; >+ if (!_mouseIsInHUD && [self playing]) // Don't fade out when paused. >+ [self performSelector:@selector(fadeWindowOut) withObject:nil afterDelay:HUDWindowFadeOutDelay]; >+} >+ >+- (void)fadeWindowOut >+{ >+ [NSCursor setHiddenUntilMouseMoves:YES]; >+ [[[self window] animator] setAlphaValue:0]; >+ [self performSelector:@selector(unscheduleTimeUpdate) withObject:nil afterDelay:1]; >+} >+ >+- (void)closeWindow >+{ >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fadeWindowOut) object:nil]; >+ [self unscheduleTimeUpdate]; >+ NSWindow *window = [self window]; >+ [[window contentView] removeTrackingArea:_area]; >+ [self setArea:nil]; >+ [window close]; >+ [window setDelegate:nil]; >+ [self setWindow:nil]; >+} >+ >+static NSControl *createMediaUIControl(MediaUIControl controlType) >+{ >+ switch (controlType) { >+ case MediaUIControl::Timeline: { >+ NSSlider *slider = [[QTHUDTimeline alloc] init]; >+ [[slider cell] setContinuous:YES]; >+ return slider; >+ } >+ case MediaUIControl::Slider: { >+ NSButton *slider = [[QTHUDSlider alloc] init]; >+ [[slider cell] setContinuous:YES]; >+ return slider; >+ } >+ case MediaUIControl::PlayPauseButton: { >+ NSButton *button = [[QTHUDButton alloc] init]; >+ [button setImage:[NSImage imageNamed:@"NSPlayTemplate"]]; >+ [button setAlternateImage:[NSImage imageNamed:@"NSPauseQTPrivateTemplate"]]; >+ >+ [[button cell] setShowsStateBy:NSContentsCellMask]; >+ [button setBordered:NO]; >+ return button; >+ } >+ case MediaUIControl::ExitFullscreenButton: { >+ NSButton *button = [[QTHUDButton alloc] init]; >+ [button setImage:[NSImage imageNamed:@"NSExitFullScreenTemplate"]]; >+ [button setBordered:NO]; >+ return button; >+ } >+ case MediaUIControl::RewindButton: { >+ NSButton *button = [[QTHUDButton alloc] init]; >+ [button setImage:[NSImage imageNamed:@"NSRewindTemplate"]]; >+ [button setBordered:NO]; >+ return button; >+ } >+ case MediaUIControl::FastForwardButton: { >+ NSButton *button = [[QTHUDButton alloc] init]; >+ [button setImage:[NSImage imageNamed:@"NSFastForwardTemplate"]]; >+ [button setBordered:NO]; >+ return button; >+ } >+ case MediaUIControl::VolumeUpButton: { >+ NSButton *button = [[QTHUDButton alloc] init]; >+ [button setImage:[NSImage imageNamed:@"NSAudioOutputVolumeHighTemplate"]]; >+ [button setBordered:NO]; >+ return button; >+ } >+ case MediaUIControl::VolumeDownButton: { >+ NSButton *button = [[QTHUDButton alloc] init]; >+ [button setImage:[NSImage imageNamed:@"NSAudioOutputVolumeLowTemplate"]]; >+ [button setBordered:NO]; >+ return button; >+ } >+ } >+ >+ ASSERT_NOT_REACHED(); >+ return nil; >+} >+ >+static NSControl *createControlWithMediaUIControlType(MediaUIControl controlType, NSRect frame) >+{ >+ NSControl *control = createMediaUIControl(controlType); >+ control.frame = frame; >+ return control; >+} >+ >+static NSTextField *createTimeTextField(NSRect frame) >+{ >+ NSTextField *textField = [[NSTextField alloc] initWithFrame:frame]; >+ [textField setTextColor:[NSColor whiteColor]]; >+ [textField setBordered:NO]; >+ [textField setFont:[NSFont boldSystemFontOfSize:10]]; >+ [textField setDrawsBackground:NO]; >+ [textField setBezeled:NO]; >+ [textField setEditable:NO]; >+ [textField setSelectable:NO]; >+ return textField; >+} >+ >+static NSView *createMediaUIBackgroundView() >+{ >+ id view = [[QTHUDBackgroundView alloc] init]; >+ >+ const CGFloat quickTimePlayerHUDHeight = 59; >+ const CGFloat quickTimePlayerHUDContentBorderPosition = 38; >+ >+ ALLOW_DEPRECATED_DECLARATIONS_BEGIN >+ [view setContentBorderPosition:quickTimePlayerHUDContentBorderPosition / quickTimePlayerHUDHeight]; >+ ALLOW_DEPRECATED_DECLARATIONS_END >+ >+ return view; >+} >+ >+- (void)windowDidLoad >+{ >+ static const CGFloat horizontalMargin = 10; >+ static const CGFloat playButtonWidth = 41; >+ static const CGFloat playButtonHeight = 35; >+ static const CGFloat playButtonTopMargin = 4; >+ static const CGFloat volumeSliderWidth = 50; >+ static const CGFloat volumeSliderHeight = 13; >+ static const CGFloat volumeButtonWidth = 18; >+ static const CGFloat volumeButtonHeight = 16; >+ static const CGFloat volumeUpButtonLeftMargin = 4; >+ static const CGFloat volumeControlsTopMargin = 13; >+ static const CGFloat exitFullscreenButtonWidth = 25; >+ static const CGFloat exitFullscreenButtonHeight = 21; >+ static const CGFloat exitFullscreenButtonTopMargin = 11; >+ static const CGFloat timelineWidth = 315; >+ static const CGFloat timelineHeight = 14; >+ static const CGFloat timelineBottomMargin = 7; >+ static const CGFloat timeTextFieldWidth = 54; >+ static const CGFloat timeTextFieldHeight = 13; >+ static const CGFloat timeTextFieldHorizontalMargin = 7; >+ >+ NSWindow *window = [self window]; >+ ASSERT(window); >+ >+ NSView *background = createMediaUIBackgroundView(); >+ >+ [window setContentView:background]; >+ _area = [[NSTrackingArea alloc] initWithRect:[background bounds] options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways owner:self userInfo:nil]; >+ [background addTrackingArea:_area]; >+ [background release]; >+ >+ NSView *contentView = [window contentView]; >+ >+ CGFloat center = CGFloor((windowWidth - playButtonWidth) / 2); >+ _playButton = (NSButton *)createControlWithMediaUIControlType(MediaUIControl::PlayPauseButton, NSMakeRect(center, windowHeight - playButtonTopMargin - playButtonHeight, playButtonWidth, playButtonHeight)); >+ ASSERT([_playButton isKindOfClass:[NSButton class]]); >+ [_playButton setTarget:self]; >+ [_playButton setAction:@selector(togglePlaying:)]; >+ [contentView addSubview:_playButton]; >+ >+ CGFloat closeToRight = windowWidth - horizontalMargin - exitFullscreenButtonWidth; >+ NSControl *exitFullscreenButton = createControlWithMediaUIControlType(MediaUIControl::ExitFullscreenButton, NSMakeRect(closeToRight, windowHeight - exitFullscreenButtonTopMargin - exitFullscreenButtonHeight, exitFullscreenButtonWidth, exitFullscreenButtonHeight)); >+ [exitFullscreenButton setAction:@selector(exitFullscreen:)]; >+ [exitFullscreenButton setTarget:self]; >+ [contentView addSubview:exitFullscreenButton]; >+ [exitFullscreenButton release]; >+ >+ CGFloat volumeControlsBottom = windowHeight - volumeControlsTopMargin - volumeButtonHeight; >+ CGFloat left = horizontalMargin; >+ NSControl *volumeDownButton = createControlWithMediaUIControlType(MediaUIControl::VolumeDownButton, NSMakeRect(left, volumeControlsBottom, volumeButtonWidth, volumeButtonHeight)); >+ [contentView addSubview:volumeDownButton]; >+ [volumeDownButton setTarget:self]; >+ [volumeDownButton setAction:@selector(setVolumeToZero:)]; >+ [volumeDownButton release]; >+ >+ left += volumeButtonWidth; >+ _volumeSlider = createControlWithMediaUIControlType(MediaUIControl::Slider, NSMakeRect(left, volumeControlsBottom + CGFloor((volumeButtonHeight - volumeSliderHeight) / 2), volumeSliderWidth, volumeSliderHeight)); >+ [_volumeSlider setValue:[NSNumber numberWithDouble:[self maxVolume]] forKey:@"maxValue"]; >+ [_volumeSlider setTarget:self]; >+ [_volumeSlider setAction:@selector(volumeChanged:)]; >+ [contentView addSubview:_volumeSlider]; >+ >+ left += volumeSliderWidth + volumeUpButtonLeftMargin; >+ NSControl *volumeUpButton = createControlWithMediaUIControlType(MediaUIControl::VolumeUpButton, NSMakeRect(left, volumeControlsBottom, volumeButtonWidth, volumeButtonHeight)); >+ [volumeUpButton setTarget:self]; >+ [volumeUpButton setAction:@selector(setVolumeToMaximum:)]; >+ [contentView addSubview:volumeUpButton]; >+ [volumeUpButton release]; >+ >+ _timeline = createMediaUIControl(MediaUIControl::Timeline); >+ >+ [_timeline setTarget:self]; >+ [_timeline setAction:@selector(timelinePositionChanged:)]; >+ [_timeline setFrame:NSMakeRect(CGFloor((windowWidth - timelineWidth) / 2), timelineBottomMargin, timelineWidth, timelineHeight)]; >+ [contentView addSubview:_timeline]; >+ >+ _elapsedTimeText = createTimeTextField(NSMakeRect(timeTextFieldHorizontalMargin, timelineBottomMargin, timeTextFieldWidth, timeTextFieldHeight)); >+ [_elapsedTimeText setAlignment:NSTextAlignmentLeft]; >+ [contentView addSubview:_elapsedTimeText]; >+ >+ _remainingTimeText = createTimeTextField(NSMakeRect(windowWidth - timeTextFieldHorizontalMargin - timeTextFieldWidth, timelineBottomMargin, timeTextFieldWidth, timeTextFieldHeight)); >+ [_remainingTimeText setAlignment:NSTextAlignmentRight]; >+ [contentView addSubview:_remainingTimeText]; >+ >+ [window recalculateKeyViewLoop]; >+ [window setInitialFirstResponder:_playButton]; >+ [window center]; >+} >+ >+- (void)updateVolume >+{ >+ [_volumeSlider setFloatValue:[self volume]]; >+} >+ >+- (void)updateTime >+{ >+ [self updateVolume]; >+ >+ [_timeline setFloatValue:[self currentTime]]; >+ [_timeline setValue:[NSNumber numberWithDouble:[self duration]] forKey:@"maxValue"]; >+ >+ [_remainingTimeText setStringValue:[self remainingTimeText]]; >+ [_elapsedTimeText setStringValue:[self elapsedTimeText]]; >+} >+ >+- (void)endScrubbing >+{ >+ ASSERT(_isScrubbing); >+ _isScrubbing = NO; >+ if (HTMLVideoElement* videoElement = [_delegate videoElement]) >+ videoElement->endScrubbing(); >+} >+ >+- (void)timelinePositionChanged:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [self setCurrentTime:[_timeline floatValue]]; >+ if (!_isScrubbing) { >+ _isScrubbing = YES; >+ if (HTMLVideoElement* videoElement = [_delegate videoElement]) >+ videoElement->beginScrubbing(); >+ static NSArray *endScrubbingModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, NSModalPanelRunLoopMode, nil]; >+ // Schedule -endScrubbing for when leaving mouse tracking mode. >+ [[NSRunLoop currentRunLoop] performSelector:@selector(endScrubbing) target:self argument:nil order:0 modes:endScrubbingModes]; >+ } >+} >+ >+- (float)currentTime >+{ >+ return [_delegate videoElement] ? [_delegate videoElement]->currentTime() : 0; >+} >+ >+- (void)setCurrentTime:(float)currentTime >+{ >+ if (![_delegate videoElement]) >+ return; >+ [_delegate videoElement]->setCurrentTime(currentTime); >+ [self updateTime]; >+} >+ >+- (double)duration >+{ >+ return [_delegate videoElement] ? [_delegate videoElement]->duration() : 0; >+} >+ >+- (float)maxVolume >+{ >+ // Set the volume slider resolution >+ return 100; >+} >+ >+- (void)volumeChanged:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [self setVolume:[_volumeSlider floatValue]]; >+} >+ >+- (void)setVolumeToZero:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [self setVolume:0]; >+} >+ >+- (void)setVolumeToMaximum:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [self setVolume:[self maxVolume]]; >+} >+ >+- (void)decrementVolume >+{ >+ if (![_delegate videoElement]) >+ return; >+ >+ float volume = [self volume] - 10; >+ [self setVolume:std::max(volume, 0.0f)]; >+} >+ >+- (void)incrementVolume >+{ >+ if (![_delegate videoElement]) >+ return; >+ >+ float volume = [self volume] + 10; >+ [self setVolume:std::min(volume, [self maxVolume])]; >+} >+ >+- (float)volume >+{ >+ return [_delegate videoElement] ? [_delegate videoElement]->volume() * [self maxVolume] : 0; >+} >+ >+- (void)setVolume:(float)volume >+{ >+ if (![_delegate videoElement]) >+ return; >+ if ([_delegate videoElement]->muted()) >+ [_delegate videoElement]->setMuted(false); >+ [_delegate videoElement]->setVolume(volume / [self maxVolume]); >+ [self updateVolume]; >+} >+ >+- (void)updatePlayButton >+{ >+ [_playButton setIntValue:[self playing]]; >+} >+ >+- (void)updateRate >+{ >+ BOOL playing = [self playing]; >+ >+ // Keep the HUD visible when paused. >+ if (!playing) >+ [self fadeWindowIn]; >+ else if (!_mouseIsInHUD) { >+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fadeWindowOut) object:nil]; >+ [self performSelector:@selector(fadeWindowOut) withObject:nil afterDelay:HUDWindowFadeOutDelay]; >+ } >+ [self updatePlayButton]; >+} >+ >+- (void)togglePlaying:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ [self setPlaying:![self playing]]; >+} >+ >+- (BOOL)playing >+{ >+ HTMLVideoElement* videoElement = [_delegate videoElement]; >+ if (!videoElement) >+ return NO; >+ >+ return !videoElement->canPlay(); >+} >+ >+- (void)setPlaying:(BOOL)playing >+{ >+ HTMLVideoElement* videoElement = [_delegate videoElement]; >+ >+ if (!videoElement) >+ return; >+ >+ if (playing) >+ videoElement->play(); >+ else >+ videoElement->pause(); >+} >+ >+static NSString *timeToString(double time) >+{ >+ ASSERT_ARG(time, time >= 0); >+ >+ if (!std::isfinite(time)) >+ time = 0; >+ >+ int seconds = narrowPrecisionToFloat(std::abs(time)); >+ int hours = seconds / (60 * 60); >+ int minutes = (seconds / 60) % 60; >+ seconds %= 60; >+ >+ if (hours) >+ return [NSString stringWithFormat:@"%d:%02d:%02d", hours, minutes, seconds]; >+ >+ return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds]; >+} >+ >+- (NSString *)remainingTimeText >+{ >+ HTMLVideoElement* videoElement = [_delegate videoElement]; >+ if (!videoElement) >+ return @""; >+ >+ double remainingTime = 0; >+ >+ if (std::isfinite(videoElement->duration()) && std::isfinite(videoElement->currentTime())) >+ remainingTime = videoElement->duration() - videoElement->currentTime(); >+ >+ return [@"-" stringByAppendingString:timeToString(remainingTime)]; >+} >+ >+- (NSString *)elapsedTimeText >+{ >+ if (![_delegate videoElement]) >+ return @""; >+ >+ return timeToString([_delegate videoElement]->currentTime()); >+} >+ >+// MARK: NSResponder >+ >+- (void)mouseEntered:(NSEvent *)theEvent >+{ >+ UNUSED_PARAM(theEvent); >+ // Make sure the HUD won't be hidden from now >+ _mouseIsInHUD = YES; >+ [self fadeWindowIn]; >+} >+ >+- (void)mouseExited:(NSEvent *)theEvent >+{ >+ UNUSED_PARAM(theEvent); >+ _mouseIsInHUD = NO; >+ [self fadeWindowIn]; >+} >+ >+- (void)rewind:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ if (![_delegate videoElement]) >+ return; >+ [_delegate videoElement]->rewind(30); >+} >+ >+- (void)fastForward:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ if (![_delegate videoElement]) >+ return; >+} >+ >+- (void)exitFullscreen:(id)sender >+{ >+ UNUSED_PARAM(sender); >+ if (_isEndingFullscreen) >+ return; >+ _isEndingFullscreen = YES; >+ [_delegate requestExitFullscreen]; >+} >+ >+// MARK: NSWindowDelegate >+ >+- (void)windowDidExpose:(NSNotification *)notification >+{ >+ UNUSED_PARAM(notification); >+ [self scheduleTimeUpdate]; >+} >+ >+- (void)windowDidClose:(NSNotification *)notification >+{ >+ UNUSED_PARAM(notification); >+ [self unscheduleTimeUpdate]; >+} >+ >+@end >+ >+#endif >diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm >index fc88076cb71a88e5f8f7c5a2c38c6cad2ffdd4da..9dde7dde1a7ad7fd6f218254f0b17d32ebf7bb3a 100644 >--- a/Source/WebKitLegacy/mac/WebView/WebView.mm >+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm >@@ -255,6 +255,7 @@ > #import "WebNSPrintOperationExtras.h" > #import "WebPDFView.h" > #import "WebSwitchingGPUClient.h" >+#import "WebVideoFullscreenController.h" > #import <WebCore/TextIndicator.h> > #import <WebCore/TextIndicatorWindow.h> > #import <pal/spi/cocoa/AVKitSPI.h> >@@ -9379,7 +9380,6 @@ bool LayerFlushController::flushLayers() > #if ENABLE(VIDEO) > - (void)_enterVideoFullscreenForVideoElement:(WebCore::HTMLVideoElement*)videoElement mode:(WebCore::HTMLMediaElementEnums::VideoFullscreenMode)mode > { >-#if PLATFORM(IOS_FAMILY) > if (_private->fullscreenController) { > if ([_private->fullscreenController videoElement] == videoElement) { > // The backend may just warn us that the underlaying plaftormMovie() >@@ -9397,22 +9397,23 @@ bool LayerFlushController::flushLayers() > if (!_private->fullscreenController) { > _private->fullscreenController = [[WebVideoFullscreenController alloc] init]; > [_private->fullscreenController setVideoElement:videoElement]; >+#if PLATFORM(IOS_FAMILY) > [_private->fullscreenController enterFullscreen:(UIView *)[[[self window] hostLayer] delegate] mode:mode]; >+#else >+ [_private->fullscreenController enterFullscreen:[[self window] screen]]; >+#endif > } > else > [_private->fullscreenController setVideoElement:videoElement]; >-#endif > } > > - (void)_exitVideoFullscreen > { >-#if PLATFORM(IOS_FAMILY) > if (!_private->fullscreenController) > return; > [_private->fullscreenController exitFullscreen]; > [_private->fullscreenController release]; > _private->fullscreenController = nil; >-#endif > } > > #if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193586
:
359534
|
359538
| 359550