mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-20 06:30:06 +01:00
hyprctl: use new hyprpaper ipc format (#12537)
--------- Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
This commit is contained in:
parent
9b1891e476
commit
d9657a95cb
13 changed files with 392 additions and 14 deletions
9
.github/actions/setup_base/action.yml
vendored
9
.github/actions/setup_base/action.yml
vendored
|
|
@ -75,6 +75,15 @@ runs:
|
|||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --install build
|
||||
|
||||
- name: Get hyprwire-git
|
||||
shell: bash
|
||||
run: |
|
||||
git clone https://github.com/hyprwm/hyprwire --recursive
|
||||
cd hyprwire
|
||||
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
|
||||
cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
|
||||
cmake --install build
|
||||
|
||||
- name: Get hyprutils-git
|
||||
shell: bash
|
||||
run: |
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -32,6 +32,8 @@ src/render/shaders/*.inc
|
|||
src/render/shaders/Shaders.hpp
|
||||
|
||||
hyprctl/hyprctl
|
||||
hyprctl/hw-protocols/*.c*
|
||||
hyprctl/hw-protocols/*.h*
|
||||
|
||||
gmon.out
|
||||
*.out
|
||||
|
|
|
|||
27
flake.lock
generated
27
flake.lock
generated
|
|
@ -297,6 +297,32 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hyprwire": {
|
||||
"inputs": {
|
||||
"hyprutils": [
|
||||
"hyprutils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": [
|
||||
"systems"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1764773840,
|
||||
"narHash": "sha256-9UcCdwe7vPgEcJJ64JseBQL0ZJZoxp/2iFuvfRI+9zk=",
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwire",
|
||||
"rev": "3f1997d6aeced318fb141810fded2255da811293",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hyprwm",
|
||||
"repo": "hyprwire",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1764517877,
|
||||
|
|
@ -345,6 +371,7 @@
|
|||
"hyprlang": "hyprlang",
|
||||
"hyprutils": "hyprutils",
|
||||
"hyprwayland-scanner": "hyprwayland-scanner",
|
||||
"hyprwire": "hyprwire",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
"systems": "systems",
|
||||
|
|
|
|||
|
|
@ -65,6 +65,13 @@
|
|||
inputs.systems.follows = "systems";
|
||||
};
|
||||
|
||||
hyprwire = {
|
||||
url = "github:hyprwm/hyprwire";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.systems.follows = "systems";
|
||||
inputs.hyprutils.follows = "hyprutils";
|
||||
};
|
||||
|
||||
xdph = {
|
||||
url = "github:hyprwm/xdg-desktop-portal-hyprland";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
|
|
|||
|
|
@ -5,11 +5,32 @@ project(
|
|||
DESCRIPTION "Control utility for Hyprland"
|
||||
)
|
||||
|
||||
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.4 re2)
|
||||
pkg_check_modules(hyprctl_deps REQUIRED IMPORTED_TARGET hyprutils>=0.2.4 hyprwire re2)
|
||||
|
||||
add_executable(hyprctl "main.cpp")
|
||||
file(GLOB_RECURSE HYPRCTL_SRCFILES CONFIGURE_DEPENDS "src/*.cpp" "hw-protocols/*.cpp" "include/*.hpp")
|
||||
|
||||
add_executable(hyprctl ${HYPRCTL_SRCFILES})
|
||||
|
||||
target_link_libraries(hyprctl PUBLIC PkgConfig::hyprctl_deps)
|
||||
target_include_directories(hyprctl PRIVATE "hw-protocols")
|
||||
|
||||
# Hyprwire
|
||||
|
||||
function(hyprprotocol protoPath protoName)
|
||||
set(path ${CMAKE_CURRENT_SOURCE_DIR}/${protoPath})
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/hw-protocols/${protoName}-client.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hw-protocols/${protoName}-client.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hw-protocols/${protoName}-spec.hpp
|
||||
COMMAND hyprwire-scanner --client ${path}/${protoName}.xml
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hw-protocols/
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_sources(hyprctl PRIVATE hw-protocols/${protoName}-client.cpp
|
||||
hw-protocols/${protoName}-client.hpp
|
||||
hw-protocols/${protoName}-spec.hpp)
|
||||
endfunction()
|
||||
|
||||
hyprprotocol(hw-protocols hyprpaper_core)
|
||||
|
||||
# binary
|
||||
install(TARGETS hyprctl)
|
||||
|
|
|
|||
144
hyprctl/hw-protocols/hyprpaper_core.xml
Normal file
144
hyprctl/hw-protocols/hyprpaper_core.xml
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="hyprpaper_core" version="1">
|
||||
<copyright>
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2025, Hypr Development
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
</copyright>
|
||||
|
||||
<object name="hyprpaper_core_manager" version="1">
|
||||
<description summary="manager object">
|
||||
This is the core manager object for hyprpaper operations
|
||||
</description>
|
||||
|
||||
<c2s name="get_wallpaper_object">
|
||||
<description summary="Get a wallpaper object">
|
||||
Creates a wallpaper object
|
||||
</description>
|
||||
<returns iface="hyprpaper_wallpaper"/>
|
||||
</c2s>
|
||||
|
||||
<s2c name="add_monitor">
|
||||
<description summary="New monitor added">
|
||||
Emitted when a new monitor is added.
|
||||
</description>
|
||||
<arg name="monitor_name" type="varchar" summary="the monitor's name"/>
|
||||
</s2c>
|
||||
|
||||
<s2c name="remove_monitor">
|
||||
<description summary="A monitor was removed">
|
||||
Emitted when a monitor is removed.
|
||||
</description>
|
||||
<arg name="monitor_name" type="varchar" summary="the monitor's name"/>
|
||||
</s2c>
|
||||
|
||||
<c2s name="destroy" destructor="true">
|
||||
<description summary="Destroy this object">
|
||||
Destroys this object. Children remain alive until destroyed.
|
||||
</description>
|
||||
</c2s>
|
||||
</object>
|
||||
|
||||
<enum name="wallpaper_fit_mode">
|
||||
<value idx="0" name="stretch"/>
|
||||
<value idx="1" name="cover"/>
|
||||
<value idx="2" name="contain"/>
|
||||
<value idx="3" name="tile"/>
|
||||
</enum>
|
||||
|
||||
<enum name="wallpaper_errors">
|
||||
<value idx="0" name="inert_wallpaper_object" description="attempted to use an inert wallpaper object"/>
|
||||
</enum>
|
||||
|
||||
<enum name="applying_error">
|
||||
<value idx="0" name="invalid_path" description="path provided was invalid"/>
|
||||
<value idx="1" name="invalid_monitor" description="monitor provided was invalid"/>
|
||||
<value idx="2" name="unknown_error" description="unknown error"/>
|
||||
</enum>
|
||||
|
||||
<object name="hyprpaper_wallpaper" version="1">
|
||||
<description summary="wallpaper object">
|
||||
This is an object describing a wallpaper
|
||||
</description>
|
||||
|
||||
<c2s name="path">
|
||||
<description summary="Set a path">
|
||||
Set a file path for the wallpaper. This has to be an absolute path from the fs root.
|
||||
This is required.
|
||||
</description>
|
||||
<arg name="wallpaper" type="varchar" summary="path"/>
|
||||
</c2s>
|
||||
|
||||
<c2s name="fit_mode">
|
||||
<description summary="Set a fit mode">
|
||||
Set a fit mode for the wallpaper. This is set to cover by default.
|
||||
</description>
|
||||
<arg name="fit_mode" type="enum" interface="wallpaper_fit_mode" summary="path"/>
|
||||
</c2s>
|
||||
|
||||
<c2s name="monitor_name">
|
||||
<description summary="Set the monitor name">
|
||||
Set a monitor for the wallpaper. Setting this to empty (or not setting at all) will
|
||||
treat this as a wildcard fallback.
|
||||
|
||||
See hyprpaper_core_manager.add_monitor and hyprpaper_core_manager.remove_monitor
|
||||
for tracking monitor names.
|
||||
</description>
|
||||
<arg name="monitor_name" type="varchar" summary="monitor name"/>
|
||||
</c2s>
|
||||
|
||||
<c2s name="apply">
|
||||
<description summary="Apply this wallpaper">
|
||||
Applies this object's state to the wallpaper state. Will emit .success on success,
|
||||
and .failed on failure.
|
||||
|
||||
This object becomes inert after .succeess or .failed, the only valid operation
|
||||
is to destroy it afterwards.
|
||||
</description>
|
||||
</c2s>
|
||||
|
||||
<s2c name="success">
|
||||
<description summary="Operation succeeded">
|
||||
Wallpaper was applied successfully.
|
||||
</description>
|
||||
</s2c>
|
||||
|
||||
<s2c name="failed">
|
||||
<description summary="Operation failed">
|
||||
Wallpaper was not applied. See the error field for more information.
|
||||
</description>
|
||||
<arg name="error" type="enum" interface="hyprpaper_wallpaper_application_error" summary="path"/>
|
||||
</s2c>
|
||||
|
||||
<c2s name="destroy" destructor="true">
|
||||
<description summary="Destroy this object">
|
||||
Destroys this object.
|
||||
</description>
|
||||
</c2s>
|
||||
</object>
|
||||
</protocol>
|
||||
|
|
@ -74,11 +74,8 @@ flags:
|
|||
const std::string_view HYPRPAPER_HELP = R"#(usage: hyprctl [flags] hyprpaper <request>
|
||||
|
||||
requests:
|
||||
listactive → Lists all active images
|
||||
listloaded → Lists all loaded images
|
||||
preload <path> → Preloads image
|
||||
unload <path> → Unloads image. Pass 'all' as path to unload all images
|
||||
wallpaper → Issue a wallpaper to call a config wallpaper dynamically
|
||||
wallpaper → Issue a wallpaper to call a config wallpaper dynamically.
|
||||
Arguments are [mon],[path],[fit_mode]. Fit mode is optional.
|
||||
|
||||
flags:
|
||||
See 'hyprctl --help')#";
|
||||
11
hyprctl/src/helpers/Memory.hpp
Normal file
11
hyprctl/src/helpers/Memory.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <hyprutils/memory/SharedPtr.hpp>
|
||||
#include <hyprutils/memory/UniquePtr.hpp>
|
||||
#include <hyprutils/memory/Atomic.hpp>
|
||||
|
||||
using namespace Hyprutils::Memory;
|
||||
|
||||
#define SP CSharedPointer
|
||||
#define WP CWeakPointer
|
||||
#define UP CUniquePointer
|
||||
148
hyprctl/src/hyprpaper/Hyprpaper.cpp
Normal file
148
hyprctl/src/hyprpaper/Hyprpaper.cpp
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#include "Hyprpaper.hpp"
|
||||
#include "../helpers/Memory.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <format>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hyprpaper_core-client.hpp>
|
||||
|
||||
#include <hyprutils/string/VarList2.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
constexpr const char* SOCKET_NAME = ".hyprpaper.sock";
|
||||
static SP<CCHyprpaperCoreImpl> g_coreImpl;
|
||||
|
||||
constexpr const uint32_t PROTOCOL_VERSION_SUPPORTED = 1;
|
||||
|
||||
//
|
||||
static hyprpaperCoreWallpaperFitMode fitFromString(const std::string_view& sv) {
|
||||
if (sv == "contain")
|
||||
return HYPRPAPER_CORE_WALLPAPER_FIT_MODE_CONTAIN;
|
||||
if (sv == "fit" || sv == "stretch")
|
||||
return HYPRPAPER_CORE_WALLPAPER_FIT_MODE_STRETCH;
|
||||
if (sv == "tile")
|
||||
return HYPRPAPER_CORE_WALLPAPER_FIT_MODE_TILE;
|
||||
return HYPRPAPER_CORE_WALLPAPER_FIT_MODE_COVER;
|
||||
}
|
||||
|
||||
static std::expected<std::string, std::string> resolvePath(const std::string_view& sv) {
|
||||
std::error_code ec;
|
||||
auto can = std::filesystem::canonical(sv, ec);
|
||||
|
||||
if (ec)
|
||||
return std::unexpected(std::format("invalid path: {}", ec.message()));
|
||||
|
||||
return can;
|
||||
}
|
||||
|
||||
static std::expected<std::string, std::string> getFullPath(const std::string_view& sv) {
|
||||
if (sv.empty())
|
||||
return std::unexpected("empty path");
|
||||
|
||||
if (sv[0] == '~') {
|
||||
static auto HOME = getenv("HOME");
|
||||
if (!HOME || HOME[0] == '\0')
|
||||
return std::unexpected("home path but no $HOME");
|
||||
|
||||
return resolvePath(std::string{HOME} + "/"s + std::string{sv.substr(1)});
|
||||
}
|
||||
|
||||
return resolvePath(sv);
|
||||
}
|
||||
|
||||
std::expected<void, std::string> Hyprpaper::makeHyprpaperRequest(const std::string_view& rq) {
|
||||
if (!rq.contains(' '))
|
||||
return std::unexpected("Invalid request");
|
||||
|
||||
if (!rq.starts_with("/hyprpaper "))
|
||||
return std::unexpected("Invalid request");
|
||||
|
||||
std::string_view LHS, RHS;
|
||||
auto spacePos = rq.find(' ', 12);
|
||||
LHS = rq.substr(11, spacePos - 11);
|
||||
RHS = rq.substr(spacePos + 1);
|
||||
|
||||
if (LHS != "wallpaper")
|
||||
return std::unexpected("Unknown hyprpaper request");
|
||||
|
||||
CVarList2 args(std::string{RHS}, 0, ',');
|
||||
|
||||
const std::string MONITOR = std::string{args[0]};
|
||||
const auto& PATH_RAW = args[1];
|
||||
const auto& FIT = args[2];
|
||||
|
||||
if (PATH_RAW.empty())
|
||||
return std::unexpected("not enough args");
|
||||
|
||||
const auto RTDIR = getenv("XDG_RUNTIME_DIR");
|
||||
|
||||
if (!RTDIR || RTDIR[0] == '\0')
|
||||
return std::unexpected("can't send: no XDG_RUNTIME_DIR");
|
||||
|
||||
const auto HIS = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||
|
||||
if (!HIS || HIS[0] == '\0')
|
||||
return std::unexpected("can't send: no HYPRLAND_INSTANCE_SIGNATURE (not running under hyprland)");
|
||||
|
||||
const auto PATH = getFullPath(PATH_RAW);
|
||||
|
||||
if (!PATH)
|
||||
return std::unexpected(std::format("bad path: {}", PATH_RAW));
|
||||
|
||||
auto socketPath = RTDIR + "/hypr/"s + HIS + "/"s + SOCKET_NAME;
|
||||
|
||||
auto socket = Hyprwire::IClientSocket::open(socketPath);
|
||||
|
||||
if (!socket)
|
||||
return std::unexpected("can't send: failed to connect to hyprpaper (is it running?)");
|
||||
|
||||
g_coreImpl = makeShared<CCHyprpaperCoreImpl>(1);
|
||||
|
||||
socket->addImplementation(g_coreImpl);
|
||||
|
||||
if (!socket->waitForHandshake())
|
||||
return std::unexpected("can't send: wire handshake failed");
|
||||
|
||||
auto spec = socket->getSpec(g_coreImpl->protocol()->specName());
|
||||
|
||||
if (!spec)
|
||||
return std::unexpected("can't send: hyprpaper doesn't have the spec?!");
|
||||
|
||||
auto manager = makeShared<CCHyprpaperCoreManagerObject>(socket->bindProtocol(g_coreImpl->protocol(), PROTOCOL_VERSION_SUPPORTED));
|
||||
|
||||
if (!manager)
|
||||
return std::unexpected("wire error: couldn't create manager");
|
||||
|
||||
auto wallpaper = makeShared<CCHyprpaperWallpaperObject>(manager->sendGetWallpaperObject());
|
||||
|
||||
if (!wallpaper)
|
||||
return std::unexpected("wire error: couldn't create wallpaper object");
|
||||
|
||||
bool canExit = false;
|
||||
std::optional<std::string> err;
|
||||
|
||||
wallpaper->setFailed([&canExit, &err](uint32_t code) {
|
||||
canExit = true;
|
||||
err = std::format("failed to set wallpaper, code {}", code);
|
||||
});
|
||||
wallpaper->setSuccess([&canExit]() { canExit = true; });
|
||||
|
||||
wallpaper->sendPath(PATH->c_str());
|
||||
wallpaper->sendMonitorName(MONITOR.c_str());
|
||||
if (!FIT.empty())
|
||||
wallpaper->sendFitMode(fitFromString(FIT));
|
||||
|
||||
wallpaper->sendApply();
|
||||
|
||||
while (!canExit) {
|
||||
socket->dispatchEvents(true);
|
||||
}
|
||||
|
||||
if (err)
|
||||
return std::unexpected(*err);
|
||||
|
||||
return {};
|
||||
}
|
||||
8
hyprctl/src/hyprpaper/Hyprpaper.hpp
Normal file
8
hyprctl/src/hyprpaper/Hyprpaper.hpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
namespace Hyprpaper {
|
||||
std::expected<void, std::string> makeHyprpaperRequest(const std::string_view& rq);
|
||||
};
|
||||
|
|
@ -31,6 +31,7 @@ using namespace Hyprutils::String;
|
|||
using namespace Hyprutils::Memory;
|
||||
|
||||
#include "Strings.hpp"
|
||||
#include "hyprpaper/Hyprpaper.hpp"
|
||||
|
||||
std::string instanceSignature;
|
||||
bool quiet = false;
|
||||
|
|
@ -305,10 +306,6 @@ int requestIPC(std::string_view filename, std::string_view arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int requestHyprpaper(std::string_view arg) {
|
||||
return requestIPC(".hyprpaper.sock", arg);
|
||||
}
|
||||
|
||||
int requestHyprsunset(std::string_view arg) {
|
||||
return requestIPC(".hyprsunset.sock", arg);
|
||||
}
|
||||
|
|
@ -500,9 +497,12 @@ int main(int argc, char** argv) {
|
|||
|
||||
if (fullRequest.contains("/--batch"))
|
||||
batchRequest(fullRequest, json);
|
||||
else if (fullRequest.contains("/hyprpaper"))
|
||||
exitStatus = requestHyprpaper(fullRequest);
|
||||
else if (fullRequest.contains("/hyprsunset"))
|
||||
else if (fullRequest.contains("/hyprpaper")) {
|
||||
auto result = Hyprpaper::makeHyprpaperRequest(fullRequest);
|
||||
if (!result)
|
||||
log(std::format("error: {}", result.error()));
|
||||
exitStatus = !result;
|
||||
} else if (fullRequest.contains("/hyprsunset"))
|
||||
exitStatus = requestHyprsunset(fullRequest);
|
||||
else if (fullRequest.contains("/switchxkblayout"))
|
||||
exitStatus = request(fullRequest, 2);
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
hyprlang,
|
||||
hyprutils,
|
||||
hyprwayland-scanner,
|
||||
hyprwire,
|
||||
libGL,
|
||||
libdrm,
|
||||
libexecinfo,
|
||||
|
|
@ -122,6 +123,7 @@ in
|
|||
|
||||
nativeBuildInputs = [
|
||||
hyprwayland-scanner
|
||||
hyprwire
|
||||
makeWrapper
|
||||
cmake
|
||||
pkg-config
|
||||
|
|
@ -144,6 +146,7 @@ in
|
|||
hyprland-protocols
|
||||
hyprlang
|
||||
hyprutils
|
||||
hyprwire
|
||||
libdrm
|
||||
libGL
|
||||
libinput
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ in {
|
|||
inputs.hyprlang.overlays.default
|
||||
inputs.hyprutils.overlays.default
|
||||
inputs.hyprwayland-scanner.overlays.default
|
||||
inputs.hyprwire.overlays.default
|
||||
self.overlays.udis86
|
||||
|
||||
# Hyprland packages themselves
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue