Merge pull request #41 from tiosgz/pointer-focus

Pointer focus improvements
This commit is contained in:
buffet 2021-09-13 19:06:18 +00:00 committed by GitHub
commit 9ae4b095d1
5 changed files with 121 additions and 48 deletions

View file

@ -67,6 +67,12 @@ struct kiwmi_cursor_scroll_event {
bool handled; 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_cursor *cursor_create(
struct kiwmi_server *server, struct kiwmi_server *server,
struct wlr_output_layout *output_layout); struct wlr_output_layout *output_layout);

View file

@ -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; struct kiwmi_output *output;
wl_list_for_each (output, &view->desktop->outputs, link) { wl_list_for_each (output, &desktop->outputs, link) {
output_damage(output); output_damage(output);
} }
} }

View file

@ -19,6 +19,7 @@
#include "desktop/desktop.h" #include "desktop/desktop.h"
#include "desktop/output.h" #include "desktop/output.h"
#include "desktop/view.h" #include "desktop/view.h"
#include "input/cursor.h"
#include "input/input.h" #include "input/input.h"
#include "input/seat.h" #include "input/seat.h"
#include "server.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_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)) { if (pixman_region32_not_empty(&view->wlr_surface->buffer_damage)) {
struct kiwmi_output *output; struct kiwmi_output *output;
wl_list_for_each (output, &view->desktop->outputs, link) { wl_list_for_each (output, &desktop->outputs, link) {
output_damage(output); output_damage(output);
} }
} }
@ -225,6 +231,7 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data))
if (seat->focused_view == view) { if (seat->focused_view == view) {
seat->focused_view = NULL; seat->focused_view = NULL;
} }
cursor_refresh_focus(server->input.cursor, NULL, NULL, NULL);
struct kiwmi_view_child *child, *tmpchild; struct kiwmi_view_child *child, *tmpchild;
wl_list_for_each_safe (child, tmpchild, &view->children, link) { wl_list_for_each_safe (child, tmpchild, &view->children, link) {

View file

@ -28,7 +28,6 @@
static void static void
process_cursor_motion(struct kiwmi_server *server, uint32_t time) process_cursor_motion(struct kiwmi_server *server, uint32_t time)
{ {
struct kiwmi_desktop *desktop = &server->desktop;
struct kiwmi_input *input = &server->input; struct kiwmi_input *input = &server->input;
struct kiwmi_cursor *cursor = input->cursor; struct kiwmi_cursor *cursor = input->cursor;
struct wlr_seat *seat = input->seat->seat; struct wlr_seat *seat = input->seat->seat;
@ -84,49 +83,14 @@ process_cursor_motion(struct kiwmi_server *server, uint32_t time)
break; break;
} }
double ox = 0; struct wlr_surface *old_focus = seat->pointer_state.focused_surface;
double oy = 0; struct wlr_surface *new_focus;
struct wlr_output *wlr_output = wlr_output_layout_output_at( double sx, sy;
desktop->output_layout, cursor->cursor->x, cursor->cursor->y); cursor_refresh_focus(cursor, &new_focus, &sx, &sy);
if (new_focus && new_focus == old_focus) {
wlr_output_layout_output_coords( wlr_seat_pointer_notify_enter(seat, new_focus, sx, sy);
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); wlr_seat_pointer_notify_motion(seat, time, sx, sy);
} }
} else {
wlr_seat_pointer_clear_focus(seat);
}
} }
static void static void
@ -308,3 +272,93 @@ cursor_destroy(struct kiwmi_cursor *cursor)
free(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 = cursor->cursor->x;
double oy = cursor->cursor->y;
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,
ox,
oy,
&sx,
&sy);
struct kiwmi_view *view;
if (!layer) {
layer = layer_at(
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
&surface,
ox,
oy,
&sx,
&sy);
}
if (!layer) {
view = view_at(
desktop, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
}
if (!layer) {
layer = layer_at(
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
&surface,
ox,
oy,
&sx,
&sy);
}
if (!layer) {
layer = layer_at(
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
&surface,
ox,
oy,
&sx,
&sy);
}
if (!layer && !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;
}
}

View file

@ -83,6 +83,7 @@ seat_focus_view(struct kiwmi_seat *seat, struct kiwmi_view *view)
// move view to front // move view to front
wl_list_remove(&view->link); wl_list_remove(&view->link);
wl_list_insert(&desktop->views, &view->link); wl_list_insert(&desktop->views, &view->link);
cursor_refresh_focus(seat->input->cursor, NULL, NULL, NULL);
seat->focused_view = view; seat->focused_view = view;
view_set_activated(view, true); view_set_activated(view, true);