From 21062c0224cf87c29c853326f0e19f107ac735c3 Mon Sep 17 00:00:00 2001 From: tiosgz Date: Sun, 5 Sep 2021 09:20:52 +0000 Subject: [PATCH] Update pointer focus more often Until now, focusing a different view didn't move pointer focus to it, even though it was under the cursor. The pointer had to move in order to switch its focus. Similar situations should be handled after this commit. --- include/input/cursor.h | 6 ++ kiwmi/desktop/view.c | 7 ++- kiwmi/desktop/xdg_shell.c | 9 ++- kiwmi/input/cursor.c | 115 +++++++++++++++++++++++--------------- kiwmi/input/seat.c | 1 + 5 files changed, 90 insertions(+), 48 deletions(-) diff --git a/include/input/cursor.h b/include/input/cursor.h index 540cc3d..c126312 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -67,6 +67,12 @@ struct kiwmi_cursor_scroll_event { bool handled; }; +void cursor_refresh_focus( + struct kiwmi_cursor *cursor, + struct wlr_surface **new_surface, + double *cursor_sx, + double *cursor_sy); + struct kiwmi_cursor *cursor_create( struct kiwmi_server *server, struct wlr_output_layout *output_layout); diff --git a/kiwmi/desktop/view.c b/kiwmi/desktop/view.c index 17b392a..aa5459c 100644 --- a/kiwmi/desktop/view.c +++ b/kiwmi/desktop/view.c @@ -113,8 +113,13 @@ view_set_pos(struct kiwmi_view *view, uint32_t x, uint32_t y) } } + struct kiwmi_desktop *desktop = view->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct kiwmi_cursor *cursor = server->input.cursor; + cursor_refresh_focus(cursor, NULL, NULL, NULL); + struct kiwmi_output *output; - wl_list_for_each (output, &view->desktop->outputs, link) { + wl_list_for_each (output, &desktop->outputs, link) { output_damage(output); } } diff --git a/kiwmi/desktop/xdg_shell.c b/kiwmi/desktop/xdg_shell.c index 345f1f1..3402a02 100644 --- a/kiwmi/desktop/xdg_shell.c +++ b/kiwmi/desktop/xdg_shell.c @@ -19,6 +19,7 @@ #include "desktop/desktop.h" #include "desktop/output.h" #include "desktop/view.h" +#include "input/cursor.h" #include "input/input.h" #include "input/seat.h" #include "server.h" @@ -204,9 +205,14 @@ xdg_surface_commit_notify(struct wl_listener *listener, void *UNUSED(data)) { struct kiwmi_view *view = wl_container_of(listener, view, commit); + struct kiwmi_desktop *desktop = view->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct kiwmi_cursor *cursor = server->input.cursor; + cursor_refresh_focus(cursor, NULL, NULL, NULL); + if (pixman_region32_not_empty(&view->wlr_surface->buffer_damage)) { struct kiwmi_output *output; - wl_list_for_each (output, &view->desktop->outputs, link) { + wl_list_for_each (output, &desktop->outputs, link) { output_damage(output); } } @@ -225,6 +231,7 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) if (seat->focused_view == view) { seat->focused_view = NULL; } + cursor_refresh_focus(server->input.cursor, NULL, NULL, NULL); struct kiwmi_view_child *child, *tmpchild; wl_list_for_each_safe (child, tmpchild, &view->children, link) { diff --git a/kiwmi/input/cursor.c b/kiwmi/input/cursor.c index dd801b1..1825a1e 100644 --- a/kiwmi/input/cursor.c +++ b/kiwmi/input/cursor.c @@ -28,10 +28,9 @@ static void process_cursor_motion(struct kiwmi_server *server, uint32_t time) { - struct kiwmi_desktop *desktop = &server->desktop; - struct kiwmi_input *input = &server->input; - struct kiwmi_cursor *cursor = input->cursor; - struct wlr_seat *seat = input->seat->seat; + struct kiwmi_input *input = &server->input; + struct kiwmi_cursor *cursor = input->cursor; + struct wlr_seat *seat = input->seat->seat; switch (cursor->cursor_mode) { case KIWMI_CURSOR_MOVE: { @@ -83,48 +82,13 @@ process_cursor_motion(struct kiwmi_server *server, uint32_t time) break; } - double ox = 0; - double oy = 0; - struct wlr_output *wlr_output = wlr_output_layout_output_at( - desktop->output_layout, cursor->cursor->x, cursor->cursor->y); - - wlr_output_layout_output_coords( - desktop->output_layout, wlr_output, &ox, &oy); - - struct kiwmi_output *output = wlr_output->data; - - struct wlr_surface *surface = NULL; - double sx; - double sy; - - struct kiwmi_layer *layer = layer_at( - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], - &surface, - cursor->cursor->x, - cursor->cursor->y, - &sx, - &sy); - - if (!layer) { - struct kiwmi_view *view = view_at( - desktop, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - - if (!view) { - wlr_xcursor_manager_set_cursor_image( - cursor->xcursor_manager, "left_ptr", cursor->cursor); - } - } - - if (surface) { - bool focus_changed = surface != seat->pointer_state.focused_surface; - - wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - - if (!focus_changed) { - wlr_seat_pointer_notify_motion(seat, time, sx, sy); - } - } else { - wlr_seat_pointer_clear_focus(seat); + struct wlr_surface *old_focus = seat->pointer_state.focused_surface; + struct wlr_surface *new_focus; + double sx, sy; + cursor_refresh_focus(cursor, &new_focus, &sx, &sy); + if (new_focus && new_focus == old_focus) { + wlr_seat_pointer_notify_enter(seat, new_focus, sx, sy); + wlr_seat_pointer_notify_motion(seat, time, sx, sy); } } @@ -307,3 +271,62 @@ cursor_destroy(struct kiwmi_cursor *cursor) free(cursor); } + +void +cursor_refresh_focus( + struct kiwmi_cursor *cursor, + struct wlr_surface **new_surface, + double *cursor_sx, + double *cursor_sy) +{ + struct kiwmi_desktop *desktop = &cursor->server->desktop; + struct wlr_seat *seat = cursor->server->input.seat->seat; + + double ox = 0; + double oy = 0; + struct wlr_output *wlr_output = wlr_output_layout_output_at( + desktop->output_layout, cursor->cursor->x, cursor->cursor->y); + + wlr_output_layout_output_coords( + desktop->output_layout, wlr_output, &ox, &oy); + + struct kiwmi_output *output = wlr_output->data; + + struct wlr_surface *surface = NULL; + double sx; + double sy; + + struct kiwmi_layer *layer = layer_at( + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], + &surface, + cursor->cursor->x, + cursor->cursor->y, + &sx, + &sy); + + if (!layer) { + struct kiwmi_view *view = view_at( + desktop, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); + + if (!view) { + wlr_xcursor_manager_set_cursor_image( + cursor->xcursor_manager, "left_ptr", cursor->cursor); + } + } + + if (surface && surface != seat->pointer_state.focused_surface) { + wlr_seat_pointer_notify_enter(seat, surface, sx, sy); + } else if (!surface) { + wlr_seat_pointer_clear_focus(seat); + } + + if (new_surface) { + *new_surface = surface; + } + if (cursor_sx) { + *cursor_sx = surface ? sx : 0; + } + if (cursor_sy) { + *cursor_sy = surface ? sy : 0; + } +} diff --git a/kiwmi/input/seat.c b/kiwmi/input/seat.c index 33bb5c3..57984f9 100644 --- a/kiwmi/input/seat.c +++ b/kiwmi/input/seat.c @@ -83,6 +83,7 @@ seat_focus_view(struct kiwmi_seat *seat, struct kiwmi_view *view) // move view to front wl_list_remove(&view->link); wl_list_insert(&desktop->views, &view->link); + cursor_refresh_focus(seat->input->cursor, NULL, NULL, NULL); seat->focused_view = view; view_set_activated(view, true);