Implement idle_inhibit_unstable_v1

* 12to11.c (XLMain): Initialize idle inhibition.
* 12to11.man: Document new resources.
* Imakefile (SRCS): Add idle_inhibit.c and process.c.
(OBJS): Add idle_inhibit.o and process.o.
(idle-inhibit-unstable-v1): New scanner target.
* README: Explain what is now supported.
* compositor.h (enum _ClientDataType): Add IdleInhibitData.
(struct _Surface): Keep track of the number of focused seats.
* fns.c (UnblockSigbus): Fix unblocking of SIGBUS.
(XLAddFdFlag): New function.
* picture_renderer.c (GetRenderDevice):
* seat.c (WriteKeymap):
* drm_lease.c (AddProvider): Make various file descriptors
close-on-exec.
* run.c (RunStep): Change poll function to one that applies the
result of SIGCHLD.
* surface.c (XLSurfaceNoteFocus): Keep track of the number of
focused seats and call idle inhibit hooks when that changes.
This commit is contained in:
hujianwei 2022-10-22 04:47:51 +00:00
parent 0b2a069ac5
commit edfdc76f6d
11 changed files with 149 additions and 10 deletions

View file

@ -240,6 +240,7 @@ XLMain (int argc, char **argv)
XLInitPointerConstraints ();
XLInitRelativePointer ();
XLInitKeyboardShortcutsInhibit ();
XLInitIdleInhibit ();
/* This has to come after the rest of the initialization. */
DetermineServerTime ();

View file

@ -105,22 +105,61 @@ list. When \fBximStyles\fP is not specified, it defaults to:
.EE
.in
.TP
.B renderer \fP (class \fBRenderer\fP)
.B renderer\fP (class \fBRenderer\fP)
Specifies the rendering backend the protocol translator uses to
composite the contents of Wayland surfaces onto X windows. This can
either be \fBpicture\fP (the XRender based compositor) or \fBegl\fP
(the OpenGL ES 2.0 based compositor).
.TP
.B useDirectPresentation \fP (class \fBUseDirectPresentation\fP)
.B useDirectPresentation\fP (class \fBUseDirectPresentation\fP)
If ``True'' or ``true'', this resource enables the use of direct
presentation on unredirected windows. This is not yet complete
pending the installation of required functionality in the X server.
.TP
.B wmProtocols \fP (class \fBWmProtocols\fP)
.B wmProtocols\fP (class \fBWmProtocols\fP)
Comma-separated list of window manager protocols, similar to
\fBinputStyles\fP, that the protocol translator should enable or
disable. The current (and default) list of supported protocols are:
\fBnetWmPing\fB.
\fBnetWmPing\fP.
.TP
.B idleInhibitCommand\fP (class \fBIdleInhibitCommand\fP)
.TP
.B idleIntervalCommand\fP (class \fBIdleInhibitCommand\fP)
.TP
.B idleDeinhibitCommand\fP (class \fBIdleDeinhibitCommand\fP)
These are commands that run when a focused Wayland client asks to
inhibit the screen saver or screen locker, usually because a video is
being played and does not require user interaction.
\fBidleInhibitCommand\fP specifies a command that is run when one such
client becomes focused or starts inhibiting the screen saver;
\fBidleIntervalCommand\fP is a command that is run every several
seconds (by default 60) while the screen saver is inhibited, and
\fBidleDeinhibitCommand\fP is a command that is run once such a client
stops inhibiting the screen saver or loses the input focus.
.IP
Since there are several different screen saver inhibition protocols
used by different X desktops, the protocol translator refrains from
implementing any of them. Instead, it provides the ability to run any
command necessary to inhibit and de-inhibit the screen saver. For
example, an
.BR XScreenSaver(1)
user may wish to apply the following resources:
.IP
.in +4
.EX
\fB12to11.IdleInhibitCommand: xscreensaver-command -deactivate\fP
.EE
.in
.IP
The commands specified are expected to finish. If the process
corresponding to one command is still running by the time another
command should have been run, the other command will be queued until
the first process exits.
.TP
.B idleCommandInterval\fP (class \fBIdleCommandInterval\fP)
The number of seconds the protocol translator waits between
invocations of the command specified in \fBidleIntervalCommand\fP.
Defaults to 60.
.IP
.SH ENVIRONMENT
Several environment variables exist that modify the behavior of the
@ -215,6 +254,7 @@ zwp_text_input_manager_v3 1
wp_single_pixel_buffer_manager_v1 1
zwp_pointer_constraints_v1 1
zwp_relative_pointer_manager 1
zwp_idle_inhibit_manager_v1 1
.TE
.PP
When the protocol translator is built with EGL support, the following

View file

@ -24,7 +24,8 @@ SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c \
picture_renderer.c explicit_synchronization.c transform.c \
wp_viewporter.c decoration.c text_input.c \
single_pixel_buffer.c drm_lease.c pointer_constraints.c \
time.c relative_pointer.c keyboard_shortcuts_inhibit.c
time.c relative_pointer.c keyboard_shortcuts_inhibit.c \
idle_inhibit.c process.c
OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
surface.o region.o shm.o atoms.o subcompositor.o positioner.o \
@ -35,7 +36,8 @@ OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
picture_renderer.o explicit_synchronization.o transform.o \
wp_viewporter.o decoration.o text_input.o \
single_pixel_buffer.o drm_lease.o pointer_constraints.o \
time.o relative_pointer.o keyboard_shortcuts_inhibit.o
time.o relative_pointer.o keyboard_shortcuts_inhibit.o \
idle_inhibit.o process.o
GENHEADERS = transfer_atoms.h
@ -122,6 +124,7 @@ ScannerTarget(drm-lease-v1)
ScannerTarget(pointer-constraints-unstable-v1)
ScannerTarget(relative-pointer-unstable-v1)
ScannerTarget(keyboard-shortcuts-inhibit-unstable-v1)
ScannerTarget(idle-inhibit-unstable-v1)
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */
$(OBJS): $(GENHEADERS)

5
README
View file

@ -67,6 +67,7 @@ complete degree:
'wp_single_pixel_buffer_manager_v1', version: 1
'zwp_pointer_constraints_v1', version: 1
'zwp_relative_pointer_manager_v1', version: 1
'zwp_idle_inhibit_manager_v1', version: 1
When built with EGL, the following Wayland protocol is also supported:
@ -110,3 +111,7 @@ Running the binary should be simple as well:
./12to11
Wayland programs will then run as regular X windows.
Be sure to configure your system so that idle inhibition is reported
correctly. For more details, see the description of the
idleInhibitCommand resource in the manual page.

View file

@ -21,6 +21,7 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <limits.h>
@ -649,6 +650,7 @@ extern void XLDeselectInputFromRootWindow (RootWindowSelection *);
extern void XLRecordBusfault (void *, size_t);
extern void XLRemoveBusfault (void *);
extern Bool XLAddFdFlag (int, int, Bool);
/* Defined in compositor.c. */
@ -914,6 +916,7 @@ enum _ClientDataType
SubsurfaceData,
PointerConfinementData,
ShortcutInhibitData,
IdleInhibitData,
MaxClientData,
};
@ -1018,6 +1021,9 @@ struct _Surface
/* The number of outputs this surface is known to be on. */
int n_outputs;
/* The number of seats that have this surface focused. */
int num_focused_seats;
/* Bounds inside which the surface output need not be
recomputed. */
pixman_region32_t output_region;
@ -1692,6 +1698,21 @@ extern void XLInitKeyboardShortcutsInhibit (void);
extern void XLCheckShortcutInhibition (Seat *, Surface *);
extern void XLReleaseShortcutInhibition (Seat *, Surface *);
/* Defined in idle_inhibit.c. */
extern void XLInitIdleInhibit (void);
extern void XLIdleInhibitNoticeSurfaceFocused (Surface *);
extern void XLDetectSurfaceIdleInhibit (void);
/* Defined in process.c. */
typedef struct _ProcessQueue ProcessQueue;
extern void ParseProcessString (const char *, char ***, size_t *);
extern void RunProcess (ProcessQueue *, char **);
extern ProcessQueue *MakeProcessQueue (void);
extern int ProcessPoll (struct pollfd *, nfds_t, struct timespec *);
/* Utility functions that don't belong in a specific file. */
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])

View file

@ -931,6 +931,9 @@ AddProvider (RRProvider provider)
fd = fds[0];
/* Make the file descriptor FD_CLOEXEC. */
XLAddFdFlag (fd, FD_CLOEXEC, True);
if (drmGetNodeTypeFromFd (fd) != DRM_NODE_RENDER)
{
name = drmGetDeviceNameFromFd2 (fd);
@ -938,7 +941,7 @@ AddProvider (RRProvider provider)
if (name)
{
DebugPrint ("device name is %s", name);
new = open (name, O_RDWR);
new = open (name, O_RDWR | O_CLOEXEC);
if (new >= 0)
{

37
fns.c
View file

@ -789,8 +789,9 @@ UnblockSigbus (void)
sigset_t sigset;
sigemptyset (&sigset);
sigaddset (&sigset, SIGBUS);
if (sigprocmask (SIG_BLOCK, &sigset, NULL))
if (sigprocmask (SIG_UNBLOCK, &sigset, NULL))
{
perror ("sigprocmask");
abort ();
@ -822,3 +823,37 @@ XLRemoveBusfault (void *data)
RemoveBusfault (&busfault_tree, data);
UnblockSigbus ();
}
Bool
XLAddFdFlag (int fd, int flag, Bool abort_on_error)
{
int flags, rc;
flags = fcntl (fd, F_GETFD);
if (flags < 0)
{
if (abort_on_error)
{
perror ("fcntl");
abort ();
}
else
return False;
}
rc = fcntl (fd, F_SETFD, flags | flag);
if (rc < 0)
{
if (abort_on_error)
{
perror ("fcntl");
abort ();
}
else
return False;
}
return True;
}

View file

@ -1746,6 +1746,8 @@ GetRenderDevice (Bool *error)
fd = fds[0];
XLAddFdFlag (fd, FD_CLOEXEC, True);
if (fstat (fd, &dev_stat) != 0)
{
close (fd);

2
run.c
View file

@ -272,7 +272,7 @@ RunStep (void)
wl_display_flush_clients (compositor.wl_display);
}
rc = ppoll (fds, 2 + i, &timeout, NULL);
rc = ProcessPoll (fds, 2 + i, &timeout);
if (rc > 0)
{

12
seat.c
View file

@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@ -4346,6 +4347,7 @@ WriteKeymap (void)
FILE *file;
XkbFileInfo result;
Bool ok;
int fd;
if (keymap_fd != -1)
close (keymap_fd);
@ -4362,7 +4364,15 @@ WriteKeymap (void)
result.type = XkmKeymapFile;
result.xkb = xkb_desc;
file = fdopen (dup (keymap_fd), "w");
fd = fcntl (keymap_fd, F_DUPFD_CLOEXEC, 0);
if (fd < 0)
{
perror ("fcntl");
exit (1);
}
file = fdopen (fd, "w");
if (!file)
{

View file

@ -1752,6 +1752,25 @@ XLSurfaceNoteFocus (Surface *surface, FocusMode focus)
if (!surface->role || !surface->role->funcs.note_focus)
return;
switch (focus)
{
case SurfaceFocusIn:
surface->num_focused_seats++;
/* Check for idle inhibition. */
XLIdleInhibitNoticeSurfaceFocused (surface);
break;
case SurfaceFocusOut:
surface->num_focused_seats
= MAX (0, surface->num_focused_seats - 1);
if (!surface->num_focused_seats)
/* Check if any idle inhibitors are still active. */
XLDetectSurfaceIdleInhibit ();
break;
}
surface->role->funcs.note_focus (surface, surface->role,
focus);
}