kranewl

A wlroots-based dynamic Wayland compositor, written in C++, configurable with Lua
git clone git://git.deurzen.net/kranewl
Log | Files | Refs | LICENSE

commit c91f6b5a1f70ac0af6d961aa47ab23d0c6a6439b
parent 4dce3ea6ad7396af946be8fe6baf9967c5372953
Author: deurzen <max@deurzen.net>
Date:   Wed,  1 Jun 2022 05:44:34 +0200

adds client-initiated drag capabilities

Diffstat:
Minclude/kranewl/input/cursor.hh | 8+++++---
Msrc/kranewl/input/cursor.cc | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 67 insertions(+), 16 deletions(-)

diff --git a/include/kranewl/input/cursor.hh b/include/kranewl/input/cursor.hh @@ -33,8 +33,8 @@ struct CursorInput { }; Target target; - Button button; - uint32_t modifiers; + Button button; + uint32_t modifiers; }; typedef class Server* Server_ptr; @@ -78,11 +78,12 @@ typedef struct Cursor { static void handle_cursor_frame(struct wl_listener*, void*); static void handle_request_start_drag(struct wl_listener*, void*); static void handle_start_drag(struct wl_listener*, void*); + static void handle_destroy_drag(struct wl_listener*, void*); static void handle_request_set_cursor(struct wl_listener*, void*); Server_ptr mp_server; Model_ptr mp_model; - Seat_ptr mp_seat; + Seat_ptr mp_seat; struct wlr_cursor* mp_wlr_cursor; struct wlr_xcursor_manager* mp_cursor_manager; @@ -105,6 +106,7 @@ typedef struct Cursor { struct wl_listener ml_cursor_frame; struct wl_listener ml_request_start_drag; struct wl_listener ml_start_drag; + struct wl_listener ml_destroy_drag; struct wl_listener ml_request_set_cursor; }* Cursor_ptr; diff --git a/src/kranewl/input/cursor.cc b/src/kranewl/input/cursor.cc @@ -53,6 +53,7 @@ Cursor::Cursor( ml_cursor_frame({ .notify = Cursor::handle_cursor_frame }), ml_request_start_drag({ .notify = Cursor::handle_request_start_drag }), ml_start_drag({ .notify = Cursor::handle_start_drag }), + ml_destroy_drag({ .notify = Cursor::handle_destroy_drag }), ml_request_set_cursor({ .notify = Cursor::handle_request_set_cursor }) { TRACE(); @@ -621,32 +622,80 @@ Cursor::handle_request_start_drag(struct wl_listener* listener, void* data) { TRACE(); - Cursor_ptr cursor = wl_container_of(listener, cursor, ml_request_set_cursor); - struct wlr_seat_pointer_request_set_cursor_event* event - = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data); + Cursor_ptr cursor = wl_container_of(listener, cursor, ml_request_start_drag); + struct wlr_seat_request_start_drag_event* event + = reinterpret_cast<struct wlr_seat_request_start_drag_event*>(data); - struct wlr_seat_client* focused_client - = cursor->mp_seat->mp_wlr_seat->pointer_state.focused_client; + if (wlr_seat_validate_pointer_grab_serial( + cursor->mp_seat->mp_wlr_seat, event->origin, event->serial)) + { + wlr_seat_start_pointer_drag( + cursor->mp_seat->mp_wlr_seat, + event->drag, + event->serial + ); + } else + wlr_data_source_destroy(event->drag->source); +} - if (focused_client == event->seat_client) - wlr_cursor_set_surface( - cursor->mp_wlr_cursor, - event->surface, - event->hotspot_x, - event->hotspot_y +void +Cursor::handle_start_drag(struct wl_listener* listener, void* data) +{ + TRACE(); + + Cursor_ptr cursor = wl_container_of(listener, cursor, ml_start_drag); + struct wlr_drag* drag = reinterpret_cast<struct wlr_drag*>(data); + + if (drag->icon) + drag->icon->data = wlr_scene_subsurface_tree_create( + cursor->mp_server->m_scene_layers[SceneLayer::SCENE_LAYER_NOFOCUS], + drag->icon->surface ); + + cursor->mp_seat->mp_cursor->process_cursor_motion(0); + + View_ptr view = cursor->view_under_cursor(); + if (view && cursor->m_cursor_mode == Mode::Passthrough) + view->mp_model->cursor_interactive(Cursor::Mode::Move, view); + + wl_signal_add(&drag->events.destroy, &cursor->ml_destroy_drag); } void -Cursor::handle_start_drag(struct wl_listener*, void*) +Cursor::handle_destroy_drag(struct wl_listener* listener, void* data) { TRACE(); + Cursor_ptr cursor = wl_container_of(listener, cursor, ml_destroy_drag); + struct wlr_drag* drag = reinterpret_cast<struct wlr_drag*>(data); + + if (drag->icon) + wlr_scene_node_destroy(reinterpret_cast<wlr_scene_node*>(drag->icon->data)); + + cursor->mp_model->refocus(); + cursor->mp_seat->mp_cursor->process_cursor_motion(0); } void -Cursor::handle_request_set_cursor(struct wl_listener*, void*) +Cursor::handle_request_set_cursor(struct wl_listener* listener, void* data) { TRACE(); + Cursor_ptr cursor = wl_container_of(listener, cursor, ml_request_set_cursor); + struct wlr_seat_pointer_request_set_cursor_event* event + = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data); + + if (cursor->m_cursor_mode != Mode::Passthrough) + return; + + struct wlr_seat_client* focused_client + = cursor->mp_seat->mp_wlr_seat->pointer_state.focused_client; + + if (event->seat_client == focused_client) + wlr_cursor_set_surface( + cursor->mp_wlr_cursor, + event->surface, + event->hotspot_x, + event->hotspot_y + ); }