diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index f7410dec..2c687a39 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -80,4 +80,7 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, struct wlr_seat_pointer_request_set_cursor_event *event); +void roots_cursor_update_position(struct roots_cursor *cursor, + uint32_t time); + #endif diff --git a/include/rootston/input.h b/include/rootston/input.h index ef46fab2..2cdb13e6 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -32,4 +32,6 @@ struct roots_seat *input_get_seat(struct roots_input *input, char *name); struct roots_seat *input_last_active_seat(struct roots_input *input); +void input_update_cursor_focus(struct roots_input *input); + #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 94f5520e..9a9f9af6 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -101,6 +101,7 @@ static void seat_view_deco_button(struct roots_seat_view *view, double sx, static void roots_passthrough_cursor(struct roots_cursor *cursor, uint32_t time) { + bool focus_changed; double sx, sy; struct roots_view *view = NULL; struct roots_seat *seat = cursor->seat; @@ -136,8 +137,11 @@ static void roots_passthrough_cursor(struct roots_cursor *cursor, } if (surface) { + focus_changed = (seat->seat->pointer_state.focused_surface != surface); wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); + if (!focus_changed) { + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); + } } else { wlr_seat_pointer_clear_focus(seat->seat); } @@ -148,8 +152,8 @@ static void roots_passthrough_cursor(struct roots_cursor *cursor, } } -static void roots_cursor_update_position( - struct roots_cursor *cursor, uint32_t time) { +void roots_cursor_update_position(struct roots_cursor *cursor, + uint32_t time) { struct roots_seat *seat = cursor->seat; struct roots_view *view; switch (cursor->mode) { @@ -266,13 +270,7 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, cursor->mode = ROOTS_CURSOR_PASSTHROUGH; } - switch (state) { - case WLR_BUTTON_RELEASED: - if (!is_touch) { - roots_cursor_update_position(cursor, time); - } - break; - case WLR_BUTTON_PRESSED: + if (state == WLR_BUTTON_PRESSED) { if (view) { roots_seat_set_focus(seat, view); } @@ -283,7 +281,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, roots_seat_set_focus_layer(seat, layer); } } - break; } } diff --git a/rootston/desktop.c b/rootston/desktop.c index 5277dcc7..17bf7ec4 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -423,6 +423,7 @@ struct roots_subsurface *subsurface_create(struct roots_view *view, view_child_init(&subsurface->view_child, view, wlr_subsurface->surface); subsurface->destroy.notify = subsurface_handle_destroy; wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); + input_update_cursor_focus(view->desktop->server->input); return subsurface; } @@ -468,6 +469,7 @@ void view_map(struct roots_view *view, struct wlr_surface *surface) { wl_list_insert(&view->desktop->views, &view->link); view_damage_whole(view); + input_update_cursor_focus(view->desktop->server->input); } void view_unmap(struct roots_view *view) { diff --git a/rootston/input.c b/rootston/input.c index 84b5acae..de847d78 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -1,5 +1,7 @@ +#define _POSIX_C_SOURCE 199309L #include #include +#include #include #include #include @@ -126,3 +128,16 @@ bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { return false; } + +static inline int64_t timespec_to_msec(const struct timespec *a) { + return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +} + +void input_update_cursor_focus(struct roots_input *input) { + struct roots_seat *seat; + struct timespec now; + wl_list_for_each(seat, &input->seats, link) { + clock_gettime(CLOCK_MONOTONIC, &now); + roots_cursor_update_position(seat->cursor, timespec_to_msec(&now)); + } +} diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index ba69c3db..6795cb58 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -291,7 +291,10 @@ static void handle_map(struct wl_listener *listener, void *data) { static void handle_unmap(struct wl_listener *listener, void *data) { struct roots_layer_surface *layer = wl_container_of( listener, layer, unmap); + struct wlr_output *wlr_output = layer->layer_surface->output; + struct roots_output *output = wlr_output->data; unmap(layer->layer_surface); + input_update_cursor_focus(output->desktop->server->input); } static void popup_handle_map(struct wl_listener *listener, void *data) { @@ -303,6 +306,7 @@ static void popup_handle_map(struct wl_listener *listener, void *data) { int oy = popup->wlr_popup->geometry.y + layer->geo.y; output_damage_whole_local_surface(output, popup->wlr_popup->base->surface, ox, oy, 0); + input_update_cursor_focus(output->desktop->server->input); } static void popup_handle_unmap(struct wl_listener *listener, void *data) { diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index d04d37e1..0c438be4 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -6,6 +6,7 @@ #include #include #include +#include "rootston/cursor.h" #include "rootston/desktop.h" #include "rootston/input.h" #include "rootston/server.h" @@ -33,6 +34,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { static void popup_handle_map(struct wl_listener *listener, void *data) { struct roots_xdg_popup *popup = wl_container_of(listener, popup, map); view_damage_whole(popup->view_child.view); + input_update_cursor_focus(popup->view_child.view->desktop->server->input); } static void popup_handle_unmap(struct wl_listener *listener, void *data) { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 219be2b0..1201ba68 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -34,6 +34,7 @@ static void popup_handle_map(struct wl_listener *listener, void *data) { struct roots_xdg_popup_v6 *popup = wl_container_of(listener, popup, map); view_damage_whole(popup->view_child.view); + input_update_cursor_focus(popup->view_child.view->desktop->server->input); } static void popup_handle_unmap(struct wl_listener *listener, void *data) {