commit 367169e60ef2d3d558547ace61a35fb93370732b
parent 037623f86bca3420ddb293c10ef881fd78fcd65d
Author: deurzen <m.deurzen@tum.de>
Date: Sun, 1 Aug 2021 22:37:14 +0200
adds consumer/producer configurability
Diffstat:
3 files changed, 152 insertions(+), 8 deletions(-)
diff --git a/src/core/model.cc b/src/core/model.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <cstdlib>
#include <cstring>
+#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
@@ -44,6 +45,8 @@ Model::Model(Connection& conn)
m_fullscreen_map({}),
m_sticky_clients({}),
m_unmanaged_windows({}),
+ m_ignored_producers({}),
+ m_ignored_consumers({}),
mp_focus(nullptr),
mp_jumped_from(nullptr),
m_key_bindings({
@@ -739,8 +742,7 @@ Model::Model(Connection& conn)
for (auto& window : m_conn.top_level_windows())
manage(window, !m_conn.must_manage_window(window));
-#ifndef DEBUG
- { // run user-configured autostart programs
+ { // user configurations
std::stringstream configdir_ss;
if (const char* env_xdgconf = std::getenv("XDG_CONFIG_HOME"))
@@ -748,11 +750,83 @@ Model::Model(Connection& conn)
else
configdir_ss << "$HOME/.config/" << WM_NAME << "/";
- spawn_external(configdir_ss.str() + std::string("blocking_autostart"));
- spawn_external(configdir_ss.str() + std::string("nonblocking_autostart &"));
- spdlog::info("ran autostart scripts");
- }
+ { // produce vector of to-ignore-{producers,consumers}
+ std::ifstream in(configdir_ss.str() + std::string("consumeignore"));
+
+ if (in.good()) {
+ std::string line;
+
+ while (std::getline(in, line)) {
+ std::string::size_type pos = line.find('#');
+
+ if (pos != std::string::npos)
+ line = line.substr(0, pos);
+
+ if (line.length() < 5)
+ continue;
+
+ line.erase(4, line.find_first_not_of(" \t\n\r\f\v"));
+ line.erase(line.find_last_not_of(" \t\n\r\f\v") + 1);
+
+ if (line.length() < 5)
+ continue;
+
+ std::vector<SearchSelector_ptr>* ignored;
+ switch (line[0]) {
+ case '<': ignored = &m_ignored_producers; break;
+ case '>': ignored = &m_ignored_consumers; break;
+ default: continue;
+ }
+
+ SearchSelector::SelectionCriterium criterium;
+
+ switch (line[2]) {
+ case 'N':
+ {
+ switch (line[1]) {
+ case '=': criterium = SearchSelector::SelectionCriterium::ByNameEquals; break;
+ case '~': criterium = SearchSelector::SelectionCriterium::ByNameContains; break;
+ default: continue;
+ }
+
+ break;
+ }
+ case 'C':
+ {
+ switch (line[1]) {
+ case '=': criterium = SearchSelector::SelectionCriterium::ByClassEquals; break;
+ case '~': criterium = SearchSelector::SelectionCriterium::ByClassContains; break;
+ default: continue;
+ }
+
+ break;
+ }
+ case 'I':
+ {
+ switch (line[1]) {
+ case '=': criterium = SearchSelector::SelectionCriterium::ByInstanceEquals; break;
+ case '~': criterium = SearchSelector::SelectionCriterium::ByInstanceContains; break;
+ default: continue;
+ }
+
+ break;
+ }
+ default: continue;
+ }
+
+ ignored->push_back(new SearchSelector{criterium, line.substr(4)});
+ }
+ }
+ }
+
+#ifndef DEBUG
+ { // run user-configured autostart programs
+ spawn_external(configdir_ss.str() + std::string("blocking_autostart"));
+ spawn_external(configdir_ss.str() + std::string("nonblocking_autostart &"));
+ spdlog::info("ran autostart scripts");
+ }
#endif
+ }
spdlog::info("initialized " + WM_NAME);
}
@@ -776,6 +850,12 @@ Model::~Model()
for (Client_ptr client : clients)
delete client;
+ for (std::size_t i = 0; i < m_ignored_producers.size(); ++i)
+ delete m_ignored_producers[i];
+
+ for (std::size_t i = 0; i < m_ignored_consumers.size(); ++i)
+ delete m_ignored_consumers[i];
+
m_partitions.clear();
m_contexts.clear();
m_workspaces.clear();
@@ -997,6 +1077,56 @@ Model::search_client(SearchSelector const& selector)
: *clients.rbegin();
}
+bool
+Model::client_matches_search(Client_ptr client, SearchSelector const& selector) const
+{
+ switch (selector.criterium()) {
+ case SearchSelector::SelectionCriterium::OnWorkspaceBySelector:
+ {
+ // TODO
+ break;
+ }
+ case SearchSelector::SelectionCriterium::ByNameEquals:
+ {
+ return client->managed
+ && client->name == selector.string_value();
+ }
+ case SearchSelector::SelectionCriterium::ByClassEquals:
+ {
+ return client->managed
+ && client->class_ == selector.string_value();
+ }
+ case SearchSelector::SelectionCriterium::ByInstanceEquals:
+ {
+ return client->managed
+ && client->instance == selector.string_value();
+ }
+ case SearchSelector::SelectionCriterium::ByNameContains:
+ {
+ return client->managed
+ && client->name.find(selector.string_value()) != std::string::npos;
+ }
+ case SearchSelector::SelectionCriterium::ByClassContains:
+ {
+ return client->managed
+ && client->class_.find(selector.string_value()) != std::string::npos;
+ }
+ case SearchSelector::SelectionCriterium::ByInstanceContains:
+ {
+ return client->managed
+ && client->instance.find(selector.string_value()) != std::string::npos;
+ }
+ case SearchSelector::SelectionCriterium::ForCondition:
+ {
+ return client->managed
+ && selector.filter()(client);
+ }
+ default: return false;
+ }
+
+ return false;
+}
+
Index
Model::active_partition() const
@@ -2764,6 +2894,14 @@ Model::consume_client(Client_ptr producer, Client_ptr client)
return;
}
+ for (SearchSelector_ptr selector : m_ignored_producers)
+ if (client_matches_search(producer, *selector))
+ return;
+
+ for (SearchSelector_ptr selector : m_ignored_consumers)
+ if (client_matches_search(client, *selector))
+ return;
+
if (m_move_buffer.client() == producer)
stop_moving();
diff --git a/src/core/model.hh b/src/core/model.hh
@@ -62,6 +62,7 @@ private:
Client_ptr get_const_client(winsys::Window) const;
Client_ptr search_client(SearchSelector const&);
+ bool client_matches_search(Client_ptr, SearchSelector const&) const;
Index active_partition() const;
Partition_ptr get_partition(Index) const;
@@ -224,6 +225,9 @@ private:
std::vector<Client_ptr> m_sticky_clients;
std::vector<winsys::Window> m_unmanaged_windows;
+ std::vector<SearchSelector_ptr> m_ignored_producers;
+ std::vector<SearchSelector_ptr> m_ignored_consumers;
+
Client_ptr mp_focus;
Client_ptr mp_jumped_from;
diff --git a/src/core/search.hh b/src/core/search.hh
@@ -9,7 +9,7 @@
#include <string>
#include <utility>
-class SearchSelector final
+typedef class SearchSelector final
{
public:
enum class SelectionCriterium
@@ -81,6 +81,8 @@ public:
}
}
+ SearchSelector(SearchSelector&&) = delete;
+
SelectionCriterium
criterium() const
{
@@ -139,6 +141,6 @@ private:
std::function<bool(const Client_ptr)> m_filter;
};
-};
+}* SearchSelector_ptr;
#endif//__SEARCH_H_GUARD__