Bug 1456898 - Implement and use solid-csd decoration style to get window offset when solid-csd is used by mShell toplevel window, r?jhorak
Implement and use solid-csd decoration style to get window offset when solid-csd is used by mShell toplevel window.
Also does not apply margin (resize handler sizes) on popup window as well as Gtk+ do in get_shadow_width().
MozReview-Commit-ID: 9xozp9CCVJj
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -1288,16 +1288,24 @@ GetCssNodeStyleInternal(WidgetNodeType a
case MOZ_GTK_WINDOW_DECORATION:
{
GtkStyleContext* parentStyle =
CreateSubStyleWithClass(MOZ_GTK_WINDOW, "csd");
style = CreateCSSNode("decoration", parentStyle);
g_object_unref(parentStyle);
break;
}
+ case MOZ_GTK_WINDOW_DECORATION_SOLID:
+ {
+ GtkStyleContext* parentStyle =
+ CreateSubStyleWithClass(MOZ_GTK_WINDOW, "solid-csd");
+ style = CreateCSSNode("decoration", parentStyle);
+ g_object_unref(parentStyle);
+ break;
+ }
default:
return GetWidgetRootStyle(aNodeType);
}
MOZ_ASSERT(style, "missing style context for node type");
sStyleStorage[aNodeType] = style;
return style;
}
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -3115,19 +3115,23 @@ GetActiveScrollbarMetrics(GtkOrientation
return metrics;
}
/*
* get_shadow_width() from gtkwindow.c is not public so we need
* to implement it.
*/
bool
-GetCSDDecorationSize(GtkBorder* aDecorationSize)
+GetCSDDecorationSize(GtkWindow *aGtkWindow, GtkBorder* aDecorationSize)
{
- GtkStyleContext* context = GetStyleContext(MOZ_GTK_WINDOW_DECORATION);
+ GtkStyleContext* context = gtk_widget_get_style_context(GTK_WIDGET(aGtkWindow));
+ bool solidDecorations = gtk_style_context_has_class(context, "solid-csd");
+ context = GetStyleContext(solidDecorations ?
+ MOZ_GTK_WINDOW_DECORATION_SOLID :
+ MOZ_GTK_WINDOW_DECORATION);
/* Always sum border + padding */
GtkBorder padding;
GtkStateFlags state = gtk_style_context_get_state(context);
gtk_style_context_get_border(context, state, aDecorationSize);
gtk_style_context_get_padding(context, state, &padding);
*aDecorationSize += padding;
@@ -3146,20 +3150,24 @@ GetCSDDecorationSize(GtkBorder* aDecorat
GdkRectangle clip;
sGtkRenderBackgroundGetClip(context, 0, 0, 0, 0, &clip);
extents.top = -clip.y;
extents.right = clip.width + clip.x;
extents.bottom = clip.height + clip.y;
extents.left = -clip.x;
- extents.top = MAX(extents.top, margin.top);
- extents.right = MAX(extents.right, margin.right);
- extents.bottom = MAX(extents.bottom, margin.bottom);
- extents.left = MAX(extents.left, margin.left);
+ // Margin is used for resize grip size - it's not present on
+ // popup windows.
+ if (gtk_window_get_window_type(aGtkWindow) != GTK_WINDOW_POPUP) {
+ extents.top = MAX(extents.top, margin.top);
+ extents.right = MAX(extents.right, margin.right);
+ extents.bottom = MAX(extents.bottom, margin.bottom);
+ extents.left = MAX(extents.left, margin.left);
+ }
} else {
/* If we can't get shadow extents use decoration-resize-handle instead
* as a workaround. This is inspired by update_border_windows()
* from gtkwindow.c although this is not 100% accurate as we emulate
* the extents here.
*/
gint handle;
gtk_widget_style_get(GetWidget(MOZ_GTK_WINDOW),
--- a/widget/gtk/gtkdrawing.h
+++ b/widget/gtk/gtkdrawing.h
@@ -334,16 +334,17 @@ typedef enum {
/* MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE is a state of
* MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE button and it's used as
* an icon placeholder only.
*/
MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE,
/* Client-side window decoration node. Available on GTK 3.20+. */
MOZ_GTK_WINDOW_DECORATION,
+ MOZ_GTK_WINDOW_DECORATION_SOLID,
MOZ_GTK_WIDGET_NODE_COUNT
} WidgetNodeType;
/*** General library functions ***/
/**
* Initializes the drawing library. You must call this function
* prior to using any other functionality.
@@ -614,20 +615,21 @@ GetToolbarButtonMetrics(WidgetNodeType a
TOOLBAR_BUTTONS wide.
*
* returns: Number of returned entries at aButtonLayout.
*/
int
GetGtkHeaderBarButtonLayout(WidgetNodeType* aButtonLayout, int aMaxButtonNums);
/**
- * Get size of CSD window extents.
+ * Get size of CSD window extents of given GtkWindow.
*
+ * aGtkWindow [IN] Decorated window.
* aDecorationSize [OUT] Returns calculated (or estimated) decoration
- * size of CSD window.
+ * size of given aGtkWindow.
*
* returns: True if we have extract decoration size (for GTK 3.20+)
* False if we have only an estimation (for GTK+ before 3.20+)
*/
bool
-GetCSDDecorationSize(GtkBorder* aDecorationSize);
+GetCSDDecorationSize(GtkWindow *aGtkWindow, GtkBorder* aDecorationSize);
#endif
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6603,17 +6603,17 @@ nsWindow::ClearCachedResources()
*/
void
nsWindow::UpdateClientOffsetForCSDWindow()
{
// _NET_FRAME_EXTENTS is not set on client decorated windows,
// so we need to read offset between mContainer and toplevel mShell
// window.
GtkBorder decorationSize;
- GetCSDDecorationSize(&decorationSize);
+ GetCSDDecorationSize(GTK_WINDOW(mShell), &decorationSize);
mClientOffset = nsIntPoint(decorationSize.left, decorationSize.top);
// Send a WindowMoved notification. This ensures that TabParent
// picks up the new client offset and sends it to the child process
// if appropriate.
NotifyWindowMoved(mBounds.x, mBounds.y);
}