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 ();
|
||||
XLInitRelativePointer ();
|
||||
XLInitKeyboardShortcutsInhibit ();
|
||||
XLInitIdleInhibit ();
|
||||
|
||||
/* This has to come after the rest of the initialization. */
|
||||
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
|
||||
\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
|
||||
|
|
|
@ -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
5
README
|
@ -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.
|
||||
|
|
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/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])
|
||||
|
|
|
@ -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
37
fns.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
2
run.c
|
@ -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
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/>. */
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
19
surface.c
19
surface.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue