commit 8bf1985cc5d177d80cf0ec3da21bc19c957f341d
parent a3047a1c85a50f15320dfef85e74bcd5f8f84896
Author: Vincent Hilla <vhilla@mozilla.com>
Date: Tue, 16 Dec 2025 18:12:06 +0000
Bug 1858562 - Part 3: Platform specific Document Picture-in-Picture adjustments. r=emilio,dom-core,win-reviewers,gstoll,smaug
Differential Revision: https://phabricator.services.mozilla.com/D265291
Diffstat:
6 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/widget/InitData.h b/widget/InitData.h
@@ -75,7 +75,9 @@ enum class TransparencyMode : uint8_t {
enum class PiPType : uint8_t {
NoPiP,
// https://w3c.github.io/picture-in-picture
- MediaPiP
+ MediaPiP,
+ // https://wicg.github.io/document-picture-in-picture
+ DocumentPiP
};
// Basic struct for widget initialization data.
diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm
@@ -5261,9 +5261,10 @@ void nsCocoaWindow::Show(bool aState) {
mWindowAnimationBehavior = behavior;
}
- // We don't want alwaysontop / alert windows to pull focus when they're
- // opened, as these tend to be for peripheral indicators and displays.
- if (mAlwaysOnTop || mIsAlert) {
+ // We don't want most alwaysontop / alert windows to pull focus when
+ // they're opened, as these tend to be for peripheral indicators and
+ // displays.
+ if ((mAlwaysOnTop && mPiPType != PiPType::DocumentPiP) || mIsAlert) {
[mWindow orderFront:nil];
} else {
[mWindow makeKeyAndOrderFront:nil];
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
@@ -6427,7 +6427,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
// alwaysontop windows are generally used for peripheral indicators,
// so we don't focus them by default.
- if (mAlwaysOnTop) {
+ const bool shouldFocus = !mAlwaysOnTop || mPiPType == PiPType::DocumentPiP;
+ if (!shouldFocus) {
gtk_window_set_focus_on_map(GTK_WINDOW(mShell), FALSE);
}
@@ -6451,7 +6452,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
// make sure this is the focus widget in the container
gtk_widget_show(container);
- if (!mAlwaysOnTop) {
+ if (shouldFocus) {
gtk_widget_grab_focus(container);
}
@@ -6622,7 +6623,9 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
nullptr);
LOG(" nsWindow type %d %s\n", int(mWindowType),
- mPiPType == PiPType::MediaPiP ? "Media PiP window" : "");
+ mPiPType == PiPType::MediaPiP
+ ? "Media PiP window"
+ : (mPiPType == PiPType::DocumentPiP ? "Document PiP window" : ""));
LOG(" mShell %p (window %p) mContainer %p mGdkWindow %p XID 0x%lx\n", mShell,
GetToplevelGdkWindow(), mContainer, mGdkWindow, GetX11Window());
diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp
@@ -167,9 +167,10 @@ void HeadlessWidget::Show(bool aState) {
LOG(("HeadlessWidget::Show [%p] state %d\n", (void*)this, aState));
// Top-level window and dialogs are activated/raised when shown.
- // NB: alwaysontop windows are generally used for peripheral indicators,
- // so we don't focus them by default.
- if (aState && !mAlwaysOnTop &&
+ // NB: alwaysontop windows are generally used for peripheral indicators.
+ // So we don't focus them by default unless they are a Document
+ // Picture-in-Picture.
+ if (aState && (!mAlwaysOnTop || mPiPType == PiPType::DocumentPiP) &&
(mWindowType == WindowType::TopLevel ||
mWindowType == WindowType::Dialog)) {
RaiseWindow();
diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp
@@ -1774,7 +1774,8 @@ void nsWindow::Show(bool aState) {
::ShowWindow(mWnd, SW_SHOWMINIMIZED);
break;
default:
- if (CanTakeFocus() && !mAlwaysOnTop) {
+ if (CanTakeFocus() &&
+ (!mAlwaysOnTop || mPiPType == PiPType::DocumentPiP)) {
::ShowWindow(mWnd, SW_SHOWNORMAL);
} else {
::ShowWindow(mWnd, SW_SHOWNOACTIVATE);
@@ -1807,7 +1808,7 @@ void nsWindow::Show(bool aState) {
if (wasVisible) {
flags |= SWP_NOZORDER;
}
- if (mAlwaysOnTop || mIsAlert) {
+ if ((mAlwaysOnTop && mPiPType != PiPType::DocumentPiP) || mIsAlert) {
flags |= SWP_NOACTIVATE;
}
diff --git a/xpfe/appshell/nsAppShellService.cpp b/xpfe/appshell/nsAppShellService.cpp
@@ -526,6 +526,12 @@ nsresult nsAppShellService::JustCreateTopWindow(
}
#endif
+ if (widgetInitData.mWindowType == widget::WindowType::TopLevel &&
+ (aChromeMask & nsIWebBrowserChrome::CHROME_DOCUMENT_PICTURE_IN_PICTURE) ==
+ nsIWebBrowserChrome::CHROME_DOCUMENT_PICTURE_IN_PICTURE) {
+ widgetInitData.mPiPType = mozilla::widget::PiPType::DocumentPiP;
+ }
+
// alert=yes is expected to be used along with dialogs, not other window
// types.
MOZ_ASSERT_IF(aChromeMask & nsIWebBrowserChrome::CHROME_ALERT,