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
This commit is contained in:
@@ -35,7 +35,7 @@
|
|||||||
* mContainer size/position is known.
|
* mContainer size/position is known.
|
||||||
* It calls moz_container_wayland_surface_create_locked(), registers
|
* It calls moz_container_wayland_surface_create_locked(), registers
|
||||||
* a frame callback handler
|
* a frame callback handler
|
||||||
* (moz_container_wayland_frame_callback_handler()).
|
* moz_container_wayland_frame_callback_handler().
|
||||||
*
|
*
|
||||||
* 2) moz_container_wayland_frame_callback_handler() is called
|
* 2) moz_container_wayland_frame_callback_handler() is called
|
||||||
* when wl_surface owned by mozContainer is ready.
|
* when wl_surface owned by mozContainer is ready.
|
||||||
@@ -86,6 +86,11 @@ static void moz_container_wayland_set_scale_factor_locked(
|
|||||||
static void moz_container_wayland_set_opaque_region_locked(
|
static void moz_container_wayland_set_opaque_region_locked(
|
||||||
MozContainer* container);
|
MozContainer* container);
|
||||||
|
|
||||||
|
static nsWindow* moz_container_get_nsWindow(MozContainer* container) {
|
||||||
|
gpointer user_data = g_object_get_data(G_OBJECT(container), "nsWindow");
|
||||||
|
return static_cast<nsWindow*>(user_data);
|
||||||
|
}
|
||||||
|
|
||||||
// Imlemented in MozContainer.cpp
|
// Imlemented in MozContainer.cpp
|
||||||
void moz_container_realize(GtkWidget* widget);
|
void moz_container_realize(GtkWidget* widget);
|
||||||
|
|
||||||
@@ -167,17 +172,6 @@ void moz_container_wayland_add_initial_draw_callback(
|
|||||||
container->wl_container.initial_draw_cbs.push_back(initial_draw_cb);
|
container->wl_container.initial_draw_cbs.push_back(initial_draw_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface* moz_gtk_widget_get_wl_surface(GtkWidget* aWidget) {
|
|
||||||
GdkWindow* window = gtk_widget_get_window(aWidget);
|
|
||||||
wl_surface* surface = gdk_wayland_window_get_wl_surface(window);
|
|
||||||
|
|
||||||
LOGWAYLAND(("moz_gtk_widget_get_wl_surface [%p] wl_surface %p ID %d\n",
|
|
||||||
(void*)aWidget, (void*)surface,
|
|
||||||
surface ? wl_proxy_get_id((struct wl_proxy*)surface) : -1));
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moz_container_wayland_frame_callback_handler(
|
static void moz_container_wayland_frame_callback_handler(
|
||||||
void* data, struct wl_callback* callback, uint32_t time) {
|
void* data, struct wl_callback* callback, uint32_t time) {
|
||||||
MozContainerWayland* wl_container = &MOZ_CONTAINER(data)->wl_container;
|
MozContainerWayland* wl_container = &MOZ_CONTAINER(data)->wl_container;
|
||||||
@@ -327,13 +321,10 @@ static void moz_container_wayland_set_opaque_region(MozContainer* container) {
|
|||||||
|
|
||||||
static void moz_container_wayland_set_scale_factor_locked(
|
static void moz_container_wayland_set_scale_factor_locked(
|
||||||
MozContainer* container) {
|
MozContainer* container) {
|
||||||
gpointer user_data = g_object_get_data(G_OBJECT(container), "nsWindow");
|
nsWindow* window = moz_container_get_nsWindow(container);
|
||||||
nsWindow* wnd = static_cast<nsWindow*>(user_data);
|
int scale = window ? window->GdkScaleFactor() : 1;
|
||||||
|
|
||||||
int scale = 1;
|
LOGWAYLAND(("%s [%p] scale %d\n", __FUNCTION__, (void*)container, scale));
|
||||||
if (wnd) {
|
|
||||||
scale = wnd->GdkScaleFactor();
|
|
||||||
}
|
|
||||||
wl_surface_set_buffer_scale(container->wl_container.surface, scale);
|
wl_surface_set_buffer_scale(container->wl_container.surface, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,25 +339,22 @@ static bool moz_container_wayland_surface_create_locked(
|
|||||||
MozContainer* container) {
|
MozContainer* container) {
|
||||||
MozContainerWayland* wl_container = &container->wl_container;
|
MozContainerWayland* wl_container = &container->wl_container;
|
||||||
|
|
||||||
LOGWAYLAND(("%s [%p] surface %p ready_to_draw %d\n", __FUNCTION__,
|
LOGWAYLAND(("%s [%p]\n", __FUNCTION__, (void*)container));
|
||||||
(void*)container, (void*)wl_container->surface,
|
|
||||||
wl_container->ready_to_draw));
|
|
||||||
|
|
||||||
wl_surface* parent_surface =
|
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
|
||||||
moz_gtk_widget_get_wl_surface(GTK_WIDGET(container));
|
wl_surface* parent_surface = gdk_wayland_window_get_wl_surface(window);
|
||||||
if (!parent_surface) {
|
if (!parent_surface) {
|
||||||
NS_WARNING(
|
LOGWAYLAND((" Failed - missing parent surface!"));
|
||||||
"moz_container_wayland_surface_create_locked(): Missing parent "
|
|
||||||
"surface!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
LOGWAYLAND((" gtk wl_surface %p ID %d\n", (void*)parent_surface,
|
||||||
|
wl_proxy_get_id((struct wl_proxy*)parent_surface)));
|
||||||
|
|
||||||
// Available as of GTK 3.8+
|
// Available as of GTK 3.8+
|
||||||
struct wl_compositor* compositor = WaylandDisplayGet()->GetCompositor();
|
struct wl_compositor* compositor = WaylandDisplayGet()->GetCompositor();
|
||||||
wl_container->surface = wl_compositor_create_surface(compositor);
|
wl_container->surface = wl_compositor_create_surface(compositor);
|
||||||
if (!wl_container->surface) {
|
if (!wl_container->surface) {
|
||||||
NS_WARNING(
|
LOGWAYLAND((" Failed - can't create surface!"));
|
||||||
"moz_container_wayland_surface_create_locked(): can't create surface!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,13 +363,20 @@ static bool moz_container_wayland_surface_create_locked(
|
|||||||
wl_container->surface, parent_surface);
|
wl_container->surface, parent_surface);
|
||||||
if (!wl_container->subsurface) {
|
if (!wl_container->subsurface) {
|
||||||
g_clear_pointer(&wl_container->surface, wl_surface_destroy);
|
g_clear_pointer(&wl_container->surface, wl_surface_destroy);
|
||||||
NS_WARNING(
|
LOGWAYLAND((" Failed - can't create sub-surface!"));
|
||||||
"moz_container_wayland_surface_create_locked(): can't create "
|
|
||||||
"sub-surface!");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wl_subsurface_set_desync(wl_container->subsurface);
|
wl_subsurface_set_desync(wl_container->subsurface);
|
||||||
|
|
||||||
|
// Try to guess subsurface offset to avoid potential flickering.
|
||||||
|
int dx, dy;
|
||||||
|
if (moz_container_get_nsWindow(container)->GetCSDDecorationOffset(&dx, &dy)) {
|
||||||
|
wl_container->subsurface_dx = dx;
|
||||||
|
wl_container->subsurface_dy = dy;
|
||||||
|
wl_subsurface_set_position(wl_container->subsurface, dx, dy);
|
||||||
|
LOGWAYLAND((" guessing subsurface position %d %d\n", dx, dy));
|
||||||
|
}
|
||||||
|
|
||||||
// Route input to parent wl_surface owned by Gtk+ so we get input
|
// Route input to parent wl_surface owned by Gtk+ so we get input
|
||||||
// events from Gtk+.
|
// events from Gtk+.
|
||||||
wl_region* region = wl_compositor_create_region(compositor);
|
wl_region* region = wl_compositor_create_region(compositor);
|
||||||
@@ -396,12 +391,15 @@ static bool moz_container_wayland_surface_create_locked(
|
|||||||
wl_container->frame_callback_handler = wl_surface_frame(parent_surface);
|
wl_container->frame_callback_handler = wl_surface_frame(parent_surface);
|
||||||
wl_callback_add_listener(wl_container->frame_callback_handler,
|
wl_callback_add_listener(wl_container->frame_callback_handler,
|
||||||
&moz_container_frame_listener, container);
|
&moz_container_frame_listener, container);
|
||||||
|
LOGWAYLAND((
|
||||||
|
" created frame callback ID %d\n",
|
||||||
|
wl_proxy_get_id((struct wl_proxy*)wl_container->frame_callback_handler)));
|
||||||
|
|
||||||
wl_surface_commit(wl_container->surface);
|
wl_surface_commit(wl_container->surface);
|
||||||
wl_display_flush(WaylandDisplayGet()->GetDisplay());
|
wl_display_flush(WaylandDisplayGet()->GetDisplay());
|
||||||
|
|
||||||
LOGWAYLAND(("%s [%p] created surface %p\n", __FUNCTION__, (void*)container,
|
LOGWAYLAND((" created surface %p ID %p\n", (void*)wl_container->surface,
|
||||||
(void*)wl_container->surface));
|
wl_proxy_get_id((struct wl_proxy*)wl_container->surface)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1013,8 +1013,9 @@ bool WindowSurfaceWayland::FlushPendingCommitsLocked() {
|
|||||||
MozContainer* container = mWindow->GetMozContainer();
|
MozContainer* container = mWindow->GetMozContainer();
|
||||||
wl_surface* waylandSurface = moz_container_wayland_surface_lock(container);
|
wl_surface* waylandSurface = moz_container_wayland_surface_lock(container);
|
||||||
if (!waylandSurface) {
|
if (!waylandSurface) {
|
||||||
LOGWAYLAND((" [%p] mWindow->GetWaylandSurface() failed, delay commit.\n",
|
LOGWAYLAND(
|
||||||
(void*)this));
|
(" moz_container_wayland_surface_lock() failed, delay commit.\n",
|
||||||
|
(void*)this));
|
||||||
|
|
||||||
// Target window is not created yet - delay the commit. This can happen only
|
// Target window is not created yet - delay the commit. This can happen only
|
||||||
// when the window is newly created and there's no active
|
// when the window is newly created and there's no active
|
||||||
|
|||||||
@@ -1072,13 +1072,26 @@ void nsWindow::SetSizeConstraints(const SizeConstraints& aConstraints) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::AddCSDDecorationSize(int* aWidth, int* aHeight) {
|
void nsWindow::AddCSDDecorationSize(int* aWidth, int* aHeight) {
|
||||||
if (mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) {
|
if (mSizeState == nsSizeMode_Normal &&
|
||||||
|
mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) {
|
||||||
GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel);
|
GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel);
|
||||||
*aWidth += decorationSize.left + decorationSize.right;
|
*aWidth += decorationSize.left + decorationSize.right;
|
||||||
*aHeight += decorationSize.top + decorationSize.bottom;
|
*aHeight += decorationSize.top + decorationSize.bottom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nsWindow::GetCSDDecorationOffset(int* aDx, int* aDy) {
|
||||||
|
if (mSizeState == nsSizeMode_Normal &&
|
||||||
|
mCSDSupportLevel == GTK_DECORATION_CLIENT && mDrawInTitlebar) {
|
||||||
|
GtkBorder decorationSize = GetCSDDecorationSize(!mIsTopLevel);
|
||||||
|
*aDx = decorationSize.left;
|
||||||
|
*aDy = decorationSize.top;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void nsWindow::ApplySizeConstraints(void) {
|
void nsWindow::ApplySizeConstraints(void) {
|
||||||
if (mShell) {
|
if (mShell) {
|
||||||
GdkGeometry geometry;
|
GdkGeometry geometry;
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ class nsWindow final : public nsBaseWidget {
|
|||||||
|
|
||||||
void UpdateClientOffsetFromFrameExtents();
|
void UpdateClientOffsetFromFrameExtents();
|
||||||
void UpdateClientOffsetFromCSDWindow();
|
void UpdateClientOffsetFromCSDWindow();
|
||||||
|
bool GetCSDDecorationOffset(int* aDx, int* aDy);
|
||||||
|
|
||||||
void DispatchContextMenuEventFromMouseEvent(uint16_t domButton,
|
void DispatchContextMenuEventFromMouseEvent(uint16_t domButton,
|
||||||
GdkEventButton* aEvent);
|
GdkEventButton* aEvent);
|
||||||
|
|||||||
Reference in New Issue
Block a user