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 53d4f062ca6ab0ac8745b2b668f76bcbb3216999
parent dafd093995a91f7ce205688fd36d45a4a26ccffd
Author: deurzen <max@deurzen.net>
Date:   Thu,  2 Jun 2022 10:56:37 +0200

adds FFC workspace switching cursor warp

Diffstat:
Minclude/kranewl/input/cursor.hh | 6+++++-
Minclude/kranewl/tree/view.hh | 3+++
Msrc/kranewl/input/cursor.cc | 24++++++++++++++++++++++++
Msrc/kranewl/model.cc | 22+++++++++++++++++++++-
Msrc/kranewl/tree/view.cc | 1+
5 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/include/kranewl/input/cursor.hh b/include/kranewl/input/cursor.hh @@ -59,8 +59,12 @@ typedef struct Cursor { ~Cursor(); - View_ptr view_under_cursor() const; + Pos cursor_pos() const; + void set_cursor_pos(Pos const&); + Node_ptr node_under_cursor() const; + View_ptr view_under_cursor() const; + Pos cursor_relative_to(View_ptr) const; void initiate_cursor_interactive(Mode, View_ptr, uint32_t); void initiate_cursor_interactive(Mode, View_ptr); diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh @@ -133,6 +133,8 @@ typedef struct View : public Node { Dim const& preferred_dim() const { return m_preferred_dim; } void set_minimum_dim(Dim const& minimum_dim) { m_minimum_dim = minimum_dim; } void set_preferred_dim(Dim const& preferred_dim) { m_preferred_dim = preferred_dim; } + std::optional<Pos> const& last_cursor_pos() const { return m_last_cursor_pos; } + void set_last_cursor_pos(std::optional<Pos> const& last_cursor_pos) { m_last_cursor_pos = last_cursor_pos; } Decoration const& free_decoration() const { return m_free_decoration; } Decoration const& tile_decoration() const { return m_tile_decoration; } @@ -192,6 +194,7 @@ private: Region m_active_region; Region m_prev_region; Region m_inner_region; + std::optional<Pos> m_last_cursor_pos; bool m_activated; bool m_focused; diff --git a/src/kranewl/input/cursor.cc b/src/kranewl/input/cursor.cc @@ -123,6 +123,21 @@ view_at( return nullptr; } +Pos +Cursor::cursor_pos() const +{ + return Pos{ + .x = mp_wlr_cursor->x, + .y = mp_wlr_cursor->y + }; +} + +void +Cursor::set_cursor_pos(Pos const& pos) +{ + wlr_cursor_warp(mp_wlr_cursor, nullptr, pos.x, pos.y); +} + Node_ptr Cursor::node_under_cursor() const { @@ -157,6 +172,15 @@ Cursor::view_under_cursor() const return view; } +Pos +Cursor::cursor_relative_to(View_ptr view) const +{ + return Pos{ + .x = mp_wlr_cursor->x - view->active_region().pos.x, + .y = mp_wlr_cursor->y - view->active_region().pos.y, + }; +} + void Cursor::initiate_cursor_interactive( Mode mode, diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc @@ -856,6 +856,16 @@ Model::activate_workspace(Workspace_ptr next_workspace) Context_ptr next_context = next_workspace->context(); Context_ptr prev_context = prev_workspace->context(); + if (prev_workspace->focus_follows_cursor()) { + View_ptr view_under_cursor + = mp_server->m_seat.mp_cursor->view_under_cursor(); + + if (view_under_cursor) + view_under_cursor->set_last_cursor_pos( + mp_server->m_seat.mp_cursor->cursor_pos() + ); + } + if (next_context == prev_context) { for (View_ptr view : *prev_workspace) if (!view->sticky()) @@ -870,8 +880,18 @@ Model::activate_workspace(Workspace_ptr next_workspace) mp_workspace = next_workspace; apply_layout(next_workspace); - mp_output->focus_at_cursor(); sync_focus(); + + if (mp_workspace->focus_follows_cursor()) { + std::optional<Pos> const& last_cursor_pos + = mp_focus ? mp_focus->last_cursor_pos() : std::nullopt; + + if (last_cursor_pos) { + mp_server->m_seat.mp_cursor->set_cursor_pos(*last_cursor_pos); + mp_focus->set_last_cursor_pos(std::nullopt); + } else + mp_output->focus_at_cursor(); + } } void diff --git a/src/kranewl/tree/view.cc b/src/kranewl/tree/view.cc @@ -51,6 +51,7 @@ View::View( m_active_region({}), m_prev_region({}), m_inner_region({}), + m_last_cursor_pos({}), m_activated(false), m_focused(false), m_mapped(false),