commit 2235bbf91db2f0c42fdeb10ef7a0785fa954a6c7
parent 14cd58224fc083fe2d0727117a3853eae2d3d09d
Author: deurzen <m.deurzen@tum.de>
Date: Wed, 29 Sep 2021 20:44:11 +0200
implements shuffle and reverse client arrangers
Diffstat:
6 files changed, 147 insertions(+), 7 deletions(-)
diff --git a/src/core/cycle.hh b/src/core/cycle.hh
@@ -120,7 +120,9 @@ public:
void swap_elements(T, T);
void swap_indices(Index, Index);
+ void reverse();
void rotate(winsys::Direction);
+ void rotate_range(winsys::Direction, Index, Index);
std::optional<T> cycle_active(winsys::Direction);
std::optional<T> drag_active(winsys::Direction);
diff --git a/src/core/cycle.t.hh b/src/core/cycle.t.hh
@@ -429,6 +429,13 @@ Cycle<T>::swap_indices(Index index1, Index index2)
template <typename T>
void
+Cycle<T>::reverse()
+{
+ std::reverse(m_elements.begin(), m_elements.end());
+}
+
+template <typename T>
+void
Cycle<T>::rotate(winsys::Direction direction)
{
switch (direction) {
@@ -457,6 +464,38 @@ Cycle<T>::rotate(winsys::Direction direction)
}
template <typename T>
+void
+Cycle<T>::rotate_range(winsys::Direction direction, Index begin, Index end)
+{
+ if (begin >= end || begin >= m_elements.size() || end > m_elements.size())
+ return;
+
+ switch (direction) {
+ case winsys::Direction::Backward:
+ {
+ std::rotate(
+ m_elements.begin() + begin,
+ std::next(m_elements.begin() + begin),
+ m_elements.begin() + end
+ );
+
+ return;
+ }
+ case winsys::Direction::Forward:
+ {
+ std::rotate(
+ m_elements.rend() - end,
+ std::next(m_elements.rend() - end),
+ m_elements.rend() - begin
+ );
+
+ return;
+ }
+ default: return;
+ }
+}
+
+template <typename T>
std::optional<T>
Cycle<T>::cycle_active(winsys::Direction direction)
{
diff --git a/src/core/model.cc b/src/core/model.cc
@@ -93,21 +93,49 @@ Model::Model(Connection& conn)
CALL(deiconify_all())
},
- // free client arrangers
+ // client arrangers
{ { Key::Space, { Main, Ctrl } },
CALL(center_focus())
},
{ { Key::H, { Main, Ctrl } },
- CALL(nudge_focus(Edge::Left, 15))
+ [](Model& model) {
+ Client_ptr focus = model.mp_focus;
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Left, 15);
+ else
+ model.shuffle_main(Direction::Backward);
+ }
},
{ { Key::J, { Main, Ctrl } },
- CALL(nudge_focus(Edge::Bottom, 15))
+ [](Model& model) {
+ Client_ptr focus = model.mp_focus;
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Bottom, 15);
+ else
+ model.shuffle_stack(Direction::Forward);
+ }
},
{ { Key::K, { Main, Ctrl } },
- CALL(nudge_focus(Edge::Top, 15))
+ [](Model& model) {
+ Client_ptr focus = model.mp_focus;
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Top, 15);
+ else
+ model.shuffle_stack(Direction::Backward);
+ }
},
{ { Key::L, { Main, Ctrl } },
- CALL(nudge_focus(Edge::Right, 15))
+ [](Model& model) {
+ Client_ptr focus = model.mp_focus;
+
+ if (focus && model.is_free(focus))
+ model.nudge_focus(Edge::Right, 15);
+ else
+ model.shuffle_main(Direction::Forward);
+ }
},
{ { Key::H, { Main, Ctrl, Shift } },
CALL(stretch_focus(Edge::Left, 15))
@@ -145,8 +173,6 @@ Model::Model(Connection& conn)
{ { Key::Right, { Main, Ctrl } },
CALL(snap_focus(Edge::Right))
},
-
- // client order modifiers
{ { Key::J, { Main } },
CALL(cycle_focus(Direction::Forward))
},
@@ -159,6 +185,9 @@ Model::Model(Connection& conn)
{ { Key::K, { Main, Shift } },
CALL(drag_focus(Direction::Backward))
},
+ { { Key::R, { Main } },
+ CALL(reverse_clients())
+ },
{ { Key::SemiColon, { Main, Shift } },
CALL(rotate_clients(Direction::Forward))
},
@@ -2330,6 +2359,20 @@ Model::drag_focus(Direction direction)
void
+Model::reverse_clients()
+{
+ if (mp_workspace->size() <= 1)
+ return;
+
+ mp_workspace->reverse();
+ focus_client(mp_workspace->active());
+ sync_focus();
+
+ apply_layout(mp_workspace);
+ apply_stack(mp_workspace);
+}
+
+void
Model::rotate_clients(Direction direction)
{
if (mp_workspace->size() <= 1)
@@ -2340,6 +2383,35 @@ Model::rotate_clients(Direction direction)
sync_focus();
apply_layout(mp_workspace);
+ apply_stack(mp_workspace);
+}
+
+void
+Model::shuffle_main(winsys::Direction direction)
+{
+ if (mp_workspace->size() <= 1)
+ return;
+
+ mp_workspace->shuffle_main(direction);
+ focus_client(mp_workspace->active());
+ sync_focus();
+
+ apply_layout(mp_workspace);
+ apply_stack(mp_workspace);
+}
+
+void
+Model::shuffle_stack(winsys::Direction direction)
+{
+ if (mp_workspace->size() <= 1)
+ return;
+
+ mp_workspace->shuffle_stack(direction);
+ focus_client(mp_workspace->active());
+ sync_focus();
+
+ apply_layout(mp_workspace);
+ apply_stack(mp_workspace);
}
diff --git a/src/core/model.hh b/src/core/model.hh
@@ -140,7 +140,10 @@ private:
void cycle_focus(winsys::Direction);
void drag_focus(winsys::Direction);
+ void reverse_clients();
void rotate_clients(winsys::Direction);
+ void shuffle_main(winsys::Direction);
+ void shuffle_stack(winsys::Direction);
void move_focus_to_next_workspace(winsys::Direction);
void move_client_to_next_workspace(winsys::Direction, Client_ptr);
diff --git a/src/core/workspace.cc b/src/core/workspace.cc
@@ -306,12 +306,33 @@ Workspace::drag(winsys::Direction direction)
}
void
+Workspace::reverse()
+{
+ m_clients.reverse();
+ mp_active = m_clients.active_element().value_or(nullptr);
+}
+
+void
Workspace::rotate(winsys::Direction direction)
{
m_clients.rotate(direction);
mp_active = m_clients.active_element().value_or(nullptr);
}
+void
+Workspace::shuffle_main(winsys::Direction direction)
+{
+ m_clients.rotate_range(direction, 0, m_layout_handler.main_count());
+ mp_active = m_clients.active_element().value_or(nullptr);
+}
+
+void
+Workspace::shuffle_stack(winsys::Direction direction)
+{
+ m_clients.rotate_range(direction, m_layout_handler.main_count(), m_clients.size());
+ mp_active = m_clients.active_element().value_or(nullptr);
+}
+
void
Workspace::activate_client(Client_ptr client)
diff --git a/src/core/workspace.hh b/src/core/workspace.hh
@@ -167,7 +167,10 @@ public:
void cycle(winsys::Direction);
void drag(winsys::Direction);
+ void reverse();
void rotate(winsys::Direction);
+ void shuffle_main(winsys::Direction);
+ void shuffle_stack(winsys::Direction);
void activate_client(Client_ptr);