Bug 1283299 - Part 7: Report GTK CSD shadow extents to window manager. r?karlt
MozReview-Commit-ID: bRlcu4RGlH
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -124,16 +124,18 @@ using namespace mozilla::widget;
#include "nsIDOMWheelEvent.h"
#include "NativeKeyBindings.h"
#include <dlfcn.h>
#include "mozilla/layers/APZCTreeManager.h"
+#include "gtkdrawing.h"
+
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::widget;
using namespace mozilla::layers;
using mozilla::gl::GLContext;
// Don't put more than this many rects in the dirty region, just fluff
// out to the bounding-box if there are more
@@ -3359,16 +3361,18 @@ nsWindow::OnWindowStateEvent(GtkWidget *
else {
LOG(("\tNormal\n"));
mSizeState = nsSizeMode_Normal;
#ifdef ACCESSIBILITY
DispatchRestoreEventAccessible();
#endif //ACCESSIBILITY
}
+ UpdateClientShadowWidth();
+
if (mWidgetListener) {
mWidgetListener->SizeModeChanged(mSizeState);
if (aEvent->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
mWidgetListener->FullscreenChanged(
aEvent->new_window_state & GDK_WINDOW_STATE_FULLSCREEN);
}
}
}
@@ -3423,16 +3427,17 @@ nsWindow::OnCompositedChanged()
{
if (mWidgetListener) {
nsIPresShell* presShell = mWidgetListener->GetPresShell();
if (presShell) {
// Update CSD after the change in alpha visibility
presShell->ThemeChanged();
}
}
+ UpdateClientShadowWidth();
CleanLayerManagerRecursive();
}
void
nsWindow::DispatchDragEvent(EventMessage aMsg, const LayoutDeviceIntPoint& aRefPoint,
guint aTime)
{
WidgetDragEvent event(true, aMsg, this);
@@ -6901,16 +6906,18 @@ nsWindow::SetDrawsInTitlebar(bool aState
return;
if (mShell) {
NS_WARNING("gtk_window_set_decorated may not have any effect when called on a window that is already visible.");
gtk_window_set_decorated(GTK_WINDOW(mShell), !aState);
}
mDrawsInTitlebar = aState;
+
+ UpdateClientShadowWidth();
}
bool
nsWindow::HasARGBVisual() const
{
if (!mGdkWindow) {
NS_WARNING("nsWindow::HasARGBVisual called before realization!");
return false;
@@ -7207,8 +7214,25 @@ nsWindow::RoundsWidgetCoordinatesTo()
return GdkScaleFactor();
}
bool
nsWindow::IsClientDecorated() const
{
return mDrawsInTitlebar;
}
+void
+nsWindow::UpdateClientShadowWidth()
+{
+ if (gtk_check_version(3, 12, 0) != nullptr)
+ return;
+
+ // Shadows are only used for normal, non-solid client windows with CSD.
+ gint top = 0, right = 0, bottom = 0, left = 0;
+ if (IsClientDecorated() && !UseSolidCSD() && mSizeState == nsSizeMode_Normal) {
+ moz_gtk_get_window_decoration_extents(&top, &right, &bottom, &left);
+ }
+
+ static auto sGdkWindowSetShadowWidth =
+ (void (*)(GdkWindow*, gint, gint, gint, gint))
+ dlsym(RTLD_DEFAULT, "gdk_window_set_shadow_width");
+ sGdkWindowSetShadowWidth(mGdkWindow, left, right, top, bottom);
+}
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -394,16 +394,19 @@ protected:
GtkWidget* aNewContainer,
GdkWindow* aNewParentWindow,
GtkWidget* aOldContainer);
virtual void RegisterTouchWindow() override;
// Decorations
bool IsClientDecorated() const;
+ // Informs the window manager about the size of the shadows surrounding
+ // a client-side decorated window.
+ void UpdateClientShadowWidth();
nsCOMPtr<nsIWidget> mParent;
// Is this a toplevel window?
bool mIsTopLevel;
// Has this widget been destroyed yet?
bool mIsDestroyed;
// Should we send resize events on all resizes?