Detect idle inhibition on subsurfaces

* compositor.h: Update prototypes.
* idle_inhibit.c (DetectSurfaceIdleInhibit): Handle subsurfaces;
when an inhibitor attached to a subsurface is displayed, check
if the subsurface's root is focused or not.
(CreateInhibitor): Likewise; handle subsurfaces specially.
* subcompositor.c (ViewisVisible): New function.
* subsurface.c (struct _Subsurface): New field `mapped'.
(Commit, Teardown): Update idle inhibition when the surface is
mapped or unmapped.
(XLSubsurfaceGetRoot): New function.
This commit is contained in:
hujianwei 2022-10-22 05:48:23 +00:00
parent edfdc76f6d
commit c4f2e07a4b
4 changed files with 63 additions and 3 deletions

View file

@ -773,6 +773,8 @@ extern void ViewInsertAfter (View *, View *, View *);
extern void ViewInsertBefore (View *, View *, View *); extern void ViewInsertBefore (View *, View *, View *);
extern void ViewInsertStart (View *, View *); extern void ViewInsertStart (View *, View *);
extern Bool ViewIsVisible (View *);
extern void ViewUnparent (View *); extern void ViewUnparent (View *);
extern View *ViewGetParent (View *); extern View *ViewGetParent (View *);
extern void ViewAttachBuffer (View *, ExtBuffer *); extern void ViewAttachBuffer (View *, ExtBuffer *);
@ -1393,6 +1395,7 @@ extern void XLSubsurfaceHandleParentCommit (Surface *);
extern void XLInitSubsurfaces (void); extern void XLInitSubsurfaces (void);
extern void XLUpdateOutputsForChildren (Surface *, int, int); extern void XLUpdateOutputsForChildren (Surface *, int, int);
extern void XLUpdateDesynchronousChildren (Surface *, int *); extern void XLUpdateDesynchronousChildren (Surface *, int *);
extern Surface *XLSubsurfaceGetRoot (Surface *);
/* Defined in data_device.c. */ /* Defined in data_device.c. */

View file

@ -133,6 +133,7 @@ static void
DetectSurfaceIdleInhibit (void) DetectSurfaceIdleInhibit (void)
{ {
IdleInhibitor *inhibitor; IdleInhibitor *inhibitor;
Surface *root;
inhibitor = all_inhibitors.global_next; inhibitor = all_inhibitors.global_next;
while (inhibitor != &all_inhibitors) while (inhibitor != &all_inhibitors)
@ -142,6 +143,18 @@ DetectSurfaceIdleInhibit (void)
ChangeInhibitionTo (IdleInhibited); ChangeInhibitionTo (IdleInhibited);
return; return;
} }
else if (inhibitor->surface->role
&& inhibitor->surface->role_type == SubsurfaceType)
{
/* This is a subsurface. If it is visible and the toplevel
parent has the input focus, then also inhibit system
idle. */
root = XLSubsurfaceGetRoot (inhibitor->surface);
if (root && ViewIsVisible (inhibitor->surface->view)
&& root->num_focused_seats)
ChangeInhibitionTo (IdleInhibited);
}
inhibitor = inhibitor->global_next; inhibitor = inhibitor->global_next;
} }
@ -286,6 +299,9 @@ CreateInhibitor (struct wl_client *client, struct wl_resource *resource,
if (surface->num_focused_seats) if (surface->num_focused_seats)
/* See the comment at the beginning of the file. */ /* See the comment at the beginning of the file. */
ChangeInhibitionTo (IdleInhibited); ChangeInhibitionTo (IdleInhibited);
else if (surface->role && surface->role_type == SubsurfaceType)
/* Check if this subsurface should cause inhibition. */
DetectSurfaceIdleInhibit ();
/* Set the implementation. */ /* Set the implementation. */
wl_resource_set_implementation (inhibitor->resource, &idle_inhibitor_impl, wl_resource_set_implementation (inhibitor->resource, &idle_inhibitor_impl,

View file

@ -721,6 +721,20 @@ ViewVisibilityState (View *view, Bool *mapped)
return view->link->next != view->link; return view->link->next != view->link;
} }
Bool
ViewIsVisible (View *view)
{
Bool mapped;
if (!ViewVisibilityState (view, &mapped))
return False;
if (IsSkipped (view))
return False;
return mapped;
}
static void static void
ViewRecomputeChildren (View *view, int *doflags) ViewRecomputeChildren (View *view, int *doflags)
{ {

View file

@ -95,6 +95,9 @@ struct _Subsurface
/* Whether or not a commit is pending. */ /* Whether or not a commit is pending. */
Bool pending_commit; Bool pending_commit;
/* Whether or not this subsurface is mapped. */
Bool mapped;
/* The last dimensions and position that were used to update this /* The last dimensions and position that were used to update this
surface's outputs. */ surface's outputs. */
int output_x, output_y, output_width, output_height; int output_x, output_y, output_width, output_height;
@ -668,11 +671,26 @@ Commit (Surface *surface, Role *role)
{ {
ViewUnmap (surface->under); ViewUnmap (surface->under);
ViewUnmap (surface->view); ViewUnmap (surface->view);
if (subsurface->mapped)
/* Check for idle inhibition changes. */
XLDetectSurfaceIdleInhibit ();
subsurface->mapped = False;
} }
else else
/* Once a buffer is attached to the view, it is automatically {
mapped. */ /* Once a buffer is attached to the view, it is automatically
ViewMap (surface->under); mapped. */
ViewMap (surface->under);
if (!subsurface->mapped)
/* Check if this subsurface being mapped would cause idle
inhibitors to change. */
XLDetectSurfaceIdleInhibit ();
subsurface->mapped = True;
}
if (!subsurface->synchronous) if (!subsurface->synchronous)
{ {
@ -824,6 +842,9 @@ Teardown (Surface *surface, Role *role)
} }
DestroyBacking (subsurface); DestroyBacking (subsurface);
/* Update whether or not idle inhibition should continue. */
XLDetectSurfaceIdleInhibit ();
} }
static void static void
@ -1079,3 +1100,9 @@ XLUpdateDesynchronousChildren (Surface *parent, int *n_children)
XLUpdateDesynchronousChildren (child, n_children); XLUpdateDesynchronousChildren (child, n_children);
} }
} }
Surface *
XLSubsurfaceGetRoot (Surface *surface)
{
return GetRootSurface (surface);
}