Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 7933f3c

Browse files
committed
Bug 1667851 [Wayland] Guess subsurface offset from window decorations size, r=jhorak
- Try to set subsurface offset even if we mozcontainer size allocation is not finished. Use window decoration size for it. - Add more logging to mozcontainer code. Depends on D104549 Differential Revision: https://phabricator.services.mozilla.com/D104550
1 parent bddb899 commit 7933f3c

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

widget/gtk/MozContainerWayland.cpp

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* mContainer size/position is known.
3636
* It calls moz_container_wayland_surface_create_locked(), registers
3737
* a frame callback handler
38-
* (moz_container_wayland_frame_callback_handler()).
38+
* moz_container_wayland_frame_callback_handler().
3939
*
4040
* 2) moz_container_wayland_frame_callback_handler() is called
4141
* when wl_surface owned by mozContainer is ready.
@@ -86,6 +86,11 @@ static void moz_container_wayland_set_scale_factor_locked(
8686
static void moz_container_wayland_set_opaque_region_locked(
8787
MozContainer* container);
8888

89+
static nsWindow* moz_container_get_nsWindow(MozContainer* container) {
90+
gpointer user_data = g_object_get_data(G_OBJECT(container), "nsWindow");
91+
return static_cast<nsWindow*>(user_data);
92+
}
93+
8994
// Imlemented in MozContainer.cpp
9095
void moz_container_realize(GtkWidget* widget);
9196

@@ -167,17 +172,6 @@ void moz_container_wayland_add_initial_draw_callback(
167172
container->wl_container.initial_draw_cbs.push_back(initial_draw_cb);
168173
}
169174

170-
wl_surface* moz_gtk_widget_get_wl_surface(GtkWidget* aWidget) {
171-
GdkWindow* window = gtk_widget_get_window(aWidget);
172-
wl_surface* surface = gdk_wayland_window_get_wl_surface(window);
173-
174-
LOGWAYLAND(("moz_gtk_widget_get_wl_surface [%p] wl_surface %p ID %d\n",
175-
(void*)aWidget, (void*)surface,
176-
surface ? wl_proxy_get_id((struct wl_proxy*)surface) : -1));
177-
178-
return surface;
179-
}
180-
181175
static void moz_container_wayland_frame_callback_handler(
182176
void* data, struct wl_callback* callback, uint32_t time) {
183177
MozContainerWayland* wl_container = &MOZ_CONTAINER(data)->wl_container;
@@ -327,13 +321,10 @@ static void moz_container_wayland_set_opaque_region(MozContainer* container) {
327321

328322
static void moz_container_wayland_set_scale_factor_locked(
329323
MozContainer* container) {
330-
gpointer user_data = g_object_get_data(G_OBJECT(container), "nsWindow");
331-
nsWindow* wnd = static_cast<nsWindow*>(user_data);
324+
nsWindow* window = moz_container_get_nsWindow(container);
325+
int scale = window ? window->GdkScaleFactor() : 1;
332326

333-
int scale = 1;
334-
if (wnd) {
335-
scale = wnd->GdkScaleFactor();
336-
}
327+
LOGWAYLAND(("%s [%p] scale %d\n", __FUNCTION__, (void*)container, scale));
337328
wl_surface_set_buffer_scale(container->wl_container.surface, scale);
338329
}
339330

@@ -348,25 +339,22 @@ static bool moz_container_wayland_surface_create_locked(
348339
MozContainer* container) {
349340
MozContainerWayland* wl_container = &container->wl_container;
350341

351-
LOGWAYLAND(("%s [%p] surface %p ready_to_draw %d\n", __FUNCTION__,
352-
(void*)container, (void*)wl_container->surface,
353-
wl_container->ready_to_draw));
342+
LOGWAYLAND(("%s [%p]\n", __FUNCTION__, (void*)container));
354343

355-
wl_surface* parent_surface =
356-
moz_gtk_widget_get_wl_surface(GTK_WIDGET(container));
344+
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
345+
wl_surface* parent_surface = gdk_wayland_window_get_wl_surface(window);
357346
if (!parent_surface) {
358-
NS_WARNING(
359-
"moz_container_wayland_surface_create_locked(): Missing parent "
360-
"surface!");
347+
LOGWAYLAND((" Failed - missing parent surface!"));
361348
return false;
362349
}
350+
LOGWAYLAND((" gtk wl_surface %p ID %d\n", (void*)parent_surface,
351+
wl_proxy_get_id((struct wl_proxy*)parent_surface)));
363352

364353
// Available as of GTK 3.8+
365354
struct wl_compositor* compositor = WaylandDisplayGet()->GetCompositor();
366355
wl_container->surface = wl_compositor_create_surface(compositor);
367356
if (!wl_container->surface) {
368-
NS_WARNING(
369-
"moz_container_wayland_surface_create_locked(): can't create surface!");
357+
LOGWAYLAND((" Failed - can't create surface!"));
370358
return false;
371359
}
372360

@@ -375,13 +363,20 @@ static bool moz_container_wayland_surface_create_locked(
375363
wl_container->surface, parent_surface);
376364
if (!wl_container->subsurface) {
377365
g_clear_pointer(&wl_container->surface, wl_surface_destroy);
378-
NS_WARNING(
379-
"moz_container_wayland_surface_create_locked(): can't create "
380-
"sub-surface!");
366+
LOGWAYLAND((" Failed - can't create sub-surface!"));
381367
return false;
382368
}
383369
wl_subsurface_set_desync(wl_container->subsurface);
384370

371+
// Try to guess subsurface offset to avoid potential flickering.
372+
int dx, dy;
373+
if (moz_container_get_nsWindow(container)->GetCSDDecorationOffset(&dx, &dy)) {
374+
wl_container->subsurface_dx = dx;
375+
wl_container->subsurface_dy = dy;
376+
wl_subsurface_set_position(wl_container->subsurface, dx, dy);
377+
LOGWAYLAND((" guessing subsurface position %d %d\n", dx, dy));
378+
}
379+
385380
// Route input to parent wl_surface owned by Gtk+ so we get input
386381
// events from Gtk+.
387382
wl_region* region = wl_compositor_create_region(compositor);
@@ -396,12 +391,15 @@ static bool moz_container_wayland_surface_create_locked(
396391
wl_container->frame_callback_handler = wl_surface_frame(parent_surface);
397392
wl_callback_add_listener(wl_container->frame_callback_handler,
398393
&moz_container_frame_listener, container);
394+
LOGWAYLAND((
395+
" created frame callback ID %d\n",
396+
wl_proxy_get_id((struct wl_proxy*)wl_container->frame_callback_handler)));
399397

400398
wl_surface_commit(wl_container->surface);
401399
wl_display_flush(WaylandDisplayGet()->GetDisplay());
402400

403-
LOGWAYLAND(("%s [%p] created surface %p\n", __FUNCTION__, (void*)container,
404-
(void*)wl_container->surface));
401+
LOGWAYLAND((" created surface %p ID %p\n", (void*)wl_container->surface,
402+
wl_proxy_get_id((struct wl_proxy*)wl_container->surface)));
405403
return true;
406404
}
407405

widget/gtk/WindowSurfaceWayland.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,8 +1013,9 @@ bool WindowSurfaceWayland::FlushPendingCommitsLocked() {
10131013
MozContainer* container = mWindow->GetMozContainer();
10141014
wl_surface* waylandSurface = moz_container_wayland_surface_lock(container);
10151015
if (!waylandSurface) {
1016-
LOGWAYLAND((" [%p] mWindow->GetWaylandSurface() failed, delay commit.\n",
1017-
(void*)this));
1016+
LOGWAYLAND(
1017+
(" moz_container_wayland_surface_lock() failed, delay commit.\n",
1018+
(void*)this));
10181019

10191020
// Target window is not created yet - delay the commit. This can happen only
10201021
// when the window is newly created and there's no active

widget/gtk/nsWindow.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,13 +1072,26 @@ void nsWindow::SetSizeConstraints(const SizeConstraints& aConstraints) {
10721072
}
10731073

10741074
void nsWindow::AddCSDDecorationSize(int* aWidth, int* aHeight) {
1075-
if (mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) {
1075+
if (mSizeState == nsSizeMode_Normal &&
1076+
mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) {
10761077
GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel);
10771078
*aWidth += decorationSize.left + decorationSize.right;
10781079
*aHeight += decorationSize.top + decorationSize.bottom;
10791080
}
10801081
}
10811082

1083+
bool nsWindow::GetCSDDecorationOffset(int* aDx, int* aDy) {
1084+
if (mSizeState == nsSizeMode_Normal &&
1085+
mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) {
1086+
GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel);
1087+
*aDx = decorationSize.left;
1088+
*aDy = decorationSize.top;
1089+
return true;
1090+
} else {
1091+
return false;
1092+
}
1093+
}
1094+
10821095
void nsWindow::ApplySizeConstraints(void) {
10831096
if (mShell) {
10841097
GdkGeometry geometry;

widget/gtk/nsWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class nsWindow final : public nsBaseWidget {
264264

265265
void UpdateClientOffsetFromFrameExtents();
266266
void UpdateClientOffsetFromCSDWindow();
267+
bool GetCSDDecorationOffset(int* aDx, int* aDy);
267268

268269
void DispatchContextMenuEventFromMouseEvent(uint16_t domButton,
269270
GdkEventButton* aEvent);

0 commit comments

Comments
 (0)