summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-11-29 13:52:37 +0100
committerwm4 <wm4@nowhere>2019-11-29 13:56:58 +0100
commitd520258ffbc3a0e4e2c9a04f62af11feb0273754 (patch)
treeee24b59ef580e8201d6b8e43693445cc2561fac1
parent40c2f2eeb05f83176d325d4efd7a2e1635447f04 (diff)
downloadmpv-d520258ffbc3a0e4e2c9a04f62af11feb0273754.tar.bz2
mpv-d520258ffbc3a0e4e2c9a04f62af11feb0273754.tar.xz
x11: handle maximize/minimize with new option stuff
Should restore full functionality. The initial state setting is a bit shoddy (instead of setting the properties before map, we use the WM commands to change it after, so you will see the normal window state for a moment; the WM commands do not work on unmapped windows, so fixing this would require more code).
-rw-r--r--video/out/x11_common.c74
1 files changed, 31 insertions, 43 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 217fd58aed..39639db376 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -145,6 +145,8 @@ static void vo_x11_xembed_handle_message(struct vo *vo, XClientMessageEvent *ce)
static void vo_x11_xembed_send_message(struct vo_x11_state *x11, long m[4]);
static void vo_x11_move_resize(struct vo *vo, bool move, bool resize,
struct mp_rect rc);
+static void vo_x11_maximize(struct vo *vo);
+static void vo_x11_minimize(struct vo *vo);
#define XA(x11, s) (XInternAtom((x11)->display, # s, False))
#define XAs(x11, s) XInternAtom((x11)->display, s, False)
@@ -1013,9 +1015,10 @@ static void vo_x11_update_composition_hint(struct vo *vo)
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&hint, 1);
}
-static void vo_x11_check_net_wm_state_fullscreen_change(struct vo *vo)
+static void vo_x11_check_net_wm_state_change(struct vo *vo)
{
struct vo_x11_state *x11 = vo->x11;
+ struct mp_vo_opts *opts = x11->opts;
if (x11->parent)
return;
@@ -1024,18 +1027,28 @@ static void vo_x11_check_net_wm_state_fullscreen_change(struct vo *vo)
int num_elems;
long *elems = x11_get_property(x11, x11->window, XA(x11, _NET_WM_STATE),
XA_ATOM, 32, &num_elems);
- int is_fullscreen = 0;
+ int is_fullscreen = 0, is_minimized = 0, is_maximized = 0;
if (elems) {
Atom fullscreen_prop = XA(x11, _NET_WM_STATE_FULLSCREEN);
+ Atom hidden = XA(x11, _NET_WM_STATE_HIDDEN);
+ Atom max_vert = XA(x11, _NET_WM_STATE_MAXIMIZED_VERT);
+ Atom max_horiz = XA(x11, _NET_WM_STATE_MAXIMIZED_HORZ);
for (int n = 0; n < num_elems; n++) {
- if (elems[n] == fullscreen_prop) {
+ if (elems[n] == fullscreen_prop)
is_fullscreen = 1;
- break;
- }
+ if (elems[n] == hidden)
+ is_minimized = 1;
+ if (elems[n] == max_vert || elems[n] == max_horiz)
+ is_maximized = 1;
}
XFree(elems);
}
+ opts->window_minimized = is_minimized;
+ m_config_cache_write_opt(x11->opts_cache, &opts->window_minimized);
+ opts->window_maximized = is_maximized;
+ m_config_cache_write_opt(x11->opts_cache, &opts->window_maximized);
+
if ((x11->opts->fullscreen && !is_fullscreen) ||
(!x11->opts->fullscreen && is_fullscreen))
{
@@ -1231,7 +1244,7 @@ void vo_x11_check_events(struct vo *vo)
x11->pseudo_mapped = true;
}
} else if (Event.xproperty.atom == XA(x11, _NET_WM_STATE)) {
- vo_x11_check_net_wm_state_fullscreen_change(vo);
+ vo_x11_check_net_wm_state_change(vo);
} else if (Event.xproperty.atom == XA(x11, _NET_WM_DESKTOP)) {
vo_x11_check_net_wm_desktop_change(vo);
} else if (Event.xproperty.atom == x11->icc_profile_property) {
@@ -1531,6 +1544,11 @@ static void vo_x11_map_window(struct vo *vo, struct mp_rect rc)
vo_x11_selectinput_witherr(vo, x11->display, x11->window, events);
XMapWindow(x11->display, x11->window);
+ if (x11->opts->window_maximized) // don't override WM default on "no"
+ vo_x11_maximize(vo);
+ if (x11->opts->window_minimized) // don't override WM default on "no"
+ vo_x11_minimize(vo);
+
if (x11->opts->fullscreen && (x11->wm_type & vo_wm_FULLSCREEN))
x11_set_ewmh_state(x11, "_NET_WM_STATE_FULLSCREEN", 1);
@@ -1805,15 +1823,8 @@ static void vo_x11_maximize(struct vo *vo)
{
struct vo_x11_state *x11 = vo->x11;
- /*
- * Although we only do full maximization, the user may do a partial
- * maximization via other means. Toggling both when one is set and
- * one is not results in implementation-dependent behaviour. In
- * testing with gnome-shell, toggling goes from HORZ to un-maximized,
- * and goes from VERT to fully maximized.
- */
long params[5] = {
- NET_WM_STATE_TOGGLE,
+ x11->opts->window_maximized ? NET_WM_STATE_ADD : NET_WM_STATE_REMOVE,
XA(x11, _NET_WM_STATE_MAXIMIZED_VERT),
XA(x11, _NET_WM_STATE_MAXIMIZED_HORZ),
1, // source indication: normal
@@ -1825,7 +1836,8 @@ static void vo_x11_minimize(struct vo *vo)
{
struct vo_x11_state *x11 = vo->x11;
- XIconifyWindow(x11->display, x11->window, x11->screen);
+ if (x11->opts->window_minimized)
+ XIconifyWindow(x11->display, x11->window, x11->screen);
}
int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
@@ -1857,6 +1869,10 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
}
x11_send_ewmh_msg(x11, "_NET_WM_DESKTOP", params);
}
+ if (opt == &opts->window_minimized)
+ vo_x11_minimize(vo);
+ if (opt == &opts->window_maximized)
+ vo_x11_maximize(vo);
}
return VO_TRUE;
}
@@ -1882,34 +1898,6 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
}
return VO_TRUE;
}
- case VOCTRL_MAXIMIZE:
- vo_x11_maximize(vo);
- return VO_TRUE;
- case VOCTRL_MINIMIZE:
- vo_x11_minimize(vo);
- return VO_TRUE;
- case VOCTRL_GET_WIN_STATE: {
- if (!x11->pseudo_mapped)
- return VO_FALSE;
- *(int *)arg = 0;
- int num_elems;
- long *elems = x11_get_property(x11, x11->window, XA(x11, _NET_WM_STATE),
- XA_ATOM, 32, &num_elems);
- if (elems) {
- Atom hidden = XA(x11, _NET_WM_STATE_HIDDEN);
- Atom max_vert = XA(x11, _NET_WM_STATE_MAXIMIZED_VERT);
- Atom max_horiz = XA(x11, _NET_WM_STATE_MAXIMIZED_HORZ);
- for (int n = 0; n < num_elems; n++) {
- if (elems[n] == hidden)
- *(int *)arg |= VO_WIN_STATE_MINIMIZED;
- else if (elems[n] == max_vert ||
- elems[n] == max_horiz)
- *(int *)arg |= VO_WIN_STATE_MAXIMIZED;
- }
- XFree(elems);
- }
- return VO_TRUE;
- }
case VOCTRL_GET_DISPLAY_NAMES: {
if (!x11->pseudo_mapped)
return VO_FALSE;