mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-02 07:45:58 +01:00
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>
This commit is contained in:
parent
cee7bc6e74
commit
60b880d931
12 changed files with 210 additions and 56 deletions
|
@ -130,4 +130,5 @@ target_link_libraries(Hyprland
|
||||||
${CMAKE_SOURCE_DIR}/ext-workspace-unstable-v1-protocol.o
|
${CMAKE_SOURCE_DIR}/ext-workspace-unstable-v1-protocol.o
|
||||||
${CMAKE_SOURCE_DIR}/wlr-foreign-toplevel-management-unstable-v1-protocol.o
|
${CMAKE_SOURCE_DIR}/wlr-foreign-toplevel-management-unstable-v1-protocol.o
|
||||||
${CMAKE_SOURCE_DIR}/hyprland-toplevel-export-v1-protocol.o
|
${CMAKE_SOURCE_DIR}/hyprland-toplevel-export-v1-protocol.o
|
||||||
|
${CMAKE_SOURCE_DIR}/fractional-scale-v1-protocol.o
|
||||||
)
|
)
|
||||||
|
|
12
Makefile
12
Makefile
|
@ -121,6 +121,16 @@ wlr-foreign-toplevel-management-unstable-v1-protocol.c:
|
||||||
|
|
||||||
wlr-foreign-toplevel-management-unstable-v1-protocol.o: wlr-foreign-toplevel-management-unstable-v1-protocol.h
|
wlr-foreign-toplevel-management-unstable-v1-protocol.o: wlr-foreign-toplevel-management-unstable-v1-protocol.h
|
||||||
|
|
||||||
|
fractional-scale-v1-protocol.h:
|
||||||
|
$(WAYLAND_SCANNER) server-header \
|
||||||
|
$(WAYLAND_PROTOCOLS)/staging/fractional-scale/fractional-scale-v1.xml $@
|
||||||
|
|
||||||
|
fractional-scale-v1-protocol.c:
|
||||||
|
$(WAYLAND_SCANNER) private-code \
|
||||||
|
$(WAYLAND_PROTOCOLS)/staging/fractional-scale/fractional-scale-v1.xml $@
|
||||||
|
|
||||||
|
fractional-scale-v1-protocol.o: fractional-scale-v1-protocol.h
|
||||||
|
|
||||||
legacyrenderer:
|
legacyrenderer:
|
||||||
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DLEGACY_RENDERER:STRING=true -H./ -B./build -G Ninja
|
||||||
cmake --build ./build --config Release --target all -j$(shell nproc)
|
cmake --build ./build --config Release --target all -j$(shell nproc)
|
||||||
|
@ -184,7 +194,7 @@ uninstall:
|
||||||
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
rm -f ${PREFIX}/share/man/man1/Hyprland.1
|
||||||
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
rm -f ${PREFIX}/share/man/man1/hyprctl.1
|
||||||
|
|
||||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o linux-dmabuf-unstable-v1-protocol.o hyprland-toplevel-export-v1-protocol.o wlr-foreign-toplevel-management-unstable-v1-protocol.o
|
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o wlr-output-power-management-unstable-v1-protocol.o linux-dmabuf-unstable-v1-protocol.o hyprland-toplevel-export-v1-protocol.o wlr-foreign-toplevel-management-unstable-v1-protocol.o fractional-scale-v1-protocol.o
|
||||||
|
|
||||||
fixwlr:
|
fixwlr:
|
||||||
sed -i -E 's/(soversion = 12)([^032]|$$)/soversion = 12032/g' subprojects/wlroots/meson.build
|
sed -i -E 's/(soversion = 12)([^032]|$$)/soversion = 12032/g' subprojects/wlroots/meson.build
|
||||||
|
|
|
@ -21,6 +21,7 @@ wayland_scanner = find_program(
|
||||||
protocols = [
|
protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||||
|
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
['wlr-output-power-management-unstable-v1.xml'],
|
['wlr-output-power-management-unstable-v1.xml'],
|
||||||
|
|
|
@ -219,6 +219,9 @@ void CWindow::moveToWorkspace(int workspaceID) {
|
||||||
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); PWORKSPACE) {
|
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); PWORKSPACE) {
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())});
|
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", getFormat("%x,%s", this, PWORKSPACE->m_szName.c_str())});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); PMONITOR)
|
||||||
|
g_pProtocolManager->m_pFractionalScaleProtocolManager->setPreferredScaleForSurface(g_pXWaylandManager->getWindowSurface(this), PMONITOR->scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -564,6 +564,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
|
|
||||||
// recalc the values for this window
|
// recalc the values for this window
|
||||||
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
|
g_pCompositor->updateWindowAnimatedDecorationValues(PWINDOW);
|
||||||
|
|
||||||
|
g_pProtocolManager->m_pFractionalScaleProtocolManager->setPreferredScaleForSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PMONITOR->scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_unmapWindow(void* owner, void* data) {
|
void Events::listener_unmapWindow(void* owner, void* data) {
|
||||||
|
|
|
@ -42,8 +42,10 @@ struct SLayerSurface {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CMonitor;
|
||||||
|
|
||||||
struct SRenderData {
|
struct SRenderData {
|
||||||
wlr_output* output;
|
CMonitor* pMonitor;
|
||||||
timespec* when;
|
timespec* when;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
@ -51,7 +53,6 @@ struct SRenderData {
|
||||||
void* data = nullptr;
|
void* data = nullptr;
|
||||||
wlr_surface* surface = nullptr;
|
wlr_surface* surface = nullptr;
|
||||||
int w, h;
|
int w, h;
|
||||||
void* pMonitor = nullptr;
|
|
||||||
|
|
||||||
// for rounding
|
// for rounding
|
||||||
bool dontRound = true;
|
bool dontRound = true;
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
CProtocolManager::CProtocolManager() {
|
CProtocolManager::CProtocolManager() {
|
||||||
m_pToplevelExportProtocolManager = std::make_unique<CToplevelExportProtocolManager>();
|
m_pToplevelExportProtocolManager = std::make_unique<CToplevelExportProtocolManager>();
|
||||||
|
m_pFractionalScaleProtocolManager = std::make_unique<CFractionalScaleProtocolManager>();
|
||||||
}
|
}
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "../protocols/ToplevelExport.hpp"
|
#include "../protocols/ToplevelExport.hpp"
|
||||||
|
#include "../protocols/FractionalScale.hpp"
|
||||||
|
|
||||||
class CProtocolManager {
|
class CProtocolManager {
|
||||||
public:
|
public:
|
||||||
CProtocolManager();
|
CProtocolManager();
|
||||||
|
|
||||||
std::unique_ptr<CToplevelExportProtocolManager> m_pToplevelExportProtocolManager;
|
std::unique_ptr<CToplevelExportProtocolManager> m_pToplevelExportProtocolManager;
|
||||||
|
std::unique_ptr<CFractionalScaleProtocolManager> m_pFractionalScaleProtocolManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CProtocolManager> g_pProtocolManager;
|
inline std::unique_ptr<CProtocolManager> g_pProtocolManager;
|
||||||
|
|
102
src/protocols/FractionalScale.cpp
Normal file
102
src/protocols/FractionalScale.cpp
Normal file
|
@ -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; });
|
||||||
|
}
|
38
src/protocols/FractionalScale.hpp
Normal file
38
src/protocols/FractionalScale.hpp
Normal file
|
@ -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;
|
||||||
|
};
|
|
@ -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));
|
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);
|
wl_resource_destroy(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???
|
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);
|
const auto PCLIENT = clientFromResource(resource);
|
||||||
|
|
||||||
g_pProtocolManager->m_pToplevelExportProtocolManager->removeClient(PCLIENT, true);
|
g_pProtocolManager->m_pToplevelExportProtocolManager->removeClient(PCLIENT, true);
|
||||||
|
|
|
@ -10,7 +10,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double outputX = 0, outputY = 0;
|
double outputX = 0, outputY = 0;
|
||||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY);
|
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->pMonitor->output, &outputX, &outputY);
|
||||||
|
|
||||||
wlr_box windowBox;
|
wlr_box windowBox;
|
||||||
if (RDATA->surface && surface == RDATA->surface)
|
if (RDATA->surface && surface == RDATA->surface)
|
||||||
|
@ -28,12 +28,12 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||||
if (RDATA->pWindow)
|
if (RDATA->pWindow)
|
||||||
g_pHyprRenderer->calculateUVForWindowSurface(RDATA->pWindow, surface, RDATA->squishOversized);
|
g_pHyprRenderer->calculateUVForWindowSurface(RDATA->pWindow, surface, RDATA->squishOversized);
|
||||||
|
|
||||||
scaleBox(&windowBox, RDATA->output->scale);
|
scaleBox(&windowBox, RDATA->pMonitor->scale);
|
||||||
|
|
||||||
static auto* const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
static auto* const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||||
|
|
||||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||||
rounding *= RDATA->output->scale;
|
rounding *= RDATA->pMonitor->scale;
|
||||||
|
|
||||||
rounding -= 1; // to fix a border issue
|
rounding -= 1; // to fix a border issue
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||||
|
|
||||||
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) {
|
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) {
|
||||||
wlr_surface_send_frame_done(surface, RDATA->when);
|
wlr_surface_send_frame_done(surface, RDATA->when);
|
||||||
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->output);
|
wlr_presentation_surface_sampled_on_output(g_pCompositor->m_sWLRPresentation, surface, RDATA->pMonitor->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the UV, we might've set it above
|
// reset the UV, we might've set it above
|
||||||
|
@ -230,7 +230,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
||||||
static auto* const PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
static auto* const PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||||
static auto* const PDIMAROUND = &g_pConfigManager->getConfigValuePtr("decoration:dim_around")->floatValue;
|
static auto* const PDIMAROUND = &g_pConfigManager->getConfigValuePtr("decoration:dim_around")->floatValue;
|
||||||
|
|
||||||
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
SRenderData renderdata = {pMonitor, time, REALPOS.x, REALPOS.y};
|
||||||
if (ignorePosition) {
|
if (ignorePosition) {
|
||||||
renderdata.x = pMonitor->vecPosition.x;
|
renderdata.x = pMonitor->vecPosition.x;
|
||||||
renderdata.y = pMonitor->vecPosition.y;
|
renderdata.y = pMonitor->vecPosition.y;
|
||||||
|
@ -352,7 +352,7 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
|
SRenderData renderdata = {pMonitor, time, pLayer->geometry.x, pLayer->geometry.y};
|
||||||
renderdata.fadeAlpha = pLayer->alpha.fl();
|
renderdata.fadeAlpha = pLayer->alpha.fl();
|
||||||
renderdata.blur = pLayer->forceBlur;
|
renderdata.blur = pLayer->forceBlur;
|
||||||
renderdata.surface = pLayer->layerSurface->surface;
|
renderdata.surface = pLayer->layerSurface->surface;
|
||||||
|
@ -368,7 +368,7 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprRenderer::renderIMEPopup(SIMEPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
void CHyprRenderer::renderIMEPopup(SIMEPopup* pPopup, CMonitor* pMonitor, timespec* time) {
|
||||||
SRenderData renderdata = {pMonitor->output, time, pPopup->realX, pPopup->realY};
|
SRenderData renderdata = {pMonitor, time, pPopup->realX, pPopup->realY};
|
||||||
|
|
||||||
renderdata.blur = false;
|
renderdata.blur = false;
|
||||||
renderdata.surface = pPopup->pSurface->surface;
|
renderdata.surface = pPopup->pSurface->surface;
|
||||||
|
@ -544,45 +544,23 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
||||||
Vector2D uvTL;
|
Vector2D uvTL;
|
||||||
Vector2D uvBR = Vector2D(1, 1);
|
Vector2D uvBR = Vector2D(1, 1);
|
||||||
|
|
||||||
wlr_box geom;
|
|
||||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
|
||||||
|
|
||||||
const auto SUBSURFACE = g_pXWaylandManager->getWindowSurface(pWindow) != pSurface && main;
|
|
||||||
|
|
||||||
// wp_viewporter_v1 implementation
|
|
||||||
if (pSurface->current.viewport.has_src) {
|
if (pSurface->current.viewport.has_src) {
|
||||||
|
// we stretch it to dest. if no dest, to 1,1
|
||||||
wlr_fbox bufferSource;
|
wlr_fbox bufferSource;
|
||||||
wlr_surface_get_buffer_source_box(pSurface, &bufferSource);
|
wlr_surface_get_buffer_source_box(pSurface, &bufferSource);
|
||||||
|
|
||||||
Vector2D surfaceSize = Vector2D(pSurface->buffer->texture->width, pSurface->buffer->texture->height);
|
Vector2D bufferSize = Vector2D(pSurface->buffer->texture->width, pSurface->buffer->texture->height);
|
||||||
|
|
||||||
uvTL = Vector2D(bufferSource.x / surfaceSize.x, bufferSource.y / surfaceSize.y);
|
// calculate UV for the basic src_box. Assume dest == size. TODO: don't.
|
||||||
uvBR = Vector2D((bufferSource.x + bufferSource.width) / surfaceSize.x, (bufferSource.y + bufferSource.height) / surfaceSize.y);
|
uvTL = Vector2D(bufferSource.x / bufferSize.x, bufferSource.y / bufferSize.y);
|
||||||
|
uvBR = Vector2D((bufferSource.x + bufferSource.width) / bufferSize.x, (bufferSource.y + bufferSource.height) / bufferSize.y);
|
||||||
|
|
||||||
if (uvBR.x < 0.01f || uvBR.y < 0.01f) {
|
if (uvBR.x < 0.01f || uvBR.y < 0.01f) {
|
||||||
uvTL = Vector2D();
|
uvTL = Vector2D();
|
||||||
uvBR = Vector2D(1, 1);
|
uvBR = Vector2D(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: (example: chromium) this still has a tiny "bump" at the end.
|
|
||||||
if (main) {
|
|
||||||
uvTL = uvTL +
|
|
||||||
(Vector2D((double)geom.x / ((double)pWindow->m_uSurface.xdg->surface->current.width),
|
|
||||||
(double)geom.y / ((double)pWindow->m_uSurface.xdg->surface->current.height)) *
|
|
||||||
(((uvBR.x - uvTL.x) * surfaceSize.x) / surfaceSize.x));
|
|
||||||
uvBR = uvBR *
|
|
||||||
Vector2D((double)(geom.width + geom.x) / ((double)pWindow->m_uSurface.xdg->surface->current.width),
|
|
||||||
(double)(geom.y + geom.height) / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
|
||||||
}
|
|
||||||
} else if (main) {
|
|
||||||
// oversized windows' UV adjusting
|
|
||||||
uvTL =
|
|
||||||
Vector2D((double)geom.x / ((double)pWindow->m_uSurface.xdg->surface->current.width), (double)geom.y / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
|
||||||
uvBR = Vector2D((double)(geom.width + geom.x) / ((double)pWindow->m_uSurface.xdg->surface->current.width),
|
|
||||||
(double)(geom.y + geom.height) / ((double)pWindow->m_uSurface.xdg->surface->current.height));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set UV
|
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = uvTL;
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = uvTL;
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = uvBR;
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = uvBR;
|
||||||
|
|
||||||
|
@ -593,20 +571,35 @@ void CHyprRenderer::calculateUVForWindowSurface(CWindow* pWindow, wlr_surface* p
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!main)
|
if (!main)
|
||||||
return; // ignore the rest
|
return;
|
||||||
|
|
||||||
// then, if the surface is too big, modify the pos UV
|
wlr_box geom;
|
||||||
if ((geom.width > pWindow->m_vRealSize.vec().x + 1 || geom.height > pWindow->m_vRealSize.vec().y + 1) && !SUBSURFACE) {
|
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||||
const auto OFF = Vector2D(pWindow->m_vRealSize.vec().x / (double)geom.width, pWindow->m_vRealSize.vec().y / (double)geom.height);
|
|
||||||
|
|
||||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D(-1, -1))
|
// ignore X and Y, adjust uv
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(0, 0);
|
if (geom.x != 0 || geom.y != 0) {
|
||||||
|
const auto XPERC = (double)geom.x / (double)pSurface->current.width;
|
||||||
|
const auto YPERC = (double)geom.y / (double)pSurface->current.height;
|
||||||
|
const auto WPERC = (double)(geom.x + geom.width) / (double)pSurface->current.width;
|
||||||
|
const auto HPERC = (double)(geom.y + geom.height) / (double)pSurface->current.height;
|
||||||
|
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight =
|
const auto TOADDTL = Vector2D(XPERC * (uvBR.x - uvTL.x), YPERC * (uvBR.y - uvTL.y));
|
||||||
Vector2D(g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x *
|
uvBR = uvBR - Vector2D(1.0 - WPERC * (uvBR.x - uvTL.x), 1.0 - HPERC * (uvBR.y - uvTL.y));
|
||||||
(pWindow->m_vRealSize.vec().x / ((double)geom.width / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.x)),
|
uvTL = uvTL + TOADDTL;
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y *
|
|
||||||
(pWindow->m_vRealSize.vec().y / ((double)geom.height / g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight.y)));
|
if (geom.width > pWindow->m_vRealSize.vec().x || geom.height > pWindow->m_vRealSize.vec().y) {
|
||||||
|
uvBR.x = uvBR.x * (pWindow->m_vRealSize.vec().x / geom.width);
|
||||||
|
uvBR.y = uvBR.y * (pWindow->m_vRealSize.vec().y / geom.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = uvTL;
|
||||||
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = uvBR;
|
||||||
|
|
||||||
|
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||||
|
// No special UV mods needed
|
||||||
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||||
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||||
|
@ -1119,7 +1112,7 @@ void CHyprRenderer::renderDragIcon(CMonitor* pMonitor, timespec* time) {
|
||||||
if (!(g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.iconMapped && g_pInputManager->m_sDrag.dragIcon->surface))
|
if (!(g_pInputManager->m_sDrag.dragIcon && g_pInputManager->m_sDrag.iconMapped && g_pInputManager->m_sDrag.dragIcon->surface))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SRenderData renderdata = {pMonitor->output, time, g_pInputManager->m_sDrag.pos.x, g_pInputManager->m_sDrag.pos.y};
|
SRenderData renderdata = {pMonitor, time, g_pInputManager->m_sDrag.pos.x, g_pInputManager->m_sDrag.pos.y};
|
||||||
renderdata.surface = g_pInputManager->m_sDrag.dragIcon->surface;
|
renderdata.surface = g_pInputManager->m_sDrag.dragIcon->surface;
|
||||||
renderdata.w = g_pInputManager->m_sDrag.dragIcon->surface->current.width;
|
renderdata.w = g_pInputManager->m_sDrag.dragIcon->surface->current.width;
|
||||||
renderdata.h = g_pInputManager->m_sDrag.dragIcon->surface->current.height;
|
renderdata.h = g_pInputManager->m_sDrag.dragIcon->surface->current.height;
|
||||||
|
|
Loading…
Reference in a new issue