mirror of
https://github.com/hyprwm/hyprpaper.git
synced 2025-12-24 14:40:02 +01:00
Merge 72408b2944 into 1733e0025b
This commit is contained in:
commit
030624b01e
4 changed files with 98 additions and 33 deletions
19
README.md
19
README.md
|
|
@ -99,6 +99,25 @@ You may add `contain:` or `tile:` before the file path in `wallpaper=` to set th
|
||||||
wallpaper = monitor,contain:/path/to/image.jpg
|
wallpaper = monitor,contain:/path/to/image.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want to rotate a wallpaper, add a ```, X``` at then end of the wallpaper rule, where ```X``` corresponds to a transform number, e.g.:
|
||||||
|
|
||||||
|
```
|
||||||
|
wallpaper = monitor,/path/to/image.jpg, 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Transform list:
|
||||||
|
|
||||||
|
```
|
||||||
|
0 -> normal (no transforms)
|
||||||
|
1 -> 90 degrees
|
||||||
|
2 -> 180 degrees
|
||||||
|
3 -> 270 degrees
|
||||||
|
4 -> flipped
|
||||||
|
5 -> flipped + 90 degrees
|
||||||
|
6 -> flipped + 180 degrees
|
||||||
|
7 -> flipped + 270 degrees
|
||||||
|
```
|
||||||
|
|
||||||
A Wallpaper ***cannot*** be applied without preloading. The config is ***not*** reloaded dynamically.
|
A Wallpaper ***cannot*** be applied without preloading. The config is ***not*** reloaded dynamically.
|
||||||
|
|
||||||
## Important note to the inner workings
|
## Important note to the inner workings
|
||||||
|
|
|
||||||
|
|
@ -529,6 +529,7 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor];
|
const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor];
|
||||||
const auto CONTAIN = m_mMonitorWallpaperRenderData[pMonitor->name].contain;
|
const auto CONTAIN = m_mMonitorWallpaperRenderData[pMonitor->name].contain;
|
||||||
const auto TILE = m_mMonitorWallpaperRenderData[pMonitor->name].tile;
|
const auto TILE = m_mMonitorWallpaperRenderData[pMonitor->name].tile;
|
||||||
|
const auto ROTATION = m_mMonitorWallpaperRenderData[pMonitor->name].rotation;
|
||||||
|
|
||||||
if (!PWALLPAPERTARGET) {
|
if (!PWALLPAPERTARGET) {
|
||||||
Debug::log(CRIT, "wallpaper target null in render??");
|
Debug::log(CRIT, "wallpaper target null in render??");
|
||||||
|
|
@ -566,32 +567,55 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
|
|
||||||
// get scale
|
// get scale
|
||||||
// we always do cover
|
// we always do cover
|
||||||
double scale;
|
double scale = 1.0;
|
||||||
Vector2D origin;
|
Vector2D origin;
|
||||||
|
|
||||||
const bool LOWASPECTRATIO = pMonitor->size.x / pMonitor->size.y > PWALLPAPERTARGET->m_vSize.x / PWALLPAPERTARGET->m_vSize.y;
|
double imgW = PWALLPAPERTARGET->m_vSize.x;
|
||||||
if ((CONTAIN && !LOWASPECTRATIO) || (!CONTAIN && LOWASPECTRATIO)) {
|
double imgH = PWALLPAPERTARGET->m_vSize.y;
|
||||||
scale = DIMENSIONS.x / PWALLPAPERTARGET->m_vSize.x;
|
|
||||||
origin.y = -(PWALLPAPERTARGET->m_vSize.y * scale - DIMENSIONS.y) / 2.0 / scale;
|
if ((ROTATION % 4 == 1) || (ROTATION % 4 == 3))
|
||||||
} else {
|
std::swap(imgW, imgH);
|
||||||
scale = DIMENSIONS.y / PWALLPAPERTARGET->m_vSize.y;
|
|
||||||
origin.x = -(PWALLPAPERTARGET->m_vSize.x * scale - DIMENSIONS.x) / 2.0 / scale;
|
cairo_save(PCAIRO);
|
||||||
|
|
||||||
|
if (ROTATION != 0) {
|
||||||
|
cairo_translate(PCAIRO, DIMENSIONS.x / 2.0, DIMENSIONS.y / 2.0);
|
||||||
|
|
||||||
|
if (ROTATION % 4 != 0)
|
||||||
|
cairo_rotate(PCAIRO, (ROTATION % 4) * M_PI_2);
|
||||||
|
|
||||||
|
if (ROTATION >= 4)
|
||||||
|
cairo_scale(PCAIRO, -1, 1);
|
||||||
|
|
||||||
|
cairo_translate(PCAIRO, -DIMENSIONS.x / 2.0, -DIMENSIONS.y / 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Image data for {}: {} at [{:.2f}, {:.2f}], scale: {:.2f} (original image size: [{}, {}])", pMonitor->name, PWALLPAPERTARGET->m_szPath, origin.x, origin.y,
|
|
||||||
scale, (int)PWALLPAPERTARGET->m_vSize.x, (int)PWALLPAPERTARGET->m_vSize.y);
|
|
||||||
|
|
||||||
if (TILE) {
|
if (TILE) {
|
||||||
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(PWALLPAPERTARGET->m_pCairoSurface->cairo());
|
cairo_pattern_t* pattern = cairo_pattern_create_for_surface(PWALLPAPERTARGET->m_pCairoSurface->cairo());
|
||||||
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
|
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
|
||||||
cairo_set_source(PCAIRO, pattern);
|
cairo_set_source(PCAIRO, pattern);
|
||||||
|
cairo_pattern_destroy(pattern);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (CONTAIN)
|
||||||
|
scale = std::min(DIMENSIONS.x / imgW, DIMENSIONS.y / imgH);
|
||||||
|
else
|
||||||
|
scale = std::max(DIMENSIONS.x / imgW, DIMENSIONS.y / imgH);
|
||||||
|
|
||||||
|
origin.x = (DIMENSIONS.x / scale - PWALLPAPERTARGET->m_vSize.x) / 2.0;
|
||||||
|
origin.y = (DIMENSIONS.y / scale - PWALLPAPERTARGET->m_vSize.y) / 2.0;
|
||||||
|
|
||||||
cairo_scale(PCAIRO, scale, scale);
|
cairo_scale(PCAIRO, scale, scale);
|
||||||
cairo_set_source_surface(PCAIRO, PWALLPAPERTARGET->m_pCairoSurface->cairo(), origin.x, origin.y);
|
cairo_set_source_surface(PCAIRO, PWALLPAPERTARGET->m_pCairoSurface->cairo(), origin.x, origin.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Image data for {}: {} at [{:.2f}, {:.2f}], scale: {:.2f} (original image size: [{}, {}])", pMonitor->name, PWALLPAPERTARGET->m_szPath, origin.x, origin.y,
|
||||||
|
scale, (int)PWALLPAPERTARGET->m_vSize.x, (int)PWALLPAPERTARGET->m_vSize.y);
|
||||||
|
|
||||||
cairo_paint(PCAIRO);
|
cairo_paint(PCAIRO);
|
||||||
|
|
||||||
|
cairo_restore(PCAIRO);
|
||||||
|
|
||||||
if (*PRENDERSPLASH && getenv("HYPRLAND_INSTANCE_SIGNATURE")) {
|
if (*PRENDERSPLASH && getenv("HYPRLAND_INSTANCE_SIGNATURE")) {
|
||||||
auto SPLASH = execAndGet("hyprctl splash");
|
auto SPLASH = execAndGet("hyprctl splash");
|
||||||
if (!SPLASH.empty())
|
if (!SPLASH.empty())
|
||||||
|
|
@ -624,8 +648,6 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
cairo_surface_flush(PWALLPAPERTARGET->m_pCairoSurface->cairo());
|
cairo_surface_flush(PWALLPAPERTARGET->m_pCairoSurface->cairo());
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_restore(PCAIRO);
|
|
||||||
|
|
||||||
if (pMonitor->pCurrentLayerSurface) {
|
if (pMonitor->pCurrentLayerSurface) {
|
||||||
pMonitor->pCurrentLayerSurface->pSurface->sendAttach(PBUFFER->buffer.get(), 0, 0);
|
pMonitor->pCurrentLayerSurface->pSurface->sendAttach(PBUFFER->buffer.get(), 0, 0);
|
||||||
pMonitor->pCurrentLayerSurface->pSurface->sendSetBufferScale(pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? 1 : pMonitor->scale);
|
pMonitor->pCurrentLayerSurface->pSurface->sendSetBufferScale(pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? 1 : pMonitor->scale);
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@
|
||||||
#include "protocols/wlr-layer-shell-unstable-v1.hpp"
|
#include "protocols/wlr-layer-shell-unstable-v1.hpp"
|
||||||
|
|
||||||
struct SWallpaperRenderData {
|
struct SWallpaperRenderData {
|
||||||
bool contain = false;
|
bool contain = false;
|
||||||
bool tile = false;
|
bool tile = false;
|
||||||
|
uint32_t rotation = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CHyprpaper {
|
class CHyprpaper {
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,18 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
const std::string VALUE = V;
|
const std::string VALUE = V;
|
||||||
Hyprlang::CParseResult result;
|
Hyprlang::CParseResult result;
|
||||||
|
Hyprutils::String::CVarList args(VALUE, 3, ',', false);
|
||||||
|
|
||||||
if (VALUE.find_first_of(',') == std::string::npos) {
|
if (args.size() < 2) {
|
||||||
result.setError("wallpaper failed (syntax)");
|
result.setError("wallpaper failed (syntax)");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
|
auto MONITOR = args[0];
|
||||||
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
auto WALLPAPER = g_pConfigManager->trimPath(args[1]);
|
||||||
|
|
||||||
bool contain = false;
|
bool contain = false;
|
||||||
|
|
||||||
|
|
@ -35,6 +36,20 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t rotation = 0;
|
||||||
|
if (args.size() >= 3) {
|
||||||
|
try {
|
||||||
|
rotation = std::stoi(args[2]);
|
||||||
|
if (rotation > 7) {
|
||||||
|
result.setError("wallpaper failed (invalid rotation input: must be 0-7)");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
result.setError("wallpaper failed (invalid rotation: not a number)");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
|
||||||
if (!std::filesystem::exists(WALLPAPER, ec)) {
|
if (!std::filesystem::exists(WALLPAPER, ec)) {
|
||||||
|
|
@ -49,17 +64,19 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprpaper->clearWallpaperFromMonitor(MONITOR);
|
g_pHyprpaper->clearWallpaperFromMonitor(MONITOR);
|
||||||
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
|
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
|
||||||
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
|
||||||
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].tile = tile;
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].tile = tile;
|
||||||
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].rotation = rotation;
|
||||||
|
|
||||||
if (MONITOR.empty()) {
|
if (MONITOR.empty()) {
|
||||||
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
||||||
if (!m->hasATarget || m->wildcard) {
|
if (!m->hasATarget || m->wildcard) {
|
||||||
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
|
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
|
||||||
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
|
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
|
||||||
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain;
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain;
|
||||||
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].tile = tile;
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].tile = tile;
|
||||||
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].rotation = rotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -141,10 +158,18 @@ static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
|
static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
const std::string VALUE = V;
|
const std::string VALUE = V;
|
||||||
|
Hyprutils::String::CVarList args(VALUE, 3, ',', false);
|
||||||
|
|
||||||
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
if (args.size() < 2) {
|
||||||
|
Hyprlang::CParseResult result;
|
||||||
|
result.setError("reload failed (syntax)");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MONITOR = args[0];
|
||||||
|
auto WALLPAPER = g_pConfigManager->trimPath(args[1]);
|
||||||
|
|
||||||
if (WALLPAPER.find("contain:") == 0) {
|
if (WALLPAPER.find("contain:") == 0) {
|
||||||
WALLPAPER = WALLPAPER.substr(8);
|
WALLPAPER = WALLPAPER.substr(8);
|
||||||
|
|
@ -157,8 +182,6 @@ static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
|
||||||
if (preloadResult.error)
|
if (preloadResult.error)
|
||||||
return preloadResult;
|
return preloadResult;
|
||||||
|
|
||||||
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
|
|
||||||
|
|
||||||
if (MONITOR.empty()) {
|
if (MONITOR.empty()) {
|
||||||
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
||||||
auto OLD_WALLPAPER = g_pHyprpaper->m_mMonitorActiveWallpapers[m->name];
|
auto OLD_WALLPAPER = g_pHyprpaper->m_mMonitorActiveWallpapers[m->name];
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue