diff --git a/csgo-vulkan-fix/README.md b/csgo-vulkan-fix/README.md index 7d4f73a..4f6db5f 100644 --- a/csgo-vulkan-fix/README.md +++ b/csgo-vulkan-fix/README.md @@ -1,6 +1,9 @@ # csgo-vulkan-fix -Updated for CS2. +Originally meant for csgo / cs2, but can work with any app, really. + +csgo-vulkan-fix is a way to force apps to a fake resolution without +them realizing it. If you want to play CS2, you're locked to your native res. Other resolutions (especially not 16:9) are wonky. @@ -18,6 +21,9 @@ 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 } } ``` diff --git a/csgo-vulkan-fix/main.cpp b/csgo-vulkan-fix/main.cpp index a3aec34..11bd435 100644 --- a/csgo-vulkan-fix/main.cpp +++ b/csgo-vulkan-fix/main.cpp @@ -16,43 +16,29 @@ typedef void (*origMotion)(wlr_seat*, uint32_t, double, double); typedef void (*origSurfaceSize)(wlr_xwayland_surface*, int16_t, int16_t, uint16_t, uint16_t); typedef void (*origSurfaceDamage)(wlr_surface*, pixman_region32_t*); -// store the surface for csgo. May be invalid, only compare against -inline wlr_surface* pCSGOSurface = nullptr; -inline wlr_xwayland_surface* pCSGOXWSurface = nullptr; -inline int csgoMonitor = 0; - // Do NOT change this function. APICALL EXPORT std::string PLUGIN_API_VERSION() { return HYPRLAND_API_VERSION; } -void onNewWindow(void* self, std::any data) { - // data is guaranteed - auto* const PWINDOW = std::any_cast(data); - - if (g_pXWaylandManager->getAppIDClass(PWINDOW) == "cs2") { - pCSGOSurface = g_pXWaylandManager->getWindowSurface(PWINDOW); - pCSGOXWSurface = PWINDOW->m_uSurface.xwayland; - csgoMonitor = PWINDOW->m_iMonitorID; - } -} - void hkNotifyMotion(wlr_seat* wlr_seat, uint32_t time_msec, double sx, double sy) { - static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue; - static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue; + static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue; + static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue; + static auto* const PCLASS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->strValue; - if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_szInitialClass == "cs2" && g_pCompositor->m_pLastMonitor) { + if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_szInitialClass == *PCLASS && g_pCompositor->m_pLastMonitor) { // fix the coords - sx *= *RESX / g_pCompositor->m_pLastMonitor->vecSize.x; - sy *= *RESY / g_pCompositor->m_pLastMonitor->vecSize.y; + sx *= (*RESX / g_pCompositor->m_pLastMonitor->vecSize.x) / g_pCompositor->m_pLastWindow->m_fX11SurfaceScaledBy; + sy *= (*RESY / g_pCompositor->m_pLastMonitor->vecSize.y) / g_pCompositor->m_pLastWindow->m_fX11SurfaceScaledBy; } (*(origMotion)g_pMouseMotionHook->m_pOriginal)(wlr_seat, time_msec, sx, sy); } void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16_t width, uint16_t height) { - static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue; - static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue; + static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue; + static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue; + static auto* const PCLASS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->strValue; if (!surface) { (*(origSurfaceSize)g_pSurfaceSizeHook->m_pOriginal)(surface, x, y, width, height); @@ -62,7 +48,7 @@ void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16 const auto SURF = surface->surface; const auto PWINDOW = g_pCompositor->getWindowFromSurface(SURF); - if (PWINDOW && PWINDOW->m_szInitialClass == "cs2") { + if (PWINDOW && PWINDOW->m_szInitialClass == *PCLASS) { width = *RESX; height = *RESY; @@ -75,12 +61,12 @@ void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16 void hkSurfaceDamage(wlr_surface* surface, pixman_region32_t* damage) { (*(origSurfaceDamage)g_pSurfaceDamageHook->m_pOriginal)(surface, damage); - if (surface == pCSGOSurface) { - const auto PMONITOR = g_pCompositor->getMonitorFromID(csgoMonitor); + static auto* const PCLASS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->strValue; - if (PMONITOR) - pixman_region32_union_rect(damage, damage, 0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y); - } + const auto SURF = CWLSurface::surfaceFromWlr(surface); + + if (SURF && SURF->exists() && SURF->m_pOwner && SURF->m_pOwner->m_szInitialClass == *PCLASS) + g_pHyprRenderer->damageWindow(SURF->m_pOwner); } APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { @@ -88,6 +74,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w", SConfigValue{.intValue = 1680}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h", SConfigValue{.intValue = 1050}); + HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class", SConfigValue{.strValue = "cs2"}); g_pMouseMotionHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_seat_pointer_notify_motion, (void*)&hkNotifyMotion); g_pSurfaceSizeHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_xwayland_surface_configure, (void*)&hkSetWindowSize); @@ -96,16 +83,14 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { hkResult = hkResult && g_pSurfaceSizeHook->hook(); hkResult = hkResult && g_pSurfaceDamageHook->hook(); - HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); }); - if (hkResult) - HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Initialized successfully! (CS2 version)", CColor{0.2, 1.0, 0.2, 1.0}, 5000); + HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Initialized successfully! (Anything version)", CColor{0.2, 1.0, 0.2, 1.0}, 5000); else { HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Failure in initialization (hook failed)!", CColor{1.0, 0.2, 0.2, 1.0}, 5000); throw std::runtime_error("[csgo-vk-fix] Hooks failed"); } - return {"csgo-vulkan-fix", "A plugin to fix incorrect mouse offsets on csgo in Vulkan", "Vaxry", "1.1"}; + return {"csgo-vulkan-fix", "A plugin to force specific apps to a fake resolution", "Vaxry", "1.2"}; } APICALL EXPORT void PLUGIN_EXIT() {