Finish off PiP

This commit is contained in:
wuggy 2026-09-13 12:18:07 -07:00
commit 55a53a2576
14 changed files with 293 additions and 21 deletions

View file

@ -259,6 +259,7 @@ public:
NS_IMETHOD Move(double aX, double aY) override;
virtual void SetSizeMode(nsSizeMode aMode) override;
NS_IMETHOD HideWindowChrome(bool aShouldHide) override;
void SetAlwaysOnTop(bool aAlwaysOnTop) override;
void EnteredFullScreen(bool aFullScreen, bool aNativeMode = true);
virtual bool PrepareForFullscreenTransition(nsISupports** aData) override;

View file

@ -1319,6 +1319,18 @@ nsCocoaWindow::SetSizeMode(nsSizeMode aMode)
// This has to preserve the window's frame bounds.
// This method requires (as does the Windows impl.) that you call Resize shortly
// after calling HideWindowChrome. See bug 498835 for fixing this.
void nsCocoaWindow::SetAlwaysOnTop(bool aAlwaysOnTop)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
nsBaseWidget::SetAlwaysOnTop(aAlwaysOnTop);
if (mWindow && (mWindowType == eWindowType_toplevel ||
mWindowType == eWindowType_dialog)) {
[mWindow setLevel:aAlwaysOnTop ? NSFloatingWindowLevel : NSNormalWindowLevel];
[mWindow setHidesOnDeactivate:NO];
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
NS_IMETHODIMP nsCocoaWindow::HideWindowChrome(bool aShouldHide)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
@ -1353,6 +1365,9 @@ NS_IMETHODIMP nsCocoaWindow::HideWindowChrome(bool aShouldHide)
// Re-import state.
[mWindow importState:state];
if (mAlwaysOnTop) {
SetAlwaysOnTop(true);
}
// Reparent the content view.
[mWindow setContentView:contentView];

View file

@ -1255,6 +1255,15 @@ nsWindow::NativeMove()
}
}
void
nsWindow::SetAlwaysOnTop(bool aAlwaysOnTop)
{
nsBaseWidget::SetAlwaysOnTop(aAlwaysOnTop);
if (mShell) {
gtk_window_set_keep_above(GTK_WINDOW(mShell), aAlwaysOnTop);
}
}
void
nsWindow::SetZIndex(int32_t aZIndex)
{

View file

@ -128,6 +128,7 @@ public:
virtual bool IsEnabled() const override;
void SetZIndex(int32_t aZIndex) override;
void SetAlwaysOnTop(bool aAlwaysOnTop) override;
virtual void SetSizeMode(nsSizeMode aMode) override;
NS_IMETHOD Enable(bool aState) override;
NS_IMETHOD SetFocus(bool aRaise = false) override;

View file

@ -803,6 +803,12 @@ class nsIWidget : public nsISupports
*/
virtual void SetZIndex(int32_t aZIndex) = 0;
// Keep a top-level window above ordinary windows, including other apps.
virtual void SetAlwaysOnTop(bool aAlwaysOnTop)
{
mAlwaysOnTop = aAlwaysOnTop;
}
/**
* Gets the widget's z-index.
*/
@ -2032,6 +2038,7 @@ protected:
bool mOnDestroyCalled;
nsWindowType mWindowType;
int32_t mZIndex;
bool mAlwaysOnTop = false;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIWidget, NS_IWIDGET_IID)

View file

@ -2033,6 +2033,17 @@ nsWindow::BeginResizeDrag(WidgetGUIEvent* aEvent,
*
**************************************************************/
void
nsWindow::SetAlwaysOnTop(bool aAlwaysOnTop)
{
nsBaseWidget::SetAlwaysOnTop(aAlwaysOnTop);
if (mWnd && (mWindowType == eWindowType_toplevel ||
mWindowType == eWindowType_dialog)) {
::SetWindowPos(mWnd, aAlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
}
// Position the window behind the given window
void
nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
@ -2059,6 +2070,10 @@ nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
flags |= SWP_NOACTIVATE;
}
// Application z-order changes must not demote an always-on-top window.
if (mAlwaysOnTop) {
behind = HWND_TOPMOST;
}
::SetWindowPos(mWnd, behind, 0, 0, 0, 0, flags);
}

View file

@ -152,6 +152,7 @@ public:
virtual nsresult MakeFullScreen(bool aFullScreen,
nsIScreen* aScreen = nullptr) override;
NS_IMETHOD HideWindowChrome(bool aShouldHide) override;
void SetAlwaysOnTop(bool aAlwaysOnTop) override;
NS_IMETHOD Invalidate(bool aEraseBackground = false,
bool aUpdateNCArea = false,
bool aIncludeChildren = false);