forked from 12to11/12to11
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:
parent
0b2a069ac5
commit
edfdc76f6d
11 changed files with 149 additions and 10 deletions
1
12to11.c
1
12to11.c
|
@ -240,6 +240,7 @@ XLMain (int argc, char **argv)
|
||||||
XLInitPointerConstraints ();
|
XLInitPointerConstraints ();
|
||||||
XLInitRelativePointer ();
|
XLInitRelativePointer ();
|
||||||
XLInitKeyboardShortcutsInhibit ();
|
XLInitKeyboardShortcutsInhibit ();
|
||||||
|
XLInitIdleInhibit ();
|
||||||
|
|
||||||
/* This has to come after the rest of the initialization. */
|
/* This has to come after the rest of the initialization. */
|
||||||
DetermineServerTime ();
|
DetermineServerTime ();
|
||||||
|
|
42
12to11.man
42
12to11.man
|
@ -120,7 +120,46 @@ pending the installation of required functionality in the X server.
|
||||||
Comma-separated list of window manager protocols, similar to
|
Comma-separated list of window manager protocols, similar to
|
||||||
\fBinputStyles\fP, that the protocol translator should enable or
|
\fBinputStyles\fP, that the protocol translator should enable or
|
||||||
disable. The current (and default) list of supported protocols are:
|
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
|
.IP
|
||||||
.SH ENVIRONMENT
|
.SH ENVIRONMENT
|
||||||
Several environment variables exist that modify the behavior of the
|
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
|
wp_single_pixel_buffer_manager_v1 1
|
||||||
zwp_pointer_constraints_v1 1
|
zwp_pointer_constraints_v1 1
|
||||||
zwp_relative_pointer_manager 1
|
zwp_relative_pointer_manager 1
|
||||||
|
zwp_idle_inhibit_manager_v1 1
|
||||||
.TE
|
.TE
|
||||||
.PP
|
.PP
|
||||||
When the protocol translator is built with EGL support, the following
|
When the protocol translator is built with EGL support, the following
|
||||||
|
|
|
@ -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 \
|
picture_renderer.c explicit_synchronization.c transform.c \
|
||||||
wp_viewporter.c decoration.c text_input.c \
|
wp_viewporter.c decoration.c text_input.c \
|
||||||
single_pixel_buffer.c drm_lease.c pointer_constraints.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 \
|
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 \
|
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 \
|
picture_renderer.o explicit_synchronization.o transform.o \
|
||||||
wp_viewporter.o decoration.o text_input.o \
|
wp_viewporter.o decoration.o text_input.o \
|
||||||
single_pixel_buffer.o drm_lease.o pointer_constraints.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
|
GENHEADERS = transfer_atoms.h
|
||||||
|
|
||||||
|
@ -122,6 +124,7 @@ ScannerTarget(drm-lease-v1)
|
||||||
ScannerTarget(pointer-constraints-unstable-v1)
|
ScannerTarget(pointer-constraints-unstable-v1)
|
||||||
ScannerTarget(relative-pointer-unstable-v1)
|
ScannerTarget(relative-pointer-unstable-v1)
|
||||||
ScannerTarget(keyboard-shortcuts-inhibit-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. */
|
/* Make OBJS depend on scanner headers, and depend on both them and SRCS. */
|
||||||
$(OBJS): $(GENHEADERS)
|
$(OBJS): $(GENHEADERS)
|
||||||
|
|
5
README
5
README
|
@ -67,6 +67,7 @@ complete degree:
|
||||||
'wp_single_pixel_buffer_manager_v1', version: 1
|
'wp_single_pixel_buffer_manager_v1', version: 1
|
||||||
'zwp_pointer_constraints_v1', version: 1
|
'zwp_pointer_constraints_v1', version: 1
|
||||||
'zwp_relative_pointer_manager_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:
|
When built with EGL, the following Wayland protocol is also supported:
|
||||||
|
|
||||||
|
@ -110,3 +111,7 @@ Running the binary should be simple as well:
|
||||||
./12to11
|
./12to11
|
||||||
|
|
||||||
Wayland programs will then run as regular X windows.
|
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.
|
||||||
|
|
21
compositor.h
21
compositor.h
|
@ -21,6 +21,7 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
@ -649,6 +650,7 @@ extern void XLDeselectInputFromRootWindow (RootWindowSelection *);
|
||||||
|
|
||||||
extern void XLRecordBusfault (void *, size_t);
|
extern void XLRecordBusfault (void *, size_t);
|
||||||
extern void XLRemoveBusfault (void *);
|
extern void XLRemoveBusfault (void *);
|
||||||
|
extern Bool XLAddFdFlag (int, int, Bool);
|
||||||
|
|
||||||
/* Defined in compositor.c. */
|
/* Defined in compositor.c. */
|
||||||
|
|
||||||
|
@ -914,6 +916,7 @@ enum _ClientDataType
|
||||||
SubsurfaceData,
|
SubsurfaceData,
|
||||||
PointerConfinementData,
|
PointerConfinementData,
|
||||||
ShortcutInhibitData,
|
ShortcutInhibitData,
|
||||||
|
IdleInhibitData,
|
||||||
MaxClientData,
|
MaxClientData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1018,6 +1021,9 @@ struct _Surface
|
||||||
/* The number of outputs this surface is known to be on. */
|
/* The number of outputs this surface is known to be on. */
|
||||||
int n_outputs;
|
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
|
/* Bounds inside which the surface output need not be
|
||||||
recomputed. */
|
recomputed. */
|
||||||
pixman_region32_t output_region;
|
pixman_region32_t output_region;
|
||||||
|
@ -1692,6 +1698,21 @@ extern void XLInitKeyboardShortcutsInhibit (void);
|
||||||
extern void XLCheckShortcutInhibition (Seat *, Surface *);
|
extern void XLCheckShortcutInhibition (Seat *, Surface *);
|
||||||
extern void XLReleaseShortcutInhibition (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. */
|
/* Utility functions that don't belong in a specific file. */
|
||||||
|
|
||||||
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])
|
#define ArrayElements(arr) (sizeof (arr) / sizeof (arr)[0])
|
||||||
|
|
|
@ -931,6 +931,9 @@ AddProvider (RRProvider provider)
|
||||||
|
|
||||||
fd = fds[0];
|
fd = fds[0];
|
||||||
|
|
||||||
|
/* Make the file descriptor FD_CLOEXEC. */
|
||||||
|
XLAddFdFlag (fd, FD_CLOEXEC, True);
|
||||||
|
|
||||||
if (drmGetNodeTypeFromFd (fd) != DRM_NODE_RENDER)
|
if (drmGetNodeTypeFromFd (fd) != DRM_NODE_RENDER)
|
||||||
{
|
{
|
||||||
name = drmGetDeviceNameFromFd2 (fd);
|
name = drmGetDeviceNameFromFd2 (fd);
|
||||||
|
@ -938,7 +941,7 @@ AddProvider (RRProvider provider)
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
DebugPrint ("device name is %s", name);
|
DebugPrint ("device name is %s", name);
|
||||||
new = open (name, O_RDWR);
|
new = open (name, O_RDWR | O_CLOEXEC);
|
||||||
|
|
||||||
if (new >= 0)
|
if (new >= 0)
|
||||||
{
|
{
|
||||||
|
|
37
fns.c
37
fns.c
|
@ -789,8 +789,9 @@ UnblockSigbus (void)
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
|
|
||||||
sigemptyset (&sigset);
|
sigemptyset (&sigset);
|
||||||
|
sigaddset (&sigset, SIGBUS);
|
||||||
|
|
||||||
if (sigprocmask (SIG_BLOCK, &sigset, NULL))
|
if (sigprocmask (SIG_UNBLOCK, &sigset, NULL))
|
||||||
{
|
{
|
||||||
perror ("sigprocmask");
|
perror ("sigprocmask");
|
||||||
abort ();
|
abort ();
|
||||||
|
@ -822,3 +823,37 @@ XLRemoveBusfault (void *data)
|
||||||
RemoveBusfault (&busfault_tree, data);
|
RemoveBusfault (&busfault_tree, data);
|
||||||
UnblockSigbus ();
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1746,6 +1746,8 @@ GetRenderDevice (Bool *error)
|
||||||
|
|
||||||
fd = fds[0];
|
fd = fds[0];
|
||||||
|
|
||||||
|
XLAddFdFlag (fd, FD_CLOEXEC, True);
|
||||||
|
|
||||||
if (fstat (fd, &dev_stat) != 0)
|
if (fstat (fd, &dev_stat) != 0)
|
||||||
{
|
{
|
||||||
close (fd);
|
close (fd);
|
||||||
|
|
2
run.c
2
run.c
|
@ -272,7 +272,7 @@ RunStep (void)
|
||||||
wl_display_flush_clients (compositor.wl_display);
|
wl_display_flush_clients (compositor.wl_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ppoll (fds, 2 + i, &timeout, NULL);
|
rc = ProcessPoll (fds, 2 + i, &timeout);
|
||||||
|
|
||||||
if (rc > 0)
|
if (rc > 0)
|
||||||
{
|
{
|
||||||
|
|
12
seat.c
12
seat.c
|
@ -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/>. */
|
along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -4346,6 +4347,7 @@ WriteKeymap (void)
|
||||||
FILE *file;
|
FILE *file;
|
||||||
XkbFileInfo result;
|
XkbFileInfo result;
|
||||||
Bool ok;
|
Bool ok;
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (keymap_fd != -1)
|
if (keymap_fd != -1)
|
||||||
close (keymap_fd);
|
close (keymap_fd);
|
||||||
|
@ -4362,7 +4364,15 @@ WriteKeymap (void)
|
||||||
result.type = XkmKeymapFile;
|
result.type = XkmKeymapFile;
|
||||||
result.xkb = xkb_desc;
|
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)
|
if (!file)
|
||||||
{
|
{
|
||||||
|
|
19
surface.c
19
surface.c
|
@ -1752,6 +1752,25 @@ XLSurfaceNoteFocus (Surface *surface, FocusMode focus)
|
||||||
if (!surface->role || !surface->role->funcs.note_focus)
|
if (!surface->role || !surface->role->funcs.note_focus)
|
||||||
return;
|
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,
|
surface->role->funcs.note_focus (surface, surface->role,
|
||||||
focus);
|
focus);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue