kranewm

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in C++
git clone git clone git://git.deurzen.net/kranewm.git
Log | Files | Refs | LICENSE

commit 367169e60ef2d3d558547ace61a35fb93370732b
parent 037623f86bca3420ddb293c10ef881fd78fcd65d
Author: deurzen <m.deurzen@tum.de>
Date:   Sun,  1 Aug 2021 22:37:14 +0200

adds consumer/producer configurability

Diffstat:
Msrc/core/model.cc | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/core/model.hh | 4++++
Msrc/core/search.hh | 6++++--
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__