Bug 1603419 [Linux] Cache GetCSDDecorationSize() results, r=jhorak

Differential Revision: https://phabricator.services.mozilla.com/D56915

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Martin Stransky 2019-12-13 07:44:48 +00:00
Родитель 142f16f7de
Коммит 9d06e4311a
3 изменённых файлов: 41 добавлений и 22 удалений

Просмотреть файл

@ -30,6 +30,8 @@ static ToggleGTKMetrics sRadioMetrics;
static ToggleGTKMetrics sMenuRadioMetrics;
static ToggleGTKMetrics sMenuCheckboxMetrics;
static ToolbarGTKMetrics sToolbarMetrics;
static CSDWindowDecorationSize sToplevelWindowDecorationSize;
static CSDWindowDecorationSize sPopupWindowDecorationSize;
#define ARROW_UP 0
#define ARROW_DOWN G_PI
@ -217,6 +219,8 @@ void moz_gtk_refresh() {
sMenuCheckboxMetrics.initialized = false;
sMenuRadioMetrics.initialized = false;
sToolbarMetrics.initialized = false;
sToplevelWindowDecorationSize.initialized = false;
sPopupWindowDecorationSize.initialized = false;
/* This will destroy all of our widgets */
ResetWidgetCache();
@ -2956,19 +2960,21 @@ const ScrollbarGTKMetrics* GetActiveScrollbarMetrics(
* get_shadow_width() from gtkwindow.c is not public so we need
* to implement it.
*/
bool GetCSDDecorationSize(GtkWindow* aGtkWindow, GtkBorder* aDecorationSize) {
void InitWindowDecorationSize(CSDWindowDecorationSize* sWindowDecorationSize,
bool aPopupWindow) {
// Available on GTK 3.20+.
static auto sGtkRenderBackgroundGetClip = (void (*)(
GtkStyleContext*, gdouble, gdouble, gdouble, gdouble,
GdkRectangle*))dlsym(RTLD_DEFAULT, "gtk_render_background_get_clip");
if (!sGtkRenderBackgroundGetClip) {
*aDecorationSize = {0, 0, 0, 0};
return false;
sWindowDecorationSize->decorationSize = {0, 0, 0, 0};
return;
}
GtkStyleContext* context =
gtk_widget_get_style_context(GTK_WIDGET(aGtkWindow));
// Scale factor is applied later when decoration size is used for actual
// gtk windows.
GtkStyleContext* context = GetStyleContext(MOZ_GTK_WINDOW, 1);
bool solidDecorations = gtk_style_context_has_class(context, "solid-csd");
context = GetStyleContext(solidDecorations ? MOZ_GTK_WINDOW_DECORATION_SOLID
: MOZ_GTK_WINDOW_DECORATION);
@ -2976,9 +2982,10 @@ bool GetCSDDecorationSize(GtkWindow* aGtkWindow, GtkBorder* aDecorationSize) {
/* 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_border(context, state,
&sWindowDecorationSize->decorationSize);
gtk_style_context_get_padding(context, state, &padding);
*aDecorationSize += padding;
sWindowDecorationSize->decorationSize += padding;
GtkBorder margin;
gtk_style_context_get_margin(context, state, &margin);
@ -2996,15 +3003,24 @@ bool GetCSDDecorationSize(GtkWindow* aGtkWindow, GtkBorder* aDecorationSize) {
// Margin is used for resize grip size - it's not present on
// popup windows.
if (gtk_window_get_window_type(aGtkWindow) != GTK_WINDOW_POPUP) {
if (!aPopupWindow) {
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);
}
*aDecorationSize += extents;
return true;
sWindowDecorationSize->decorationSize += extents;
}
GtkBorder GetCSDDecorationSize(bool aIsPopup) {
auto metrics =
aIsPopup ? &sPopupWindowDecorationSize : &sToplevelWindowDecorationSize;
if (!metrics->initialized) {
InitWindowDecorationSize(metrics, aIsPopup);
metrics->initialized = true;
}
return metrics->decorationSize;
}
/* cairo_t *cr argument has to be a system-cairo. */

Просмотреть файл

@ -106,6 +106,11 @@ typedef struct {
ToolbarButtonGTKMetrics button[TOOLBAR_BUTTONS];
} ToolbarGTKMetrics;
typedef struct {
bool initialized;
GtkBorder decorationSize;
} CSDWindowDecorationSize;
typedef enum {
MOZ_GTK_STEPPER_DOWN = 1 << 0,
MOZ_GTK_STEPPER_BOTTOM = 1 << 1,
@ -611,15 +616,12 @@ int GetGtkHeaderBarButtonLayout(WidgetNodeType* aButtonLayout,
bool* aReversedButtonsPlacement);
/**
* Get size of CSD window extents of given GtkWindow.
* Get size of CSD window extents.
*
* aGtkWindow [IN] Decorated window.
* aDecorationSize [OUT] Returns calculated (or estimated) decoration
* size of given aGtkWindow.
* aIsPopup: [IN] Get decoration size for popup or toplevel window.
*
* returns: True if we have extract decoration size (for GTK 3.20+)
* False if we have only an estimation (for GTK+ before 3.20+)
* returns: Calculated (or estimated) decoration size of given aGtkWindow.
*/
bool GetCSDDecorationSize(GtkWindow* aGtkWindow, GtkBorder* aDecorationSize);
GtkBorder GetCSDDecorationSize(bool aIsPopup);
#endif

Просмотреть файл

@ -4829,7 +4829,8 @@ void nsWindow::UpdateOpaqueRegion(const LayoutDeviceIntRegion& aOpaqueRegion) {
GtkBorder decorationSize = {0, 0, 0, 0};
if (mCSDSupportLevel == CSD_SUPPORT_CLIENT &&
mSizeState == nsSizeMode_Normal) {
GetCSDDecorationSize(GTK_WINDOW(mShell), &decorationSize);
decorationSize = GetCSDDecorationSize(
gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP);
}
int scale = GdkScaleFactor();
@ -6834,8 +6835,8 @@ void nsWindow::UpdateClientOffsetForCSDWindow() {
// so we need to read offset between mContainer and toplevel mShell
// window.
if (mSizeState == nsSizeMode_Normal) {
GtkBorder decorationSize;
GetCSDDecorationSize(GTK_WINDOW(mShell), &decorationSize);
GtkBorder decorationSize = GetCSDDecorationSize(
gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP);
mClientOffset = nsIntPoint(decorationSize.left, decorationSize.top);
} else {
mClientOffset = nsIntPoint(0, 0);
@ -7662,8 +7663,8 @@ void nsWindow::LockAspectRatio(bool aShouldLock) {
float height = (float)mBounds.Height() / scale;
if (mCSDSupportLevel == CSD_SUPPORT_CLIENT) {
GtkBorder decorationSize;
GetCSDDecorationSize(GTK_WINDOW(mShell), &decorationSize);
GtkBorder decorationSize = GetCSDDecorationSize(
gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP);
width += decorationSize.left + decorationSize.right;
height += decorationSize.top + decorationSize.bottom;
}