csgo-vk-fix: allow more configs

This commit is contained in:
Vaxry 2025-07-30 18:51:22 +02:00
parent 14f9a44479
commit bf310cda4a
No known key found for this signature in database
GPG Key ID: 665806380871D640
2 changed files with 83 additions and 28 deletions

View File

@ -10,6 +10,8 @@ Other resolutions (especially not 16:9) are wonky.
With this plugin, you aren't anymore.
This is also useful for when you are scaling and want to force any game to a custom resolution.
CS2 launch options:
```
-vulkan -window -w <RESX> -h <RESY> -vulkan
@ -19,14 +21,12 @@ example plugin config:
```
plugin {
csgo-vulkan-fix {
res_w = 1680
res_h = 1050
# NOT a regex! This is a string and has to exactly match initial_class
class = cs2
# Whether to fix the mouse position. A select few apps might be wonky with this.
fix_mouse = true
# Add apps with vkfix-app = initialClass, width, height
vkfix-app = cs2, 1650, 1050
vkfix-app = myapp, 1920, 1080
}
}
```

View File

@ -11,6 +11,9 @@
#include "globals.hpp"
#include <hyprutils/string/ConstVarList.hpp>
using namespace Hyprutils::String;
// Methods
inline CFunctionHook* g_pMouseMotionHook = nullptr;
inline CFunctionHook* g_pSurfaceSizeHook = nullptr;
@ -24,28 +27,39 @@ APICALL EXPORT std::string PLUGIN_API_VERSION() {
return HYPRLAND_API_VERSION;
}
struct SAppConfig {
std::string szClass;
Vector2D res;
};
std::vector<SAppConfig> g_appConfigs;
static const SAppConfig* getAppConfig(const std::string& appClass) {
for (const auto& ac : g_appConfigs) {
if (ac.szClass != appClass)
continue;
return &ac;
}
return nullptr;
}
void hkNotifyMotion(CSeatManager* thisptr, uint32_t time_msec, const Vector2D& local) {
static auto* const RESX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->getDataStaticPtr();
static auto* const RESY = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->getDataStaticPtr();
static auto* const PCLASS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->getDataStaticPtr();
static auto* const PFIX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:fix_mouse")->getDataStaticPtr();
static auto* const PFIX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:fix_mouse")->getDataStaticPtr();
Vector2D newCoords = local;
if (**PFIX && !g_pCompositor->m_lastWindow.expired() && g_pCompositor->m_lastWindow->m_initialClass == *PCLASS && g_pCompositor->m_lastMonitor) {
const auto CONFIG = g_pCompositor->m_lastWindow && g_pCompositor->m_lastMonitor ? getAppConfig(g_pCompositor->m_lastWindow->m_initialClass) : nullptr;
if (**PFIX && CONFIG) {
// fix the coords
newCoords.x *= (**RESX / g_pCompositor->m_lastMonitor->m_size.x) / g_pCompositor->m_lastWindow->m_X11SurfaceScaledBy;
newCoords.y *= (**RESY / g_pCompositor->m_lastMonitor->m_size.y) / g_pCompositor->m_lastWindow->m_X11SurfaceScaledBy;
newCoords.x *= (CONFIG->res.x / g_pCompositor->m_lastMonitor->m_size.x) / g_pCompositor->m_lastWindow->m_X11SurfaceScaledBy;
newCoords.y *= (CONFIG->res.y / g_pCompositor->m_lastMonitor->m_size.y) / g_pCompositor->m_lastWindow->m_X11SurfaceScaledBy;
}
(*(origMotion)g_pMouseMotionHook->m_original)(thisptr, time_msec, newCoords);
}
void hkSetWindowSize(CXWaylandSurface* surface, const CBox& box) {
static auto* const RESX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->getDataStaticPtr();
static auto* const RESY = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->getDataStaticPtr();
static auto* const PCLASS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->getDataStaticPtr();
if (!surface) {
(*(origSurfaceSize)g_pSurfaceSizeHook->m_original)(surface, box);
return;
@ -56,9 +70,14 @@ void hkSetWindowSize(CXWaylandSurface* surface, const CBox& box) {
CBox newBox = box;
if (PWINDOW && PWINDOW->m_initialClass == *PCLASS) {
newBox.w = **RESX;
newBox.h = **RESY;
if (!PWINDOW) {
(*(origSurfaceSize)g_pSurfaceSizeHook->m_original)(surface, newBox);
return;
}
if (const auto CONFIG = getAppConfig(PWINDOW->m_initialClass); CONFIG) {
newBox.w = CONFIG->res.x;
newBox.h = CONFIG->res.y;
CWLSurface::fromResource(SURF)->m_fillIgnoreSmall = true;
}
@ -67,16 +86,18 @@ void hkSetWindowSize(CXWaylandSurface* surface, const CBox& box) {
}
CRegion hkWLSurfaceDamage(CWLSurface* thisptr) {
const auto RG = (*(origWLSurfaceDamage)g_pWLSurfaceDamageHook->m_original)(thisptr);
const auto RG = (*(origWLSurfaceDamage)g_pWLSurfaceDamageHook->m_original)(thisptr);
static auto* const PCLASS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->getDataStaticPtr();
if (thisptr->exists() && thisptr->getWindow()) {
const auto CONFIG = getAppConfig(thisptr->getWindow()->m_initialClass);
if (thisptr->exists() && thisptr->getWindow() && thisptr->getWindow()->m_initialClass == *PCLASS) {
const auto PMONITOR = thisptr->getWindow()->m_monitor.lock();
if (PMONITOR)
g_pHyprRenderer->damageMonitor(PMONITOR);
else
g_pHyprRenderer->damageWindow(thisptr->getWindow());
if (CONFIG) {
const auto PMONITOR = thisptr->getWindow()->m_monitor.lock();
if (PMONITOR)
g_pHyprRenderer->damageMonitor(PMONITOR);
else
g_pHyprRenderer->damageWindow(thisptr->getWindow());
}
}
return RG;
@ -98,6 +119,40 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:fix_mouse", Hyprlang::INT{1});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class", Hyprlang::STRING{"cs2"});
static auto P = HyprlandAPI::registerCallbackDynamic(PHANDLE, "preConfigReload", [&](void* self, SCallbackInfo& info, std::any data) {
g_appConfigs.clear();
static auto* const RESX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->getDataStaticPtr();
static auto* const RESY = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->getDataStaticPtr();
static auto* const PCLASS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->getDataStaticPtr();
g_appConfigs.emplace_back(SAppConfig{.szClass = *PCLASS, .res = Vector2D{(int)**RESX, (int)**RESY}});
});
HyprlandAPI::addConfigKeyword(PHANDLE, "vkfix-app", [](const char* l, const char* r) -> Hyprlang::CParseResult {
const std::string str = r;
CConstVarList data(str, 0, ',', true);
Hyprlang::CParseResult result;
if (data.size() != 3) {
result.setError("vkfix-app requires 3 params");
return result;
}
try {
SAppConfig config;
config.szClass = data[0];
config.res = Vector2D{std::stoi(std::string{data[1]}), std::stoi(std::string{data[2]})};
g_appConfigs.emplace_back(std::move(config));
} catch (std::exception& e) {
result.setError("failed to parse line");
return result;
}
return result;
}, Hyprlang::SHandlerOptions{});
auto FNS = HyprlandAPI::findFunctionsByName(PHANDLE, "sendPointerMotion");
for (auto& fn : FNS) {
if (!fn.demangled.contains("CSeatManager"))