core: add tile as an image mode (#207)

---------

Co-authored-by: gkdwoe <gkdwoe>
This commit is contained in:
gkdwoe 2024-10-25 04:29:16 -07:00 committed by GitHub
parent 1c18ad6503
commit e6e5c471e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 27 additions and 7 deletions

View file

@ -4,7 +4,7 @@ Hyprpaper is a blazing fast wallpaper utility for Hyprland with the ability to d
# Features # Features
- Per-output wallpapers - Per-output wallpapers
- fill or contain modes - fill, tile or contain modes
- fractional scaling support - fractional scaling support
- IPC for blazing fast wallpaper switches - IPC for blazing fast wallpaper switches
- preloading targets into memory - preloading targets into memory
@ -91,7 +91,7 @@ splash = true
Preload will tell Hyprland to load a particular image (supported formats: png, jpg, jpeg, webp). Wallpaper will apply the wallpaper to the selected output (`monitor` is the monitor's name, easily can be retrieved with `hyprctl monitors`. You can leave it empty to set all monitors without an active wallpaper. You can also use `desc:` followed by the monitor's description without the (PORT) at the end) Preload will tell Hyprland to load a particular image (supported formats: png, jpg, jpeg, webp). Wallpaper will apply the wallpaper to the selected output (`monitor` is the monitor's name, easily can be retrieved with `hyprctl monitors`. You can leave it empty to set all monitors without an active wallpaper. You can also use `desc:` followed by the monitor's description without the (PORT) at the end)
You may add `contain:` before the file path in `wallpaper=` to set the mode to contain instead of cover: You may add `contain:` or `tile:` before the file path in `wallpaper=` to set the mode to either contain or tile, respectively, instead of cover:
``` ```
wallpaper = monitor,contain:/path/to/image.jpg wallpaper = monitor,contain:/path/to/image.jpg

View file

@ -515,6 +515,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;
if (!PWALLPAPERTARGET) { if (!PWALLPAPERTARGET) {
Debug::log(CRIT, "wallpaper target null in render??"); Debug::log(CRIT, "wallpaper target null in render??");
@ -567,8 +568,14 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
Debug::log(LOG, "Image data for %s: %s at [%.2f, %.2f], scale: %.2f (original image size: [%i, %i])", pMonitor->name.c_str(), PWALLPAPERTARGET->m_szPath.c_str(), origin.x, Debug::log(LOG, "Image data for %s: %s at [%.2f, %.2f], scale: %.2f (original image size: [%i, %i])", pMonitor->name.c_str(), PWALLPAPERTARGET->m_szPath.c_str(), origin.x,
origin.y, scale, (int)PWALLPAPERTARGET->m_vSize.x, (int)PWALLPAPERTARGET->m_vSize.y); origin.y, scale, (int)PWALLPAPERTARGET->m_vSize.x, (int)PWALLPAPERTARGET->m_vSize.y);
cairo_scale(PCAIRO, scale, scale); if (TILE) {
cairo_set_source_surface(PCAIRO, PWALLPAPERTARGET->m_pCairoSurface, origin.x, origin.y); cairo_pattern_t* pattern = cairo_pattern_create_for_surface(PWALLPAPERTARGET->m_pCairoSurface);
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
cairo_set_source(PCAIRO, pattern);
} else {
cairo_scale(PCAIRO, scale, scale);
cairo_set_source_surface(PCAIRO, PWALLPAPERTARGET->m_pCairoSurface, origin.x, origin.y);
}
cairo_paint(PCAIRO); cairo_paint(PCAIRO);

View file

@ -18,6 +18,7 @@
struct SWallpaperRenderData { struct SWallpaperRenderData {
bool contain = false; bool contain = false;
bool tile = false;
}; };
class CHyprpaper { class CHyprpaper {

View file

@ -4,8 +4,8 @@
#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;
if (VALUE.find_first_of(',') == std::string::npos) { if (VALUE.find_first_of(',') == std::string::npos) {
@ -23,6 +23,13 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
contain = true; contain = true;
} }
bool tile = false;
if (WALLPAPER.find("tile:") == 0) {
WALLPAPER = WALLPAPER.substr(5);
tile = true;
}
if (WALLPAPER[0] == '~') { if (WALLPAPER[0] == '~') {
static const char* const ENVHOME = getenv("HOME"); static const char* const ENVHOME = getenv("HOME");
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1); WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
@ -44,6 +51,7 @@ 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;
if (MONITOR.empty()) { if (MONITOR.empty()) {
for (auto& m : g_pHyprpaper->m_vMonitors) { for (auto& m : g_pHyprpaper->m_vMonitors) {
@ -51,6 +59,7 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
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;
} }
} }
} else { } else {
@ -141,6 +150,9 @@ static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
WALLPAPER = WALLPAPER.substr(8); WALLPAPER = WALLPAPER.substr(8);
} }
if (WALLPAPER.find("tile:") == 0)
WALLPAPER = WALLPAPER.substr(5);
auto preloadResult = handlePreload(C, WALLPAPER.c_str()); auto preloadResult = handlePreload(C, WALLPAPER.c_str());
if (preloadResult.error) if (preloadResult.error)
return preloadResult; return preloadResult;