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 22704901286c3517da3ca54dd37c2215e4d6e951
parent 4bc4980e3d28a1df5b35963d426e20d820138477
Author: deurzen <max@deurzen.net>
Date:   Sat, 28 May 2022 02:58:01 +0200

implements focus shifting and state changing

Diffstat:
Minclude/kranewl/model.hh | 2+-
Minclude/kranewl/tree/view.hh | 4++++
Minclude/kranewl/tree/xdg_view.hh | 1+
Minclude/kranewl/tree/xwayland_view.hh | 1+
Msrc/kranewl/model.cc | 20++++++++++++--------
Msrc/kranewl/tree/view.cc | 7+++++++
Msrc/kranewl/tree/xdg_view.cc | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/kranewl/tree/xwayland_view.cc | 7+++++++
8 files changed, 105 insertions(+), 15 deletions(-)

diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh @@ -49,7 +49,7 @@ public: #ifdef XWAYLAND XWaylandView_ptr create_xwayland_view(struct wlr_xwayland_surface*, Seat_ptr); #endif - void register_view(View_ptr); + void register_view(View_ptr, Workspace_ptr); void unregister_view(View_ptr); void destroy_view(View_ptr); diff --git a/include/kranewl/tree/view.hh b/include/kranewl/tree/view.hh @@ -75,6 +75,7 @@ typedef struct View { virtual void map() = 0; virtual void unmap() = 0; + virtual void focus(Toggle) = 0; virtual void activate(Toggle) = 0; virtual void set_tiled(Toggle) = 0; virtual void set_fullscreen(Toggle) = 0; @@ -87,6 +88,7 @@ typedef struct View { void render_decoration(); + bool activated() const { return m_activated; } bool focused() const { return m_focused; } bool mapped() const { return m_mapped; } bool managed() const { return m_managed; } @@ -100,6 +102,7 @@ typedef struct View { bool iconifyable() const { return m_iconifyable; } bool iconified() const { return m_iconified; } bool disowned() const { return m_disowned; } + void set_activated(bool); void set_focused(bool); void set_mapped(bool); void set_managed(bool); @@ -192,6 +195,7 @@ private: Region m_previous_region; Region m_inner_region; + bool m_activated; bool m_focused; bool m_mapped; bool m_managed; diff --git a/include/kranewl/tree/xdg_view.hh b/include/kranewl/tree/xdg_view.hh @@ -29,6 +29,7 @@ typedef struct XDGView final : public View { void map() override; void unmap() override; + void focus(Toggle) override; void activate(Toggle) override; void set_tiled(Toggle) override; void set_fullscreen(Toggle) override; diff --git a/include/kranewl/tree/xwayland_view.hh b/include/kranewl/tree/xwayland_view.hh @@ -28,6 +28,7 @@ typedef struct XWaylandView final : public View { void map() override; void unmap() override; + void focus(Toggle) override; void activate(Toggle) override; void set_tiled(Toggle) override; void set_fullscreen(Toggle) override; diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc @@ -322,9 +322,16 @@ Model::sync_focus() View_ptr active = mp_workspace->active(); - if (active && active != mp_focus) - active->activate(Toggle::On); - else if (mp_workspace->empty()) { + if (active == mp_focus) + return; + + if (mp_focus) + mp_focus->focus(Toggle::Off); + + if (active) { + active->focus(Toggle::On); + mp_focus = active; + } else if (mp_workspace->empty()) { mp_server->relinquish_focus(); mp_focus = nullptr; } @@ -1584,13 +1591,10 @@ Model::create_xwayland_view( #endif void -Model::register_view(View_ptr view) +Model::register_view(View_ptr view, Workspace_ptr workspace) { TRACE(); - if (view->mp_workspace) - view->mp_workspace->add_view(view); - std::stringstream uid_ss; uid_ss << std::hex << view->m_uid; spdlog::info( @@ -1600,7 +1604,7 @@ Model::register_view(View_ptr view) view->m_pid ); - sync_focus(); + move_view_to_workspace(view, workspace); } 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_previous_region({}), m_inner_region({}), + m_activated(false), m_focused(false), m_mapped(false), m_managed(true), @@ -127,6 +128,12 @@ View::~View() {} void +View::set_activated(bool activated) +{ + m_activated = activated; +} + +void View::set_focused(bool focused) { auto now = std::chrono::steady_clock::now(); diff --git a/src/kranewl/tree/xdg_view.cc b/src/kranewl/tree/xdg_view.cc @@ -112,6 +112,45 @@ XDGView::unmap() } void +XDGView::focus(Toggle toggle) +{ + TRACE(); + + switch (toggle) { + case Toggle::On: + { + if (focused()) + return; + + set_focused(true); + activate(toggle); + render_decoration(); + break; + } + case Toggle::Off: + { + if (!focused()) + return; + + set_focused(false); + activate(toggle); + render_decoration(); + break; + } + case Toggle::Reverse: + { + focus( + focused() + ? Toggle::Off + : Toggle::On + ); + return; + } + default: break; + } +} + +void XDGView::activate(Toggle toggle) { TRACE(); @@ -119,20 +158,45 @@ XDGView::activate(Toggle toggle) switch (toggle) { case Toggle::On: { + if (activated()) + return; + + set_activated(true); + + struct wlr_keyboard* keyboard = wlr_seat_get_keyboard(mp_seat->mp_wlr_seat); + if (keyboard) + wlr_seat_keyboard_notify_enter( + mp_seat->mp_wlr_seat, + mp_wlr_surface, + keyboard->keycodes, + keyboard->num_keycodes, + &keyboard->modifiers + ); + else + wlr_seat_keyboard_notify_enter( + mp_seat->mp_wlr_seat, + mp_wlr_surface, + nullptr, + 0, + nullptr + ); + wlr_xdg_toplevel_set_activated(mp_wlr_xdg_surface, true); - set_focused(true); break; } case Toggle::Off: { + if (!activated()) + return; + + set_activated(false); wlr_xdg_toplevel_set_activated(mp_wlr_xdg_surface, false); - set_focused(false); break; } case Toggle::Reverse: { activate( - focused() + activated() ? Toggle::Off : Toggle::On ); @@ -372,11 +436,9 @@ XDGView::handle_map(struct wl_listener* listener, void* data) } else workspace = model->mp_workspace; - model->move_view_to_workspace(view, workspace); - view->set_mapped(true); view->render_decoration(); - model->register_view(view); + model->register_view(view, workspace); } void @@ -394,11 +456,15 @@ XDGView::handle_unmap(struct wl_listener* listener, void* data) wl_list_remove(&view->ml_set_title.link); wl_list_remove(&view->ml_set_app_id.link); + view->activate(Toggle::Off); view->mp_model->unregister_view(view); wlr_scene_node_destroy(view->mp_scene); view->mp_wlr_surface = nullptr; view->set_managed(false); + + if (view->mp_model->mp_workspace) + view->mp_model->apply_layout(view->mp_workspace); } void diff --git a/src/kranewl/tree/xwayland_view.cc b/src/kranewl/tree/xwayland_view.cc @@ -100,6 +100,13 @@ XWaylandView::unmap() } void +XWaylandView::focus(Toggle) +{ + TRACE(); + +} + +void XWaylandView::activate(Toggle) { TRACE();