commit 37695b23b396c523337ff4897379e96bb2940602
parent b614c5ffff2b35530444446c9ec20b7b821202f5
Author: deurzen <m.deurzen@tum.de>
Date: Tue, 21 Sep 2021 23:15:41 +0200
adds initial partition (screen) syncing functionality
Diffstat:
6 files changed, 108 insertions(+), 10 deletions(-)
diff --git a/src/core/cycle.hh b/src/core/cycle.hh
@@ -81,11 +81,39 @@ public:
void activate_at_index(Index);
void activate_element(T);
+ template<typename UnaryPredicate>
+ void activate_for_condition(UnaryPredicate predicate)
+ {
+ auto it = std::find_if(
+ m_elements.begin(),
+ m_elements.end(),
+ predicate
+ );
+
+ if (it != m_elements.end())
+ activate_element(*it);
+ }
+
bool remove_first();
bool remove_last();
bool remove_at_index(Index);
bool remove_element(T);
+ template<typename UnaryPredicate>
+ bool remove_for_condition(UnaryPredicate predicate)
+ {
+ auto it = std::find_if(
+ m_elements.begin(),
+ m_elements.end(),
+ predicate
+ );
+
+ if (it != m_elements.end())
+ return remove_element(*it);
+
+ return false;
+ }
+
std::optional<T> pop_back();
void replace_element(T, T);
diff --git a/src/core/model.cc b/src/core/model.cc
@@ -848,23 +848,64 @@ void
Model::acquire_partitions()
{
std::size_t index = m_partitions.active_index();
+ std::vector<Screen> connected_outputs = m_conn.connected_outputs();
- for (std::size_t i = 0; i < m_partitions.size(); ++i)
+ connected_outputs.erase(
+ std::unique(
+ connected_outputs.begin(),
+ connected_outputs.end(),
+ [](Screen const& screen1, Screen const& screen2) {
+ return screen1.full_region() == screen2.full_region();
+ }
+ ),
+ connected_outputs.end()
+ );
+
+ if (connected_outputs.size() > m_contexts.size()) {
+ // TODO: generate more contexts?
+ spdlog::warn("more outputs than available contexts");
+ return;
+ }
+
+ if (connected_outputs.empty()) {
+ spdlog::warn("could not acquire any partitions");
+ return;
+ }
+
+ std::vector<Context_ptr> partition_contexts(
+ std::max(connected_outputs.size(), m_partitions.size()),
+ nullptr
+ );
+
+ std::unordered_set<Index> used_contexts{};
+
+ for (std::size_t i = 0; i < m_partitions.size(); ++i) {
+ partition_contexts[m_partitions[i]->index()] = m_partitions[i]->context();
+ used_contexts.insert(m_partitions[i]->context()->index());
delete m_partitions[i];
+ }
m_partitions.clear();
- std::vector<Screen> connected_outputs = m_conn.connected_outputs();
+ std::vector<Partition_ptr> contextless_partitions{};
- for (std::size_t i = 0; i < connected_outputs.size(); ++i)
+ for (std::size_t i = 0; i < connected_outputs.size(); ++i) {
m_partitions.insert_at_back(new Partition(
connected_outputs[i],
i
));
- if (m_partitions.empty()) {
- spdlog::warn("could not acquire any partitions");
- return;
+ if (partition_contexts[i] != nullptr)
+ m_partitions[i]->set_context(partition_contexts[i]);
+ else
+ contextless_partitions.push_back(m_partitions[i]);
+ }
+
+ for (std::size_t i = 0, context_index = 0; i < contextless_partitions.size(); ++context_index) {
+ if (Util::contains(used_contexts, context_index))
+ continue;
+
+ contextless_partitions[i++]->set_context(m_contexts[context_index]);
}
if (index < m_partitions.size())
diff --git a/src/core/partition.hh b/src/core/partition.hh
@@ -3,13 +3,15 @@
#include "../winsys/common.hh"
#include "../winsys/screen.hh"
+#include "context.hh"
typedef class Partition final
{
public:
Partition(winsys::Screen screen, Index index)
: m_screen(screen),
- m_index(index)
+ m_index(index),
+ mp_context(nullptr)
{}
winsys::Screen&
@@ -30,10 +32,27 @@ public:
return m_index;
}
+ void
+ set_context(Context_ptr context)
+ {
+ Util::assert(context != nullptr,
+ "partition must contain valid context");
+
+ mp_context = context;
+ }
+
+ Context_ptr
+ context()
+ {
+ return mp_context;
+ }
+
private:
winsys::Screen m_screen;
Index m_index;
+ Context_ptr mp_context;
+
}* Partition_ptr;
#endif//__PARTITION_H_GUARD__
diff --git a/src/winsys/geometry.hh b/src/winsys/geometry.hh
@@ -36,7 +36,7 @@ namespace winsys
};
inline bool
- operator==(Dim& lhs, Dim& rhs)
+ operator==(Dim const& lhs, Dim const& rhs)
{
return lhs.w == rhs.w && lhs.h == rhs.h;
}
@@ -63,7 +63,7 @@ namespace winsys
};
inline bool
- operator==(Pos& lhs, Pos& rhs)
+ operator==(Pos const& lhs, Pos const& rhs)
{
return lhs.x == rhs.x && lhs.y == rhs.y;
}
@@ -89,7 +89,7 @@ namespace winsys
};
inline bool
- operator==(Region& lhs, Region& rhs)
+ operator==(Region const& lhs, Region const& rhs)
{
return lhs.pos == rhs.pos && lhs.dim == rhs.dim;
}
diff --git a/src/winsys/util.cc b/src/winsys/util.cc
@@ -1,5 +1,7 @@
#include "util.hh"
+#include <utility>
+
extern "C" {
#include <unistd.h>
}
@@ -16,3 +18,10 @@ Util::warn(const std::string&& msg)
{
std::cerr << msg << std::endl;
}
+
+void
+Util::assert(bool condition, const std::string&& msg)
+{
+ if (!condition)
+ Util::die(std::forward<const std::string&&>(msg));
+}
diff --git a/src/winsys/util.hh b/src/winsys/util.hh
@@ -13,6 +13,7 @@ namespace Util
void die(const std::string&&);
void warn(const std::string&&);
+ void assert(bool, const std::string&&);
template <
typename T,