Commit cfc312b72488fbe77f72df0b44cc2bdfdba3295e Parent: f2964736038a8b50b74ec633c9355bdd53c1bcfd Author: mcol <mcol@posteo.net> Date: 2020-11-05 11:44:32 +0000 Committer: mcol <mcol@posteo.net> Committed: 2020-11-05 11:44:32 +0000 Add template cursor-processing from wlroots/tinywm
src/types.h Modified
@@ -45,7 +45,7 @@ struct wl_listener request_set_selection_listener; struct wl_list keyboards; enum cursor_mode cursor_mode; - struct deskwm_view *grabbed_view; + struct view *grabbed_view; double grab_x, grab_y; struct wlr_box grab_geobox; uint32_t resize_edges;
src/input.c Modified
@@ -5,13 +5,138 @@ #include "types.h" +static void process_cursor_move(struct server *server, uint32_t time) { + server->grabbed_view->x = server->cursor->x - server->grab_x; + server->grabbed_view->y = server->cursor->y - server->grab_y; +} + + +static void process_cursor_resize(struct server *server, uint32_t time) { + struct view *view = server->grabbed_view; + double border_x = server->cursor->x - server->grab_x; + double border_y = server->cursor->y - server->grab_y; + int new_left = server->grab_geobox.x; + int new_right = server->grab_geobox.x + server->grab_geobox.width; + int new_top = server->grab_geobox.y; + int new_bottom = server->grab_geobox.y + server->grab_geobox.height; + + if (server->resize_edges & WLR_EDGE_TOP) { + new_top = border_y; + if (new_top >= new_bottom) { + new_top = new_bottom - 1; + } + } else if (server->resize_edges & WLR_EDGE_BOTTOM) { + new_bottom = border_y; + if (new_bottom <= new_top) { + new_bottom = new_top + 1; + } + } + if (server->resize_edges & WLR_EDGE_LEFT) { + new_left = border_x; + if (new_left >= new_right) { + new_left = new_right - 1; + } + } else if (server->resize_edges & WLR_EDGE_RIGHT) { + new_right = border_x; + if (new_right <= new_left) { + new_right = new_left + 1; + } + } + + struct wlr_box geo_box; + wlr_xdg_surface_get_geometry(view->surface, &geo_box); + view->x = new_left - geo_box.x; + view->y = new_top - geo_box.y; + + int new_width = new_right - new_left; + int new_height = new_bottom - new_top; + wlr_xdg_toplevel_set_size(view->surface, new_width, new_height); +} + + +static bool view_at( + struct view *view, double lx, double ly, struct wlr_surface **surface, + double *sx, double *sy +) { + double view_sx = lx - view->x; + double view_sy = ly - view->y; + + double _sx, _sy; + struct wlr_surface *_surface = NULL; + _surface = wlr_xdg_surface_surface_at( + view->surface, view_sx, view_sy, &_sx, &_sy + ); + if (_surface != NULL) { + *sx = _sx; + *sy = _sy; + *surface = _surface; + return true; + } + return false; +} + + +static struct view *desktop_view_at( + struct server *server, double lx, double ly, struct wlr_surface **surface, + double *sx, double *sy +) { + struct view *view; + wl_list_for_each(view, &server->views, link) { + if (view_at(view, lx, ly, surface, sx, sy)) { + return view; + } + } + return NULL; +} + + +static void process_cursor_motion(struct server *server, uint32_t time) { + double sx, sy; + struct wlr_seat *seat; + struct wlr_surface *surface; + struct view *view; + + switch (server->cursor_mode) { + case CURSOR_MOVE: + process_cursor_move(server, time); + case CURSOR_RESIZE: + process_cursor_resize(server, time); + case CURSOR_PASSTHROUGH: + seat = server->seat; + surface = NULL; + view = desktop_view_at(server, server->cursor->x, + server->cursor->y, &surface, &sx, &sy); + if (!view) { + wlr_xcursor_manager_set_cursor_image( + server->cursor_manager, "left_ptr", server->cursor + ); + } + if (surface) { + bool focus_changed = seat->pointer_state.focused_surface != 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); + } + } +} + void on_cursor_motion(struct wl_listener *listener, void *data){ - return; + struct server *server = wl_container_of(listener, server, cursor_motion_listener); + struct wlr_event_pointer_motion *event = data; + wlr_cursor_move(server->cursor, event->device, event->delta_x, event->delta_y); + process_cursor_motion(server, event->time_msec); } void on_cursor_motion_absolute(struct wl_listener *listener, void *data) { - return; + struct server *server = wl_container_of(listener, server, + cursor_motion_absolute_listener); + struct wlr_event_pointer_motion_absolute *event = data; + wlr_cursor_warp_absolute(server->cursor, event->device, event->x, event->y); + process_cursor_motion(server, event->time_msec); } @@ -44,7 +169,6 @@ } - void set_up_cursor(struct server *server) { server->cursor = wlr_cursor_create(); wlr_cursor_attach_output_layout(server->cursor, server->output_layout);