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:
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();