diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2023-01-20 19:44:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-20 19:44:30 +0100 |
| commit | 60b880d9312574c3115d973fd532f2e15d1eafff (patch) | |
| tree | b88cad7335c97c876f069f9d378589210332a95f /src/protocols | |
| parent | cee7bc6e742aa02675701f772f5e7ebfb56f11ab (diff) | |
wp-fractional-scaling-v1 impl (#1373)
* Initial fractional scaling impl
* apply UV after geom calcs
* fix scaling -> scale
* meson: add fractional scale proto
Co-authored-by: Mihai Fufezan <fufexan@protonmail.com>
Diffstat (limited to 'src/protocols')
| -rw-r--r-- | src/protocols/FractionalScale.cpp | 102 | ||||
| -rw-r--r-- | src/protocols/FractionalScale.hpp | 38 | ||||
| -rw-r--r-- | src/protocols/ToplevelExport.cpp | 8 |
3 files changed, 144 insertions, 4 deletions
diff --git a/src/protocols/FractionalScale.cpp b/src/protocols/FractionalScale.cpp new file mode 100644 index 00000000..40d838d1 --- /dev/null +++ b/src/protocols/FractionalScale.cpp @@ -0,0 +1,102 @@ +#include "FractionalScale.hpp" + +#include "../Compositor.hpp" + +#define FRACTIONAL_SCALE_VERSION 1 + +static void bindManagerInt(wl_client* client, void* data, uint32_t version, uint32_t id) { + g_pProtocolManager->m_pFractionalScaleProtocolManager->bindManager(client, data, version, id); +} + +static void handleDisplayDestroy(struct wl_listener* listener, void* data) { + g_pProtocolManager->m_pFractionalScaleProtocolManager->displayDestroy(); +} + +void CFractionalScaleProtocolManager::displayDestroy() { + wl_global_destroy(m_pGlobal); +} + +static void handleDestroy(wl_client* client, wl_resource* resource) { + wl_resource_destroy(resource); +} + +void handleGetFractionalScale(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* surface) { + g_pProtocolManager->m_pFractionalScaleProtocolManager->getFractionalScale(client, resource, id, surface); +} + +CFractionalScaleProtocolManager::CFractionalScaleProtocolManager() { + m_pGlobal = wl_global_create(g_pCompositor->m_sWLDisplay, &wp_fractional_scale_manager_v1_interface, FRACTIONAL_SCALE_VERSION, this, bindManagerInt); + + if (!m_pGlobal) { + Debug::log(ERR, "FractionalScaleManager could not start! Fractional scaling will not work!"); + return; + } + + m_liDisplayDestroy.notify = handleDisplayDestroy; + wl_display_add_destroy_listener(g_pCompositor->m_sWLDisplay, &m_liDisplayDestroy); + + Debug::log(LOG, "FractionalScaleManager started successfully!"); +} + +static const struct wp_fractional_scale_manager_v1_interface fractionalScaleManagerImpl = { + .destroy = handleDestroy, + .get_fractional_scale = handleGetFractionalScale, +}; + +void CFractionalScaleProtocolManager::bindManager(wl_client* client, void* data, uint32_t version, uint32_t id) { + const auto RESOURCE = wl_resource_create(client, &wp_fractional_scale_manager_v1_interface, version, id); + wl_resource_set_implementation(RESOURCE, &fractionalScaleManagerImpl, this, nullptr); + + Debug::log(LOG, "FractionalScaleManager bound successfully!"); +} + +void handleDestroyScaleAddon(wl_client* client, wl_resource* resource); +// + +static const struct wp_fractional_scale_v1_interface fractionalScaleAddonImpl { .destroy = handleDestroyScaleAddon }; + +// +SFractionalScaleAddon* addonFromResource(wl_resource* resource) { + ASSERT(wl_resource_instance_of(resource, &wp_fractional_scale_v1_interface, &fractionalScaleAddonImpl)); + return (SFractionalScaleAddon*)wl_resource_get_user_data(resource); +} + +void handleDestroyScaleAddon(wl_client* client, wl_resource* resource) { + g_pProtocolManager->m_pFractionalScaleProtocolManager->removeAddon(addonFromResource(resource)->pSurface); + wl_resource_destroy(resource); +} + +void CFractionalScaleProtocolManager::getFractionalScale(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* surface) { + const auto PSURFACE = wlr_surface_from_resource(surface); + const auto PADDON = getAddonForSurface(PSURFACE); + + PADDON->pResource = wl_resource_create(client, &wp_fractional_scale_v1_interface, wl_resource_get_version(resource), id); + + wp_fractional_scale_v1_send_preferred_scale(PADDON->pResource, (uint32_t)std::round(PADDON->preferredScale * 120.0)); +} + +SFractionalScaleAddon* CFractionalScaleProtocolManager::getAddonForSurface(wlr_surface* surface) { + const auto IT = std::find_if(m_vFractionalScaleAddons.begin(), m_vFractionalScaleAddons.end(), [&](const auto& other) { return other->pSurface == surface; }); + + if (IT != m_vFractionalScaleAddons.end()) + return IT->get(); + + m_vFractionalScaleAddons.emplace_back(std::make_unique<SFractionalScaleAddon>()); + + m_vFractionalScaleAddons.back()->pSurface = surface; + + return m_vFractionalScaleAddons.back().get(); +} + +void CFractionalScaleProtocolManager::setPreferredScaleForSurface(wlr_surface* surface, double scale) { + const auto PADDON = getAddonForSurface(surface); + + PADDON->preferredScale = scale; + + if (PADDON->pResource) + wp_fractional_scale_v1_send_preferred_scale(PADDON->pResource, (uint32_t)std::round(scale * 120.0)); +} + +void CFractionalScaleProtocolManager::removeAddon(wlr_surface* surface) { + std::erase_if(m_vFractionalScaleAddons, [&](const auto& other) { return other->pSurface == surface; }); +}
\ No newline at end of file diff --git a/src/protocols/FractionalScale.hpp b/src/protocols/FractionalScale.hpp new file mode 100644 index 00000000..71b2c858 --- /dev/null +++ b/src/protocols/FractionalScale.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "../defines.hpp" +#include "fractional-scale-v1-protocol.h" + +#include <vector> +#include <algorithm> + +struct SFractionalScaleAddon { + wlr_surface* pSurface = nullptr; + double preferredScale = 1.0; + wl_resource* pResource = nullptr; +}; + +class CFractionalScaleProtocolManager { + public: + CFractionalScaleProtocolManager(); + + void bindManager(wl_client* client, void* data, uint32_t version, uint32_t id); + + void displayDestroy(); + + void setPreferredScaleForSurface(wlr_surface*, double); + + void removeAddon(wlr_surface*); + + // handlers + + void getFractionalScale(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* surface); + + private: + SFractionalScaleAddon* getAddonForSurface(wlr_surface*); + + std::vector<std::unique_ptr<SFractionalScaleAddon>> m_vFractionalScaleAddons; + + wl_global* m_pGlobal = nullptr; + wl_listener m_liDisplayDestroy; +};
\ No newline at end of file diff --git a/src/protocols/ToplevelExport.cpp b/src/protocols/ToplevelExport.cpp index 309a6856..98afb154 100644 --- a/src/protocols/ToplevelExport.cpp +++ b/src/protocols/ToplevelExport.cpp @@ -53,7 +53,7 @@ void handleCaptureToplevelWithWlr(wl_client* client, wl_resource* resource, uint g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromZWLRHandle(handle)); } -void handleDestroy(wl_client* client, wl_resource* resource) { +static void handleDestroy(wl_client* client, wl_resource* resource) { wl_resource_destroy(resource); } @@ -74,8 +74,8 @@ static const struct hyprland_toplevel_export_manager_v1_interface toplevelExport static const struct hyprland_toplevel_export_frame_v1_interface toplevelFrameImpl = {.copy = handleCopyFrame, .destroy = handleDestroyFrame}; SToplevelClient* clientFromResource(wl_resource* resource) { - ASSERT(wl_resource_instance_of(resource, &hyprland_toplevel_export_manager_v1_interface, &toplevelExportManagerImpl)); - return (SToplevelClient*)wl_resource_get_user_data(resource); + ASSERT(wl_resource_instance_of(resource, &hyprland_toplevel_export_manager_v1_interface, &toplevelExportManagerImpl)); + return (SToplevelClient*)wl_resource_get_user_data(resource); } SToplevelFrame* frameFromResource(wl_resource* resource) { @@ -95,7 +95,7 @@ void CToplevelExportProtocolManager::removeClient(SToplevelClient* client, bool m_lClients.remove(*client); // TODO: this doesn't get cleaned up after sharing app exits??? } -void handleManagerResourceDestroy(wl_resource* resource) { +static void handleManagerResourceDestroy(wl_resource* resource) { const auto PCLIENT = clientFromResource(resource); g_pProtocolManager->m_pToplevelExportProtocolManager->removeClient(PCLIENT, true); |
