diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index 7916dae13e76..db1bdd05979e 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -776,7 +776,7 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) { // Enable transparent titlebar corners for titlebar mode. GdkScreen* screen = gdk_screen_get_default(); aResult = gdk_screen_is_composited(screen) - ? (nsWindow::GtkWindowDecoration() != + ? (nsWindow::GetSystemCSDSupportLevel() != nsWindow::GTK_DECORATION_NONE) : false; break; @@ -1435,7 +1435,7 @@ void nsLookAndFeel::EnsureInit() { g_object_unref(labelWidget); mCSDAvailable = - nsWindow::GtkWindowDecoration() != nsWindow::GTK_DECORATION_NONE; + nsWindow::GetSystemCSDSupportLevel() != nsWindow::GTK_DECORATION_NONE; mCSDHideTitlebarByDefault = nsWindow::HideTitlebarByDefault(); mCSDCloseButton = false; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 427def8c1af8..37aceee7b221 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -310,8 +310,7 @@ static SystemTimeConverter& TimeConverter() { return sTimeConverterSingleton; } -nsWindow::GtkWindowDecoration nsWindow::sGtkWindowDecoration = - GTK_DECORATION_UNKNOWN; +nsWindow::CSDSupportLevel nsWindow::sCSDSupportLevel = GTK_DECORATION_UNKNOWN; bool nsWindow::sTransparentMainWindow = false; static bool sIgnoreChangedSettings = false; @@ -543,7 +542,7 @@ nsWindow::nsWindow() { mLastScrollEventTime = GDK_CURRENT_TIME; mPendingConfigures = 0; - mGtkWindowDecoration = GTK_DECORATION_NONE; + mCSDSupportLevel = GTK_DECORATION_NONE; mDrawToContainer = false; mDrawInTitlebar = false; mTitlebarBackdropState = false; @@ -1074,7 +1073,7 @@ void nsWindow::SetSizeConstraints(const SizeConstraints& aConstraints) { void nsWindow::AddCSDDecorationSize(int* aWidth, int* aHeight) { if (mSizeState == nsSizeMode_Normal && - mGtkWindowDecoration == GTK_DECORATION_CLIENT && mDrawInTitlebar) { + mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) { GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel); *aWidth += decorationSize.left + decorationSize.right; *aHeight += decorationSize.top + decorationSize.bottom; @@ -1084,7 +1083,7 @@ void nsWindow::AddCSDDecorationSize(int* aWidth, int* aHeight) { #ifdef MOZ_WAYLAND bool nsWindow::GetCSDDecorationOffset(int* aDx, int* aDy) { if (mSizeState == nsSizeMode_Normal && - mGtkWindowDecoration == GTK_DECORATION_CLIENT && mDrawInTitlebar) { + mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) { GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel); *aDx = decorationSize.left; *aDy = decorationSize.top; @@ -2315,7 +2314,7 @@ LayoutDeviceIntRect nsWindow::GetClientBounds() { void nsWindow::UpdateClientOffsetFromFrameExtents() { AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffsetFromFrameExtents", OTHER); - if (mGtkWindowDecoration == GTK_DECORATION_CLIENT && mDrawInTitlebar) { + if (mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) { return; } @@ -3219,7 +3218,7 @@ void nsWindow::OnSizeAllocate(GtkAllocation* aAllocation) { // is enabled. In either cases (Wayland or system titlebar is off on X11) // we don't get _NET_FRAME_EXTENTS X11 property notification so we derive // it from mContainer position. - if (mGtkWindowDecoration == GTK_DECORATION_CLIENT) { + if (mCSDSupportLevel == GTK_DECORATION_CLIENT) { if (!mIsX11Display || (mIsX11Display && mDrawInTitlebar)) { UpdateClientOffsetFromCSDWindow(); } @@ -4228,7 +4227,7 @@ void nsWindow::OnScaleChanged(GtkAllocation* aAllocation) { // is enabled. In ither cases (Wayland or system titlebar is off on X11) // we don't get _NET_FRAME_EXTENTS X11 property notification so we derive // it from mContainer position. - if (mGtkWindowDecoration == GTK_DECORATION_CLIENT) { + if (mCSDSupportLevel == GTK_DECORATION_CLIENT) { if (!mIsX11Display || (mIsX11Display && mDrawInTitlebar)) { UpdateClientOffsetFromCSDWindow(); } @@ -4422,7 +4421,7 @@ bool nsWindow::IsToplevelWindowTransparent() { // Enable transparent toplevel window if we can draw main window // without system titlebar as Gtk+ themes use titlebar round corners. sTransparentMainWindow = - GetSystemGtkWindowDecoration() != GTK_DECORATION_NONE; + GetSystemCSDSupportLevel() != GTK_DECORATION_NONE; } } transparencyConfigured = true; @@ -4624,7 +4623,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent, if (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog) { - mGtkWindowDecoration = GetSystemGtkWindowDecoration(); + mCSDSupportLevel = GetSystemCSDSupportLevel(); } // Don't use transparency for PictureInPicture windows. @@ -4813,7 +4812,7 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent, */ GtkStyleContext* style = gtk_widget_get_style_context(mShell); mDrawToContainer = !mIsX11Display || - (mGtkWindowDecoration == GTK_DECORATION_CLIENT) || + (mCSDSupportLevel == GTK_DECORATION_CLIENT) || gtk_style_context_has_class(style, "csd"); eventWidget = (mDrawToContainer) ? container : mShell; @@ -7673,22 +7672,22 @@ nsresult nsWindow::SetNonClientMargins(LayoutDeviceIntMargin& aMargins) { } void nsWindow::SetDrawsInTitlebar(bool aState) { - LOG(("nsWindow::SetDrawsInTitlebar() [%p] State %d mGtkWindowDecoration %d\n", - (void*)this, aState, (int)mGtkWindowDecoration)); + LOG(("nsWindow::SetDrawsInTitlebar() [%p] State %d mCSDSupportLevel %d\n", + (void*)this, aState, (int)mCSDSupportLevel)); if (mIsPIPWindow && aState == mDrawInTitlebar) { gtk_window_set_decorated(GTK_WINDOW(mShell), !aState); return; } - if (!mShell || mGtkWindowDecoration == GTK_DECORATION_NONE || + if (!mShell || mCSDSupportLevel == GTK_DECORATION_NONE || aState == mDrawInTitlebar) { return; } - if (mGtkWindowDecoration == GTK_DECORATION_SYSTEM) { + if (mCSDSupportLevel == GTK_DECORATION_SYSTEM) { SetWindowDecoration(aState ? eBorderStyle_border : mBorderStyle); - } else if (mGtkWindowDecoration == GTK_DECORATION_CLIENT) { + } else if (mCSDSupportLevel == GTK_DECORATION_CLIENT) { LOG((" Using CSD mode\n")); /* Window manager does not support GDK_DECOR_BORDER, @@ -8028,87 +8027,93 @@ nsresult nsWindow::SynthesizeNativeTouchPoint(uint32_t aPointerId, return NS_OK; } -nsWindow::GtkWindowDecoration nsWindow::GetSystemGtkWindowDecoration() { - if (sGtkWindowDecoration != GTK_DECORATION_UNKNOWN) { - return sGtkWindowDecoration; +nsWindow::CSDSupportLevel nsWindow::GetSystemCSDSupportLevel() { + if (sCSDSupportLevel != GTK_DECORATION_UNKNOWN) { + return sCSDSupportLevel; } // Allow MOZ_GTK_TITLEBAR_DECORATION to override our heuristics const char* decorationOverride = getenv("MOZ_GTK_TITLEBAR_DECORATION"); if (decorationOverride) { if (strcmp(decorationOverride, "none") == 0) { - sGtkWindowDecoration = GTK_DECORATION_NONE; + sCSDSupportLevel = GTK_DECORATION_NONE; } else if (strcmp(decorationOverride, "client") == 0) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else if (strcmp(decorationOverride, "system") == 0) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; } - return sGtkWindowDecoration; + return sCSDSupportLevel; } - // nsWindow::GetSystemGtkWindowDecoration can be called from various threads + // nsWindow::GetSystemCSDSupportLevel can be called from various threads // so we can't use gfxPlatformGtk here. if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; - return sGtkWindowDecoration; - } - - // GTK_CSD forces CSD mode - use also CSD because window manager - // decorations does not work with CSD. - // We check GTK_CSD as well as gtk_window_should_use_csd() does. - if (sGtkWindowDecoration == GTK_DECORATION_SYSTEM) { - const char* csdOverride = getenv("GTK_CSD"); - if (csdOverride && atoi(csdOverride)) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; - return sGtkWindowDecoration; - } + sCSDSupportLevel = GTK_DECORATION_CLIENT; + return sCSDSupportLevel; } const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP"); if (currentDesktop) { // GNOME Flashback (fallback) if (strstr(currentDesktop, "GNOME-Flashback:GNOME") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; // Pop Linux Bug 1629198 } else if (strstr(currentDesktop, "pop:GNOME") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; // gnome-shell } else if (strstr(currentDesktop, "GNOME") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; } else if (strstr(currentDesktop, "XFCE") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else if (strstr(currentDesktop, "X-Cinnamon") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; // KDE Plasma } else if (strstr(currentDesktop, "KDE") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else if (strstr(currentDesktop, "Enlightenment") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else if (strstr(currentDesktop, "LXDE") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else if (strstr(currentDesktop, "openbox") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else if (strstr(currentDesktop, "i3") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_NONE; + sCSDSupportLevel = GTK_DECORATION_NONE; } else if (strstr(currentDesktop, "MATE") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; // Ubuntu Unity } else if (strstr(currentDesktop, "Unity") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; // Elementary OS } else if (strstr(currentDesktop, "Pantheon") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; } else if (strstr(currentDesktop, "LXQt") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_SYSTEM; + sCSDSupportLevel = GTK_DECORATION_SYSTEM; } else if (strstr(currentDesktop, "Deepin") != nullptr) { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_CLIENT; } else { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; +// Release or beta builds are not supposed to be broken +// so disable titlebar rendering on untested/unknown systems. +#if defined(RELEASE_OR_BETA) + sCSDSupportLevel = GTK_DECORATION_NONE; +#else + sCSDSupportLevel = GTK_DECORATION_CLIENT; +#endif } } else { - sGtkWindowDecoration = GTK_DECORATION_CLIENT; + sCSDSupportLevel = GTK_DECORATION_NONE; } - return sGtkWindowDecoration; + + // GTK_CSD forces CSD mode - use also CSD because window manager + // decorations does not work with CSD. + // We check GTK_CSD as well as gtk_window_should_use_csd() does. + if (sCSDSupportLevel == GTK_DECORATION_SYSTEM) { + const char* csdOverride = getenv("GTK_CSD"); + if (csdOverride && g_strcmp0(csdOverride, "1") == 0) { + sCSDSupportLevel = GTK_DECORATION_CLIENT; + } + } + + return sCSDSupportLevel; } bool nsWindow::TitlebarUseShapeMask() { @@ -8145,8 +8150,7 @@ bool nsWindow::HideTitlebarByDefault() { // Don't hide titlebar when it's disabled on current desktop. const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP"); - if (!currentDesktop || - GetSystemGtkWindowDecoration() == GTK_DECORATION_NONE) { + if (!currentDesktop || GetSystemCSDSupportLevel() == GTK_DECORATION_NONE) { return false; } diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index b34e9fb81b25..cbe4ade8c4cf 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -406,12 +406,12 @@ class nsWindow final : public nsBaseWidget { GTK_DECORATION_CLIENT, // CSD without shadows GTK_DECORATION_NONE, // WM does not support CSD at all GTK_DECORATION_UNKNOWN - } GtkWindowDecoration; + } CSDSupportLevel; /** * Get the support of Client Side Decoration by checking * the XDG_CURRENT_DESKTOP environment variable. */ - static GtkWindowDecoration GetSystemGtkWindowDecoration(); + static CSDSupportLevel GetSystemCSDSupportLevel(); static bool HideTitlebarByDefault(); static bool GetTopLevelWindowActiveState(nsIFrame* aFrame); @@ -563,7 +563,7 @@ class nsWindow final : public nsBaseWidget { // Window titlebar rendering mode, GTK_DECORATION_NONE if it's disabled // for this window. - GtkWindowDecoration mGtkWindowDecoration; + CSDSupportLevel mCSDSupportLevel; // Use dedicated GdkWindow for mContainer bool mDrawToContainer; // If true, draw our own window titlebar. @@ -712,7 +712,7 @@ class nsWindow final : public nsBaseWidget { RefPtr mIMContext; mozilla::UniquePtr mCurrentTimeGetter; - static GtkWindowDecoration sGtkWindowDecoration; + static CSDSupportLevel sCSDSupportLevel; static bool sTransparentMainWindow; };