summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2019-11-26 07:52:53 +0800
committerPhilip Langdale <github.philipl@overt.org>2019-11-29 16:56:20 +0800
commit4c179a27c2fe301d51232934275250b63275f86b (patch)
treebc62f95e3e1afd14548d4aa6f34e87e1493d7557
parentf09570664fd870cbd7403575c8f2a31e34d4c570 (diff)
downloadmpv-4c179a27c2fe301d51232934275250b63275f86b.tar.bz2
mpv-4c179a27c2fe301d51232934275250b63275f86b.tar.xz
wayland: add grab zone for resizing window with mouse
Today, we support resizing wayland windows when we detect a touch event in a defined grab zone. As part of implementing pseudo-decorations, we should have equivalent functionality for mouse input. And if we detect support for actual decorations we will not activate the grab zone as the decorations will provide this.
-rw-r--r--video/out/wayland_common.c92
-rw-r--r--video/out/wayland_common.h2
2 files changed, 54 insertions, 40 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 2007836a3b..c9da326b5a 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -56,6 +56,9 @@ const struct m_sub_options wayland_conf = {
},
};
+#define POINTER_EDGE_PIXELS 5
+#define TOUCH_EDGE_PIXELS 64
+
static void xdg_wm_base_ping(void *data, struct xdg_wm_base *wm_base, uint32_t serial)
{
xdg_wm_base_pong(wm_base, serial);
@@ -155,6 +158,8 @@ static void pointer_handle_motion(void *data, struct wl_pointer *pointer,
wl->prev_fullscreen = wl->fullscreen;
wl->mouse_x = wl_fixed_to_int(sx) * wl->scaling;
wl->mouse_y = wl_fixed_to_int(sy) * wl->scaling;
+ wl->mouse_unscaled_x = sx;
+ wl->mouse_unscaled_y = sy;
mp_input_set_mouse_pos(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y);
}
@@ -165,6 +170,42 @@ static void window_move(struct vo_wayland_state *wl, uint32_t serial)
xdg_toplevel_move(wl->xdg_toplevel, wl->seat, serial);
}
+static int check_for_resize(struct vo_wayland_state *wl, wl_fixed_t x_w, wl_fixed_t y_w,
+ int edge_pixels, enum xdg_toplevel_resize_edge *edge)
+{
+ if (wl->touch_entries || wl->fullscreen || wl->maximized)
+ return 0;
+
+ int pos[2] = { wl_fixed_to_double(x_w), wl_fixed_to_double(y_w) };
+ int left_edge = pos[0] < edge_pixels;
+ int top_edge = pos[1] < edge_pixels;
+ int right_edge = pos[0] > (mp_rect_w(wl->geometry) - edge_pixels);
+ int bottom_edge = pos[1] > (mp_rect_h(wl->geometry) - edge_pixels);
+
+ if (left_edge) {
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
+ if (top_edge)
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
+ else if (bottom_edge)
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
+ } else if (right_edge) {
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
+ if (top_edge)
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
+ else if (bottom_edge)
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
+ } else if (top_edge) {
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
+ } else if (bottom_edge) {
+ *edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
+ } else {
+ *edge = 0;
+ return 0;
+ }
+
+ return 1;
+}
+
static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, uint32_t time, uint32_t button,
uint32_t state)
@@ -200,8 +241,16 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
}
if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) &&
- (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN))
- window_move(wl, serial);
+ (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN)) {
+ uint32_t edges;
+ // Implement an edge resize zone if there are no decorations
+ if (!wl->xdg_toplevel_decoration &&
+ check_for_resize(wl, wl->mouse_unscaled_x, wl->mouse_unscaled_y,
+ POINTER_EDGE_PIXELS, &edges))
+ xdg_toplevel_resize(wl->xdg_toplevel, wl->seat, serial, edges);
+ else
+ window_move(wl, serial);
+ }
}
static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
@@ -235,43 +284,6 @@ static const struct wl_pointer_listener pointer_listener = {
pointer_handle_axis,
};
-static int check_for_resize(struct vo_wayland_state *wl, wl_fixed_t x_w, wl_fixed_t y_w,
- enum xdg_toplevel_resize_edge *edge)
-{
- if (wl->touch_entries || wl->fullscreen || wl->maximized)
- return 0;
-
- const int edge_pixels = 64;
- int pos[2] = { wl_fixed_to_double(x_w), wl_fixed_to_double(y_w) };
- int left_edge = pos[0] < edge_pixels;
- int top_edge = pos[1] < edge_pixels;
- int right_edge = pos[0] > (mp_rect_w(wl->geometry) - edge_pixels);
- int bottom_edge = pos[1] > (mp_rect_h(wl->geometry) - edge_pixels);
-
- if (left_edge) {
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
- if (top_edge)
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
- else if (bottom_edge)
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
- } else if (right_edge) {
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
- if (top_edge)
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
- else if (bottom_edge)
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
- } else if (top_edge) {
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
- } else if (bottom_edge) {
- *edge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
- } else {
- *edge = 0;
- return 0;
- }
-
- return 1;
-}
-
static void touch_handle_down(void *data, struct wl_touch *wl_touch,
uint32_t serial, uint32_t time, struct wl_surface *surface,
int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
@@ -279,7 +291,7 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch,
struct vo_wayland_state *wl = data;
enum xdg_toplevel_resize_edge edge;
- if (check_for_resize(wl, x_w, y_w, &edge)) {
+ if (check_for_resize(wl, x_w, y_w, TOUCH_EDGE_PIXELS, &edge)) {
wl->touch_entries = 0;
xdg_toplevel_resize(wl->xdg_toplevel, wl->seat, serial, edge);
return;
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index f0c11e080a..2ca7d86a96 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -77,6 +77,8 @@ struct vo_wayland_state {
int pending_vo_events;
int mouse_x;
int mouse_y;
+ int mouse_unscaled_x;
+ int mouse_unscaled_y;
int scaling;
int touch_entries;
uint32_t pointer_id;