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.
This commit is contained in:
parent
a4865b1963
commit
21062c0224
5 changed files with 90 additions and 48 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -28,10 +28,9 @@
|
||||||
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;
|
|
||||||
|
|
||||||
switch (cursor->cursor_mode) {
|
switch (cursor->cursor_mode) {
|
||||||
case KIWMI_CURSOR_MOVE: {
|
case KIWMI_CURSOR_MOVE: {
|
||||||
|
@ -83,48 +82,13 @@ 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);
|
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,3 +271,62 @@ 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 = 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue