From 43b07b122a1fa460bdda3edc529726e3b6a6463d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 29 Feb 2020 12:52:55 +0100 Subject: [PATCH] input: csd: add a small delay before initiating a move This ensures the user has time to double-click to toggle the maximized state. --- input.c | 41 ++++++++++++++++++++++++++++++++++++----- wayland.c | 4 ++++ wayland.h | 3 +++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/input.c b/input.c index a7a78a5d..1db3541f 100644 --- a/input.c +++ b/input.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -833,6 +834,19 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, term, wayl->mouse.button, wayl->mouse.row, wayl->mouse.col); } +static bool +fdm_csd_move(struct fdm *fdm, int fd, int events, void *data) +{ + struct wl_window *win = data; + struct wayland *wayl = win->term->wl; + + fdm_del(fdm, fd); + win->csd.move_timeout_fd = -1; + + xdg_toplevel_move(win->xdg_toplevel, wayl->seat, win->csd.serial); + return true; +} + static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) @@ -891,16 +905,33 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, case TERM_SURF_TITLE: if (state == WL_POINTER_BUTTON_STATE_PRESSED) { + struct wl_window *win = term->window; + /* Toggle maximized state on double-click */ if (button == BTN_LEFT && wayl->mouse.count == 2) { - if (term->window->is_maximized) - xdg_toplevel_unset_maximized(term->window->xdg_toplevel); + if (win->is_maximized) + xdg_toplevel_unset_maximized(win->xdg_toplevel); else - xdg_toplevel_set_maximized(term->window->xdg_toplevel); + xdg_toplevel_set_maximized(win->xdg_toplevel); } - else if (button == BTN_LEFT) - xdg_toplevel_move(term->window->xdg_toplevel, term->wl->seat, serial); + else if (button == BTN_LEFT && win->csd.move_timeout_fd == -1) { + const struct itimerspec timeout = { + .it_value = {.tv_nsec = 100000000}, + }; + + int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); + if (fd >= 0 && + timerfd_settime(fd, 0, &timeout, NULL) == 0 && + fdm_add(wayl->fdm, fd, EPOLLIN, &fdm_csd_move, win)) + { + win->csd.move_timeout_fd = fd; + win->csd.serial = serial; + } else { + LOG_ERRNO("failed to configure XDG toplevel move timer FD"); + close(fd); + } + } } return; diff --git a/wayland.c b/wayland.c index 5d3a30df..7322a32f 100644 --- a/wayland.c +++ b/wayland.c @@ -1014,6 +1014,7 @@ wayl_win_init(struct terminal *term) struct wl_window *win = calloc(1, sizeof(*win)); win->term = term; win->use_csd = CSD_UNKNOWN; + win->csd.move_timeout_fd = -1; win->surface = wl_compositor_create_surface(wayl->compositor); if (win->surface == NULL) { @@ -1072,6 +1073,9 @@ wayl_win_destroy(struct wl_window *win) if (win == NULL) return; + if (win->csd.move_timeout_fd != -1) + close(win->csd.move_timeout_fd); + /* * First, unmap all surfaces to trigger things like * keyboard_leave() and wl_pointer_leave(). diff --git a/wayland.h b/wayland.h index a18b40a3..4d73be42 100644 --- a/wayland.h +++ b/wayland.h @@ -106,6 +106,9 @@ struct wl_window { struct wl_surface *surface[5]; struct wl_subsurface *sub_surface[5]; int x, y; + + int move_timeout_fd; + uint32_t serial; } csd; /* Scrollback search */