Fix crashes during scale changes

* compositor.h (struct _XdgRoleImplementationFuncs): New
function `rescale'.
* subsurface.c (Rescale): If the parent has been detached, don't
call MoveFractional.
* xdg_surface.c (Rescale): Call rescale hook.
* xdg_toplevel.c (SendOutputBounds): Check that some fields are
present.  Scale geometry correctly.
(Rescale): New function.
(ShowWindowMenu): Scale coordinates correctly.
(XLGetXdgToplevel): Add Rescale hook.
This commit is contained in:
hujianwei 2022-11-15 12:17:26 +00:00
parent 62a055983c
commit e7b89cec3b
4 changed files with 51 additions and 4 deletions

View file

@ -1344,6 +1344,7 @@ struct _XdgRoleImplementationFuncs
void (*outputs_changed) (Role *, XdgRoleImplementation *);
void (*after_commit) (Role *, Surface *, XdgRoleImplementation *);
void (*activate) (Role *, XdgRoleImplementation *, int, Time);
void (*rescale) (Role *, XdgRoleImplementation *);
};
struct _XdgRoleImplementation

View file

@ -884,6 +884,11 @@ Rescale (Surface *surface, Role *role)
subsurface = SubsurfaceFromRole (role);
/* If the parent has been detached, return immediately. */
if (!subsurface->parent)
return;
/* The scale factor changed; move the subsurface to the new correct
position. */

View file

@ -1332,6 +1332,11 @@ Rescale (Surface *surface, Role *role)
if (xdg_role->impl->funcs.handle_geometry_change)
xdg_role->impl->funcs.handle_geometry_change (role, xdg_role->impl);
/* Also update the configure bounds if necessary. */
if (xdg_role->impl->funcs.rescale)
xdg_role->impl->funcs.rescale (role, xdg_role->impl);
}
static void

View file

@ -1235,12 +1235,46 @@ AckConfigure (Role *role, XdgRoleImplementation *impl, uint32_t serial)
static void
SendOutputBounds (XdgToplevel *toplevel)
{
int x_min, y_min, x_max, y_max;
int x_min, y_min, x_max, y_max, width, height;
XLGetMaxOutputBounds (&x_min, &y_min, &x_max, &y_max);
if (!toplevel->role->surface || !toplevel->role->resource)
return;
/* Adjust these bounds by the scale factor of the surface. The
bounds are specified in the window coordinate system, and have to
be converted to the surface ones. */
TruncateScaleToSurface (toplevel->role->surface,
x_max - x_min + 1,
y_max - y_min + 1,
&width, &height);
xdg_toplevel_send_configure_bounds (toplevel->resource,
x_max - x_min + 1,
y_max - y_min + 1);
width, height);
}
static void
Rescale (Role *role, XdgRoleImplementation *impl)
{
XdgToplevel *toplevel;
int width, height;
toplevel = ToplevelFromRoleImpl (impl);
if (!toplevel->resource)
return;
/* The scale changed. Send the output bounds again if
necessary. */
if (wl_resource_get_version (toplevel->resource) < 4)
return;
SendOutputBounds (toplevel);
CurrentWindowGeometry (toplevel, &width, &height);
SendConfigure (toplevel, width, height);
}
/* Forward declaration. */
@ -1971,7 +2005,8 @@ ShowWindowMenu (struct wl_client *client, struct wl_resource *resource,
XLXdgRoleCurrentRootPosition (toplevel->role, &root_x, &root_y);
XLSeatShowWindowMenu (seat, toplevel->role->surface,
root_x + x, root_y + y);
root_x + x * toplevel->role->surface->factor,
root_y + y * toplevel->role->surface->factor);
}
static void
@ -2363,6 +2398,7 @@ XLGetXdgToplevel (struct wl_client *client, struct wl_resource *resource,
toplevel->impl.funcs.outputs_changed = OutputsChanged;
toplevel->impl.funcs.after_commit = AfterCommit;
toplevel->impl.funcs.activate = Activate;
toplevel->impl.funcs.rescale = Rescale;
if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED))
/* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing