Revert r238815, it broke WK1 video fullscreen on Mac
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 19 Jan 2019 00:22:41 +0000 (00:22 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 19 Jan 2019 00:22:41 +0000 (00:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193586
<rdar://problem/47358941>

Reviewed by Jer Noble.

Source/WebCore:

* PlatformMac.cmake:
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::supportsFullscreen const):

Source/WebKitLegacy:

* WebKitLegacy.xcodeproj/project.pbxproj:

Source/WebKitLegacy/mac:

* 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]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240190 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/PlatformMac.cmake
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebKitLegacy/ChangeLog
Source/WebKitLegacy/WebKitLegacy.xcodeproj/project.pbxproj
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.h [new file with mode: 0644]
Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.mm [new file with mode: 0644]
Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.h [new file with mode: 0644]
Source/WebKitLegacy/mac/WebView/WebVideoFullscreenHUDWindowController.mm [new file with mode: 0644]
Source/WebKitLegacy/mac/WebView/WebView.mm

index fe9a500..c041dc2 100644 (file)
@@ -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  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: Audit: don't keep the injected sub-objects alive between runs
index 8dd999e..866ea6a 100644 (file)
@@ -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
index 3103073..2899231 100644 (file)
@@ -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
index 0256b9c..1b4bbf7 100644 (file)
@@ -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
index f209004..b3ca2f8 100644 (file)
                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 */; };
                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>"; };
                                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 */,
                                Spanish,
                                Dutch,
                                Italian,
+                               en,
                        );
                        mainGroup = 0867D691FE84028FC02AAC07 /* WebKit */;
                        productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
                                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 */,
index 282261c..1e064fe 100644 (file)
@@ -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/WebKitLegacy/mac/WebView/WebVideoFullscreenController.h b/Source/WebKitLegacy/mac/WebView/WebVideoFullscreenController.h
new file mode 100644 (file)
index 0000000..f57578b
--- /dev/null
@@ -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 (file)
index 0000000..c6e0716
--- /dev/null
@@ -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 (file)
index 0000000..f67feae
--- /dev/null
@@ -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 (file)
index 0000000..7c3f506
--- /dev/null
@@ -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
index fc88076..9dde7dd 100644 (file)
 #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)