diff --git a/config.d/x11.m4 b/config.d/x11.m4
index ee521f296..23f950087 100644
--- a/config.d/x11.m4
+++ b/config.d/x11.m4
@@ -35,6 +35,27 @@ if test "x$HAVE_VIDMODE" != xno; then
 fi
 AC_SUBST(VIDMODE_LIBS)
 
+dnl Check for XScreenSaver support
+AC_ARG_ENABLE(xi2,
+	AS_HELP_STRING([--disable-xss], [do not use Xorg XScreenSaver extension]),
+	HAVE_XSS=$enable_xi2, HAVE_XSS=auto)
+if test "x$HAVE_XSS" != xno; then
+	save_CPPFLAGS="$CPPFLAGS"
+	CPPFLAGS="$X_CFLAGS $CPPFLAGS"
+	AC_CHECK_HEADER(X11/extensions/scrnsaver.h,
+		dnl Make sure the library works
+		[AC_CHECK_LIB(Xss, XScreenSaverQueryExtension,
+			AC_DEFINE(HAVE_XSS, 1, [Define if you have the Xorg XScreenSaver extension])
+			HAVE_XSS=yes
+			XSS_LIBS="-lXss",,
+			[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS]
+		)],,
+		[#include <X11/Xlib.h>]
+	)
+	CPPFLAGS="$save_CPPFLAGS"
+fi
+AC_SUBST(XSS_LIBS)
+
 dnl Check for XInput2 support
 AC_ARG_ENABLE(xi2,
 	AS_HELP_STRING([--disable-xi2], [do not use Xorg XInput2 extension]),
diff --git a/include/context_x11.h b/include/context_x11.h
index 1dd9e67d3..f9fc66964 100644
--- a/include/context_x11.h
+++ b/include/context_x11.h
@@ -64,6 +64,7 @@ extern bool     x_have_focus;
 bool X11_AddEvent (int event, void (*event_handler)(XEvent *));
 bool X11_RemoveEvent (int event, void (*event_handler)(XEvent *));
 bool X11_SetGamma (double);
+void X11_SetScreenSaver (void);
 void X11_CloseDisplay (void);
 void X11_CreateNullCursor (void);
 void X11_CreateWindow (int, int);
@@ -74,6 +75,7 @@ void X11_OpenDisplay (void);
 void X11_ProcessEvent (void);
 void X11_ProcessEvents (void);
 void X11_RestoreGamma (void);
+void X11_RestoreScreenSaver (void);
 void X11_RestoreVidMode (void);
 void X11_SetCaption (const char *);
 void X11_SetVidMode (int, int);
diff --git a/libs/video/targets/context_x11.c b/libs/video/targets/context_x11.c
index 5b8237257..8aabf434a 100644
--- a/libs/video/targets/context_x11.c
+++ b/libs/video/targets/context_x11.c
@@ -44,18 +44,13 @@
 # include <unistd.h>
 #endif
 
-#include <stdlib.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
 #include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XShm.h>
-
 #ifdef HAVE_VIDMODE
 # include <X11/extensions/xf86vmode.h>
 #endif
+#ifdef HAVE_XSS
+# include <X11/extensions/scrnsaver.h>
+#endif
 
 #include "QF/cmd.h"
 #include "QF/cvar.h"
@@ -78,8 +73,9 @@ bool		oktodraw = false;
 int 		x_shmeventtype;
 
 static int	x_disp_ref_count = 0;
+static bool x_have_xss = false;
 
-Display 	*x_disp = NULL;
+Display 	*x_disp = nullptr;
 int 		x_screen;
 int			x_width;
 int			x_height;
@@ -99,8 +95,8 @@ static XF86VidModeModeInfo **vidmodes;
 static int		nummodes;
 static int		original_mode = 0;
 static vec3_t	x_gamma = {-1, -1, -1};
-static bool		vidmode_avail = false;
 #endif
+static bool		vidmode_avail = false;
 
 static bool		vidmode_active = false;
 
@@ -205,7 +201,7 @@ X11_RemoveEvent (int event, void (*event_handler) (XEvent *))
 	if (event_handlers[event] != event_handler)
 		return false;
 
-	event_handlers[event] = NULL;
+	event_handlers[event] = nullptr;
 	return true;
 }
 
@@ -252,34 +248,72 @@ X11_ProcessEvents (void)
 		X11_ProcessEvent ();
 }
 
-#ifdef HAVE_VIDMODE
-static void
+void
 X11_SetScreenSaver (void)
 {
-	XGetScreenSaver (x_disp, &xss_timeout, &xss_interval, &xss_blanking,
-					 &xss_exposures);
-	XSetScreenSaver (x_disp, 0, xss_interval, xss_blanking, xss_exposures);
+	if (x_have_xss) {
+#ifdef HAVE_XSS
+		XScreenSaverSuspend (x_disp, true);
+#endif
+	} else {
+#ifdef HAVE_VIDMODE
+		XGetScreenSaver (x_disp, &xss_timeout, &xss_interval, &xss_blanking,
+						 &xss_exposures);
+		XSetScreenSaver (x_disp, 0, xss_interval, xss_blanking, xss_exposures);
+#endif
+	}
+}
+
+void
+X11_RestoreScreenSaver (void)
+{
+	if (x_have_xss) {
+#ifdef HAVE_XSS
+		XScreenSaverSuspend (x_disp, false);
+#endif
+	} else {
+#ifdef HAVE_VIDMODE
+		XSetScreenSaver (x_disp, xss_timeout, xss_interval, xss_blanking,
+						 xss_exposures);
+#endif
+	}
 }
 
 static void
-X11_RestoreScreenSaver (void)
+X11_CheckScreenSaver (void)
 {
-	XSetScreenSaver (x_disp, xss_timeout, xss_interval, xss_blanking,
-					 xss_exposures);
-}
+#ifdef HAVE_XSS
+	int ev_base, err_base;
+	int maj_ver, min_ver;
+	if (!XScreenSaverQueryExtension (x_disp, &ev_base, &err_base)) {
+		Sys_MaskPrintf (SYS_vid, "XSS not supported\n");
+		return;
+	}
+	if (!XScreenSaverQueryVersion (x_disp, &maj_ver, &min_ver)) {
+		Sys_MaskPrintf (SYS_vid, "XScreenSaver version query failed\n");
+		return;
+	}
+	Sys_MaskPrintf (SYS_vid, "XSS supperted: version %d.%d (ev:%d, err:%d)\n",
+					maj_ver, min_ver, ev_base, err_base);
+	x_have_xss = true;
+#else
+	Sys_MaskPrintf (SYS_vid, "X11: XScreenSaver support not compiled in\n");
 #endif
+}
 
 void
 X11_OpenDisplay (void)
 {
 	qfZoneScoped (true);
 	if (!x_disp) {
-		x_disp = XOpenDisplay (NULL);
+		x_disp = XOpenDisplay (nullptr);
 		if (!x_disp) {
 			Sys_Error ("X11_OpenDisplay: Could not open display [%s]",
-					   XDisplayName (NULL));
+					   XDisplayName (nullptr));
 		}
 
+		X11_CheckScreenSaver ();
+
 		x_net_state = XInternAtom (x_disp, "_NET_WM_STATE", False);
 		x_net_fullscreen = XInternAtom (x_disp, "_NET_WM_STATE_FULLSCREEN",
 										False);
@@ -304,6 +338,7 @@ X11_CloseDisplay (void)
 		X11_RestoreVidMode ();
 
 		X11_RestoreGamma ();
+		X11_RestoreScreenSaver ();
 
 		if (x_nullcursor != None) {
 			XFreeCursor (x_disp, x_nullcursor);
@@ -363,11 +398,11 @@ X11_GetGamma (void)
 				(*temp)[2] = xgamma.blue;
 				return temp;
 			}
-			return NULL;
+			return nullptr;
 		}
 	}
 	vid_gamma_avail = false;
-	return NULL;
+	return nullptr;
 }
 #endif
 
@@ -393,7 +428,7 @@ X11_SetVidMode (int width, int height)
 		static int  initialized = 0;
 
 		if (!vidmode_avail)
-			vidmode_avail = VID_CheckVMode (x_disp, NULL, NULL);
+			vidmode_avail = VID_CheckVMode (x_disp, nullptr, nullptr);
 
 		if (!initialized && vidmode_avail) {
 			vec3_t	*temp;
@@ -461,7 +496,6 @@ X11_SetVidMode (int width, int height)
 										 vidmodes[best_mode]);
 				}
 				vidmode_active = true;
-				X11_SetScreenSaver ();
 			} else {
 				Sys_Printf ("VID: Mode %dx%d can't go fullscreen.\n",
 							viddef.width, viddef.height);
@@ -569,14 +603,13 @@ X11_CreateWindow (int width, int height)
 void
 X11_RestoreVidMode (void)
 {
-#ifdef HAVE_VIDMODE
 	if (vidmode_active) {
-		X11_RestoreScreenSaver ();
+#ifdef HAVE_VIDMODE
 		//XF86VidModeSwitchToMode (x_disp, x_screen, vidmodes[original_mode]);
 		XFree (vidmodes);
 		vidmode_active = false;
-	}
 #endif
+	}
 }
 
 void
diff --git a/libs/video/targets/in_x11.c b/libs/video/targets/in_x11.c
index 02badd3af..60032d413 100644
--- a/libs/video/targets/in_x11.c
+++ b/libs/video/targets/in_x11.c
@@ -1143,6 +1143,7 @@ event_focusout (XEvent *event)
 			CDAudio_Pause ();
 		}
 		X11_RestoreGamma ();
+		X11_RestoreScreenSaver ();
 	}
 }
 
@@ -1162,6 +1163,10 @@ event_focusin (XEvent *event)
 #endif
 	}
 	VID_UpdateGamma ();
+	// The assumption is that kb+mouse will generate enough input it doesn't
+	// matter, and that if the game is in focus, then assume a controller
+	// (which does not generate X11 events) might be in use.
+	X11_SetScreenSaver ();
 }
 
 static void
diff --git a/nq/source/Makemodule.am b/nq/source/Makemodule.am
index 0670d205d..48e4cb274 100644
--- a/nq/source/Makemodule.am
+++ b/nq/source/Makemodule.am
@@ -93,8 +93,8 @@ nq_x11_libs=  \
 			$(nq_client_LIBS)
 nq_x11_SOURCES= 	nq/source/sys_unix.c $(tracy_src) $(tracyvk_src)
 nq_x11_LDADD=		$(nq_x11_libs) \
-			$(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(X_LIBS) \
-			-lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(DL_LIBS)
+			$(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(XSS_LIBS) \
+			$(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(DL_LIBS)
 nq_x11_LDFLAGS= 	$(common_ldflags)
 nq_x11_DEPENDENCIES=	$(nq_x11_libs)
 
diff --git a/qw/source/Makemodule.am b/qw/source/Makemodule.am
index a061b74a4..58e40a2a4 100644
--- a/qw/source/Makemodule.am
+++ b/qw/source/Makemodule.am
@@ -118,9 +118,9 @@ qw_client_x11_libs= \
 			$(qw_client_LIBS)
 qw_client_x11_SOURCES=	qw/source/cl_sys_unix.c $(tracy_src) $(tracyvk_src)
 qw_client_x11_LDADD= $(qw_client_x11_libs) \
-			$(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(X_LIBS) \
-			-lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(LIBCURL_LIBS) \
-			$(DL_LIBS)
+			$(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(XSS_LIBS) \
+			$(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) \
+			$(LIBCURL_LIBS) $(DL_LIBS)
 qw_client_x11_LDFLAGS=	$(common_ldflags)
 qw_client_x11_DEPENDENCIES= $(qw_client_x11_libs)
 
diff --git a/ruamoko/qwaq/Makemodule.am b/ruamoko/qwaq/Makemodule.am
index 225d7953b..8de33c572 100644
--- a/ruamoko/qwaq/Makemodule.am
+++ b/ruamoko/qwaq/Makemodule.am
@@ -124,8 +124,9 @@ ruamoko_qwaq_qwaq_x11_SOURCES= \
 	ruamoko/qwaq/builtins/qwaq-graphics.c \
 	ruamoko/qwaq/builtins/graphics.c $(tracy_src) $(tracyvk_src)
 ruamoko_qwaq_qwaq_x11_LDADD= $(qwaq_x11_libs) $(QWAQ_LIBS) \
-			$(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(X_LIBS) \
-			-lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(PTHREAD_LDFLAGS) $(DL_LIBS)
+		$(VIDMODE_LIBS) $(DGA_LIBS) ${XFIXES_LIBS} $(XI2_LIBS) $(XSS_LIBS)\
+		$(X_LIBS) -lX11 $(X_EXTRA_LIBS) $(X_SHM_LIB) $(PTHREAD_LDFLAGS) \
+		$(DL_LIBS)
 ruamoko_qwaq_qwaq_x11_LDFLAGS=
 ruamoko_qwaq_qwaq_x11_DEPENDENCIES= $(qwaq_x11_libs) $(QWAQ_DEPS)