commit 40cde757c5c9d758f6fb8b98da0bafe0153ed918
parent 7e4f4bda6b4bb314ef85ed9f7fa56f448f19a54d
Author: deurzen <m.deurzen@tum.de>
Date: Thu, 30 Sep 2021 04:58:31 +0200
layout overhaul; adds deck layouts
Diffstat:
7 files changed, 576 insertions(+), 280 deletions(-)
diff --git a/src/core/client.cc b/src/core/client.cc
@@ -53,6 +53,7 @@ Client::Client(
attaching(false),
pid(pid),
ppid(ppid),
+ last_touched(std::chrono::steady_clock::now()),
last_focused(std::chrono::steady_clock::now()),
managed_since(std::chrono::steady_clock::now()),
expected_unmap_count(0),
@@ -72,10 +73,19 @@ Client::get_outside_state() const
}
void
+Client::touch()
+{
+ last_touched = std::chrono::steady_clock::now();
+}
+
+void
Client::focus()
{
focused = true;
- last_focused = std::chrono::steady_clock::now();
+
+ auto now = std::chrono::steady_clock::now();
+ last_touched = now;
+ last_focused = now;
switch (m_outside_state) {
case OutsideState::Unfocused: m_outside_state = OutsideState::Focused; return;
diff --git a/src/core/client.hh b/src/core/client.hh
@@ -61,6 +61,7 @@ typedef struct Client final
OutsideState get_outside_state() const;
+ void touch();
void focus();
void unfocus();
@@ -121,6 +122,7 @@ typedef struct Client final
bool attaching;
std::optional<winsys::Pid> pid;
std::optional<winsys::Pid> ppid;
+ std::chrono::time_point<std::chrono::steady_clock> last_touched;
std::chrono::time_point<std::chrono::steady_clock> last_focused;
std::chrono::time_point<std::chrono::steady_clock> managed_since;
std::size_t expected_unmap_count;
diff --git a/src/core/layout.cc b/src/core/layout.cc
@@ -33,22 +33,25 @@ LayoutHandler::LayoutHandler()
: m_kind(LayoutKind::Float),
m_prev_kind(LayoutKind::Float),
m_layouts({
- { LayoutKind::Float, new Layout(LayoutKind::Float) },
- { LayoutKind::BLFloat, new Layout(LayoutKind::BLFloat) },
- { LayoutKind::SingleFloat, new Layout(LayoutKind::SingleFloat) },
- { LayoutKind::BLSingleFloat, new Layout(LayoutKind::BLSingleFloat) },
- { LayoutKind::Center, new Layout(LayoutKind::Center) },
- { LayoutKind::Monocle, new Layout(LayoutKind::Monocle) },
- { LayoutKind::Paper, new Layout(LayoutKind::Paper) },
- { LayoutKind::SPaper, new Layout(LayoutKind::SPaper) },
- { LayoutKind::Stack, new Layout(LayoutKind::Stack) },
- { LayoutKind::SStack, new Layout(LayoutKind::SStack) },
- { LayoutKind::BStack, new Layout(LayoutKind::BStack) },
- { LayoutKind::SBStack, new Layout(LayoutKind::SBStack) },
- { LayoutKind::Horz, new Layout(LayoutKind::Horz) },
- { LayoutKind::SHorz, new Layout(LayoutKind::SHorz) },
- { LayoutKind::Vert, new Layout(LayoutKind::Vert) },
- { LayoutKind::SVert, new Layout(LayoutKind::SVert) }
+#define NEW_LAYOUT(layout) { layout, new Layout(layout) }
+ NEW_LAYOUT(LayoutKind::Float),
+ NEW_LAYOUT(LayoutKind::FramelessFloat),
+ NEW_LAYOUT(LayoutKind::SingleFloat),
+ NEW_LAYOUT(LayoutKind::FramelessSingleFloat),
+ NEW_LAYOUT(LayoutKind::Center),
+ NEW_LAYOUT(LayoutKind::Monocle),
+ NEW_LAYOUT(LayoutKind::MainDeck),
+ NEW_LAYOUT(LayoutKind::StackDeck),
+ NEW_LAYOUT(LayoutKind::DoubleDeck),
+ NEW_LAYOUT(LayoutKind::Paper),
+ NEW_LAYOUT(LayoutKind::CompactPaper),
+ NEW_LAYOUT(LayoutKind::DoubleStack),
+ NEW_LAYOUT(LayoutKind::CompactDoubleStack),
+ NEW_LAYOUT(LayoutKind::HorizontalStack),
+ NEW_LAYOUT(LayoutKind::CompactHorizontalStack),
+ NEW_LAYOUT(LayoutKind::VerticalStack),
+ NEW_LAYOUT(LayoutKind::CompactVerticalStack),
+#undef NEW_LAYOUT
}),
mp_layout(m_layouts.at(m_kind)),
mp_prev_layout(m_layouts.at(m_kind))
@@ -80,22 +83,91 @@ LayoutHandler::arrange(
}
switch (m_kind) {
- case LayoutKind::Float: arrange_float(screen_region, placements, begin, end); break;
- case LayoutKind::BLFloat: arrange_blfloat(screen_region, placements, begin, end); break;
- case LayoutKind::SingleFloat: arrange_singlefloat(screen_region, placements, begin, end); break;
- case LayoutKind::BLSingleFloat: arrange_blsinglefloat(screen_region, placements, begin, end); break;
- case LayoutKind::Center: arrange_center(screen_region, placements, begin, end); break;
- case LayoutKind::Monocle: arrange_monocle(screen_region, placements, begin, end); break;
- case LayoutKind::Paper: arrange_paper(screen_region, placements, begin, end); break;
- case LayoutKind::SPaper: arrange_spaper(screen_region, placements, begin, end); break;
- case LayoutKind::Stack: arrange_stack(screen_region, placements, begin, end); break;
- case LayoutKind::SStack: arrange_sstack(screen_region, placements, begin, end); break;
- case LayoutKind::BStack: arrange_bstack(screen_region, placements, begin, end); break;
- case LayoutKind::SBStack: arrange_sbstack(screen_region, placements, begin, end); break;
- case LayoutKind::Horz: arrange_horz(screen_region, placements, begin, end); break;
- case LayoutKind::SHorz: arrange_shorz(screen_region, placements, begin, end); break;
- case LayoutKind::Vert: arrange_vert(screen_region, placements, begin, end); break;
- case LayoutKind::SVert: arrange_svert(screen_region, placements, begin, end); break;
+ case LayoutKind::Float:
+ {
+ arrange_float(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::FramelessFloat:
+ {
+ arrange_frameless_float(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::SingleFloat:
+ {
+ arrange_single_float(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::FramelessSingleFloat:
+ {
+ arrange_frameless_single_float(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::Center:
+ {
+ arrange_center(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::Monocle:
+ {
+ arrange_monocle(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::MainDeck:
+ {
+ arrange_main_deck(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::StackDeck:
+ {
+ arrange_stack_deck(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::DoubleDeck:
+ {
+ arrange_double_deck(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::Paper:
+ {
+ arrange_paper(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::CompactPaper:
+ {
+ arrange_compact_paper(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::DoubleStack:
+ {
+ arrange_double_stack(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::CompactDoubleStack:
+ {
+ arrange_compact_double_stack(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::HorizontalStack:
+ {
+ arrange_horizontal_stack(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::CompactHorizontalStack:
+ {
+ arrange_compact_horizontal_stack(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::VerticalStack:
+ {
+ arrange_vertical_stack(screen_region, placements, begin, end);
+ break;
+ }
+ case LayoutKind::CompactVerticalStack:
+ {
+ arrange_compact_vertical_stack(screen_region, placements, begin, end);
+ break;
+ }
}
if (mp_layout->config.gap) {
@@ -445,7 +517,7 @@ LayoutHandler::arrange_float(
}
void
-LayoutHandler::arrange_blfloat(
+LayoutHandler::arrange_frameless_float(
Region screen_region,
placement_vector placements,
client_iter begin,
@@ -456,7 +528,7 @@ LayoutHandler::arrange_blfloat(
}
void
-LayoutHandler::arrange_singlefloat(
+LayoutHandler::arrange_single_float(
Region,
placement_vector placements,
client_iter begin,
@@ -479,14 +551,14 @@ LayoutHandler::arrange_singlefloat(
}
void
-LayoutHandler::arrange_blsinglefloat(
+LayoutHandler::arrange_frameless_single_float(
Region screen_region,
placement_vector placements,
client_iter begin,
client_iter end
) const
{
- arrange_singlefloat(screen_region, placements, begin, end);
+ arrange_single_float(screen_region, placements, begin, end);
}
void
@@ -556,6 +628,271 @@ LayoutHandler::arrange_monocle(
}
void
+LayoutHandler::arrange_main_deck(
+ Region screen_region,
+ placement_vector placements,
+ client_iter begin,
+ client_iter end
+) const
+{
+ const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
+ std::size_t n = end - begin;
+
+ if (n == 1) {
+ placements.emplace_back(Placement {
+ mp_layout->config.method,
+ *begin,
+ Decoration::NO_DECORATION,
+ screen_region
+ });
+
+ return;
+ }
+
+ std::size_t n_main;
+ std::size_t n_stack;
+
+ if (n <= data->main_count) {
+ n_main = n;
+ n_stack = 0;
+ } else {
+ n_main = data->main_count;
+ n_stack = n - n_main;
+ }
+
+ int w_main
+ = data->main_count > 0
+ ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ : 0;
+
+ int x_stack = screen_region.pos.x + w_main;
+ int w_stack = screen_region.dim.w - w_main;
+ int h_main = n_main > 0 ? screen_region.dim.h : 0;
+ int h_stack = n_stack > 0 ? screen_region.dim.h / n_stack : 0;
+
+ std::size_t i = 0;
+
+ std::transform(
+ begin,
+ end,
+ std::back_inserter(placements),
+ [=,this,&i](Client_ptr client) -> Placement {
+ if (i < data->main_count) {
+ ++i;
+ return Placement {
+ mp_layout->config.method,
+ client,
+ mp_layout->config.decoration,
+ Region {
+ Pos {
+ screen_region.pos.x,
+ screen_region.pos.y
+ },
+ Dim {
+ n_stack == 0 ? screen_region.dim.w : w_main,
+ h_main
+ }
+ }
+ };
+ } else {
+ return Placement {
+ mp_layout->config.method,
+ client,
+ mp_layout->config.decoration,
+ Region {
+ Pos {
+ x_stack,
+ screen_region.pos.y
+ + static_cast<int>((i++ - data->main_count) * h_stack)
+ },
+ Dim {
+ w_stack,
+ h_stack
+ }
+ }
+ };
+ }
+ }
+ );
+}
+
+void
+LayoutHandler::arrange_stack_deck(
+ Region screen_region,
+ placement_vector placements,
+ client_iter begin,
+ client_iter end
+) const
+{
+ const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
+ std::size_t n = end - begin;
+
+ if (n == 1) {
+ placements.emplace_back(Placement {
+ mp_layout->config.method,
+ *begin,
+ Decoration::NO_DECORATION,
+ screen_region
+ });
+
+ return;
+ }
+
+ std::size_t n_main;
+ std::size_t n_stack;
+
+ if (n <= data->main_count) {
+ n_main = n;
+ n_stack = 0;
+ } else {
+ n_main = data->main_count;
+ n_stack = n - n_main;
+ }
+
+ int w_main
+ = data->main_count > 0
+ ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ : 0;
+
+ int x_stack = screen_region.pos.x + w_main;
+ int w_stack = screen_region.dim.w - w_main;
+ int h_main = n_main > 0 ? screen_region.dim.h / n_main : 0;
+ int h_stack = n_stack > 0 ? screen_region.dim.h : 0;
+
+ std::size_t i = 0;
+
+ std::transform(
+ begin,
+ end,
+ std::back_inserter(placements),
+ [=,this,&i](Client_ptr client) -> Placement {
+ if (i < data->main_count) {
+ return Placement {
+ mp_layout->config.method,
+ client,
+ mp_layout->config.decoration,
+ Region {
+ Pos {
+ screen_region.pos.x,
+ screen_region.pos.y
+ + static_cast<int>(i++) * h_main
+ },
+ Dim {
+ n_stack == 0 ? screen_region.dim.w : w_main,
+ h_main
+ }
+ }
+ };
+ } else {
+ ++i;
+ return Placement {
+ mp_layout->config.method,
+ client,
+ mp_layout->config.decoration,
+ Region {
+ Pos {
+ x_stack,
+ screen_region.pos.y
+ },
+ Dim {
+ w_stack,
+ h_stack
+ }
+ }
+ };
+ }
+ }
+ );
+}
+
+void
+LayoutHandler::arrange_double_deck(
+ Region screen_region,
+ placement_vector placements,
+ client_iter begin,
+ client_iter end
+) const
+{
+ const Layout::LayoutData_ptr data = *mp_layout->data.active_element();
+ std::size_t n = end - begin;
+
+ if (n == 1) {
+ placements.emplace_back(Placement {
+ mp_layout->config.method,
+ *begin,
+ Decoration::NO_DECORATION,
+ screen_region
+ });
+
+ return;
+ }
+
+ std::size_t n_main;
+ std::size_t n_stack;
+
+ if (n <= data->main_count) {
+ n_main = n;
+ n_stack = 0;
+ } else {
+ n_main = data->main_count;
+ n_stack = n - n_main;
+ }
+
+ int w_main
+ = data->main_count > 0
+ ? static_cast<float>(screen_region.dim.w) * data->main_factor
+ : 0;
+
+ int x_stack = screen_region.pos.x + w_main;
+ int w_stack = screen_region.dim.w - w_main;
+ int h_main = n_main > 0 ? screen_region.dim.h : 0;
+ int h_stack = n_stack > 0 ? screen_region.dim.h : 0;
+
+ std::size_t i = 0;
+
+ std::transform(
+ begin,
+ end,
+ std::back_inserter(placements),
+ [=,this,&i](Client_ptr client) -> Placement {
+ if (i++ < data->main_count) {
+ return Placement {
+ mp_layout->config.method,
+ client,
+ mp_layout->config.decoration,
+ Region {
+ Pos {
+ screen_region.pos.x,
+ screen_region.pos.y
+ },
+ Dim {
+ n_stack == 0 ? screen_region.dim.w : w_main,
+ h_main
+ }
+ }
+ };
+ } else {
+ return Placement {
+ mp_layout->config.method,
+ client,
+ mp_layout->config.decoration,
+ Region {
+ Pos {
+ x_stack,
+ screen_region.pos.y
+ },
+ Dim {
+ w_stack,
+ h_stack
+ }
+ }
+ };
+ }
+ }
+ );
+}
+
+void
LayoutHandler::arrange_paper(
Region screen_region,
placement_vector placements,
@@ -659,7 +996,7 @@ LayoutHandler::arrange_paper(
}
void
-LayoutHandler::arrange_spaper(
+LayoutHandler::arrange_compact_paper(
Region screen_region,
placement_vector placements,
client_iter begin,
@@ -670,7 +1007,7 @@ LayoutHandler::arrange_spaper(
}
void
-LayoutHandler::arrange_stack(
+LayoutHandler::arrange_double_stack(
Region screen_region,
placement_vector placements,
client_iter begin,
@@ -759,40 +1096,18 @@ LayoutHandler::arrange_stack(
}
void
-LayoutHandler::arrange_sstack(
- Region screen_region,
- placement_vector placements,
- client_iter begin,
- client_iter end
-) const
-{
- arrange_stack(screen_region, placements, begin, end);
-}
-
-void
-LayoutHandler::arrange_bstack(
- Region screen_region,
- placement_vector placements,
- client_iter begin,
- client_iter end
-) const
-{
- arrange_stack(screen_region, placements, begin, end);
-}
-
-void
-LayoutHandler::arrange_sbstack(
+LayoutHandler::arrange_compact_double_stack(
Region screen_region,
placement_vector placements,
client_iter begin,
client_iter end
) const
{
- arrange_bstack(screen_region, placements, begin, end);
+ arrange_double_stack(screen_region, placements, begin, end);
}
void
-LayoutHandler::arrange_horz(
+LayoutHandler::arrange_horizontal_stack(
Region screen_region,
placement_vector placements,
client_iter begin,
@@ -840,18 +1155,18 @@ LayoutHandler::arrange_horz(
}
void
-LayoutHandler::arrange_shorz(
+LayoutHandler::arrange_compact_horizontal_stack(
Region screen_region,
placement_vector placements,
client_iter begin,
client_iter end
) const
{
- arrange_horz(screen_region, placements, begin, end);
+ arrange_horizontal_stack(screen_region, placements, begin, end);
}
void
-LayoutHandler::arrange_vert(
+LayoutHandler::arrange_vertical_stack(
Region screen_region,
placement_vector placements,
client_iter begin,
@@ -899,14 +1214,14 @@ LayoutHandler::arrange_vert(
}
void
-LayoutHandler::arrange_svert(
+LayoutHandler::arrange_compact_vertical_stack(
Region screen_region,
placement_vector placements,
client_iter begin,
client_iter end
) const
{
- arrange_vert(screen_region, placements, begin, end);
+ arrange_vertical_stack(screen_region, placements, begin, end);
}
@@ -926,7 +1241,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::BLFloat:
+ case LayoutKind::FramelessFloat:
{
return LayoutConfig {
Placement::PlacementMethod::Free,
@@ -950,7 +1265,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::BLSingleFloat:
+ case LayoutKind::FramelessSingleFloat:
{
return LayoutConfig {
Placement::PlacementMethod::Free,
@@ -986,43 +1301,43 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::Paper:
+ case LayoutKind::MainDeck:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
Decoration {
std::nullopt,
Frame {
- Extents { 1, 1, 0, 0 },
+ Extents { 0, 0, 3, 0 },
ColorScheme::DEFAULT_COLOR_SCHEME
}
},
true,
true,
- true,
false,
- false
+ false,
+ true
};
}
- case LayoutKind::SPaper:
+ case LayoutKind::StackDeck:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
Decoration {
std::nullopt,
Frame {
- Extents { 1, 1, 0, 0 },
+ Extents { 0, 0, 3, 0 },
ColorScheme::DEFAULT_COLOR_SCHEME
}
},
true,
- false,
true,
false,
- false
+ false,
+ true
};
}
- case LayoutKind::Stack:
+ case LayoutKind::DoubleDeck:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1040,25 +1355,43 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::SStack:
+ case LayoutKind::Paper:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
Decoration {
std::nullopt,
Frame {
- Extents { 0, 0, 3, 0 },
+ Extents { 1, 1, 0, 0 },
ColorScheme::DEFAULT_COLOR_SCHEME
}
},
true,
+ true,
+ true,
false,
+ false
+ };
+ }
+ case LayoutKind::CompactPaper:
+ {
+ return LayoutConfig {
+ Placement::PlacementMethod::Tile,
+ Decoration {
+ std::nullopt,
+ Frame {
+ Extents { 1, 1, 0, 0 },
+ ColorScheme::DEFAULT_COLOR_SCHEME
+ }
+ },
+ true,
false,
+ true,
false,
- true
+ false
};
}
- case LayoutKind::BStack:
+ case LayoutKind::DoubleStack:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1076,7 +1409,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::SBStack:
+ case LayoutKind::CompactDoubleStack:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1094,7 +1427,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::Horz:
+ case LayoutKind::HorizontalStack:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1112,7 +1445,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::SHorz:
+ case LayoutKind::CompactHorizontalStack:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1130,7 +1463,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::Vert:
+ case LayoutKind::VerticalStack:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1148,7 +1481,7 @@ LayoutHandler::Layout::kind_to_config(LayoutKind kind)
true
};
}
- case LayoutKind::SVert:
+ case LayoutKind::CompactVerticalStack:
{
return LayoutConfig {
Placement::PlacementMethod::Tile,
@@ -1176,42 +1509,6 @@ LayoutHandler::Layout::LayoutData
LayoutHandler::Layout::kind_to_default_data(LayoutKind kind)
{
switch (kind) {
- case LayoutKind::Float:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::BLFloat:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::SingleFloat:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::BLSingleFloat:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
case LayoutKind::Center:
{
return Layout::LayoutData {
@@ -1221,97 +1518,22 @@ LayoutHandler::Layout::kind_to_default_data(LayoutKind kind)
.40f
};
}
- case LayoutKind::Monocle:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::Paper:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::SPaper:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::Stack:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::SStack:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::BStack:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::SBStack:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::Horz:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::SHorz:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::Vert:
- {
- return Layout::LayoutData {
- Extents { 0, 0, 0, 0 },
- 0,
- 1,
- .50f
- };
- }
- case LayoutKind::SVert:
+ case LayoutKind::Float: // fallthrough
+ case LayoutKind::FramelessFloat: // fallthrough
+ case LayoutKind::SingleFloat: // fallthrough
+ case LayoutKind::FramelessSingleFloat: // fallthrough
+ case LayoutKind::Monocle: // fallthrough
+ case LayoutKind::MainDeck: // fallthrough
+ case LayoutKind::StackDeck: // fallthrough
+ case LayoutKind::DoubleDeck: // fallthrough
+ case LayoutKind::Paper: // fallthrough
+ case LayoutKind::CompactPaper: // fallthrough
+ case LayoutKind::DoubleStack: // fallthrough
+ case LayoutKind::CompactDoubleStack: // fallthrough
+ case LayoutKind::HorizontalStack: // fallthrough
+ case LayoutKind::CompactHorizontalStack: // fallthrough
+ case LayoutKind::VerticalStack: // fallthrough
+ case LayoutKind::CompactVerticalStack:
{
return Layout::LayoutData {
Extents { 0, 0, 0, 0 },
diff --git a/src/core/layout.hh b/src/core/layout.hh
@@ -20,25 +20,26 @@ public:
{
/// free layouts
Float,
- BLFloat,
+ FramelessFloat,
SingleFloat,
- BLSingleFloat,
+ FramelessSingleFloat,
// overlapping tiled layouts
Center,
Monocle,
+ MainDeck,
+ StackDeck,
+ DoubleDeck,
// non-overlapping tiled layouts
Paper,
- SPaper,
- Stack,
- SStack,
- BStack,
- SBStack,
- Horz,
- SHorz,
- Vert,
- SVert,
+ CompactPaper,
+ DoubleStack,
+ CompactDoubleStack,
+ HorizontalStack,
+ CompactHorizontalStack,
+ VerticalStack,
+ CompactVerticalStack,
};
private:
@@ -153,21 +154,22 @@ private:
Layout_ptr mp_prev_layout;
void arrange_float(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_blfloat(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_singlefloat(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_blsinglefloat(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_frameless_float(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_single_float(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_frameless_single_float(winsys::Region, placement_vector, client_iter, client_iter) const;
void arrange_center(winsys::Region, placement_vector, client_iter, client_iter) const;
void arrange_monocle(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_main_deck(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_stack_deck(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_double_deck(winsys::Region, placement_vector, client_iter, client_iter) const;
void arrange_paper(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_spaper(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_sstack(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_bstack(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_sbstack(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_horz(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_shorz(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_vert(winsys::Region, placement_vector, client_iter, client_iter) const;
- void arrange_svert(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_compact_paper(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_double_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_compact_double_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_horizontal_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_compact_horizontal_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_vertical_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
+ void arrange_compact_vertical_stack(winsys::Region, placement_vector, client_iter, client_iter) const;
};
diff --git a/src/core/model.cc b/src/core/model.cc
@@ -250,49 +250,52 @@ Model::Model(Connection& conn)
CALL(set_layout(LayoutHandler::LayoutKind::Float))
},
{ { Key::L, { Main, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::BLFloat))
+ CALL(set_layout(LayoutHandler::LayoutKind::FramelessFloat))
},
{ { Key::Z, { Main } },
CALL(set_layout(LayoutHandler::LayoutKind::SingleFloat))
},
{ { Key::Z, { Main, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::BLSingleFloat))
+ CALL(set_layout(LayoutHandler::LayoutKind::FramelessSingleFloat))
},
{ { Key::M, { Main } },
CALL(set_layout(LayoutHandler::LayoutKind::Monocle))
},
+ { { Key::D, { Main, Ctrl } },
+ CALL(set_layout(LayoutHandler::LayoutKind::MainDeck))
+ },
+ { { Key::D, { Main, Shift } },
+ CALL(set_layout(LayoutHandler::LayoutKind::StackDeck))
+ },
+ { { Key::D, { Main, Ctrl, Shift } },
+ CALL(set_layout(LayoutHandler::LayoutKind::DoubleDeck))
+ },
{ { Key::G, { Main } },
CALL(set_layout(LayoutHandler::LayoutKind::Center))
},
{ { Key::T, { Main } },
- CALL(set_layout(LayoutHandler::LayoutKind::Stack))
+ CALL(set_layout(LayoutHandler::LayoutKind::DoubleStack))
},
{ { Key::T, { Main, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::SStack))
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactDoubleStack))
},
{ { Key::P, { Main, Ctrl, Shift } },
CALL(set_layout(LayoutHandler::LayoutKind::Paper))
},
{ { Key::P, { Main, Sec, Ctrl, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::SPaper))
- },
- { { Key::B, { Main, Ctrl, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::BStack))
- },
- { { Key::B, { Main, Sec, Ctrl, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::SBStack))
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactPaper))
},
{ { Key::Y, { Main, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::Horz))
+ CALL(set_layout(LayoutHandler::LayoutKind::HorizontalStack))
},
{ { Key::Y, { Main, Ctrl } },
- CALL(set_layout(LayoutHandler::LayoutKind::SHorz))
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactHorizontalStack))
},
{ { Key::V, { Main, Shift } },
- CALL(set_layout(LayoutHandler::LayoutKind::Vert))
+ CALL(set_layout(LayoutHandler::LayoutKind::VerticalStack))
},
{ { Key::V, { Main, Ctrl } },
- CALL(set_layout(LayoutHandler::LayoutKind::SVert))
+ CALL(set_layout(LayoutHandler::LayoutKind::CompactVerticalStack))
},
{ { Key::F, { Main, Ctrl, Shift } },
CALL(set_layout_retain_region(LayoutHandler::LayoutKind::Float))
@@ -2181,10 +2184,29 @@ Model::apply_stack(Workspace_ptr workspace)
{
static std::vector<Window> stack;
+ static constexpr struct LastTouchedComparer final {
+ bool
+ operator()(const Client_ptr lhs, const Client_ptr rhs) const
+ {
+ return lhs->last_touched < rhs->last_touched;
+ }
+ } last_touched_comparer{};
+
+ static std::set<Client_ptr, LastTouchedComparer> last_touched_clients{{}, last_touched_comparer};
+
if (workspace != mp_workspace)
return;
- std::vector<Client_ptr> clients = workspace->stack_after_focus();
+ last_touched_clients.clear();
+ std::for_each(
+ workspace->begin(),
+ workspace->end(),
+ [](Client_ptr client) {
+ last_touched_clients.insert(client);
+ }
+ );
+
+ std::vector<Client_ptr> clients{last_touched_clients.begin(), last_touched_clients.end()};
auto fullscreen_iter = std::stable_partition(
clients.begin(),
@@ -2271,7 +2293,6 @@ Model::apply_stack(Workspace_ptr workspace)
} managed_since_comparer{};
static std::set<Client_ptr, ManagedSinceComparer> managed_since_clients{{}, managed_since_comparer};
-
managed_since_clients.clear();
std::for_each(
@@ -2297,32 +2318,21 @@ Model::apply_stack(Workspace_ptr workspace)
m_conn.update_client_list(order_list);
- static constexpr struct LastFocusedComparer final {
- bool
- operator()(const Client_ptr lhs, const Client_ptr rhs) const
- {
- return lhs->last_focused < rhs->last_focused;
- }
- } last_focused_comparer{};
-
- static std::set<Client_ptr, LastFocusedComparer> last_focused_clients{{}, last_focused_comparer};
-
- last_focused_clients.clear();
-
+ last_touched_clients.clear();
std::for_each(
m_client_map.begin(),
m_client_map.end(),
[](auto kv) {
- last_focused_clients.insert(kv.second);
+ last_touched_clients.insert(kv.second);
}
);
- order_list.reserve(last_focused_clients.size());
+ order_list.reserve(last_touched_clients.size());
order_list.clear();
std::transform(
- last_focused_clients.begin(),
- last_focused_clients.end(),
+ last_touched_clients.begin(),
+ last_touched_clients.end(),
std::back_inserter(order_list),
[](Client_ptr client) -> Window {
return client->window;
@@ -2389,13 +2399,35 @@ Model::rotate_clients(Direction direction)
void
Model::shuffle_main(winsys::Direction direction)
{
- if (mp_workspace->size() <= 1)
+ std::size_t main_count
+ = std::min(mp_workspace->main_count(), mp_workspace->size());
+
+ if (main_count <= 1)
return;
+ Index focus_index = *mp_workspace->clients().index();
+ std::optional<Index> last_touched_index = std::nullopt;
+
+ if (focus_index >= main_count) {
+ Client_ptr last_touched = *std::max_element(
+ mp_workspace->begin(),
+ mp_workspace->begin() + main_count,
+ [](Client_ptr client1, Client_ptr client2) -> bool {
+ return client1->last_touched < client2->last_touched;
+ }
+ );
+
+ last_touched_index
+ = mp_workspace->clients().index_of_element(last_touched);
+ }
+
mp_workspace->shuffle_main(direction);
focus_client(mp_workspace->active());
sync_focus();
+ if (last_touched_index)
+ (*mp_workspace)[*last_touched_index]->touch();
+
apply_layout(mp_workspace);
apply_stack(mp_workspace);
}
@@ -2403,13 +2435,35 @@ Model::shuffle_main(winsys::Direction direction)
void
Model::shuffle_stack(winsys::Direction direction)
{
- if (mp_workspace->size() <= 1)
+ std::size_t main_count
+ = std::min(mp_workspace->main_count(), mp_workspace->size());
+
+ if ((mp_workspace->size() - main_count) <= 1)
return;
+ Index focus_index = *mp_workspace->clients().index();
+ std::optional<Index> last_touched_index = std::nullopt;
+
+ if (focus_index < main_count) {
+ Client_ptr last_touched = *std::max_element(
+ mp_workspace->begin() + main_count,
+ mp_workspace->end(),
+ [](Client_ptr client1, Client_ptr client2) -> bool {
+ return client1->last_touched < client2->last_touched;
+ }
+ );
+
+ last_touched_index
+ = mp_workspace->clients().index_of_element(last_touched);
+ }
+
mp_workspace->shuffle_stack(direction);
focus_client(mp_workspace->active());
sync_focus();
+ if (last_touched_index)
+ (*mp_workspace)[*last_touched_index]->touch();
+
apply_layout(mp_workspace);
apply_stack(mp_workspace);
}
@@ -2514,7 +2568,7 @@ Model::set_layout(LayoutHandler::LayoutKind layout)
void
Model::set_layout_retain_region(LayoutHandler::LayoutKind layout)
{
- std::deque<Client_ptr> const& clients = mp_workspace->clients();
+ Cycle<Client_ptr> const& clients = mp_workspace->clients();
std::vector<Region> regions;
bool was_tiled = !mp_workspace->layout_is_free();
diff --git a/src/core/workspace.cc b/src/core/workspace.cc
@@ -131,6 +131,12 @@ Workspace::length() const
return m_clients.length();
}
+std::size_t
+Workspace::main_count() const
+{
+ return m_layout_handler.main_count();
+}
+
Context_ptr
Workspace::context() const
@@ -173,10 +179,10 @@ Workspace::active() const
}
-std::deque<Client_ptr> const&
+Cycle<Client_ptr> const&
Workspace::clients() const
{
- return m_clients.as_deque();
+ return m_clients;
}
std::vector<Client_ptr>
@@ -548,8 +554,7 @@ Workspace::set_layout(LayoutHandler::LayoutKind layout)
std::vector<Placement>
Workspace::arrange(winsys::Region region) const
{
- std::deque<Client_ptr> clients = this->clients();
-
+ std::deque<Client_ptr> clients = m_clients.as_deque();
std::vector<Placement> placements;
placements.reserve(clients.size());
diff --git a/src/core/workspace.hh b/src/core/workspace.hh
@@ -149,6 +149,7 @@ public:
std::size_t size() const;
std::size_t length() const;
+ std::size_t main_count() const;
Context_ptr context() const;
@@ -157,7 +158,7 @@ public:
std::string identifier() const;
Client_ptr active() const;
- std::deque<Client_ptr> const& clients() const;
+ Cycle<Client_ptr> const& clients() const;
std::vector<Client_ptr> stack_after_focus() const;
Client_ptr next_client() const;