Update upstream source from tag 'upstream/0.7.0'

Update to upstream version '0.7.0'
with Debian dir 6496c7e80a
This commit is contained in:
alan (NyxTrail) 2024-06-13 09:42:27 +00:00
commit f8d744b847
13 changed files with 403 additions and 221 deletions

2
.gitignore vendored
View File

@ -24,5 +24,3 @@ hyprctl/hyprctl
gmon.out
*.out
*.tar.gz
.pc

View File

@ -35,8 +35,38 @@ execute_process(
#
#
find_program(WaylandScanner NAMES wayland-scanner)
message(STATUS "Found WaylandScanner at ${WaylandScanner}")
execute_process(
COMMAND pkg-config --variable=pkgdatadir wayland-protocols
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
function(protocol protoPath protoName external)
if (external)
execute_process(
COMMAND ${WaylandScanner} client-header ${protoPath} ${protoName}-protocol.h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
execute_process(
COMMAND ${WaylandScanner} private-code ${protoPath} ${protoName}-protocol.c
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
target_sources(hyprpaper PRIVATE ${protoName}-protocol.h ${protoName}-protocol.c)
else()
execute_process(
COMMAND ${WaylandScanner} client-header ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${protoName}-protocol.h
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
execute_process(
COMMAND ${WaylandScanner} private-code ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${protoName}-protocol.c
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
target_sources(hyprpaper PRIVATE ${protoName}-protocol.h ${protoName}-protocol.c)
endif()
endfunction()
include_directories(.)
add_compile_options(-std=c++2b -DWLR_USE_UNSTABLE )
set(CMAKE_CXX_STANDARD 23)
add_compile_options(-DWLR_USE_UNSTABLE)
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
find_package(Threads REQUIRED)
@ -47,6 +77,11 @@ file(GLOB_RECURSE SRCFILES "src/*.cpp")
add_executable(hyprpaper ${SRCFILES})
protocol("protocols/wlr-layer-shell-unstable-v1.xml" "wlr-layer-shell-unstable-v1" true)
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
protocol("stable/viewporter/viewporter.xml" "viewporter" false)
protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
target_compile_definitions(hyprpaper PRIVATE "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
target_compile_definitions(hyprpaper PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"")
target_compile_definitions(hyprpaper PRIVATE "-DGIT_COMMIT_MESSAGE=\"${GIT_COMMIT_MESSAGE}\"")
@ -66,10 +101,6 @@ target_link_libraries(hyprpaper
pthread
magic
${CMAKE_THREAD_LIBS_INIT}
${CMAKE_SOURCE_DIR}/wlr-layer-shell-unstable-v1-protocol.o
${CMAKE_SOURCE_DIR}/xdg-shell-protocol.o
${CMAKE_SOURCE_DIR}/fractional-scale-v1-protocol.o
${CMAKE_SOURCE_DIR}/viewporter-protocol.o
wayland-cursor
)
@ -78,3 +109,5 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg -no-pie -fno-builtin")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg -no-pie -fno-builtin")
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
install(TARGETS hyprpaper)

View File

@ -1,74 +0,0 @@
PREFIX ?= /usr
CFLAGS ?= -g -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare -Wno-unused-function -Wno-unused-variable -Wno-unused-result -Wdeclaration-after-statement
CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99
WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
PKGS = wlroots wayland-server
CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p)))
LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
wlr-layer-shell-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) client-header \
protocols/wlr-layer-shell-unstable-v1.xml $@
wlr-layer-shell-unstable-v1-protocol.c:
$(WAYLAND_SCANNER) private-code \
protocols/wlr-layer-shell-unstable-v1.xml $@
wlr-layer-shell-unstable-v1-protocol.o: wlr-layer-shell-unstable-v1-protocol.h
xdg-shell-protocol.h:
$(WAYLAND_SCANNER) client-header \
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
xdg-shell-protocol.c:
$(WAYLAND_SCANNER) private-code \
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
xdg-shell-protocol.o: xdg-shell-protocol.h
fractional-scale-v1-protocol.h:
$(WAYLAND_SCANNER) client-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
viewporter-protocol.h:
$(WAYLAND_SCANNER) client-header \
$(WAYLAND_PROTOCOLS)/stable/viewporter/viewporter.xml $@
viewporter-protocol.c:
$(WAYLAND_SCANNER) private-code \
$(WAYLAND_PROTOCOLS)/stable/viewporter/viewporter.xml $@
viewporter-protocol.o: viewporter-protocol.h
protocols: wlr-layer-shell-unstable-v1-protocol.o xdg-shell-protocol.o fractional-scale-v1-protocol.o viewporter-protocol.o
clear:
rm -rf build
rm -f *.o *-protocol.h *-protocol.c
release:
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -H./ -B./build -G Ninja
cmake --build ./build --config Release --target all -j 10
debug:
mkdir -p build && cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -H./ -B./build -G Ninja
cmake --build ./build --config Debug --target all -j 10
all:
make clear
make protocols
make release
install:
make all
cp ./build/hyprpaper $(PREFIX)/bin -f

View File

@ -11,7 +11,9 @@ Hyprpaper is a blazing fast wallpaper utility for Hyprland with the ability to d
# Installation
[Arch Linux](https://archlinux.org/packages/community/x86_64/hyprpaper/): `pacman -S hyprpaper`
[Arch Linux](https://archlinux.org/packages/extra/x86_64/hyprpaper/): `pacman -S hyprpaper`
[OpenSuse Linux](https://software.opensuse.org/package/hyprpaper): `zypper install hyprpaper`
## Manual:
@ -34,7 +36,7 @@ and might not be packaged for your distro yet. If that's the case, build and ins
To install all of these in Fedora, run this command:
```
sudo dnf install wayland-devel wayland-protocols-devel pango-devel cairo-devel file-devel libglvnd-devel libglvnd-core-devel libjpeg-turbo-devel libwebp-devel gcc-c++
sudo dnf install wayland-devel wayland-protocols-devel hyprlang-devel pango-devel cairo-devel file-devel libglvnd-devel libglvnd-core-devel libjpeg-turbo-devel libwebp-devel gcc-c++
```
On Arch:
@ -49,13 +51,18 @@ sudo zypper install ninja gcc-c++ wayland-protocols-devel Mesa-libGLESv3-devel f
### Building
```
git clone https://github.com/hyprwm/hyprpaper
cd hyprpaper
make all
Building is done via CMake:
```sh
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
cmake --build ./build --config Release --target hyprpaper -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
```
*the output binary will be in `./build/`, copy it to your PATH, e.g. `/usr/bin`*
Install with:
```sh
cmake --install ./build
```
# Usage
@ -68,14 +75,22 @@ preload = /path/to/image.png
preload = /path/to/next_image.png
# .. more preloads
#set the default wallpaper(s) seen on inital workspace(s) --depending on the number of monitors used
#set the default wallpaper(s) seen on initial workspace(s) --depending on the number of monitors used
wallpaper = monitor1,/path/to/image.png
#if more than one monitor in use, can load a 2nd image
wallpaper = monitor2,/path/to/next_image.png
# .. more monitors
#enable splash text rendering over the wallpaper
splash = true
#fully disable ipc
# ipc = off
```
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 for a wildcard (aka fallback). 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:
@ -120,7 +135,7 @@ $w3 = hyprctl hyprpaper wallpaper "DP-1,~/Pictures/myepicpngAlso.png"
#yes use quotes around desired monitor and wallpaper
#... continued with desired amount
```
With the varibles created we can now "exec" the actions.
With the variables created we can now "exec" the actions.
Remember in Hyprland we can bind more than one action to a key so in the case where we'd like to change the wallpaper when we switch workspace we have to ensure that the actions are bound to the same key such as...
@ -144,6 +159,13 @@ bind=SUPERSHIFT,1,movetoworkspace,1 #Superkey + Shift + 1 moves windows and swi
bind=SUPERSHIFT,1,exec,$w1 #SuperKey + Shift + 1 switches to wallpaper $w1 on DP-1 as defined in the variable
```
## Getting information from hyprpaper
You can also use `hyprctl hyprpaper` to get information about the state of hyprpaper using the following commands:
```
listloaded - lists the wallpapers that are currently preloaded (useful for dynamically preloading and unloading)
listactive - prints the active wallpapers hyprpaper is displaying, along with its accociated monitor
```
# Battery life
Since the IPC has to tick every now and then, and poll in the background, battery life might be a tiny bit worse with IPC on. If you want to fully disable it, use
```

View File

@ -2,14 +2,15 @@
"nodes": {
"hyprlang": {
"inputs": {
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs",
"systems": "systems"
},
"locked": {
"lastModified": 1704230242,
"narHash": "sha256-S8DM+frECqmAdaUb3y5n3RjY73ajZcL5rnmx5YO+CkY=",
"lastModified": 1711250455,
"narHash": "sha256-LSq1ZsTpeD7xsqvlsepDEelWRDtAhqwetp6PusHXJRo=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "db5e1399b90d5a339330bdd49c5bca6fe58d6f60",
"rev": "b3e430f81f3364c5dd1a3cc9995706a4799eb3fa",
"type": "github"
},
"original": {
@ -20,11 +21,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1702645756,
"narHash": "sha256-qKI6OR3TYJYQB3Q8mAZ+DG4o/BR9ptcv9UnRV2hzljc=",
"owner": "nixos",
"lastModified": 1708475490,
"narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "40c3c94c241286dd2243ea34d3aef8a488f9e4d0",
"rev": "0e74ca98a74bc7270d28838369593635a5db3260",
"type": "github"
},
"original": {
@ -36,11 +37,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1703637592,
"narHash": "sha256-8MXjxU0RfFfzl57Zy3OfXCITS0qWDNLzlBAdwxGZwfY=",
"lastModified": 1711163522,
"narHash": "sha256-YN/Ciidm+A0fmJPWlHBGvVkcarYWSC+s3NTPk/P+q3c=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "cfc3698c31b1fb9cdcf10f36c9643460264d0ca8",
"rev": "44d0940ea560dee511026a53f0e2e2cde489b4d4",
"type": "github"
},
"original": {
@ -53,7 +54,38 @@
"root": {
"inputs": {
"hyprlang": "hyprlang",
"nixpkgs": "nixpkgs_2"
"nixpkgs": "nixpkgs_2",
"systems": "systems_2"
}
},
"systems": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
}
},

View File

@ -5,40 +5,53 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
hyprlang.url = "github:hyprwm/hyprlang";
systems.url = "github:nix-systems/default-linux";
};
outputs = {
self,
nixpkgs,
systems,
...
} @ inputs: let
inherit (nixpkgs) lib;
genSystems = lib.genAttrs [
# Add more systems if they are supported
"x86_64-linux"
"aarch64-linux"
];
pkgsFor = nixpkgs.legacyPackages;
eachSystem = lib.genAttrs (import systems);
pkgsFor = eachSystem (system:
import nixpkgs {
localSystem.system = system;
overlays = with self.overlays; [hyprpaper];
});
mkDate = longDate: (lib.concatStringsSep "-" [
(__substring 0 4 longDate)
(__substring 4 2 longDate)
(__substring 6 2 longDate)
(builtins.substring 0 4 longDate)
(builtins.substring 4 2 longDate)
(builtins.substring 6 2 longDate)
]);
in {
overlays.default = _: prev: rec {
hyprpaper = prev.callPackage ./nix/default.nix {
stdenv = prev.gcc13Stdenv;
version = "0.pre" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
inherit (prev.xorg) libXdmcp;
inherit (inputs.hyprlang.packages.${prev.system}) hyprlang;
overlays = {
default = self.overlays.hyprpaper;
hyprpaper = final: prev: rec {
hyprpaper = final.callPackage ./nix/default.nix {
stdenv = final.gcc13Stdenv;
version = "0.pre" + "+date=" + (mkDate (self.lastModifiedDate or "19700101")) + "_" + (self.shortRev or "dirty");
inherit (final.xorg) libXdmcp;
inherit (inputs.hyprlang.packages.${final.system}) hyprlang;
};
hyprpaper-debug = hyprpaper.override {debug = true;};
};
hyprpaper-debug = hyprpaper.override {debug = true;};
};
packages = genSystems (system:
(self.overlays.default null pkgsFor.${system})
// {default = self.packages.${system}.hyprpaper;});
packages = eachSystem (system: {
default = self.packages.${system}.hyprpaper;
inherit (pkgsFor.${system}) hyprpaper hyprpaper-debug;
});
formatter = genSystems (system: pkgsFor.${system}.alejandra);
homeManagerModules = {
default = self.homeManagerModules.hyprpaper;
hyprpaper = import ./nix/hm-module.nix self;
};
formatter = eachSystem (system: pkgsFor.${system}.alejandra);
};
}

View File

@ -3,7 +3,6 @@
stdenv,
pkg-config,
cmake,
ninja,
cairo,
expat,
file,
@ -30,11 +29,16 @@
stdenv.mkDerivation {
pname = "hyprpaper" + lib.optionalString debug "-debug";
inherit version;
src = ../.;
cmakeBuildType =
if debug
then "Debug"
else "Release";
nativeBuildInputs = [
cmake
ninja
pkg-config
];
@ -61,33 +65,6 @@ stdenv.mkDerivation {
util-linux
];
configurePhase = ''
runHook preConfigure
make protocols
runHook postConfigure
'';
buildPhase = ''
runHook preBuild
make release
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/{bin,share/licenses}
install -Dm755 build/hyprpaper -t $out/bin
install -Dm644 LICENSE -t $out/share/licenses/hyprpaper
runHook postInstall
'';
meta = with lib; {
homepage = "https://github.com/hyprwm/hyprpaper";
description = "A blazing fast wayland wallpaper utility with IPC controls";

102
nix/hm-module.nix Normal file
View File

@ -0,0 +1,102 @@
self: {
config,
pkgs,
lib,
...
}: let
inherit (builtins) toString;
inherit (lib.types) bool float listOf package str;
inherit (lib.modules) mkIf;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.meta) getExe;
boolToString = x:
if x
then "true"
else "false";
cfg = config.services.hyprpaper;
in {
options.services.hyprpaper = {
enable = mkEnableOption "Hyprpaper, Hyprland's wallpaper utility";
package = mkOption {
description = "The hyprpaper package";
type = package;
default = self.packages.${pkgs.stdenv.hostPlatform.system}.hyprpaper;
};
ipc = mkOption {
description = "Whether to enable IPC";
type = bool;
default = true;
};
splash = mkOption {
description = "Enable rendering of the hyprland splash over the wallpaper";
type = bool;
default = false;
};
splash_offset = mkOption {
description = "How far (in % of height) up should the splash be displayed";
type = float;
default = 2.0;
};
preloads = mkOption {
description = "List of paths to images that will be loaded into memory.";
type = listOf str;
example = [
"~/Images/wallpapers/forest.png"
"~/Images/wallpapers/desert.png"
];
};
wallpapers = mkOption {
description = "The wallpapers";
type = listOf str;
example = [
"eDP-1,~/Images/wallpapers/forest.png"
"DP-7,~/Images/wallpapers/desert.png"
];
};
};
config = mkIf cfg.enable {
xdg.configFile."hypr/hyprpaper.conf".text = ''
ipc = ${
if cfg.ipc
then "on"
else "off"
}
splash = ${boolToString cfg.splash}
splash_offset = ${toString cfg.splash_offset}
${
builtins.concatStringsSep "\n"
(
map (preload: "preload = ${preload}") cfg.preloads
)
}
${
builtins.concatStringsSep "\n"
(
map (wallpaper: "wallpaper = ${wallpaper}") cfg.wallpapers
)
}
'';
systemd.user.services.hyprpaper = {
Unit = {
Description = "Hyprland wallpaper daemon";
PartOf = ["graphical-session.target"];
};
Service = {
ExecStart = "${getExe cfg.package}";
Restart = "on-failure";
};
Install.WantedBy = ["graphical-session.target"];
};
};
}

View File

@ -15,11 +15,6 @@ void CHyprpaper::init() {
removeOldHyprpaperImages();
g_pConfigManager = std::make_unique<CConfigManager>();
g_pIPCSocket = std::make_unique<CIPCSocket>();
g_pConfigManager->parse();
m_sDisplay = (wl_display*)wl_display_connect(nullptr);
if (!m_sDisplay) {
@ -27,25 +22,36 @@ void CHyprpaper::init() {
exit(1);
}
// run
wl_registry* registry = wl_display_get_registry(m_sDisplay);
wl_registry_add_listener(registry, &Events::registryListener, nullptr);
wl_display_roundtrip(m_sDisplay);
while (m_vMonitors.size() < 1 || m_vMonitors[0]->name.empty()) {
wl_display_dispatch(m_sDisplay);
}
g_pConfigManager = std::make_unique<CConfigManager>();
g_pIPCSocket = std::make_unique<CIPCSocket>();
g_pConfigManager->parse();
preloadAllWallpapersFromConfig();
if (std::any_cast<Hyprlang::INT>(g_pConfigManager->config->getConfigValue("ipc")))
g_pIPCSocket->initialize();
// run
wl_registry* registry = wl_display_get_registry(m_sDisplay);
wl_registry_add_listener(registry, &Events::registryListener, nullptr);
while (wl_display_dispatch(m_sDisplay) != -1) {
do {
std::lock_guard<std::mutex> lg(m_mtTickMutex);
tick(true);
}
} while (wl_display_dispatch(m_sDisplay) != -1);
unlockSingleInstance();
}
void CHyprpaper::tick(bool force) {
bool reload = g_pIPCSocket->mainThreadParseRequest();
bool reload = g_pIPCSocket && g_pIPCSocket->mainThreadParseRequest();
if (!reload && !force)
return;
@ -453,6 +459,10 @@ SPoolBuffer* CHyprpaper::getPoolBuffer(SMonitor* pMonitor, CWallpaperTarget* pWa
void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
static auto* const PRENDERSPLASH = reinterpret_cast<Hyprlang::INT* const*>(g_pConfigManager->config->getConfigValuePtr("splash")->getDataStaticPtr());
static auto* const PSPLASHOFFSET = reinterpret_cast<Hyprlang::FLOAT* const*>(g_pConfigManager->config->getConfigValuePtr("splash_offset")->getDataStaticPtr());
if (!m_mMonitorActiveWallpaperTargets[pMonitor])
recheckMonitor(pMonitor);
const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor];
const auto CONTAIN = m_mMonitorWallpaperRenderData[pMonitor->name].contain;
@ -522,7 +532,11 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
const auto FONTSIZE = (int)(DIMENSIONS.y / 76.0 / scale);
cairo_set_font_size(PCAIRO, FONTSIZE);
cairo_set_source_rgba(PCAIRO, 1.0, 1.0, 1.0, 0.32);
static auto* const PSPLASHCOLOR = reinterpret_cast<Hyprlang::INT* const*>(g_pConfigManager->config->getConfigValuePtr("splash_color")->getDataStaticPtr());
Debug::log(LOG, "Splash color: %x", **PSPLASHCOLOR);
cairo_set_source_rgba(PCAIRO, ((**PSPLASHCOLOR >> 16) & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 8) & 0xFF) / 255.0, (**PSPLASHCOLOR & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 24) & 0xFF) / 255.0);
cairo_text_extents_t textExtents;
cairo_text_extents(PCAIRO, SPLASH.c_str(), &textExtents);

View File

@ -40,6 +40,20 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
if (MONITOR.empty()) {
for (auto& m : g_pHyprpaper->m_vMonitors) {
if (!m->hasATarget || m->wildcard) {
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain;
}
}
} else {
const auto PMON = g_pHyprpaper->getMonitorFromName(MONITOR);
if (PMON)
PMON->wildcard = false;
}
return result;
}
@ -70,17 +84,18 @@ static Hyprlang::CParseResult handleUnloadAll(const char* C, const char* V) {
std::vector<std::string> toUnload;
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
bool exists = false;
for (auto& [mon, target2] : g_pHyprpaper->m_mMonitorActiveWallpaperTargets) {
if (&target == target2) {
exists = true;
break;
if (VALUE == "unused") {
bool exists = false;
for (auto& [mon, target2] : g_pHyprpaper->m_mMonitorActiveWallpaperTargets) {
if (&target == target2) {
exists = true;
break;
}
}
}
if (exists)
continue;
if (exists)
continue;
}
toUnload.emplace_back(name);
}
@ -96,7 +111,7 @@ static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
const std::string VALUE = V;
auto WALLPAPER = VALUE;
if (VALUE == "all")
if (VALUE == "all" || VALUE == "unused")
return handleUnloadAll(C, V);
if (WALLPAPER[0] == '~') {
@ -118,9 +133,10 @@ CConfigManager::CConfigManager() {
config = std::make_unique<Hyprlang::CConfig>(configPath.c_str(), Hyprlang::SConfigOptions{.allowMissingConfig = true});
config->addConfigValue("ipc", {1L});
config->addConfigValue("splash", {1L});
config->addConfigValue("splash_offset", {2.F});
config->addConfigValue("ipc", Hyprlang::INT{1L});
config->addConfigValue("splash", Hyprlang::INT{0L});
config->addConfigValue("splash_offset", Hyprlang::FLOAT{2.F});
config->addConfigValue("splash_color", Hyprlang::INT{0x55ffffff});
config->registerHandler(&handleWallpaper, "wallpaper", {.allowFlags = false});
config->registerHandler(&handleUnload, "unload", {.allowFlags = false});

View File

@ -1,72 +1,76 @@
#include "Events.hpp"
#include "../Hyprpaper.hpp"
void Events::geometry(void *data, wl_output *output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform) {
void Events::geometry(void* data, wl_output* output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char* make, const char* model, int32_t transform) {
// ignored
}
void Events::mode(void *data, wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
void Events::mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
const auto PMONITOR = (SMonitor*)data;
PMONITOR->size = Vector2D(width, height);
}
void Events::done(void *data, wl_output *wl_output) {
void Events::done(void* data, wl_output* wl_output) {
const auto PMONITOR = (SMonitor*)data;
PMONITOR->readyForLS = true;
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
g_pHyprpaper->tick(true);
if (g_pConfigManager) // don't tick if this is the first roundtrip
g_pHyprpaper->tick(true);
}
void Events::scale(void *data, wl_output *wl_output, int32_t scale) {
void Events::scale(void* data, wl_output* wl_output, int32_t scale) {
const auto PMONITOR = (SMonitor*)data;
PMONITOR->scale = scale;
}
void Events::name(void *data, wl_output *wl_output, const char *name) {
void Events::name(void* data, wl_output* wl_output, const char* name) {
const auto PMONITOR = (SMonitor*)data;
PMONITOR->name = name;
}
void Events::description(void *data, wl_output *wl_output, const char *description) {
void Events::description(void* data, wl_output* wl_output, const char* description) {
const auto PMONITOR = (SMonitor*)data;
// remove comma character from description. This allow monitor specific rules to work on monitor with comma on their description
std::string m_description = description;
std::erase(m_description, ',');
PMONITOR->description = description;
PMONITOR->description = m_description;
}
void Events::handleCapabilities(void *data, wl_seat *wl_seat, uint32_t capabilities) {
void Events::handleCapabilities(void* data, wl_seat* wl_seat, uint32_t capabilities) {
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
wl_pointer_add_listener(wl_seat_get_pointer(wl_seat), &pointerListener, wl_seat);
}
}
void Events::handlePointerLeave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) {
void Events::handlePointerLeave(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface) {
// ignored
wl_surface_commit(surface);
g_pHyprpaper->m_pLastMonitor = nullptr;
}
void Events::handlePointerAxis(void *data, wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {
void Events::handlePointerAxis(void* data, wl_pointer* wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {
// ignored
}
void Events::handlePointerMotion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
void Events::handlePointerMotion(void* data, struct wl_pointer* wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
// ignored
if (g_pHyprpaper->m_pLastMonitor) {
wl_surface_commit(g_pHyprpaper->m_pLastMonitor->pCurrentLayerSurface->pSurface);
}
}
void Events::handlePointerButton(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) {
void Events::handlePointerButton(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) {
// ignored
}
void Events::handlePointerEnter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
void Events::handlePointerEnter(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
for (auto& mon : g_pHyprpaper->m_vMonitors) {
if (mon->pCurrentLayerSurface->pSurface == surface) {
g_pHyprpaper->m_pLastMonitor = mon.get();
@ -79,7 +83,7 @@ void Events::handlePointerEnter(void *data, struct wl_pointer *wl_pointer, uint3
}
}
void Events::ls_configure(void *data, zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) {
void Events::ls_configure(void* data, zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) {
const auto PLAYERSURFACE = (CLayerSurface*)data;
PLAYERSURFACE->m_pMonitor->size = Vector2D(width, height);
@ -91,7 +95,7 @@ void Events::ls_configure(void *data, zwlr_layer_surface_v1 *surface, uint32_t s
Debug::log(LOG, "configure for %s", PLAYERSURFACE->m_pMonitor->name.c_str());
}
void Events::handleLSClosed(void *data, zwlr_layer_surface_v1 *zwlr_layer_surface_v1) {
void Events::handleLSClosed(void* data, zwlr_layer_surface_v1* zwlr_layer_surface_v1) {
const auto PLAYERSURFACE = (CLayerSurface*)data;
for (auto& m : g_pHyprpaper->m_vMonitors) {
@ -107,18 +111,18 @@ void Events::handleLSClosed(void *data, zwlr_layer_surface_v1 *zwlr_layer_surfac
}
}
void Events::handleGlobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
void Events::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
if (strcmp(interface, wl_compositor_interface.name) == 0) {
g_pHyprpaper->m_sCompositor = (wl_compositor *)wl_registry_bind(registry, name, &wl_compositor_interface, 4);
g_pHyprpaper->m_sCompositor = (wl_compositor*)wl_registry_bind(registry, name, &wl_compositor_interface, 4);
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
g_pHyprpaper->m_sSHM = (wl_shm *)wl_registry_bind(registry, name, &wl_shm_interface, 1);
g_pHyprpaper->m_sSHM = (wl_shm*)wl_registry_bind(registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, wl_output_interface.name) == 0) {
g_pHyprpaper->m_mtTickMutex.lock();
const auto PMONITOR = g_pHyprpaper->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get();
PMONITOR->wayland_name = name;
PMONITOR->name = "";
PMONITOR->output = (wl_output *)wl_registry_bind(registry, name, &wl_output_interface, 4);
PMONITOR->output = (wl_output*)wl_registry_bind(registry, name, &wl_output_interface, 4);
wl_output_add_listener(PMONITOR->output, &Events::outputListener, PMONITOR);
g_pHyprpaper->m_mtTickMutex.unlock();
@ -133,7 +137,7 @@ void Events::handleGlobal(void *data, struct wl_registry *registry, uint32_t nam
}
}
void Events::handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name) {
void Events::handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name) {
for (auto& m : g_pHyprpaper->m_vMonitors) {
if (m->wayland_name == name) {
Debug::log(LOG, "Destroying output %s", m->name.c_str());
@ -144,10 +148,10 @@ void Events::handleGlobalRemove(void *data, struct wl_registry *registry, uint32
}
}
void Events::handlePreferredScale(void *data, wp_fractional_scale_v1* fractionalScaleInfo, uint32_t scale) {
void Events::handlePreferredScale(void* data, wp_fractional_scale_v1* fractionalScaleInfo, uint32_t scale) {
const double SCALE = scale / 120.0;
CLayerSurface *const pLS = (CLayerSurface*)data;
CLayerSurface* const pLS = (CLayerSurface*)data;
Debug::log(LOG, "handlePreferredScale: %.2lf for %lx", SCALE, pLS);
@ -157,4 +161,3 @@ void Events::handlePreferredScale(void *data, wp_fractional_scale_v1* fractional
g_pHyprpaper->tick(true);
}
}

View File

@ -1,8 +1,8 @@
#pragma once
#include "../defines.hpp"
#include "PoolBuffer.hpp"
#include "../render/LayerSurface.hpp"
#include "PoolBuffer.hpp"
struct SMonitor {
std::string name = "";
@ -15,6 +15,8 @@ struct SMonitor {
bool readyForLS = false;
bool hasATarget = true;
bool wildcard = true;
uint32_t configureSerial = 0;
SPoolBuffer buffer;

View File

@ -11,6 +11,7 @@
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <pwd.h>
void CIPCSocket::initialize() {
std::thread([&]() {
@ -24,12 +25,14 @@ void CIPCSocket::initialize() {
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE");
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
std::string socketPath = HISenv ? "/tmp/hypr/" + std::string(HISenv) + "/.hyprpaper.sock" : "/tmp/hypr/.hyprpaper.sock";
const auto USERDIR = "/run/user/" + USERID + "/hypr/";
if (!HISenv) {
mkdir("/tmp/hypr", S_IRWXU | S_IRWXG);
}
std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock";
if (!HISenv)
mkdir(USERDIR.c_str(), S_IRWXU);
unlink(socketPath.c_str());
@ -90,34 +93,75 @@ bool CIPCSocket::mainThreadParseRequest() {
std::string copy = m_szRequest;
// now we can work on the copy
if (copy == "")
return false;
// now we can work on the copy
Debug::log(LOG, "Received a request: %s", copy.c_str());
// parse
// set default reply
m_szReply = "ok";
m_bReplyReady = true;
m_bRequestReady = false;
// config commands
if (copy.find("wallpaper") == 0 || copy.find("preload") == 0 || copy.find("unload") == 0) {
const auto RESULT = g_pConfigManager->config->parseDynamic(copy.substr(0, copy.find_first_of(' ')).c_str(), copy.substr(copy.find_first_of(' ') + 1).c_str());
if (RESULT.error) {
m_szReply = RESULT.getError();
m_bReplyReady = true;
m_bRequestReady = false;
return false;
}
} else {
m_szReply = "invalid command";
m_bReplyReady = true;
m_bRequestReady = false;
return false;
return true;
}
m_szReply = "ok";
m_bReplyReady = true;
m_bRequestReady = false;
if (copy.find("listloaded") == 0) {
return true;
const auto numWallpapersLoaded = g_pHyprpaper->m_mWallpaperTargets.size();
Debug::log(LOG, "numWallpapersLoaded: %d", numWallpapersLoaded);
if (numWallpapersLoaded == 0) {
m_szReply = "no wallpapers loaded";
return false;
}
m_szReply = "";
long unsigned int i = 0;
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
m_szReply += name;
i++;
if (i < numWallpapersLoaded)
m_szReply += '\n'; // dont add newline on last entry
}
return true;
}
if (copy.find("listactive") == 0) {
const auto numWallpapersActive = g_pHyprpaper->m_mMonitorActiveWallpapers.size();
Debug::log(LOG, "numWallpapersActive: %d", numWallpapersActive);
if (numWallpapersActive == 0) {
m_szReply = "no wallpapers active";
return false;
}
m_szReply = "";
long unsigned int i = 0;
for (auto& [mon, path1] : g_pHyprpaper->m_mMonitorActiveWallpapers) {
m_szReply += mon + " = " + path1;
i++;
if (i < numWallpapersActive)
m_szReply += '\n'; // dont add newline on last entry
}
return true;
}
m_szReply = "invalid command";
return false;
}