From 705230d4aa7ad639198fa65388e04acf6ab6fc73 Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Thu, 22 Mar 2018 13:22:38 +0100 Subject: [PATCH] Bug 1441873 - [CSD] Remove nsWindow::mIsCSDAvailable and replace with CSDSupportLevel state, r=jhorak MozReview-Commit-ID: KOiSzNvZfjg --HG-- extra : rebase_source : 146d55491e600409b73353bc71580eb1237e72f0 --- widget/gtk/nsLookAndFeel.cpp | 5 +- widget/gtk/nsWindow.cpp | 151 +++++++++++++++++------------------ widget/gtk/nsWindow.h | 10 +-- 3 files changed, 81 insertions(+), 85 deletions(-) diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index ba05e25f4585..696ab419ad1d 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -1081,9 +1081,8 @@ nsLookAndFeel::EnsureInit() gtk_widget_destroy(window); g_object_unref(labelWidget); - // Require GTK 3.10 for GtkHeaderBar support and compatible window manager. - mCSDAvailable = (gtk_check_version(3, 10, 0) == nullptr && - nsWindow::GetCSDSupportLevel() != nsWindow::CSD_SUPPORT_NONE); + mCSDAvailable = + nsWindow::GetSystemCSDSupportLevel() != nsWindow::CSD_SUPPORT_NONE; mCSDCloseButton = false; mCSDMinimizeButton = false; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index b2b41eefa886..49d58a5acf3c 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -479,8 +479,8 @@ nsWindow::nsWindow() mLastScrollEventTime = GDK_CURRENT_TIME; #endif mPendingConfigures = 0; - mIsCSDAvailable = false; - mIsCSDEnabled = false; + mCSDSupportLevel = CSD_SUPPORT_NONE; + mDrawInTitlebar = false; } nsWindow::~nsWindow() @@ -2819,7 +2819,7 @@ nsWindow::OnButtonReleaseEvent(GdkEventButton *aEvent) // Check if mouse position in titlebar and doubleclick happened to // trigger restore/maximize. if (!defaultPrevented - && mIsCSDEnabled + && mDrawInTitlebar && event.button == WidgetMouseEvent::eLeftButton && event.mClickCount == 2 && mDraggableRegion.Contains(pos.x, pos.y)) { @@ -3767,12 +3767,8 @@ nsWindow::Create(nsIWidget* aParent, gtk_window_group_add_window(group, GTK_WINDOW(mShell)); g_object_unref(group); - int32_t isCSDAvailable = false; - nsresult rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable, - &isCSDAvailable); - if (NS_SUCCEEDED(rv)) { - mIsCSDAvailable = isCSDAvailable; - } + // We enable titlebar rendering for toplevel windows only. + mCSDSupportLevel = GetSystemCSDSupportLevel(); } // Create a container to hold child windows and child GtkWidgets. @@ -3797,7 +3793,7 @@ nsWindow::Create(nsIWidget* aParent, GtkStyleContext* style = gtk_widget_get_style_context(mShell); drawToContainer = !mIsX11Display || - (mIsCSDAvailable && GetCSDSupportLevel() == CSD_SUPPORT_CLIENT) || + (mCSDSupportLevel == CSD_SUPPORT_CLIENT) || gtk_style_context_has_class(style, "csd"); eventWidget = (drawToContainer) ? container : mShell; @@ -6590,80 +6586,81 @@ nsWindow::ClearCachedResources() nsresult nsWindow::SetNonClientMargins(LayoutDeviceIntMargin &aMargins) { - SetDrawsInTitlebar(aMargins.top == 0); - return NS_OK; + SetDrawsInTitlebar(aMargins.top == 0); + return NS_OK; } void nsWindow::SetDrawsInTitlebar(bool aState) { - if (!mIsCSDAvailable || aState == mIsCSDEnabled) - return; + if (!mShell || + mCSDSupportLevel == CSD_SUPPORT_NONE || + aState == mDrawInTitlebar) { + return; + } - if (mShell) { - if (GetCSDSupportLevel() == CSD_SUPPORT_SYSTEM) { - SetWindowDecoration(aState ? eBorderStyle_border : mBorderStyle); - } - else { - /* Window manager does not support GDK_DECOR_BORDER, - * emulate it by CSD. - * - * gtk_window_set_titlebar() works on unrealized widgets only, - * we need to handle mShell carefully here. - * When CSD is enabled mGdkWindow is owned by mContainer which is good - * as we can't delete our mGdkWindow. To make mShell unrealized while - * mContainer is preserved we temporary reparent mContainer to an - * invisible GtkWindow. - */ - NativeShow(false); + if (mCSDSupportLevel == CSD_SUPPORT_SYSTEM) { + SetWindowDecoration(aState ? eBorderStyle_border : mBorderStyle); + } + else if (mCSDSupportLevel == CSD_SUPPORT_CLIENT) { + /* Window manager does not support GDK_DECOR_BORDER, + * emulate it by CSD. + * + * gtk_window_set_titlebar() works on unrealized widgets only, + * we need to handle mShell carefully here. + * When CSD is enabled mGdkWindow is owned by mContainer which is good + * as we can't delete our mGdkWindow. To make mShell unrealized while + * mContainer is preserved we temporary reparent mContainer to an + * invisible GtkWindow. + */ + NativeShow(false); - // Using GTK_WINDOW_POPUP rather than - // GTK_WINDOW_TOPLEVEL in the hope that POPUP results in less - // initialization and window manager interaction. - GtkWidget* tmpWindow = gtk_window_new(GTK_WINDOW_POPUP); - gtk_widget_realize(tmpWindow); + // Using GTK_WINDOW_POPUP rather than + // GTK_WINDOW_TOPLEVEL in the hope that POPUP results in less + // initialization and window manager interaction. + GtkWidget* tmpWindow = gtk_window_new(GTK_WINDOW_POPUP); + gtk_widget_realize(tmpWindow); - gtk_widget_reparent(GTK_WIDGET(mContainer), tmpWindow); - gtk_widget_unrealize(GTK_WIDGET(mShell)); + gtk_widget_reparent(GTK_WIDGET(mContainer), tmpWindow); + gtk_widget_unrealize(GTK_WIDGET(mShell)); - // Available as of GTK 3.10+ - static auto sGtkWindowSetTitlebar = (void (*)(GtkWindow*, GtkWidget*)) - dlsym(RTLD_DEFAULT, "gtk_window_set_titlebar"); - MOZ_ASSERT(sGtkWindowSetTitlebar, - "Missing gtk_window_set_titlebar(), old Gtk+ library?"); + // Available as of GTK 3.10+ + static auto sGtkWindowSetTitlebar = (void (*)(GtkWindow*, GtkWidget*)) + dlsym(RTLD_DEFAULT, "gtk_window_set_titlebar"); + MOZ_ASSERT(sGtkWindowSetTitlebar, + "Missing gtk_window_set_titlebar(), old Gtk+ library?"); - if (aState) { - // Add a hidden titlebar widget to trigger CSD, but disable the default - // titlebar. GtkFixed is a somewhat random choice for a simple unused - // widget. gtk_window_set_titlebar() takes ownership of the titlebar - // widget. - sGtkWindowSetTitlebar(GTK_WINDOW(mShell), gtk_fixed_new()); - } else { - sGtkWindowSetTitlebar(GTK_WINDOW(mShell), nullptr); - } + if (aState) { + // Add a hidden titlebar widget to trigger CSD, but disable the default + // titlebar. GtkFixed is a somewhat random choice for a simple unused + // widget. gtk_window_set_titlebar() takes ownership of the titlebar + // widget. + sGtkWindowSetTitlebar(GTK_WINDOW(mShell), gtk_fixed_new()); + } else { + sGtkWindowSetTitlebar(GTK_WINDOW(mShell), nullptr); + } - /* A workaround for https://bugzilla.gnome.org/show_bug.cgi?id=791081 - * gtk_widget_realize() throws: - * "In pixman_region32_init_rect: Invalid rectangle passed" - * when mShell has default 1x1 size. - */ - GtkAllocation allocation = {0, 0, 0, 0}; - gtk_widget_get_preferred_width(GTK_WIDGET(mShell), nullptr, - &allocation.width); - gtk_widget_get_preferred_height(GTK_WIDGET(mShell), nullptr, - &allocation.height); - gtk_widget_size_allocate(GTK_WIDGET(mShell), &allocation); + /* A workaround for https://bugzilla.gnome.org/show_bug.cgi?id=791081 + * gtk_widget_realize() throws: + * "In pixman_region32_init_rect: Invalid rectangle passed" + * when mShell has default 1x1 size. + */ + GtkAllocation allocation = {0, 0, 0, 0}; + gtk_widget_get_preferred_width(GTK_WIDGET(mShell), nullptr, + &allocation.width); + gtk_widget_get_preferred_height(GTK_WIDGET(mShell), nullptr, + &allocation.height); + gtk_widget_size_allocate(GTK_WIDGET(mShell), &allocation); - gtk_widget_realize(GTK_WIDGET(mShell)); - gtk_widget_reparent(GTK_WIDGET(mContainer), GTK_WIDGET(mShell)); - mNeedsShow = true; - NativeResize(); + gtk_widget_realize(GTK_WIDGET(mShell)); + gtk_widget_reparent(GTK_WIDGET(mContainer), GTK_WIDGET(mShell)); + mNeedsShow = true; + NativeResize(); - gtk_widget_destroy(tmpWindow); - } - } + gtk_widget_destroy(tmpWindow); + } - mIsCSDEnabled = aState; + mDrawInTitlebar = aState; } gint @@ -6932,18 +6929,18 @@ nsWindow::SynthesizeNativeTouchPoint(uint32_t aPointerId, } #endif -bool -nsWindow::DoDrawTitlebar() const -{ - return mIsCSDEnabled && mSizeState == nsSizeMode_Normal; -} - nsWindow::CSDSupportLevel -nsWindow::GetCSDSupportLevel() { +nsWindow::GetSystemCSDSupportLevel() { if (sCSDSupportLevel != CSD_SUPPORT_UNKNOWN) { return sCSDSupportLevel; } + // Require GTK 3.10 for GtkHeaderBar support and compatible window manager. + if (gtk_check_version(3, 10, 0) != nullptr) { + sCSDSupportLevel = CSD_SUPPORT_NONE; + return sCSDSupportLevel; + } + const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP"); if (currentDesktop) { // GNOME Flashback (fallback) diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 505aa018fe86..eeeb8851a761 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -400,8 +400,6 @@ public: virtual bool WidgetTypeSupportsAcceleration() override; - bool DoDrawTitlebar() const; - typedef enum { CSD_SUPPORT_SYSTEM, // CSD including shadows CSD_SUPPORT_CLIENT, // CSD without shadows CSD_SUPPORT_NONE, // WM does not support CSD at all @@ -411,7 +409,7 @@ public: * Get the support of Client Side Decoration by checking * the XDG_CURRENT_DESKTOP environment variable. */ - static CSDSupportLevel GetCSDSupportLevel(); + static CSDSupportLevel GetSystemCSDSupportLevel(); protected: virtual ~nsWindow(); @@ -517,9 +515,11 @@ private: // window. See bug 1225044. unsigned int mPendingConfigures; - bool mIsCSDAvailable; + // Window titlebar rendering mode, CSD_SUPPORT_NONE if it's disabled + // for this window. + CSDSupportLevel mCSDSupportLevel; // If true, draw our own window titlebar. - bool mIsCSDEnabled; + bool mDrawInTitlebar; // Draggable titlebar region maintained by UpdateWindowDraggingRegion LayoutDeviceIntRegion mDraggableRegion;