From c4f2e07a4b79fffacd7d6823958ceb91332ce5f7 Mon Sep 17 00:00:00 2001 From: hujianwei Date: Sat, 22 Oct 2022 05:48:23 +0000 Subject: [PATCH] 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. --- compositor.h | 3 +++ idle_inhibit.c | 16 ++++++++++++++++ subcompositor.c | 14 ++++++++++++++ subsurface.c | 33 ++++++++++++++++++++++++++++++--- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/compositor.h b/compositor.h index 8e00a6e..616e8f0 100644 --- a/compositor.h +++ b/compositor.h @@ -773,6 +773,8 @@ extern void ViewInsertAfter (View *, View *, View *); extern void ViewInsertBefore (View *, View *, View *); extern void ViewInsertStart (View *, View *); +extern Bool ViewIsVisible (View *); + extern void ViewUnparent (View *); extern View *ViewGetParent (View *); extern void ViewAttachBuffer (View *, ExtBuffer *); @@ -1393,6 +1395,7 @@ extern void XLSubsurfaceHandleParentCommit (Surface *); extern void XLInitSubsurfaces (void); extern void XLUpdateOutputsForChildren (Surface *, int, int); extern void XLUpdateDesynchronousChildren (Surface *, int *); +extern Surface *XLSubsurfaceGetRoot (Surface *); /* Defined in data_device.c. */ diff --git a/idle_inhibit.c b/idle_inhibit.c index e37ee17..90a1a1e 100644 --- a/idle_inhibit.c +++ b/idle_inhibit.c @@ -133,6 +133,7 @@ static void DetectSurfaceIdleInhibit (void) { IdleInhibitor *inhibitor; + Surface *root; inhibitor = all_inhibitors.global_next; while (inhibitor != &all_inhibitors) @@ -142,6 +143,18 @@ DetectSurfaceIdleInhibit (void) ChangeInhibitionTo (IdleInhibited); 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; } @@ -286,6 +299,9 @@ CreateInhibitor (struct wl_client *client, struct wl_resource *resource, if (surface->num_focused_seats) /* See the comment at the beginning of the file. */ ChangeInhibitionTo (IdleInhibited); + else if (surface->role && surface->role_type == SubsurfaceType) + /* Check if this subsurface should cause inhibition. */ + DetectSurfaceIdleInhibit (); /* Set the implementation. */ wl_resource_set_implementation (inhibitor->resource, &idle_inhibitor_impl, diff --git a/subcompositor.c b/subcompositor.c index cc73a4a..a4b0a3e 100644 --- a/subcompositor.c +++ b/subcompositor.c @@ -721,6 +721,20 @@ ViewVisibilityState (View *view, Bool *mapped) 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 ViewRecomputeChildren (View *view, int *doflags) { diff --git a/subsurface.c b/subsurface.c index 211803a..9f29de4 100644 --- a/subsurface.c +++ b/subsurface.c @@ -95,6 +95,9 @@ struct _Subsurface /* Whether or not a commit is pending. */ Bool pending_commit; + /* Whether or not this subsurface is mapped. */ + Bool mapped; + /* The last dimensions and position that were used to update this surface's outputs. */ int output_x, output_y, output_width, output_height; @@ -668,11 +671,26 @@ Commit (Surface *surface, Role *role) { ViewUnmap (surface->under); ViewUnmap (surface->view); + + if (subsurface->mapped) + /* Check for idle inhibition changes. */ + XLDetectSurfaceIdleInhibit (); + + subsurface->mapped = False; } else - /* Once a buffer is attached to the view, it is automatically - mapped. */ - ViewMap (surface->under); + { + /* Once a buffer is attached to the view, it is automatically + 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) { @@ -824,6 +842,9 @@ Teardown (Surface *surface, Role *role) } DestroyBacking (subsurface); + + /* Update whether or not idle inhibition should continue. */ + XLDetectSurfaceIdleInhibit (); } static void @@ -1079,3 +1100,9 @@ XLUpdateDesynchronousChildren (Surface *parent, int *n_children) XLUpdateDesynchronousChildren (child, n_children); } } + +Surface * +XLSubsurfaceGetRoot (Surface *surface) +{ + return GetRootSurface (surface); +}