Fractional-scale: move to new impl
This commit is contained in:
parent
ea95449402
commit
ea47e8c92a
9 changed files with 126 additions and 118 deletions
|
|
@ -1,118 +1,93 @@
|
|||
#include "FractionalScale.hpp"
|
||||
|
||||
#include "../Compositor.hpp"
|
||||
static void onWlrSurfaceDestroy(void* owner, void* data) {
|
||||
const auto SURF = (wlr_surface*)owner;
|
||||
|
||||
#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);
|
||||
PROTO::fractional->onSurfaceDestroy(SURF);
|
||||
}
|
||||
|
||||
static void handleDisplayDestroy(struct wl_listener* listener, void* data) {
|
||||
g_pProtocolManager->m_pFractionalScaleProtocolManager->displayDestroy();
|
||||
CFractionalScaleProtocol::CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
;
|
||||
}
|
||||
|
||||
void CFractionalScaleProtocolManager::displayDestroy() {
|
||||
wl_global_destroy(m_pGlobal);
|
||||
void CFractionalScaleProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CWpFractionalScaleManagerV1>(client, ver, id)).get();
|
||||
RESOURCE->setOnDestroy([this](CWpFractionalScaleManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
|
||||
|
||||
RESOURCE->setDestroy([this](CWpFractionalScaleManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
|
||||
RESOURCE->setGetFractionalScale(
|
||||
[this](CWpFractionalScaleManagerV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetFractionalScale(pMgr, id, wlr_surface_from_resource(surface)); });
|
||||
}
|
||||
|
||||
static void handleDestroy(wl_client* client, wl_resource* resource) {
|
||||
wl_resource_destroy(resource);
|
||||
void CFractionalScaleProtocol::removeAddon(CFractionalScaleAddon* addon) {
|
||||
m_mAddons.erase(addon->surf());
|
||||
}
|
||||
|
||||
void handleGetFractionalScale(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* surface) {
|
||||
g_pProtocolManager->m_pFractionalScaleProtocolManager->getFractionalScale(client, resource, id, surface);
|
||||
void CFractionalScaleProtocol::onManagerResourceDestroy(wl_resource* res) {
|
||||
std::erase_if(m_vManagers, [res](const auto& other) { return other->resource() == res; });
|
||||
}
|
||||
|
||||
CFractionalScaleProtocolManager::CFractionalScaleProtocolManager() {
|
||||
m_pGlobal = wl_global_create(g_pCompositor->m_sWLDisplay, &wp_fractional_scale_manager_v1_interface, FRACTIONAL_SCALE_VERSION, this, bindManagerInt);
|
||||
void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1* pMgr, uint32_t id, wlr_surface* surface) {
|
||||
const auto PADDON = m_mAddons
|
||||
.emplace(surface,
|
||||
std::make_unique<CFractionalScaleAddon>(
|
||||
std::make_shared<CWpFractionalScaleV1>(wl_resource_get_client(pMgr->resource()), wl_resource_get_version(pMgr->resource()), id), surface))
|
||||
.first->second.get();
|
||||
|
||||
if (!m_pGlobal) {
|
||||
Debug::log(ERR, "FractionalScaleManager could not start! Fractional scaling will not work!");
|
||||
if (!PADDON->good()) {
|
||||
m_mAddons.erase(surface);
|
||||
wl_resource_post_no_memory(pMgr->resource());
|
||||
return;
|
||||
}
|
||||
|
||||
m_liDisplayDestroy.notify = handleDisplayDestroy;
|
||||
wl_display_add_destroy_listener(g_pCompositor->m_sWLDisplay, &m_liDisplayDestroy);
|
||||
PADDON->resource->setOnDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); });
|
||||
PADDON->resource->setDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); });
|
||||
|
||||
Debug::log(LOG, "FractionalScaleManager started successfully!");
|
||||
if (!m_mSurfaceScales.contains(surface))
|
||||
m_mSurfaceScales[surface] = 1.F;
|
||||
|
||||
PADDON->setScale(m_mSurfaceScales[surface]);
|
||||
registerSurface(surface);
|
||||
}
|
||||
|
||||
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 CFractionalScaleProtocol::sendScale(wlr_surface* surf, const float& scale) {
|
||||
m_mSurfaceScales[surf] = scale;
|
||||
if (m_mAddons.contains(surf))
|
||||
m_mAddons[surf]->setScale(scale);
|
||||
registerSurface(surf);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static void handleDestroyScaleAddon(wl_client* client, wl_resource* resource) {
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static void handleAddonDestroy(wl_resource* resource) {
|
||||
const auto PADDON = addonFromResource(resource);
|
||||
if (PADDON->pResource) {
|
||||
wl_resource_set_user_data(PADDON->pResource, nullptr);
|
||||
}
|
||||
|
||||
g_pProtocolManager->m_pFractionalScaleProtocolManager->removeAddon(PADDON->pSurface);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (PADDON->pResource) {
|
||||
wl_resource_post_error(resource, WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS, "Fractional scale exists.");
|
||||
void CFractionalScaleProtocol::registerSurface(wlr_surface* surf) {
|
||||
if (m_mSurfaceDestroyListeners.contains(surf))
|
||||
return;
|
||||
}
|
||||
|
||||
PADDON->pResource = wl_resource_create(client, &wp_fractional_scale_v1_interface, wl_resource_get_version(resource), id);
|
||||
wl_resource_set_implementation(PADDON->pResource, &fractionalScaleAddonImpl, PADDON, handleAddonDestroy);
|
||||
|
||||
wp_fractional_scale_v1_send_preferred_scale(PADDON->pResource, (uint32_t)std::round(PADDON->preferredScale * 120.0));
|
||||
m_mSurfaceDestroyListeners[surf].hyprListener_surfaceDestroy.initCallback(&surf->events.destroy, ::onWlrSurfaceDestroy, surf, "FractionalScale");
|
||||
}
|
||||
|
||||
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 CFractionalScaleProtocol::onSurfaceDestroy(wlr_surface* surf) {
|
||||
m_mSurfaceDestroyListeners.erase(surf);
|
||||
m_mSurfaceScales.erase(surf);
|
||||
if (m_mAddons.contains(surf))
|
||||
m_mAddons[surf]->onSurfaceDestroy();
|
||||
}
|
||||
|
||||
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));
|
||||
CFractionalScaleAddon::CFractionalScaleAddon(SP<CWpFractionalScaleV1> resource_, wlr_surface* surf_) : resource(resource_), surface(surf_) {
|
||||
resource->setDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); });
|
||||
resource->setOnDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); });
|
||||
}
|
||||
|
||||
void CFractionalScaleProtocolManager::removeAddon(wlr_surface* surface) {
|
||||
std::erase_if(m_vFractionalScaleAddons, [&](const auto& other) { return other->pSurface == surface; });
|
||||
void CFractionalScaleAddon::onSurfaceDestroy() {
|
||||
surfaceGone = true;
|
||||
}
|
||||
|
||||
void CFractionalScaleAddon::setScale(const float& scale) {
|
||||
resource->sendPreferredScale(std::round(scale * 120.0));
|
||||
}
|
||||
|
||||
bool CFractionalScaleAddon::good() {
|
||||
return resource->resource();
|
||||
}
|
||||
|
||||
wlr_surface* CFractionalScaleAddon::surf() {
|
||||
return surface;
|
||||
}
|
||||
|
|
@ -1,38 +1,68 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "fractional-scale-v1-protocol.h"
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include "WaylandProtocol.hpp"
|
||||
#include "fractional-scale-v1.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
class CFractionalScaleProtocol;
|
||||
|
||||
struct SFractionalScaleAddon {
|
||||
wlr_surface* pSurface = nullptr;
|
||||
double preferredScale = 1.0;
|
||||
wl_resource* pResource = nullptr;
|
||||
};
|
||||
|
||||
class CFractionalScaleProtocolManager {
|
||||
class CFractionalScaleAddon {
|
||||
public:
|
||||
CFractionalScaleProtocolManager();
|
||||
CFractionalScaleAddon(SP<CWpFractionalScaleV1> resource_, wlr_surface* surf_);
|
||||
|
||||
void bindManager(wl_client* client, void* data, uint32_t version, uint32_t id);
|
||||
void setScale(const float& scale);
|
||||
void onSurfaceDestroy();
|
||||
|
||||
void displayDestroy();
|
||||
bool good();
|
||||
|
||||
void setPreferredScaleForSurface(wlr_surface*, double);
|
||||
wlr_surface* surf();
|
||||
|
||||
void removeAddon(wlr_surface*);
|
||||
bool operator==(const wl_resource* other) const {
|
||||
return other == resource->resource();
|
||||
}
|
||||
|
||||
// handlers
|
||||
|
||||
void getFractionalScale(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* surface);
|
||||
bool operator==(const CFractionalScaleAddon* other) const {
|
||||
return other->resource == resource;
|
||||
}
|
||||
|
||||
private:
|
||||
SFractionalScaleAddon* getAddonForSurface(wlr_surface*);
|
||||
SP<CWpFractionalScaleV1> resource;
|
||||
float scale = 1.F;
|
||||
wlr_surface* surface = nullptr;
|
||||
bool surfaceGone = false;
|
||||
|
||||
std::vector<std::unique_ptr<SFractionalScaleAddon>> m_vFractionalScaleAddons;
|
||||
friend class CFractionalScaleProtocol;
|
||||
};
|
||||
|
||||
wl_global* m_pGlobal = nullptr;
|
||||
wl_listener m_liDisplayDestroy;
|
||||
struct SSurfaceListener {
|
||||
DYNLISTENER(surfaceDestroy);
|
||||
};
|
||||
|
||||
class CFractionalScaleProtocol : public IWaylandProtocol {
|
||||
public:
|
||||
CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name);
|
||||
|
||||
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void onGetFractionalScale(CWpFractionalScaleManagerV1* pMgr, uint32_t id, wlr_surface* surface);
|
||||
|
||||
void sendScale(wlr_surface* surf, const float& scale);
|
||||
void onSurfaceDestroy(wlr_surface* surf);
|
||||
|
||||
void removeAddon(CFractionalScaleAddon*);
|
||||
|
||||
private:
|
||||
void registerSurface(wlr_surface*);
|
||||
|
||||
std::unordered_map<wlr_surface*, SSurfaceListener> m_mSurfaceDestroyListeners;
|
||||
|
||||
std::unordered_map<wlr_surface*, float> m_mSurfaceScales;
|
||||
std::unordered_map<wlr_surface*, UP<CFractionalScaleAddon>> m_mAddons;
|
||||
std::vector<UP<CWpFractionalScaleManagerV1>> m_vManagers;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
inline UP<CFractionalScaleProtocol> fractional;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue