Merge pull request #41 from tiosgz/pointer-focus
Pointer focus improvements
This commit is contained in:
commit
9ae4b095d1
5 changed files with 121 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: {
|
||||||
|
@ -84,48 +83,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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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