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 037623f86bca3420ddb293c10ef881fd78fcd65d
parent e013a7f803a39668257a7272b01df319c682eb34
Author: deurzen <m.deurzen@tum.de>
Date:   Sun,  1 Aug 2021 19:52:09 +0200

generalizes client searching

Diffstat:
Dsrc/core/jump.hh | 144-------------------------------------------------------------------------------
Msrc/core/model.cc | 227+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/core/model.hh | 6++++--
Asrc/core/search.hh | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 266 insertions(+), 255 deletions(-)

diff --git a/src/core/jump.hh b/src/core/jump.hh @@ -1,144 +0,0 @@ -#ifndef __JUMP_H_GUARD__ -#define __JUMP_H_GUARD__ - -#include "../winsys/common.hh" -#include "client.hh" -#include "workspace.hh" - -#include <functional> -#include <string> -#include <utility> - -class JumpSelector final -{ -public: - enum class SelectionCriterium - { - OnWorkspaceBySelector, - ByNameEquals, - ByClassEquals, - ByInstanceEquals, - ByNameContains, - ByClassContains, - ByInstanceContains, - ForCondition, - }; - - JumpSelector(Index index, Workspace::ClientSelector::SelectionCriterium criterium) - : m_tag(JumpSelectorTag::OnWorkspaceBySelector), - m_workspace_selector(std::pair(index, criterium)) - {} - - JumpSelector(SelectionCriterium criterium, std::string&& str_) - : m_string(str_) - { - switch (criterium) { - case SelectionCriterium::ByNameEquals: m_tag = JumpSelectorTag::ByNameEquals; return; - case SelectionCriterium::ByClassEquals: m_tag = JumpSelectorTag::ByClassEquals; return; - case SelectionCriterium::ByInstanceEquals: m_tag = JumpSelectorTag::ByInstanceEquals; return; - case SelectionCriterium::ByNameContains: m_tag = JumpSelectorTag::ByNameContains; return; - case SelectionCriterium::ByClassContains: m_tag = JumpSelectorTag::ByClassContains; return; - case SelectionCriterium::ByInstanceContains: m_tag = JumpSelectorTag::ByInstanceContains; return; - default: return; - } - } - - JumpSelector(std::function<bool(const Client_ptr)>&& filter) - : m_tag(JumpSelectorTag::ForCondition), - m_filter(filter) - {} - - ~JumpSelector() - { - switch (m_tag) { - case JumpSelectorTag::OnWorkspaceBySelector: - { - (&m_workspace_selector)->std::pair< - Index, - Workspace::ClientSelector::SelectionCriterium - >::~pair(); - - return; - } - case JumpSelectorTag::ByNameEquals: // fallthrough - case JumpSelectorTag::ByClassEquals: // fallthrough - case JumpSelectorTag::ByInstanceEquals: // fallthrough - case JumpSelectorTag::ByNameContains: // fallthrough - case JumpSelectorTag::ByClassContains: // fallthrough - case JumpSelectorTag::ByInstanceContains: - { - (&m_string)->std::string::~string(); - - return; - } - case JumpSelectorTag::ForCondition: - { - (&m_filter)->std::function<bool(const Client_ptr)>::~function(); - - return; - } - default: return; - } - } - - SelectionCriterium - criterium() const - { - switch (m_tag) { - case JumpSelectorTag::OnWorkspaceBySelector: return SelectionCriterium::OnWorkspaceBySelector; - case JumpSelectorTag::ByNameEquals: return SelectionCriterium::ByNameEquals; - case JumpSelectorTag::ByClassEquals: return SelectionCriterium::ByClassEquals; - case JumpSelectorTag::ByInstanceEquals: return SelectionCriterium::ByInstanceEquals; - case JumpSelectorTag::ByNameContains: return SelectionCriterium::ByNameContains; - case JumpSelectorTag::ByClassContains: return SelectionCriterium::ByClassContains; - case JumpSelectorTag::ByInstanceContains: return SelectionCriterium::ByInstanceContains; - case JumpSelectorTag::ForCondition: return SelectionCriterium::ForCondition; - default: Util::die("no associated criterium"); - } - - return {}; - } - - std::pair<Index, Workspace::ClientSelector::SelectionCriterium> const& - workspace_selector() const - { - return m_workspace_selector; - } - - std::string const& - string_value() const - { - return m_string; - } - - std::function<bool(const Client_ptr)> const& - filter() const - { - return m_filter; - } - -private: - enum class JumpSelectorTag - { - OnWorkspaceBySelector, - ByNameEquals, - ByClassEquals, - ByInstanceEquals, - ByNameContains, - ByClassContains, - ByInstanceContains, - ForCondition, - }; - - JumpSelectorTag m_tag; - - union - { - std::pair<Index, Workspace::ClientSelector::SelectionCriterium> m_workspace_selector; - std::string m_string; - std::function<bool(const Client_ptr)> m_filter; - }; - -}; - -#endif//__JUMP_H_GUARD__ diff --git a/src/core/model.cc b/src/core/model.cc @@ -160,31 +160,31 @@ Model::Model(Connection& conn) // client jump criteria { { Key::B, { Main } }, CALL(jump_client({ - JumpSelector::SelectionCriterium::ByClassEquals, + SearchSelector::SelectionCriterium::ByClassEquals, "qutebrowser" })) }, { { Key::B, { Main, Shift } }, CALL(jump_client({ - JumpSelector::SelectionCriterium::ByClassEquals, + SearchSelector::SelectionCriterium::ByClassEquals, "Firefox" })) }, { { Key::B, { Main, Ctrl } }, CALL(jump_client({ - JumpSelector::SelectionCriterium::ByClassContains, + SearchSelector::SelectionCriterium::ByClassContains, "Chromium" })) }, { { Key::Space, { Main, Sec } }, CALL(jump_client({ - JumpSelector::SelectionCriterium::ByClassEquals, + SearchSelector::SelectionCriterium::ByClassEquals, "Spotify" })) }, { { Key::E, { Main } }, CALL(jump_client({ - JumpSelector::SelectionCriterium::ByNameContains, + SearchSelector::SelectionCriterium::ByNameContains, "[vim]" })) }, @@ -888,6 +888,116 @@ Model::get_const_client(Window window) const } +Client_ptr +Model::search_client(SearchSelector const& selector) +{ + 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> clients + = {{}, last_focused_comparer}; + + clients.clear(); + + switch (selector.criterium()) { + case SearchSelector::SelectionCriterium::OnWorkspaceBySelector: + { + auto const& [index,selector_] = selector.workspace_selector(); + + if (index <= m_workspaces.size()) { + Workspace_ptr workspace = m_workspaces[index]; + std::optional<Client_ptr> client = workspace->find_client(selector_); + + if (client && (*client)->managed) + clients.insert(*client); + } + + break; + } + case SearchSelector::SelectionCriterium::ByNameEquals: + { + std::string const& name = selector.string_value(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && client->name == name) + clients.insert(client); + + break; + } + case SearchSelector::SelectionCriterium::ByClassEquals: + { + std::string const& class_ = selector.string_value(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && client->class_ == class_) + clients.insert(client); + + break; + } + case SearchSelector::SelectionCriterium::ByInstanceEquals: + { + std::string const& instance = selector.string_value(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && client->instance == instance) + clients.insert(client); + + break; + } + case SearchSelector::SelectionCriterium::ByNameContains: + { + std::string const& name = selector.string_value(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && client->name.find(name) != std::string::npos) + clients.insert(client); + + break; + } + case SearchSelector::SelectionCriterium::ByClassContains: + { + std::string const& class_ = selector.string_value(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && client->class_.find(class_) != std::string::npos) + clients.insert(client); + + break; + } + case SearchSelector::SelectionCriterium::ByInstanceContains: + { + std::string const& instance = selector.string_value(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && client->instance.find(instance) != std::string::npos) + clients.insert(client); + + break; + } + case SearchSelector::SelectionCriterium::ForCondition: + { + std::function<bool(const Client_ptr)> const& filter = selector.filter(); + + for (auto const&[_,client] : m_client_map) + if (client->managed && filter(client)) + clients.insert(client); + + break; + } + default: return nullptr; + } + + return clients.empty() + ? nullptr + : *clients.rbegin(); +} + + Index Model::active_partition() const { @@ -2257,112 +2367,11 @@ Model::kill_client(Client_ptr client) void -Model::jump_client(JumpSelector const& selector) +Model::jump_client(SearchSelector const& selector) { - 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> clients - = {{}, last_focused_comparer}; - - clients.clear(); - - switch (selector.criterium()) { - case JumpSelector::SelectionCriterium::OnWorkspaceBySelector: - { - auto const& [index,selector_] = selector.workspace_selector(); - - if (index <= m_workspaces.size()) { - Workspace_ptr workspace = m_workspaces[index]; - std::optional<Client_ptr> client = workspace->find_client(selector_); - - if (client && (*client)->managed) - clients.insert(*client); - } - - break; - } - case JumpSelector::SelectionCriterium::ByNameEquals: - { - std::string const& name = selector.string_value(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && client->name == name) - clients.insert(client); - - break; - } - case JumpSelector::SelectionCriterium::ByClassEquals: - { - std::string const& class_ = selector.string_value(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && client->class_ == class_) - clients.insert(client); - - break; - } - case JumpSelector::SelectionCriterium::ByInstanceEquals: - { - std::string const& instance = selector.string_value(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && client->instance == instance) - clients.insert(client); - - break; - } - case JumpSelector::SelectionCriterium::ByNameContains: - { - std::string const& name = selector.string_value(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && client->name.find(name) != std::string::npos) - clients.insert(client); - - break; - } - case JumpSelector::SelectionCriterium::ByClassContains: - { - std::string const& class_ = selector.string_value(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && client->class_.find(class_) != std::string::npos) - clients.insert(client); - - break; - } - case JumpSelector::SelectionCriterium::ByInstanceContains: - { - std::string const& instance = selector.string_value(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && client->instance.find(instance) != std::string::npos) - clients.insert(client); - - break; - } - case JumpSelector::SelectionCriterium::ForCondition: - { - std::function<bool(const Client_ptr)> const& filter = selector.filter(); - - for (auto const&[_,client] : m_client_map) - if (client->managed && filter(client)) - clients.insert(client); - - break; - } - default: return; - } - - if (!clients.empty()) { - Client_ptr client = *clients.rbegin(); + Client_ptr client = search_client(selector); + if (client) { if (client == mp_focus) { if (mp_jumped_from && client != mp_jumped_from) client = mp_jumped_from; diff --git a/src/core/model.hh b/src/core/model.hh @@ -7,11 +7,11 @@ #include "client.hh" #include "context.hh" #include "cycle.hh" -#include "jump.hh" #include "layout.hh" #include "partition.hh" #include "partition.hh" #include "rules.hh" +#include "search.hh" #include "stack.hh" #include "workspace.hh" @@ -61,6 +61,8 @@ private: Client_ptr get_client(winsys::Window); Client_ptr get_const_client(winsys::Window) const; + Client_ptr search_client(SearchSelector const&); + Index active_partition() const; Partition_ptr get_partition(Index) const; @@ -151,7 +153,7 @@ private: void kill_focus(); void kill_client(Client_ptr); - void jump_client(JumpSelector const&); + void jump_client(SearchSelector const&); void set_floating_focus(winsys::Toggle); void set_floating_client(winsys::Toggle, Client_ptr); diff --git a/src/core/search.hh b/src/core/search.hh @@ -0,0 +1,144 @@ +#ifndef __SEARCH_H_GUARD__ +#define __SEARCH_H_GUARD__ + +#include "../winsys/common.hh" +#include "client.hh" +#include "workspace.hh" + +#include <functional> +#include <string> +#include <utility> + +class SearchSelector final +{ +public: + enum class SelectionCriterium + { + OnWorkspaceBySelector, + ByNameEquals, + ByClassEquals, + ByInstanceEquals, + ByNameContains, + ByClassContains, + ByInstanceContains, + ForCondition, + }; + + SearchSelector(Index index, Workspace::ClientSelector::SelectionCriterium criterium) + : m_tag(SearchSelectorTag::OnWorkspaceBySelector), + m_workspace_selector(std::pair(index, criterium)) + {} + + SearchSelector(SelectionCriterium criterium, std::string&& str_) + : m_string(str_) + { + switch (criterium) { + case SelectionCriterium::ByNameEquals: m_tag = SearchSelectorTag::ByNameEquals; return; + case SelectionCriterium::ByClassEquals: m_tag = SearchSelectorTag::ByClassEquals; return; + case SelectionCriterium::ByInstanceEquals: m_tag = SearchSelectorTag::ByInstanceEquals; return; + case SelectionCriterium::ByNameContains: m_tag = SearchSelectorTag::ByNameContains; return; + case SelectionCriterium::ByClassContains: m_tag = SearchSelectorTag::ByClassContains; return; + case SelectionCriterium::ByInstanceContains: m_tag = SearchSelectorTag::ByInstanceContains; return; + default: return; + } + } + + SearchSelector(std::function<bool(const Client_ptr)>&& filter) + : m_tag(SearchSelectorTag::ForCondition), + m_filter(filter) + {} + + ~SearchSelector() + { + switch (m_tag) { + case SearchSelectorTag::OnWorkspaceBySelector: + { + (&m_workspace_selector)->std::pair< + Index, + Workspace::ClientSelector::SelectionCriterium + >::~pair(); + + return; + } + case SearchSelectorTag::ByNameEquals: // fallthrough + case SearchSelectorTag::ByClassEquals: // fallthrough + case SearchSelectorTag::ByInstanceEquals: // fallthrough + case SearchSelectorTag::ByNameContains: // fallthrough + case SearchSelectorTag::ByClassContains: // fallthrough + case SearchSelectorTag::ByInstanceContains: + { + (&m_string)->std::string::~string(); + + return; + } + case SearchSelectorTag::ForCondition: + { + (&m_filter)->std::function<bool(const Client_ptr)>::~function(); + + return; + } + default: return; + } + } + + SelectionCriterium + criterium() const + { + switch (m_tag) { + case SearchSelectorTag::OnWorkspaceBySelector: return SelectionCriterium::OnWorkspaceBySelector; + case SearchSelectorTag::ByNameEquals: return SelectionCriterium::ByNameEquals; + case SearchSelectorTag::ByClassEquals: return SelectionCriterium::ByClassEquals; + case SearchSelectorTag::ByInstanceEquals: return SelectionCriterium::ByInstanceEquals; + case SearchSelectorTag::ByNameContains: return SelectionCriterium::ByNameContains; + case SearchSelectorTag::ByClassContains: return SelectionCriterium::ByClassContains; + case SearchSelectorTag::ByInstanceContains: return SelectionCriterium::ByInstanceContains; + case SearchSelectorTag::ForCondition: return SelectionCriterium::ForCondition; + default: Util::die("no associated criterium"); + } + + return {}; + } + + std::pair<Index, Workspace::ClientSelector::SelectionCriterium> const& + workspace_selector() const + { + return m_workspace_selector; + } + + std::string const& + string_value() const + { + return m_string; + } + + std::function<bool(const Client_ptr)> const& + filter() const + { + return m_filter; + } + +private: + enum class SearchSelectorTag + { + OnWorkspaceBySelector, + ByNameEquals, + ByClassEquals, + ByInstanceEquals, + ByNameContains, + ByClassContains, + ByInstanceContains, + ForCondition, + }; + + SearchSelectorTag m_tag; + + union + { + std::pair<Index, Workspace::ClientSelector::SelectionCriterium> m_workspace_selector; + std::string m_string; + std::function<bool(const Client_ptr)> m_filter; + }; + +}; + +#endif//__SEARCH_H_GUARD__