mirror of https://github.com/mpv-player/mpv
x11: use xdg-screensaver suspend/resume
If it doesn't work this time, I'll remove all X11 screensaver code. Fixes #4763.
This commit is contained in:
parent
34ab0386cb
commit
6694048272
|
@ -37,6 +37,8 @@
|
||||||
#include <X11/extensions/Xinerama.h>
|
#include <X11/extensions/Xinerama.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
|
||||||
|
#include "osdep/atomic.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "misc/bstr.h"
|
#include "misc/bstr.h"
|
||||||
#include "options/options.h"
|
#include "options/options.h"
|
||||||
|
@ -135,7 +137,6 @@ static atomic_int x11_error_silence;
|
||||||
|
|
||||||
static void vo_x11_update_geometry(struct vo *vo);
|
static void vo_x11_update_geometry(struct vo *vo);
|
||||||
static void vo_x11_fullscreen(struct vo *vo);
|
static void vo_x11_fullscreen(struct vo *vo);
|
||||||
static void xscreensaver_heartbeat(struct vo_x11_state *x11);
|
|
||||||
static void set_screensaver(struct vo_x11_state *x11, bool enabled);
|
static void set_screensaver(struct vo_x11_state *x11, bool enabled);
|
||||||
static void vo_x11_selectinput_witherr(struct vo *vo, Display *display,
|
static void vo_x11_selectinput_witherr(struct vo *vo, Display *display,
|
||||||
Window w, long event_mask);
|
Window w, long event_mask);
|
||||||
|
@ -503,27 +504,63 @@ static void vo_x11_get_bounding_monitors(struct vo_x11_state *x11, long b[4])
|
||||||
static void *screensaver_thread(void *arg)
|
static void *screensaver_thread(void *arg)
|
||||||
{
|
{
|
||||||
struct vo_x11_state *x11 = arg;
|
struct vo_x11_state *x11 = arg;
|
||||||
|
bool suspend = false;
|
||||||
|
bool run = true;
|
||||||
|
|
||||||
for (;;) {
|
while (run) {
|
||||||
sem_wait(&x11->screensaver_sem);
|
pthread_mutex_lock(&x11->screensaver_thread_lock);
|
||||||
// don't queue multiple wakeups
|
bool suspend_new = suspend;
|
||||||
while (!sem_trywait(&x11->screensaver_sem)) {}
|
for (;;) {
|
||||||
|
run = x11->screensaver_thread_running;
|
||||||
|
suspend_new = x11->screensaver_thread_suspend;
|
||||||
|
if (!run || suspend != suspend_new)
|
||||||
|
break;
|
||||||
|
pthread_cond_wait(&x11->screensaver_thread_wakeup,
|
||||||
|
&x11->screensaver_thread_lock);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&x11->screensaver_thread_lock);
|
||||||
|
|
||||||
if (atomic_load(&x11->screensaver_terminate))
|
if (!run) {
|
||||||
break;
|
suspend_new = false; // make sure to resume on exit
|
||||||
|
if (suspend == suspend_new)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
char *args[] = {"xdg-screensaver", "reset", NULL};
|
char *args[] = {"xdg-screensaver", suspend_new ? "suspend" : "resume",
|
||||||
int status = mp_subprocess(args, NULL, NULL, mp_devnull, mp_devnull, &(char*){0});
|
mp_tprintf(32, "%lx", x11->screensaver_thread_window),
|
||||||
|
NULL};
|
||||||
|
int status = mp_subprocess(args, NULL, NULL, mp_devnull, mp_devnull,
|
||||||
|
&(char*){0});
|
||||||
if (status) {
|
if (status) {
|
||||||
MP_VERBOSE(x11, "Disabling screensaver failed (%d). Make sure the "
|
MP_VERBOSE(x11, "Updating screensaver failed (%d). Make sure the "
|
||||||
"xdg-screensaver script is installed.\n", status);
|
"xdg-screensaver script is installed.\n", status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend = suspend_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void screensaver_thread_update(struct vo_x11_state *x11)
|
||||||
|
{
|
||||||
|
if (!x11->screensaver_thread_running && x11->window) {
|
||||||
|
x11->screensaver_thread_window = x11->window;
|
||||||
|
x11->screensaver_thread_running = true;
|
||||||
|
if (pthread_create(&x11->screensaver_thread, NULL, screensaver_thread, x11))
|
||||||
|
x11->screensaver_thread_running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!x11->screensaver_thread_running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&x11->screensaver_thread_lock);
|
||||||
|
x11->screensaver_thread_suspend = !x11->screensaver_enabled;
|
||||||
|
pthread_cond_signal(&x11->screensaver_thread_wakeup);
|
||||||
|
pthread_mutex_unlock(&x11->screensaver_thread_lock);
|
||||||
|
}
|
||||||
|
|
||||||
int vo_x11_init(struct vo *vo)
|
int vo_x11_init(struct vo *vo)
|
||||||
{
|
{
|
||||||
struct mp_vo_opts *opts = vo->opts;
|
struct mp_vo_opts *opts = vo->opts;
|
||||||
|
@ -544,12 +581,8 @@ int vo_x11_init(struct vo *vo)
|
||||||
};
|
};
|
||||||
vo->x11 = x11;
|
vo->x11 = x11;
|
||||||
|
|
||||||
sem_init(&x11->screensaver_sem, 0, 0);
|
pthread_mutex_init(&x11->screensaver_thread_lock, NULL);
|
||||||
if (pthread_create(&x11->screensaver_thread, NULL, screensaver_thread, x11)) {
|
pthread_cond_init(&x11->screensaver_thread_wakeup, NULL);
|
||||||
sem_destroy(&x11->screensaver_sem);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
x11->screensaver_thread_running = true;
|
|
||||||
|
|
||||||
x11_error_output = x11->log;
|
x11_error_output = x11->log;
|
||||||
XSetErrorHandler(x11_errorhandler);
|
XSetErrorHandler(x11_errorhandler);
|
||||||
|
@ -773,12 +806,16 @@ void vo_x11_uninit(struct vo *vo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x11->screensaver_thread_running) {
|
if (x11->screensaver_thread_running) {
|
||||||
atomic_store(&x11->screensaver_terminate, true);
|
pthread_mutex_lock(&x11->screensaver_thread_lock);
|
||||||
sem_post(&x11->screensaver_sem);
|
x11->screensaver_thread_running = false;
|
||||||
|
pthread_cond_signal(&x11->screensaver_thread_wakeup);
|
||||||
|
pthread_mutex_unlock(&x11->screensaver_thread_lock);
|
||||||
pthread_join(x11->screensaver_thread, NULL);
|
pthread_join(x11->screensaver_thread, NULL);
|
||||||
sem_destroy(&x11->screensaver_sem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&x11->screensaver_thread_lock);
|
||||||
|
pthread_cond_destroy(&x11->screensaver_thread_wakeup);
|
||||||
|
|
||||||
if (x11->wakeup_pipe[0] >= 0) {
|
if (x11->wakeup_pipe[0] >= 0) {
|
||||||
close(x11->wakeup_pipe[0]);
|
close(x11->wakeup_pipe[0]);
|
||||||
close(x11->wakeup_pipe[1]);
|
close(x11->wakeup_pipe[1]);
|
||||||
|
@ -1041,8 +1078,6 @@ void vo_x11_check_events(struct vo *vo)
|
||||||
Display *display = vo->x11->display;
|
Display *display = vo->x11->display;
|
||||||
XEvent Event;
|
XEvent Event;
|
||||||
|
|
||||||
xscreensaver_heartbeat(vo->x11);
|
|
||||||
|
|
||||||
while (XPending(display)) {
|
while (XPending(display)) {
|
||||||
XNextEvent(display, &Event);
|
XNextEvent(display, &Event);
|
||||||
MP_TRACE(x11, "XEvent: %d\n", Event.type);
|
MP_TRACE(x11, "XEvent: %d\n", Event.type);
|
||||||
|
@ -1424,6 +1459,8 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis,
|
||||||
vo_x11_set_property_utf8(vo, XA(x11, _GTK_THEME_VARIANT), "dark");
|
vo_x11_set_property_utf8(vo, XA(x11, _GTK_THEME_VARIANT), "dark");
|
||||||
}
|
}
|
||||||
vo_x11_xembed_update(x11, 0);
|
vo_x11_xembed_update(x11, 0);
|
||||||
|
|
||||||
|
screensaver_thread_update(x11);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vo_x11_map_window(struct vo *vo, struct mp_rect rc)
|
static void vo_x11_map_window(struct vo *vo, struct mp_rect rc)
|
||||||
|
@ -1898,18 +1935,6 @@ void vo_x11_wait_events(struct vo *vo, int64_t until_time_us)
|
||||||
mp_flush_wakeup_pipe(x11->wakeup_pipe[0]);
|
mp_flush_wakeup_pipe(x11->wakeup_pipe[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xscreensaver_heartbeat(struct vo_x11_state *x11)
|
|
||||||
{
|
|
||||||
double time = mp_time_sec();
|
|
||||||
|
|
||||||
if (x11->display && !x11->screensaver_enabled &&
|
|
||||||
(time - x11->screensaver_time_last) >= 10)
|
|
||||||
{
|
|
||||||
x11->screensaver_time_last = time;
|
|
||||||
sem_post(&x11->screensaver_sem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_screensaver(struct vo_x11_state *x11, bool enabled)
|
static void set_screensaver(struct vo_x11_state *x11, bool enabled)
|
||||||
{
|
{
|
||||||
Display *mDisplay = x11->display;
|
Display *mDisplay = x11->display;
|
||||||
|
@ -1917,6 +1942,7 @@ static void set_screensaver(struct vo_x11_state *x11, bool enabled)
|
||||||
return;
|
return;
|
||||||
MP_VERBOSE(x11, "%s screensaver.\n", enabled ? "Enabling" : "Disabling");
|
MP_VERBOSE(x11, "%s screensaver.\n", enabled ? "Enabling" : "Disabling");
|
||||||
x11->screensaver_enabled = enabled;
|
x11->screensaver_enabled = enabled;
|
||||||
|
screensaver_thread_update(x11);
|
||||||
int nothing;
|
int nothing;
|
||||||
if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) {
|
if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) {
|
||||||
BOOL onoff = 0;
|
BOOL onoff = 0;
|
||||||
|
|
|
@ -24,9 +24,6 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
#include "osdep/atomic.h"
|
|
||||||
#include "osdep/semaphore.h"
|
|
||||||
|
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
struct vo;
|
struct vo;
|
||||||
|
@ -66,11 +63,13 @@ struct vo_x11_state {
|
||||||
|
|
||||||
bool screensaver_enabled;
|
bool screensaver_enabled;
|
||||||
bool dpms_touched;
|
bool dpms_touched;
|
||||||
double screensaver_time_last;
|
|
||||||
|
long screensaver_thread_window;
|
||||||
pthread_t screensaver_thread;
|
pthread_t screensaver_thread;
|
||||||
|
pthread_mutex_t screensaver_thread_lock;
|
||||||
|
pthread_cond_t screensaver_thread_wakeup;
|
||||||
bool screensaver_thread_running;
|
bool screensaver_thread_running;
|
||||||
sem_t screensaver_sem;
|
bool screensaver_thread_suspend;
|
||||||
atomic_bool screensaver_terminate;
|
|
||||||
|
|
||||||
XIM xim;
|
XIM xim;
|
||||||
XIC xic;
|
XIC xic;
|
||||||
|
|
Loading…
Reference in New Issue