-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathmain.cpp
More file actions
143 lines (110 loc) · 5.24 KB
/
Copy pathmain.cpp
File metadata and controls
143 lines (110 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#define WLR_USE_UNSTABLE
#include <hyprland/src/Compositor.hpp>
#include <hyprland/src/config/ConfigManager.hpp>
#include <hyprland/src/desktop/DesktopTypes.hpp>
#include <hyprland/src/render/Renderer.hpp>
#include <hyprland/src/event/EventBus.hpp>
#include "Dispatchers.hpp"
#include "globals.hpp"
#include "Overview.hpp"
#include "PluginConfig.hpp"
#include <stdexcept>
#include <string>
// Plugin version, baked in at build time from the VERSION file (see
// scripts/version.sh). The fallback only applies to ad-hoc builds that bypass
// the build system; real builds always define this.
#ifndef HYPREXPO_VERSION
#define HYPREXPO_VERSION "v0.0.0-dev"
#endif
// Methods
inline CFunctionHook* g_pRenderWorkspaceHook = nullptr;
inline CFunctionHook* g_pAddDamageHookA = nullptr;
inline CFunctionHook* g_pAddDamageHookB = nullptr;
typedef void (*origRenderWorkspace)(void*, PHLMONITOR, PHLWORKSPACE, timespec*, const CBox&);
typedef void (*origAddDamageA)(void*, const CBox&);
typedef void (*origAddDamageB)(void*, const pixman_region32_t*);
static void hkRenderWorkspace(void* thisptr, PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) {
if (!g_pOverview || isRenderingOverview() || g_pOverview->blockOverviewRendering || !g_pOverview->shouldRenderOverviewForMonitor(pMonitor))
((origRenderWorkspace)(g_pRenderWorkspaceHook->m_original))(thisptr, pMonitor, pWorkspace, now, geometry);
else
g_pOverview->render();
}
static void hkAddDamageA(void* thisptr, const CBox& box) {
const auto PMONITOR = (CMonitor*)thisptr;
if (!g_pOverview || !g_pOverview->shouldRenderOverviewForMonitor(PMONITOR->m_self.lock()) || g_pOverview->blockDamageReporting) {
((origAddDamageA)g_pAddDamageHookA->m_original)(thisptr, box);
return;
}
g_pOverview->onDamageReported();
}
static void hkAddDamageB(void* thisptr, const pixman_region32_t* rg) {
const auto PMONITOR = (CMonitor*)thisptr;
if (!g_pOverview || !g_pOverview->shouldRenderOverviewForMonitor(PMONITOR->m_self.lock()) || g_pOverview->blockDamageReporting) {
((origAddDamageB)g_pAddDamageHookB->m_original)(thisptr, rg);
return;
}
g_pOverview->onDamageReported();
}
static void failNotif(const std::string& reason) {
HyprlandAPI::addNotification(PHANDLE, "[hyprexpo] Failure in initialization: " + reason, CHyprColor{1.0, 0.2, 0.2, 1.0}, 5000);
}
APICALL EXPORT std::string PLUGIN_API_VERSION() {
return HYPRLAND_API_VERSION;
}
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
PHANDLE = handle;
const std::string HASH = __hyprland_api_get_hash();
if (HASH != __hyprland_api_get_client_hash()) {
failNotif("Version mismatch (headers ver is not equal to running hyprland ver)");
throw std::runtime_error("[he] Version mismatch");
}
auto FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "renderWorkspace");
if (FNS.empty()) {
failNotif("no fns for hook renderWorkspace");
throw std::runtime_error("[he] No fns for hook renderWorkspace");
}
g_pRenderWorkspaceHook = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkRenderWorkspace);
FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "addDamageEPK15pixman_region32");
if (FNS.empty()) {
failNotif("no fns for hook addDamageEPK15pixman_region32");
throw std::runtime_error("[he] No fns for hook addDamageEPK15pixman_region32");
}
g_pAddDamageHookB = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkAddDamageB);
FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "_ZN8CMonitor9addDamageERKN9Hyprutils4Math4CBoxE");
if (FNS.empty()) {
failNotif("no fns for hook _ZN8CMonitor9addDamageERKN9Hyprutils4Math4CBoxE");
throw std::runtime_error("[he] No fns for hook _ZN8CMonitor9addDamageERKN9Hyprutils4Math4CBoxE");
}
g_pAddDamageHookA = HyprlandAPI::createFunctionHook(PHANDLE, FNS[0].address, (void*)hkAddDamageA);
bool success = g_pRenderWorkspaceHook->hook();
success = success && g_pAddDamageHookA->hook();
success = success && g_pAddDamageHookB->hook();
if (!success) {
failNotif("Failed initializing hooks");
throw std::runtime_error("[he] Failed initializing hooks");
}
static auto P = Event::bus()->m_events.render.pre.listen([](PHLMONITOR pMonitor) {
if (!g_pOverview)
return;
g_pOverview->onPreRender();
});
static auto PKEY = Event::bus()->m_events.input.keyboard.key.listen([](IKeyboard::SKeyEvent event, Event::SCallbackInfo& info) {
if (shouldCancelOverview(event)) {
info.cancelled = true;
g_pOverview->close(false);
return;
}
if (shouldSelectWorkspaceFromKey(event))
info.cancelled = true;
});
registerHyprexpoDispatchers();
registerHyprexpoConfigValues();
HyprlandAPI::reloadConfig();
return {"hyprexpo", "hyprexpo+ with keyboard selection, labels, and borders", "sandwich", HYPREXPO_VERSION};
}
APICALL EXPORT void PLUGIN_EXIT() {
g_pOverview.reset();
g_pHyprRenderer->m_renderPass.removeAllOfType("COverviewPassElement");
Config::mgr()->reload(); // we need to reload now to clear all the gestures
resetDispatcherRuntime();
}