diff --git a/include/rootston/view.h b/include/rootston/view.h index 9e7c4a01..b74d1075 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -28,6 +28,7 @@ enum roots_view_type { }; struct roots_view { + struct roots_desktop *desktop; double x, y; float rotation; // TODO: Something for roots-enforced width/height diff --git a/rootston/cursor.c b/rootston/cursor.c index 9c2ff8c3..0e9bf748 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,5 +1,7 @@ #include #include +// TODO: BSD et al +#include #include #include #include @@ -18,7 +20,6 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { view_get_input_bounds(view, &box); double sx = input->cursor->x - view->x; double sy = input->cursor->y - view->y; - wlr_log(L_DEBUG, "Moving cursor in view at %f, %f", sx, sy); wlr_seat_pointer_enter(input->wl_seat, view->wlr_surface, sx, sy); wlr_seat_pointer_send_motion(input->wl_seat, time, sx, sy); } else { @@ -26,21 +27,16 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { } break; case ROOTS_CURSOR_MOVE: + if (input->active_view) { + input->active_view->x = input->cursor->x - input->offs_x; + input->active_view->y = input->cursor->y - input->offs_y; + } break; case ROOTS_CURSOR_RESIZE: break; case ROOTS_CURSOR_ROTATE: break; } - /* - if (input->motion_context.surface) { - struct example_xdg_surface_v6 *surface; - surface = sample->motion_context.surface; - surface->position.lx = sample->cursor->x - sample->motion_context.off_x; - surface->position.ly = sample->cursor->y - sample->motion_context.off_y; - return; - } - */ } static void set_view_focus(struct roots_input *input, @@ -82,27 +78,25 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { event->orientation, event->delta); } -static void handle_cursor_button(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_button); - struct wlr_event_pointer_button *event = data; - +static void do_cursor_button_press(struct roots_input *input, + struct wlr_cursor *cursor, struct wlr_input_device *device, + uint32_t time, uint32_t button, uint32_t state) { struct roots_desktop *desktop = input->server->desktop; - struct roots_view *view = view_at( - desktop, input->cursor->x, input->cursor->y); - - uint32_t serial = wlr_seat_pointer_send_button(input->wl_seat, - (uint32_t)event->time_usec, event->button, event->state); - + struct roots_view *view = view_at(desktop, + input->cursor->x, input->cursor->y); + uint32_t serial = wlr_seat_pointer_send_button( + input->wl_seat, time, button, state); int i; - switch (event->state) { + switch (state) { case WLR_BUTTON_RELEASED: input->active_view = NULL; + input->mode = ROOTS_CURSOR_PASSTHROUGH; break; case WLR_BUTTON_PRESSED: i = input->input_events_idx; input->input_events[i].serial = serial; - input->input_events[i].cursor = input->cursor; - input->input_events[i].device = event->device; + input->input_events[i].cursor = cursor; + input->input_events[i].device = device; input->input_events_idx = (i + 1) % (sizeof(input->input_events) / sizeof(input->input_events[0])); set_view_focus(input, desktop, view); @@ -110,6 +104,13 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { } } +static void handle_cursor_button(struct wl_listener *listener, void *data) { + struct roots_input *input = wl_container_of(listener, input, cursor_button); + struct wlr_event_pointer_button *event = data; + do_cursor_button_press(input, input->cursor, event->device, + (uint32_t)event->time_usec, event->button, event->state); +} + static void handle_tool_axis(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, cursor_tool_axis); struct wlr_event_tablet_tool_axis *event = data; @@ -122,15 +123,10 @@ static void handle_tool_axis(struct wl_listener *listener, void *data) { } static void handle_tool_tip(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, tool_tip); + struct roots_input *input = wl_container_of(listener, input, cursor_tool_tip); struct wlr_event_tablet_tool_tip *event = data; - - struct roots_desktop *desktop = input->server->desktop; - struct roots_view *view = view_at( - desktop, input->cursor->x, input->cursor->y); - set_view_focus(input, desktop, view); - wlr_seat_pointer_send_button(input->wl_seat, (uint32_t)event->time_usec, - BTN_LEFT, event->state); + do_cursor_button_press(input, input->cursor, event->device, + (uint32_t)event->time_usec, BTN_LEFT, event->state); } void cursor_initialize(struct roots_input *input) { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 0c32bd97..4a809930 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -8,6 +8,7 @@ #include #include "rootston/desktop.h" #include "rootston/server.h" +#include "rootston/input.h" static void get_input_bounds(struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); @@ -23,6 +24,32 @@ static void activate(struct roots_view *view, bool active) { } } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, request_move); + struct roots_view *view = roots_xdg_surface->view; + struct roots_input *input = view->desktop->server->input; + struct wlr_xdg_toplevel_v6_move_event *e = data; + + // TODO: Some of this might want to live in cursor.c I guess + struct roots_input_event *event = NULL; + size_t len = sizeof(input->input_events) / sizeof(*input->input_events); + for (size_t i = 0; i < len; ++i) { + if (input->input_events[i].cursor + && input->input_events[i].serial == e->serial) { + event = &input->input_events[i]; + break; + } + } + if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + return; + } + input->mode = ROOTS_CURSOR_MOVE; + input->offs_x = input->cursor->x - view->x; + input->offs_y = input->cursor->y - view->y; + wlr_seat_pointer_clear_focus(input->wl_seat); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = wl_container_of(listener, roots_xdg_surface, destroy); @@ -54,6 +81,8 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { wl_list_init(&roots_surface->ping_timeout.link); wl_list_init(&roots_surface->request_minimize.link); wl_list_init(&roots_surface->request_move.link); + roots_surface->request_move.notify = handle_request_move; + wl_signal_add(&surface->events.request_move, &roots_surface->request_move); wl_list_init(&roots_surface->request_resize.link); wl_list_init(&roots_surface->request_show_window_menu.link); @@ -65,6 +94,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->wlr_surface = surface->surface; view->get_input_bounds = get_input_bounds; view->activate = activate; + view->desktop = desktop; roots_surface->view = view; wl_list_insert(&desktop->views, &view->link); }