forked from 12to11/12to11
Send correct surface bounds to xdg_toplevel resources
* compositor.h (struct _RoleFuncs) (struct _XdgRoleImplementationFuncs): New role functions `outputs_changed'. * output.c (NoticeOutputsMaybeChanged): Call surface outputs_changed hook if it exists. (XLGetMaxOutputBounds): New function. * xdg_surface.c (OutputsChanged): New function. (XLGetXdgSurface): Add new role function. * xdg_toplevel.c (CurrentWindowGeometry): New function. (SendStates): Factor out geometry calculation to that function. (SendOutputBounds): New function. (Commit, OutputsChanged): Send output bounds whenever appropriate. (XLGetXdgToplevel): Add new impl func.
This commit is contained in:
parent
6e062e2e2f
commit
276445926e
4 changed files with 129 additions and 10 deletions
|
@ -1083,6 +1083,7 @@ struct _RoleFuncs
|
||||||
void (*note_child_synced) (Surface *, Role *);
|
void (*note_child_synced) (Surface *, Role *);
|
||||||
void (*select_extra_events) (Surface *, Role *, unsigned long);
|
void (*select_extra_events) (Surface *, Role *, unsigned long);
|
||||||
void (*note_focus) (Surface *, Role *, FocusMode);
|
void (*note_focus) (Surface *, Role *, FocusMode);
|
||||||
|
void (*outputs_changed) (Surface *, Role *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Role
|
struct _Role
|
||||||
|
@ -1156,6 +1157,7 @@ extern void *XLAddScaleChangeCallback (void *, void (*) (void *, int));
|
||||||
extern void XLRemoveScaleChangeCallback (void *);
|
extern void XLRemoveScaleChangeCallback (void *);
|
||||||
extern void XLClearOutputs (Surface *);
|
extern void XLClearOutputs (Surface *);
|
||||||
extern void XLOutputSetChangeFunction (void (*) (Time));
|
extern void XLOutputSetChangeFunction (void (*) (Time));
|
||||||
|
extern void XLGetMaxOutputBounds (int *, int *, int *, int *);
|
||||||
|
|
||||||
/* Defined in atoms.c. */
|
/* Defined in atoms.c. */
|
||||||
|
|
||||||
|
@ -1275,6 +1277,7 @@ struct _XdgRoleImplementationFuncs
|
||||||
void (*commit_inside_frame) (Role *, XdgRoleImplementation *);
|
void (*commit_inside_frame) (Role *, XdgRoleImplementation *);
|
||||||
Bool (*is_window_mapped) (Role *, XdgRoleImplementation *);
|
Bool (*is_window_mapped) (Role *, XdgRoleImplementation *);
|
||||||
void (*note_focus) (Role *, XdgRoleImplementation *, FocusMode);
|
void (*note_focus) (Role *, XdgRoleImplementation *, FocusMode);
|
||||||
|
void (*outputs_changed) (Role *, XdgRoleImplementation *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _XdgRoleImplementation
|
struct _XdgRoleImplementation
|
||||||
|
|
54
output.c
54
output.c
|
@ -653,7 +653,13 @@ NoticeOutputsMaybeChanged (void)
|
||||||
|
|
||||||
surface = all_surfaces.next;
|
surface = all_surfaces.next;
|
||||||
for (; surface != &all_surfaces; surface = surface->next)
|
for (; surface != &all_surfaces; surface = surface->next)
|
||||||
pixman_region32_clear (&surface->output_region);
|
{
|
||||||
|
pixman_region32_clear (&surface->output_region);
|
||||||
|
|
||||||
|
if (surface->role
|
||||||
|
&& surface->role->funcs.outputs_changed)
|
||||||
|
surface->role->funcs.outputs_changed (surface, surface->role);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,6 +1097,51 @@ XLOutputSetChangeFunction (void (*change_func) (Time))
|
||||||
change_hook = change_func;
|
change_hook = change_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
XLGetMaxOutputBounds (int *x_min, int *y_min, int *x_max,
|
||||||
|
int *y_max)
|
||||||
|
{
|
||||||
|
int x1, y1, x2, y2;
|
||||||
|
Output *output;
|
||||||
|
XLList *tem;
|
||||||
|
|
||||||
|
x1 = y1 = INT_MAX;
|
||||||
|
x2 = y2 = INT_MIN;
|
||||||
|
|
||||||
|
if (!all_outputs)
|
||||||
|
{
|
||||||
|
*x_min = 0;
|
||||||
|
*y_min = 0;
|
||||||
|
*x_max = DisplayWidth (compositor.display,
|
||||||
|
DefaultScreen (compositor.display)) - 1;
|
||||||
|
*y_max = DisplayHeight (compositor.display,
|
||||||
|
DefaultScreen (compositor.display)) - 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tem = all_outputs; tem; tem = tem->next)
|
||||||
|
{
|
||||||
|
output = tem->data;
|
||||||
|
|
||||||
|
if (output->x < x1)
|
||||||
|
x1 = output->x;
|
||||||
|
|
||||||
|
if (output->y < y1)
|
||||||
|
y1 = output->y;
|
||||||
|
|
||||||
|
if (output->x + output->width - 1 > x2)
|
||||||
|
x2 = output->x + output->width - 1;
|
||||||
|
|
||||||
|
if (output->y + output->height - 1 > y2)
|
||||||
|
y2 = output->y + output->height - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*x_min = x1;
|
||||||
|
*y_min = y1;
|
||||||
|
*x_max = x2;
|
||||||
|
*y_max = y2;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
XLInitRROutputs (void)
|
XLInitRROutputs (void)
|
||||||
{
|
{
|
||||||
|
@ -1153,3 +1204,4 @@ XLInitRROutputs (void)
|
||||||
all_outputs = BuildOutputTree ();
|
all_outputs = BuildOutputTree ();
|
||||||
MakeGlobalsForOutputTree (all_outputs);
|
MakeGlobalsForOutputTree (all_outputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1457,6 +1457,17 @@ NoteFocus (Surface *surface, Role *role, FocusMode focus)
|
||||||
focus);
|
focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
OutputsChanged (Surface *surface, Role *role)
|
||||||
|
{
|
||||||
|
XdgRole *xdg_role;
|
||||||
|
|
||||||
|
xdg_role = XdgRoleFromRole (role);
|
||||||
|
|
||||||
|
if (xdg_role->impl && xdg_role->impl->funcs.outputs_changed)
|
||||||
|
xdg_role->impl->funcs.outputs_changed (role, xdg_role->impl);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
XLGetXdgSurface (struct wl_client *client, struct wl_resource *resource,
|
XLGetXdgSurface (struct wl_client *client, struct wl_resource *resource,
|
||||||
uint32_t id, struct wl_resource *surface_resource)
|
uint32_t id, struct wl_resource *surface_resource)
|
||||||
|
@ -1543,6 +1554,7 @@ XLGetXdgSurface (struct wl_client *client, struct wl_resource *resource,
|
||||||
role->role.funcs.note_child_synced = NoteChildSynced;
|
role->role.funcs.note_child_synced = NoteChildSynced;
|
||||||
role->role.funcs.select_extra_events = SelectExtraEvents;
|
role->role.funcs.select_extra_events = SelectExtraEvents;
|
||||||
role->role.funcs.note_focus = NoteFocus;
|
role->role.funcs.note_focus = NoteFocus;
|
||||||
|
role->role.funcs.outputs_changed = OutputsChanged;
|
||||||
|
|
||||||
attrs.colormap = compositor.colormap;
|
attrs.colormap = compositor.colormap;
|
||||||
attrs.border_pixel = border_pixel;
|
attrs.border_pixel = border_pixel;
|
||||||
|
|
|
@ -572,6 +572,22 @@ WriteStates (XdgToplevel *toplevel)
|
||||||
AddState (toplevel, XDG_TOPLEVEL_STATE_RESIZING);
|
AddState (toplevel, XDG_TOPLEVEL_STATE_RESIZING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CurrentWindowGeometry (XdgToplevel *toplevel,
|
||||||
|
int *width, int *height)
|
||||||
|
{
|
||||||
|
/* Calculate the current window geometry for sending a configure
|
||||||
|
event. */
|
||||||
|
|
||||||
|
TruncateScaleToSurface (toplevel->role->surface,
|
||||||
|
toplevel->width,
|
||||||
|
toplevel->height,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
XLXdgRoleCalcNewWindowSize (toplevel->role, *width,
|
||||||
|
*height, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SendStates (XdgToplevel *toplevel)
|
SendStates (XdgToplevel *toplevel)
|
||||||
{
|
{
|
||||||
|
@ -579,16 +595,9 @@ SendStates (XdgToplevel *toplevel)
|
||||||
|
|
||||||
WriteStates (toplevel);
|
WriteStates (toplevel);
|
||||||
|
|
||||||
/* Adjust the width and height we're sending by the window geometry.
|
/* toplevel->role->surface should not be NULL here. */
|
||||||
toplevel->role->surface should not be NULL here. */
|
|
||||||
|
|
||||||
TruncateScaleToSurface (toplevel->role->surface,
|
|
||||||
toplevel->width, toplevel->height,
|
|
||||||
&width, &height);
|
|
||||||
|
|
||||||
XLXdgRoleCalcNewWindowSize (toplevel->role, width,
|
|
||||||
height, &width, &height);
|
|
||||||
|
|
||||||
|
CurrentWindowGeometry (toplevel, &width, &height);
|
||||||
SendConfigure (toplevel, width, height);
|
SendConfigure (toplevel, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,6 +1227,17 @@ AckConfigure (Role *role, XdgRoleImplementation *impl, uint32_t serial)
|
||||||
toplevel->conf_reply = False;
|
toplevel->conf_reply = False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SendOutputBounds (XdgToplevel *toplevel)
|
||||||
|
{
|
||||||
|
int x_min, y_min, x_max, y_max;
|
||||||
|
|
||||||
|
XLGetMaxOutputBounds (&x_min, &y_min, &x_max, &y_max);
|
||||||
|
xdg_toplevel_send_configure_bounds (toplevel->resource,
|
||||||
|
x_max - x_min + 1,
|
||||||
|
y_max - y_min + 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Commit (Role *role, Surface *surface, XdgRoleImplementation *impl)
|
Commit (Role *role, Surface *surface, XdgRoleImplementation *impl)
|
||||||
{
|
{
|
||||||
|
@ -1255,6 +1275,14 @@ Commit (Role *role, Surface *surface, XdgRoleImplementation *impl)
|
||||||
Unmap (toplevel);
|
Unmap (toplevel);
|
||||||
|
|
||||||
FlushConfigurationTimer (toplevel);
|
FlushConfigurationTimer (toplevel);
|
||||||
|
|
||||||
|
if (wl_resource_get_version (toplevel->resource) >= 4)
|
||||||
|
/* Send the maximum bounds of the window to the client. It
|
||||||
|
isn't possible to predict where the window will be mapped,
|
||||||
|
so unfortunately the precise output bounds can't be used
|
||||||
|
here. */
|
||||||
|
SendOutputBounds (toplevel);
|
||||||
|
|
||||||
SendConfigure (toplevel, 0, 0);
|
SendConfigure (toplevel, 0, 0);
|
||||||
}
|
}
|
||||||
else if (!toplevel->conf_reply)
|
else if (!toplevel->conf_reply)
|
||||||
|
@ -2181,6 +2209,29 @@ NoteFocus (Role *role, XdgRoleImplementation *impl, FocusMode mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
OutputsChanged (Role *role, XdgRoleImplementation *impl)
|
||||||
|
{
|
||||||
|
XdgToplevel *toplevel;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
toplevel = ToplevelFromRoleImpl (impl);
|
||||||
|
|
||||||
|
/* The list of outputs changed. Send the new bounds to the
|
||||||
|
client. */
|
||||||
|
if (toplevel->resource)
|
||||||
|
{
|
||||||
|
if (wl_resource_get_version (toplevel->resource) < 4)
|
||||||
|
/* The client is too old to accept configure_bounds. */
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Send the updated bounds to the toplevel. */
|
||||||
|
SendOutputBounds (toplevel);
|
||||||
|
CurrentWindowGeometry (toplevel, &width, &height);
|
||||||
|
SendConfigure (toplevel, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct xdg_toplevel_interface xdg_toplevel_impl =
|
static const struct xdg_toplevel_interface xdg_toplevel_impl =
|
||||||
{
|
{
|
||||||
.destroy = Destroy,
|
.destroy = Destroy,
|
||||||
|
@ -2242,6 +2293,7 @@ XLGetXdgToplevel (struct wl_client *client, struct wl_resource *resource,
|
||||||
toplevel->impl.funcs.post_resize = PostResize;
|
toplevel->impl.funcs.post_resize = PostResize;
|
||||||
toplevel->impl.funcs.commit_inside_frame = CommitInsideFrame;
|
toplevel->impl.funcs.commit_inside_frame = CommitInsideFrame;
|
||||||
toplevel->impl.funcs.is_window_mapped = IsWindowMapped;
|
toplevel->impl.funcs.is_window_mapped = IsWindowMapped;
|
||||||
|
toplevel->impl.funcs.outputs_changed = OutputsChanged;
|
||||||
|
|
||||||
if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED))
|
if (!XLWmSupportsHint (_NET_WM_STATE_FOCUSED))
|
||||||
/* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing
|
/* If _NET_WM_STATE_FOCUSED is unsupported, fall back to utilizing
|
||||||
|
|
Loading…
Add table
Reference in a new issue