summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-02 20:48:45 +0100
committerwm4 <wm4@nowhere>2014-11-02 20:55:07 +0100
commit416c86f3cb3535a5b252b8c08a7f4cb253fa495a (patch)
treee4124d52d879ee55ceca6896da16ebf832f49129
parent4e2574f025b9f143140008cbed48f6ee9705f813 (diff)
downloadmpv-416c86f3cb3535a5b252b8c08a7f4cb253fa495a.tar.bz2
mpv-416c86f3cb3535a5b252b8c08a7f4cb253fa495a.tar.xz
command: add window-minimized property (X11 only)
More or less requested by #1237. Should be simple to extend this to other backends.
-rw-r--r--DOCS/man/input.rst3
-rw-r--r--player/command.c18
-rw-r--r--player/command.h1
-rw-r--r--player/playloop.c2
-rw-r--r--video/out/vo.h9
-rw-r--r--video/out/x11_common.c19
-rw-r--r--video/out/x11_common.h1
7 files changed, 52 insertions, 1 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index e62552cd35..94c54d1029 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -1115,6 +1115,9 @@ Property list
(or to be exact, the size the video filters output). ``2`` will set the
double size, ``0.5`` halves the size.
+``window-minimized``
+ Return whether the video window is minimized or not.
+
``video-aspect`` (RW)
Video aspect, see ``--video-aspect``.
diff --git a/player/command.c b/player/command.c
index 391cc5b30a..d97460ab91 100644
--- a/player/command.c
+++ b/player/command.c
@@ -2445,6 +2445,21 @@ static int mp_property_window_scale(void *ctx, struct m_property *prop,
return M_PROPERTY_NOT_IMPLEMENTED;
}
+static int mp_property_win_minimized(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ struct vo *vo = mpctx->video_out;
+ if (!vo)
+ return M_PROPERTY_UNAVAILABLE;
+
+ int state = 0;
+ if (vo_control(vo, VOCTRL_GET_WIN_STATE, &state) < 1)
+ return M_PROPERTY_UNAVAILABLE;
+
+ return m_property_flag_ro(action, arg, state & VO_WIN_STATE_MINIMIZED);
+}
+
static int mp_property_vo_configured(void *ctx, struct m_property *prop,
int action, void *arg)
{
@@ -3166,6 +3181,8 @@ static const struct m_property mp_properties[] = {
M_PROPERTY_ALIAS("audio", "aid"),
M_PROPERTY_ALIAS("sub", "sid"),
+ {"window-minimized", mp_property_win_minimized},
+
{"mpv-version", mp_property_version},
{"options", mp_property_options},
@@ -3202,6 +3219,7 @@ static const char *const *const mp_event_property_change[] = {
E(MP_EVENT_CACHE_UPDATE, "cache", "cache-free", "cache-used", "cache-idle",
"demuxer-cache-duration", "demuxer-cache-idle"),
E(MP_EVENT_WIN_RESIZE, "window-scale"),
+ E(MP_EVENT_WIN_STATE, "window-minimized"),
};
#undef E
diff --git a/player/command.h b/player/command.h
index 3469e32948..d4097fee6f 100644
--- a/player/command.h
+++ b/player/command.h
@@ -45,6 +45,7 @@ enum {
INTERNAL_EVENT_BASE = 24,
MP_EVENT_CACHE_UPDATE,
MP_EVENT_WIN_RESIZE,
+ MP_EVENT_WIN_STATE,
};
bool mp_hook_test_completion(struct MPContext *mpctx, char *type);
diff --git a/player/playloop.c b/player/playloop.c
index 85d962fffe..9e1cef957d 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -676,6 +676,8 @@ static void handle_vo_events(struct MPContext *mpctx)
int events = vo ? vo_query_events(vo, VO_EVENTS_USER, true) : 0;
if (events & VO_EVENT_RESIZE)
mp_notify(mpctx, MP_EVENT_WIN_RESIZE, NULL);
+ if (events & VO_EVENT_WIN_STATE)
+ mp_notify(mpctx, MP_EVENT_WIN_STATE, NULL);
}
void add_frame_pts(struct MPContext *mpctx, double pts)
diff --git a/video/out/vo.h b/video/out/vo.h
index 035b4dc1d6..6906cab222 100644
--- a/video/out/vo.h
+++ b/video/out/vo.h
@@ -36,9 +36,11 @@
#define VO_EVENT_RESIZE 2
// The ICC profile needs to be reloaded
#define VO_EVENT_ICC_PROFILE_PATH_CHANGED 4
+// Some other window state changed
+#define VO_EVENT_WIN_STATE 8
// Set of events the player core may be interested in.
-#define VO_EVENTS_USER (VO_EVENT_RESIZE)
+#define VO_EVENTS_USER (VO_EVENT_RESIZE | VO_EVENT_WIN_STATE)
enum mp_voctrl {
/* signal a device reset seek */
@@ -83,6 +85,8 @@ enum mp_voctrl {
VOCTRL_GET_UNFS_WINDOW_SIZE, // int[2] (w/h)
VOCTRL_SET_UNFS_WINDOW_SIZE, // int[2] (w/h)
+ VOCTRL_GET_WIN_STATE, // int* (VO_WIN_STATE_* flags)
+
// The VO is supposed to set "known" fields, and leave the others
// untouched or set to 0.
// imgfmt/w/h/d_w/d_h can be omitted for convenience.
@@ -130,6 +134,9 @@ struct voctrl_screenshot_args {
bool has_osd;
};
+// VOCTRL_GET_WIN_STATE
+#define VO_WIN_STATE_MINIMIZED 1
+
#define VO_TRUE true
#define VO_FALSE false
#define VO_ERROR -1
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 04f475ec5f..1779c5c29e 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -952,6 +952,8 @@ int vo_x11_check_events(struct vo *vo)
MP_VERBOSE(x11, "not waiting for MapNotify\n");
x11->pseudo_mapped = true;
}
+ } else if (Event.xproperty.atom == x11->atom_wm_state) {
+ x11->pending_vo_events |= VO_EVENT_WIN_STATE;
}
break;
default:
@@ -1229,6 +1231,7 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis,
}
x11->atom_frame_exts = XA(x11, _NET_FRAME_EXTENTS);
+ x11->atom_wm_state = XA(x11, _NET_WM_STATE);
}
static void vo_x11_map_window(struct vo *vo, struct mp_rect rc)
@@ -1584,6 +1587,22 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
}
return VO_TRUE;
}
+ case VOCTRL_GET_WIN_STATE: {
+ if (!x11->window)
+ return VO_FALSE;
+ int num_elems;
+ long *elems = x11_get_property(x11, x11->window, x11->atom_wm_state,
+ XA_ATOM, 32, &num_elems);
+ if (elems) {
+ Atom hidden = XA(x11, _NET_WM_STATE_HIDDEN);
+ for (int n = 0; n < num_elems; n++) {
+ if (elems[n] == hidden)
+ *(int *)arg |= VO_WIN_STATE_MINIMIZED;
+ }
+ XFree(elems);
+ }
+ return VO_TRUE;
+ }
case VOCTRL_SET_CURSOR_VISIBILITY:
vo_set_cursor_hidden(vo, !(*(bool *)arg));
return VO_TRUE;
diff --git a/video/out/x11_common.h b/video/out/x11_common.h
index 696e73aff3..d5927933c3 100644
--- a/video/out/x11_common.h
+++ b/video/out/x11_common.h
@@ -108,6 +108,7 @@ struct vo_x11_state {
Window dnd_src_window;
Atom atom_frame_exts;
+ Atom atom_wm_state;
/* dragging the window */
bool win_drag_button1_down;