Skip to content

Commit eea9cd1

Browse files
committed
finders/font: init font finder
fixes #91
1 parent aa4b65d commit eea9cd1

12 files changed

Lines changed: 156 additions & 10 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pkg_check_modules(
3030
hyprwire
3131
icu-uc
3232
hyprlang
33+
fontconfig
3334
libqalculate
3435
)
3536

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ A multipurpose and versatile launcher / picker for Hyprland
55

66
## Features
77

8-
- Various providers: Desktop, Unicode, Emoji, Math ...
8+
- Various providers: Desktop, Unicode, Emoji, Math, Font ...
99
- Speedy: Fast, multi-threaded fuzzy searching
1010
- Daemon by default: instant opening of the launcher
1111
- Entry frequency caching: commonly used entries appear above others
@@ -16,3 +16,4 @@ A multipurpose and versatile launcher / picker for Hyprland
1616
- Desktop: none
1717
- Unicode: `wl-copy`
1818
- Math: `wl-copy` for copying the result
19+
- Font: `wl-copy` for copying the result

src/config/ConfigManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ CConfigManager::CConfigManager() : m_inotifyFd(inotify_init()) {
2020
m_config->addConfigValue("finders:desktop_prefix", Hyprlang::STRING{""});
2121
m_config->addConfigValue("finders:unicode_prefix", Hyprlang::STRING{"."});
2222
m_config->addConfigValue("finders:math_prefix", Hyprlang::STRING{"="});
23+
m_config->addConfigValue("finders:font_prefix", Hyprlang::STRING{"'"});
2324

2425
m_config->addConfigValue("finders:desktop_launch_prefix", Hyprlang::STRING{""});
2526
m_config->addConfigValue("finders:desktop_icons", Hyprlang::INT{1});

src/finders/FinderTypes.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ enum eFinderTypes : uint8_t {
77
FINDER_UNICODE = 1,
88
FINDER_MATH = 2,
99
FINDER_IPC = 3,
10+
FINDER_FONT = 4,
1011
};

src/finders/IFinder.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55

66
#include <string>
77
#include <vector>
8+
#include <optional>
89

910
struct SFinderResult {
10-
std::string label;
11-
std::string icon;
12-
SP<IFinderResult> result;
11+
std::string label;
12+
std::string icon;
13+
SP<IFinderResult> result;
14+
std::optional<std::string> overrideFont;
1315
};
1416

1517
constexpr const size_t MAX_RESULTS_PER_FINDER = 15;

src/finders/font/FontFinder.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include "FontFinder.hpp"
2+
#include "../../helpers/Log.hpp"
3+
#include "../Fuzzy.hpp"
4+
5+
#include <hyprutils/os/Process.hpp>
6+
#include <fontconfig/fontconfig.h>
7+
8+
#include <algorithm>
9+
10+
using namespace Hyprutils::OS;
11+
12+
class CFontEntry : public IFinderResult {
13+
public:
14+
CFontEntry() = default;
15+
virtual ~CFontEntry() = default;
16+
17+
virtual const std::string& fuzzable() {
18+
return m_fuzzable;
19+
}
20+
21+
virtual eFinderTypes type() {
22+
return FINDER_MATH;
23+
}
24+
25+
virtual const std::string& name() {
26+
return m_font;
27+
}
28+
29+
virtual void run() {
30+
Debug::log(TRACE, "Copying {} with wl-copy", m_font);
31+
32+
CProcess proc("wl-copy", {m_font});
33+
proc.runAsync();
34+
}
35+
36+
std::string m_font, m_fuzzable;
37+
};
38+
39+
CFontFinder::CFontFinder() : m_valid(FcInit()) {
40+
if (!m_valid)
41+
Debug::log(ERR, "font: FcInit failed, fonts unavailable");
42+
43+
refreshFonts();
44+
}
45+
46+
CFontFinder::~CFontFinder() {
47+
FcFini();
48+
}
49+
50+
void CFontFinder::refreshFonts() {
51+
if (!m_valid)
52+
return;
53+
54+
m_entries.clear();
55+
m_entriesGeneric.clear();
56+
57+
FcPattern* pattern = FcPatternCreate();
58+
FcObjectSet* objectSet = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FILE, nullptr);
59+
FcFontSet* fontSet = FcFontList(nullptr, pattern, objectSet);
60+
61+
if (fontSet) {
62+
for (int i = 0; i < fontSet->nfont; i++) {
63+
FcPattern* font = fontSet->fonts[i];
64+
FcChar8 * family = nullptr, *style = nullptr;
65+
66+
if (FcPatternGetString(font, FC_FAMILY, 0, &family) != FcResultMatch || FcPatternGetString(font, FC_STYLE, 0, &style) != FcResultMatch)
67+
continue;
68+
69+
if (!family || !style)
70+
continue;
71+
72+
auto e = m_entries.emplace_back(makeShared<CFontEntry>());
73+
e->m_font = std::format("{} {}", (char*)family, (char*)style);
74+
e->m_fuzzable = e->m_font;
75+
std::ranges::transform(e->m_fuzzable, e->m_fuzzable.begin(), ::tolower);
76+
m_entriesGeneric.emplace_back(std::move(e));
77+
}
78+
}
79+
80+
FcFontSetDestroy(fontSet);
81+
FcObjectSetDestroy(objectSet);
82+
FcPatternDestroy(pattern);
83+
}
84+
85+
std::vector<SFinderResult> CFontFinder::getResultsForQuery(const std::string& query) {
86+
std::vector<SFinderResult> results;
87+
88+
std::vector<SP<IFinderResult>> fuzzed;
89+
if (!query.empty())
90+
fuzzed = Fuzzy::getNResults(m_entriesGeneric, query, MAX_RESULTS_PER_FINDER);
91+
else
92+
fuzzed = std::vector<SP<IFinderResult>>{m_entriesGeneric.begin(), m_entriesGeneric.begin() + std::min(m_entriesGeneric.size(), MAX_RESULTS_PER_FINDER)};
93+
94+
results.reserve(fuzzed.size());
95+
96+
for (const auto& f : fuzzed) {
97+
const auto p = reinterpretPointerCast<CFontEntry>(f);
98+
if (!p)
99+
continue;
100+
results.emplace_back(SFinderResult{
101+
.label = p->m_font,
102+
.icon = "",
103+
.result = p,
104+
.overrideFont = p->m_font,
105+
});
106+
}
107+
108+
return results;
109+
}

src/finders/font/FontFinder.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "../IFinder.hpp"
4+
5+
class CFontEntry;
6+
7+
class CFontFinder : public IFinder {
8+
public:
9+
CFontFinder();
10+
virtual ~CFontFinder();
11+
12+
virtual std::vector<SFinderResult> getResultsForQuery(const std::string& query);
13+
14+
private:
15+
std::vector<SP<CFontEntry>> m_entries;
16+
std::vector<SP<IFinderResult>> m_entriesGeneric;
17+
18+
void refreshFonts();
19+
20+
bool m_valid = false;
21+
};
22+
23+
inline UP<CFontFinder> g_fontFinder;

src/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "finders/unicode/UnicodeFinder.hpp"
55
#include "finders/math/MathFinder.hpp"
66
#include "finders/ipc/IPCFinder.hpp"
7+
#include "finders/font/FontFinder.hpp"
78
#include "socket/ClientSocket.hpp"
89
#include "socket/ServerSocket.hpp"
910
#include "query/QueryProcessor.hpp"
@@ -105,11 +106,13 @@ int main(int argc, char** argv, char** envp) {
105106
g_unicodeFinder = makeUnique<CUnicodeFinder>();
106107
g_mathFinder = makeUnique<CMathFinder>();
107108
g_ipcFinder = makeUnique<CIPCFinder>();
109+
g_fontFinder = makeUnique<CFontFinder>();
108110

109111
g_desktopFinder->init();
110112
g_unicodeFinder->init();
111113
g_mathFinder->init();
112114
g_ipcFinder->init();
115+
g_fontFinder->init();
113116

114117
socket.reset();
115118

src/query/QueryProcessor.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "../finders/desktop/DesktopFinder.hpp"
66
#include "../finders/unicode/UnicodeFinder.hpp"
77
#include "../finders/math/MathFinder.hpp"
8+
#include "../finders/font/FontFinder.hpp"
89

910
#include <hyprutils/utils/ScopeGuard.hpp>
1011

@@ -26,13 +27,16 @@ static std::pair<WP<IFinder>, bool> finderForPrefix(const char x) {
2627
static auto PDESKTOPPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:desktop_prefix");
2728
static auto PUNICODEPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:unicode_prefix");
2829
static auto PMATHPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:math_prefix");
30+
static auto PFONTPREFIX = Hyprlang::CSimpleConfigValue<Hyprlang::STRING>(g_configManager->m_config.get(), "finders:font_prefix");
2931

3032
if (x == (*PDESKTOPPREFIX)[0])
3133
return {g_desktopFinder, true};
3234
if (x == (*PUNICODEPREFIX)[0])
3335
return {g_unicodeFinder, true};
3436
if (x == (*PMATHPREFIX)[0])
3537
return {g_mathFinder, true};
38+
if (x == (*PFONTPREFIX)[0])
39+
return {g_fontFinder, true};
3640
return {finderForName(*PDEFAULTFINDER), false};
3741
}
3842

src/ui/ResultButton.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void CResultButton::setActive(bool active) {
6363
->commence();
6464
}
6565

66-
void CResultButton::setLabel(const std::string& x, const std::string& icon) {
66+
void CResultButton::setLabel(const std::string& x, const std::string& icon, const std::string& font) {
6767

6868
if (const auto FONT_SIZE = Hyprtoolkit::CFontSize{Hyprtoolkit::CFontSize::HT_FONT_TEXT}.ptSize(); FONT_SIZE != m_lastFontSize)
6969
updatedFontSize();
@@ -88,7 +88,7 @@ void CResultButton::setLabel(const std::string& x, const std::string& icon) {
8888
if (x != m_lastLabel) {
8989
m_lastLabel = x;
9090

91-
m_label->rebuild()->text(std::string{x})->commence();
91+
m_label->rebuild()->text(std::string{x})->fontFamily(std::string{font})->commence();
9292
}
9393
}
9494

0 commit comments

Comments
 (0)