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 3e5ddde6aeac0a8014efc2b33586d436ec1316f6
parent 525244b9d582743727fc1fa841de2b882d242942
Author: deurzen <max@deurzen.net>
Date:   Sun, 29 May 2022 20:24:21 +0200

implements cursor-interactive move

Diffstat:
Minclude/kranewl/input/cursor-bindings.hh | 8++++----
Minclude/kranewl/input/cursor.hh | 7+++++--
Minclude/kranewl/model.hh | 2++
Msrc/kranewl/input/cursor.cc | 62++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/kranewl/model.cc | 22+++++++++++++++++++++-
Msrc/kranewl/tree/output.cc | 2+-
6 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/include/kranewl/input/cursor-bindings.hh b/include/kranewl/input/cursor-bindings.hh @@ -76,14 +76,14 @@ static const CursorBindings cursor_bindings = { }, { { VIEW, LEFT, MODKEY }, CALL_FOCUS({ - /* if (view) */ - /* model.start_moving(view); */ + if (view) + model.cursor_interactive(Cursor::Mode::Move, view); }) }, { { VIEW, RIGHT, MODKEY }, CALL_FOCUS({ - /* if (view) */ - /* model.start_resizing(view); */ + if (view) + model.cursor_interactive(Cursor::Mode::Resize, view); }) }, { { GLOBAL, SCROLLDOWN, MODKEY }, diff --git a/include/kranewl/input/cursor.hh b/include/kranewl/input/cursor.hh @@ -41,7 +41,7 @@ typedef class Seat* Seat_ptr; typedef struct View* View_ptr; typedef struct Cursor { - enum class CursorMode { + enum class Mode { Passthrough, Move, Resize, @@ -59,6 +59,9 @@ typedef struct Cursor { View_ptr view_under_cursor() const; + void initiate_cursor_interactive(Mode, View_ptr); + void abort_cursor_interactive(); + static void handle_cursor_motion(struct wl_listener*, void*); static void handle_cursor_motion_absolute(struct wl_listener*, void*); static void handle_cursor_button(struct wl_listener*, void*); @@ -71,13 +74,13 @@ typedef struct Cursor { Server_ptr mp_server; Seat_ptr mp_seat; - CursorMode m_cursor_mode; struct wlr_cursor* mp_wlr_cursor; struct wlr_xcursor_manager* mp_cursor_manager; struct wlr_pointer_constraints_v1* mp_pointer_constraints; struct wlr_relative_pointer_manager_v1* mp_relative_pointer_manager; struct wlr_virtual_pointer_manager_v1* mp_virtual_pointer_manager; + Mode m_cursor_mode; struct { View_ptr view; double x, y; diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh @@ -56,6 +56,8 @@ public: void focus_view(View_ptr); void place_view(Placement&); + void cursor_interactive(Cursor::Mode, View_ptr); + void abort_cursor_interactive(); void sync_focus(); void cycle_focus(Direction); diff --git a/src/kranewl/input/cursor.cc b/src/kranewl/input/cursor.cc @@ -120,6 +120,40 @@ Cursor::view_under_cursor() const return view; } +void +Cursor::initiate_cursor_interactive(Mode mode, View_ptr view) +{ + TRACE(); + + double sx, sy; + struct wlr_surface* surface = nullptr; + + view_at( + mp_server, + mp_wlr_cursor->x, + mp_wlr_cursor->y, + &surface, + &sx, &sy + ); + + m_cursor_mode = mode; + Extents const& extents = view->active_decoration().extents(); + + m_grab_state = { + .view = view, + .x = sx + extents.left, + .y = sy + extents.top, + .resize_edges = WLR_EDGE_NONE + }; +} + +void +Cursor::abort_cursor_interactive() +{ + m_cursor_mode = Mode::Passthrough; + m_grab_state.view = nullptr; +} + static inline void process_cursor_move(Cursor_ptr cursor, uint32_t time) { @@ -154,7 +188,9 @@ cursor_motion_to_client( uint32_t time ) { - if (true /* TODO: focus_follows_cursor */ && time && view && view->managed()) + static View_ptr previous_view = nullptr; + + if (true /* TODO: focus_follows_cursor */ && time && view && view != previous_view && view->managed()) cursor->mp_seat->mp_model->focus_view(view); if (!surface) { @@ -170,13 +206,13 @@ cursor_motion_to_client( wlr_seat_pointer_notify_enter(cursor->mp_seat->mp_wlr_seat, surface, sx, sy); wlr_seat_pointer_notify_motion(cursor->mp_seat->mp_wlr_seat, time, sx, sy); + + previous_view = view; } static inline void process_cursor_motion(Cursor_ptr cursor, uint32_t time) { - TRACE(); - struct wlr_drag_icon* icon; if (cursor->mp_seat->mp_wlr_seat->drag && (icon = cursor->mp_seat->mp_wlr_seat->drag->icon)) wlr_scene_node_set_position( @@ -186,9 +222,9 @@ process_cursor_motion(Cursor_ptr cursor, uint32_t time) ); switch (cursor->m_cursor_mode) { - case Cursor::CursorMode::Move: process_cursor_move(cursor, time); return; - case Cursor::CursorMode::Resize: process_cursor_resize(cursor, time); return; - case Cursor::CursorMode::Passthrough: // fallthrough + case Cursor::Mode::Move: process_cursor_move(cursor, time); return; + case Cursor::Mode::Resize: process_cursor_resize(cursor, time); return; + case Cursor::Mode::Passthrough: // fallthrough default: break; } @@ -217,8 +253,6 @@ process_cursor_motion(Cursor_ptr cursor, uint32_t time) void Cursor::handle_cursor_motion(struct wl_listener* listener, void* data) { - TRACE(); - Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_motion); struct wlr_event_pointer_motion* event = reinterpret_cast<struct wlr_event_pointer_motion*>(data); @@ -230,8 +264,6 @@ Cursor::handle_cursor_motion(struct wl_listener* listener, void* data) void Cursor::handle_cursor_motion_absolute(struct wl_listener* listener, void* data) { - TRACE(); - Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_motion_absolute); struct wlr_event_pointer_motion_absolute* event = reinterpret_cast<struct wlr_event_pointer_motion_absolute*>(data); @@ -333,8 +365,8 @@ Cursor::handle_cursor_button(struct wl_listener* listener, void* data) } case WLR_BUTTON_RELEASED: { - if (cursor->m_cursor_mode != CursorMode::Passthrough) { - cursor->m_cursor_mode = CursorMode::Passthrough; + if (cursor->m_cursor_mode != Mode::Passthrough) { + cursor->m_cursor_mode = Mode::Passthrough; wlr_xcursor_manager_set_cursor_image( cursor->mp_cursor_manager, @@ -368,7 +400,7 @@ Cursor::handle_cursor_axis(struct wl_listener* listener, void* data) struct wlr_keyboard* keyboard = wlr_seat_get_keyboard(cursor->mp_seat->mp_wlr_seat); - uint32_t button; + uint32_t button = 0; uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; @@ -387,7 +419,7 @@ Cursor::handle_cursor_axis(struct wl_listener* listener, void* data) ? CursorInput::Button::ScrollLeft : CursorInput::Button::ScrollRight; break; - default: button = 0; break; + default: break; } if (!process_cursorbinding(cursor, button, modifiers)) @@ -404,8 +436,6 @@ Cursor::handle_cursor_axis(struct wl_listener* listener, void* data) void Cursor::handle_cursor_frame(struct wl_listener* listener, void*) { - TRACE(); - Cursor_ptr cursor = wl_container_of(listener, cursor, ml_cursor_frame); wlr_seat_pointer_notify_frame(cursor->mp_seat->mp_wlr_seat); } diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc @@ -270,7 +270,11 @@ Model::place_view(Placement& placement) } } - spdlog::info("Placing view {} at {}", view->m_uid, std::to_string(view->active_region())); + spdlog::info( + "Placing view {} at {}", + view->m_uid_formatted, + std::to_string(view->active_region()) + ); view->map(); view->configure( @@ -281,6 +285,22 @@ Model::place_view(Placement& placement) } void +Model::cursor_interactive(Cursor::Mode mode, View_ptr view) +{ + TRACE(); + + if (is_free(view)) + mp_server->m_seat.mp_cursor->initiate_cursor_interactive(mode, view); +} + +void +Model::abort_cursor_interactive() +{ + TRACE(); + mp_server->m_seat.mp_cursor->abort_cursor_interactive(); +} + +void Model::sync_focus() { TRACE(); diff --git a/src/kranewl/tree/output.cc b/src/kranewl/tree/output.cc @@ -90,7 +90,7 @@ Output::handle_present(struct wl_listener* listener, void*) View_ptr view_under_cursor = output->mp_server->m_seat.mp_cursor->view_under_cursor(); - if (view_under_cursor) + if (view_under_cursor && view_under_cursor->managed()) output->mp_model->focus_view(view_under_cursor); }