Merge branch 'DRAGONTOS-main'

This commit is contained in:
Kaley, Fischer 2024-04-01 20:50:23 +02:00
commit d963c47063
109 changed files with 4315 additions and 3037 deletions

View file

@ -12,6 +12,7 @@ runs:
- name: Get required pacman pkgs - name: Get required pacman pkgs
shell: bash shell: bash
run: | run: |
sed -i -e "1i [extra-testing]\nInclude = /etc/pacman.d/mirrorlist" "/etc/pacman.conf"
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
pacman --noconfirm --noprogressbar -Syyu pacman --noconfirm --noprogressbar -Syyu
pacman --noconfirm --noprogressbar -Sy \ pacman --noconfirm --noprogressbar -Sy \
@ -51,7 +52,18 @@ runs:
wayland-protocols \ wayland-protocols \
xcb-util-errors \ xcb-util-errors \
xcb-util-renderutil \ xcb-util-renderutil \
xcb-util-wm xcb-util-wm \
libzip \
librsvg
- name: Get hyprcursor-git
shell: bash
run: |
git clone https://github.com/hyprwm/hyprcursor --recursive
cd hyprcursor
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 Xorg pacman pkgs - name: Get Xorg pacman pkgs
shell: bash shell: bash

View file

@ -31,6 +31,7 @@ jobs:
cp ./LICENSE hyprland/ cp ./LICENSE hyprland/
cp build/Hyprland hyprland/ cp build/Hyprland hyprland/
cp build/hyprctl/hyprctl hyprland/ cp build/hyprctl/hyprctl hyprland/
cp build/hyprpm/hyprpm hyprland/
cp subprojects/wlroots/build/libwlroots.so.13032 hyprland/ cp subprojects/wlroots/build/libwlroots.so.13032 hyprland/
cp build/Hyprland hyprland/ cp build/Hyprland hyprland/
cp -r example/ hyprland/ cp -r example/ hyprland/

View file

@ -19,7 +19,7 @@ jobs:
with: with:
ref: ${{ github.ref }} ref: ${{ github.ref }}
- uses: DeterminateSystems/nix-installer-action@main - uses: cachix/install-nix-action@v25
- uses: DeterminateSystems/magic-nix-cache-action@main - uses: DeterminateSystems/magic-nix-cache-action@main
- uses: cachix/cachix-action@v12 - uses: cachix/cachix-action@v12
with: with:

View file

@ -24,44 +24,3 @@ jobs:
uses: github/codeql-action/upload-sarif@v2 uses: github/codeql-action/upload-sarif@v2
with: with:
sarif_file: ${{github.workspace}}/flawfinder_results.sarif sarif_file: ${{github.workspace}}/flawfinder_results.sarif
codeql:
name: CodeQL
runs-on: ubuntu-latest
container:
image: archlinux
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
steps:
- name: Checkout repository actions
uses: actions/checkout@v4
with:
sparse-checkout: .github/actions
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Setup base
uses: ./.github/actions/setup_base
with:
INSTALL_XORG_PKGS: true
- name: Build Hyprland
run: |
make all
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

3
.gitmodules vendored
View file

@ -1,7 +1,6 @@
[submodule "wlroots"] [submodule "wlroots"]
path = subprojects/wlroots path = subprojects/wlroots
url = https://github.com/DRAGONTOS/wlroots.git url = https://git.kaleyfischer.xyz/DRAGONTOS/wlroots
branch = 0.18.0-dev
[submodule "subprojects/hyprland-protocols"] [submodule "subprojects/hyprland-protocols"]
path = subprojects/hyprland-protocols path = subprojects/hyprland-protocols
url = https://github.com/hyprwm/hyprland-protocols url = https://github.com/hyprwm/hyprland-protocols

View file

@ -101,7 +101,7 @@ message(STATUS "Checking deps...")
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2) # we do not check for wlroots, as we provide it ourselves pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2 hyprcursor) # we do not check for wlroots, as we provide it ourselves
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp") file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")

View file

@ -106,3 +106,24 @@ man:
--variable=section:1 \ --variable=section:1 \
--from rst \ --from rst \
--to man > ./docs/hyprctl.1 --to man > ./docs/hyprctl.1
asan:
@echo -en "!!WARNING!!\nOnly run this in the TTY.\n"
@pidof Hyprland > /dev/null && echo -ne "Refusing to run with Hyprland running.\n" || echo ""
@pidof Hyprland > /dev/null && exit 1 || echo ""
rm -rf ./wayland
git reset --hard
git clone --recursive https://gitlab.freedesktop.org/wayland/wayland
cd wayland && patch -p1 < ../scripts/waylandStatic.diff && meson setup build --buildtype=debug -Db_sanitize=address -Ddocumentation=false && ninja -C build && cd ..
cp ./wayland/build/src/libwayland-server.a .
@echo "Wayland done"
patch -p1 < ./scripts/hyprlandStaticAsan.diff
cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DWITH_ASAN:STRING=True -DUSE_TRACY:STRING=False -DUSE_TRACY_GPU:STRING=False -S . -B ./build -G Ninja
cmake --build ./build --config Debug --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
@echo "Hyprland done"
ASAN_OPTIONS="detect_odr_violation=0,log_path=asan.log" HYPRLAND_NO_CRASHREPORTER=1 ./build/Hyprland -c ~/.config/hypr/hyprland.conf

View file

@ -124,7 +124,7 @@ easy IPC, much more QoL stuff than other wlr-based compositors and more...
[Wayfire]: https://github.com/WayfireWM/wayfire [Wayfire]: https://github.com/WayfireWM/wayfire
[TinyWl]: https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/tinywl/tinywl.c [TinyWl]: https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/tinywl/tinywl.c
[Sway]: https://github.com/swaywm/sway [Sway]: https://github.com/swaywm/sway
[DWL]: https://github.com/djpohly/dwl [DWL]: https://codeberg.org/dwl/dwl
<!----------------------------------{ Images }---------------------------------> <!----------------------------------{ Images }--------------------------------->

92
flake.lock generated
View file

@ -1,5 +1,29 @@
{ {
"nodes": { "nodes": {
"hyprcursor": {
"inputs": {
"hyprlang": "hyprlang",
"nixpkgs": [
"nixpkgs"
],
"systems": [
"systems"
]
},
"locked": {
"lastModified": 1710257359,
"narHash": "sha256-43re5pzE/cswFAgw92/ugsB3+d5ufDaCcLtl9ztKfBo=",
"owner": "hyprwm",
"repo": "hyprcursor",
"rev": "1761f6cefd77f4fcd2039d930c88d6716ddc4974",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprcursor",
"type": "github"
}
},
"hyprland-protocols": { "hyprland-protocols": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -24,6 +48,28 @@
} }
}, },
"hyprlang": { "hyprlang": {
"inputs": {
"nixpkgs": [
"hyprcursor",
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1709914708,
"narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=",
"owner": "hyprwm",
"repo": "hyprlang",
"rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2",
"type": "github"
},
"original": {
"owner": "hyprwm",
"repo": "hyprlang",
"type": "github"
}
},
"hyprlang_2": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
@ -33,11 +79,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1708787654, "lastModified": 1709914708,
"narHash": "sha256-7ACgM3ZuAhPqurXHUvR2nWMRcnmzGGPjLK6q4DSTelI=", "narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprlang", "repo": "hyprlang",
"rev": "0fce791ba2334aca183f2ed42399518947550d0d", "rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -48,11 +94,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1708807242, "lastModified": 1710272261,
"narHash": "sha256-sRTRkhMD4delO/hPxxi+XwLqPn8BuUq6nnj4JqLwOu0=", "narHash": "sha256-g0bDwXFmTE7uGDOs9HcJsfLFhH7fOsASbAuOzDC+fhQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "73de017ef2d18a04ac4bfd0c02650007ccb31c2a", "rev": "0ad13a6833440b8e238947e47bea7f11071dc2b2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -64,10 +110,11 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"hyprcursor": "hyprcursor",
"hyprland-protocols": "hyprland-protocols", "hyprland-protocols": "hyprland-protocols",
"hyprlang": "hyprlang", "hyprlang": "hyprlang_2",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"systems": "systems", "systems": "systems_2",
"wlroots": "wlroots", "wlroots": "wlroots",
"xdph": "xdph" "xdph": "xdph"
} }
@ -87,22 +134,37 @@
"type": "github" "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"
}
},
"wlroots": { "wlroots": {
"flake": false, "flake": false,
"locked": { "locked": {
"host": "gitlab.freedesktop.org", "host": "gitlab.freedesktop.org",
"lastModified": 1708558866, "lastModified": 1709983277,
"narHash": "sha256-Mz6hCtommq7RQfcPnxLINigO4RYSNt23HeJHC6mVmWI=", "narHash": "sha256-wXWIJLd4F2JZeMaihWVDW/yYXCLEC8OpeNJZg9a9ly8=",
"owner": "wlroots", "owner": "wlroots",
"repo": "wlroots", "repo": "wlroots",
"rev": "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5", "rev": "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {
"host": "gitlab.freedesktop.org", "host": "gitlab.freedesktop.org",
"owner": "wlroots", "owner": "wlroots",
"repo": "wlroots", "repo": "wlroots",
"rev": "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5", "rev": "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b",
"type": "gitlab" "type": "gitlab"
} }
}, },
@ -122,11 +184,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1708696469, "lastModified": 1709299639,
"narHash": "sha256-shh5wmpeYy3MmsBfkm4f76yPsBDGk6OLYRVG+ARy2F0=", "narHash": "sha256-jYqJM5khksLIbqSxCLUUcqEgI+O2LdlSlcMEBs39CAU=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "xdg-desktop-portal-hyprland", "repo": "xdg-desktop-portal-hyprland",
"rev": "1b713911c2f12b96c2574474686e4027ac4bf826", "rev": "2d2fb547178ec025da643db57d40a971507b82fe",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -12,10 +12,16 @@
host = "gitlab.freedesktop.org"; host = "gitlab.freedesktop.org";
owner = "wlroots"; owner = "wlroots";
repo = "wlroots"; repo = "wlroots";
rev = "0cb091f1a2d345f37d2ee445f4ffd04f7f4ec9e5"; rev = "50eae512d9cecbf0b3b1898bb1f0b40fa05fe19b";
flake = false; flake = false;
}; };
hyprcursor = {
url = "github:hyprwm/hyprcursor";
inputs.nixpkgs.follows = "nixpkgs";
inputs.systems.follows = "systems";
};
hyprland-protocols = { hyprland-protocols = {
url = "github:hyprwm/hyprland-protocols"; url = "github:hyprwm/hyprland-protocols";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
@ -71,9 +77,9 @@
# hyprland-packages # hyprland-packages
hyprland hyprland
hyprland-unwrapped
hyprland-debug hyprland-debug
hyprland-legacy-renderer hyprland-legacy-renderer
hyprland-unwrapped
# hyprland-extras # hyprland-extras
xdg-desktop-portal-hyprland xdg-desktop-portal-hyprland
@ -91,7 +97,7 @@
stdenv = pkgsFor.${system}.gcc13Stdenv; stdenv = pkgsFor.${system}.gcc13Stdenv;
} { } {
name = "hyprland-shell"; name = "hyprland-shell";
nativeBuildInputs = with pkgsFor.${system}; [cmake python3]; nativeBuildInputs = with pkgsFor.${system}; [cmake python3 expat libxml2];
buildInputs = [self.packages.${system}.wlroots-hyprland]; buildInputs = [self.packages.${system}.wlroots-hyprland];
hardeningDisable = ["fortify"]; hardeningDisable = ["fortify"];
inputsFrom = [ inputsFrom = [

View file

@ -315,6 +315,8 @@ int main(int argc, char** argv) {
json = true; json = true;
} else if (ARGS[i] == "-r" && !fullArgs.contains("r")) { } else if (ARGS[i] == "-r" && !fullArgs.contains("r")) {
fullArgs += "r"; fullArgs += "r";
} else if (ARGS[i] == "-a" && !fullArgs.contains("a")) {
fullArgs += "a";
} else if (ARGS[i] == "--batch") { } else if (ARGS[i] == "--batch") {
fullRequest = "--batch "; fullRequest = "--batch ";
} else if (ARGS[i] == "--instance" || ARGS[i] == "-i") { } else if (ARGS[i] == "--instance" || ARGS[i] == "-i") {
@ -429,6 +431,8 @@ int main(int argc, char** argv) {
request(fullRequest, 3); request(fullRequest, 3);
else if (fullRequest.contains("/plugin")) else if (fullRequest.contains("/plugin"))
request(fullRequest, 1); request(fullRequest, 1);
else if (fullRequest.contains("/dismissnotify"))
request(fullRequest, 0);
else if (fullRequest.contains("/notify")) else if (fullRequest.contains("/notify"))
request(fullRequest, 2); request(fullRequest, 2);
else if (fullRequest.contains("/output")) else if (fullRequest.contains("/output"))

View file

@ -45,11 +45,13 @@ void DataState::addNewPluginRepo(const SPluginRepository& repo) {
{"repository", toml::table{ {"repository", toml::table{
{"name", repo.name}, {"name", repo.name},
{"hash", repo.hash}, {"hash", repo.hash},
{"url", repo.url} {"url", repo.url},
{"rev", repo.rev}
}} }}
}; };
for (auto& p : repo.plugins) { for (auto& p : repo.plugins) {
// copy .so to the good place // copy .so to the good place
if (std::filesystem::exists(p.filename))
std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so"); std::filesystem::copy_file(p.filename, PATH + "/" + p.name + ".so");
DATA.emplace(p.name, toml::table{ DATA.emplace(p.name, toml::table{
@ -177,12 +179,14 @@ std::vector<SPluginRepository> DataState::getAllRepositories() {
const auto NAME = STATE["repository"]["name"].value_or(""); const auto NAME = STATE["repository"]["name"].value_or("");
const auto URL = STATE["repository"]["url"].value_or(""); const auto URL = STATE["repository"]["url"].value_or("");
const auto REV = STATE["repository"]["rev"].value_or("");
const auto HASH = STATE["repository"]["hash"].value_or(""); const auto HASH = STATE["repository"]["hash"].value_or("");
SPluginRepository repo; SPluginRepository repo;
repo.hash = HASH; repo.hash = HASH;
repo.name = NAME; repo.name = NAME;
repo.url = URL; repo.url = URL;
repo.rev = REV;
for (const auto& [key, val] : STATE) { for (const auto& [key, val] : STATE) {
if (key == "repository") if (key == "repository")

View file

@ -12,6 +12,7 @@ struct SPlugin {
struct SPluginRepository { struct SPluginRepository {
std::string url; std::string url;
std::string rev;
std::string name; std::string name;
std::vector<SPlugin> plugins; std::vector<SPlugin> plugins;
std::string hash; std::string hash;

View file

@ -77,8 +77,7 @@ SHyprlandVersion CPluginManager::getHyprlandVersion() {
return ver; return ver;
} }
bool CPluginManager::addNewPluginRepo(const std::string& url) { bool CPluginManager::addNewPluginRepo(const std::string& url, const std::string& rev) {
const auto HLVER = getHyprlandVersion(); const auto HLVER = getHyprlandVersion();
if (DataState::pluginRepoExists(url)) { if (DataState::pluginRepoExists(url)) {
@ -134,6 +133,14 @@ bool CPluginManager::addNewPluginRepo(const std::string& url) {
return false; return false;
} }
if (!rev.empty()) {
std::string ret = execAndGet("git -C /tmp/hyprpm/new reset --hard --recurse-submodules " + rev);
if (ret.compare(0, 6, "fatal:") == 0) {
std::cerr << "\n" << Colors::RED << "" << Colors::RESET << " Could not check out revision " << rev << ". shell returned:\n" << ret << "\n";
return false;
}
}
progress.m_iSteps = 1; progress.m_iSteps = 1;
progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " cloned"); progress.printMessageAbove(std::string{Colors::GREEN} + "" + Colors::RESET + " cloned");
progress.m_szCurrentMessage = "Reading the manifest"; progress.m_szCurrentMessage = "Reading the manifest";
@ -240,6 +247,7 @@ bool CPluginManager::addNewPluginRepo(const std::string& url) {
repohash.pop_back(); repohash.pop_back();
repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name; repo.name = pManifest->m_sRepository.name.empty() ? url.substr(url.find_last_of('/') + 1) : pManifest->m_sRepository.name;
repo.url = url; repo.url = url;
repo.rev = rev;
repo.hash = repohash; repo.hash = repohash;
for (auto& p : pManifest->m_vPlugins) { for (auto& p : pManifest->m_vPlugins) {
repo.plugins.push_back(SPlugin{p.name, "/tmp/hyprpm/new/" + p.output, false, p.failed}); repo.plugins.push_back(SPlugin{p.name, "/tmp/hyprpm/new/" + p.output, false, p.failed});
@ -494,6 +502,16 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
return false; return false;
} }
if (!repo.rev.empty()) {
progress.printMessageAbove(std::string{Colors::RESET} + " → Plugin has revision set, resetting: " + repo.rev);
std::string ret = execAndGet("git -C /tmp/hyprpm reset --hard --recurse-submodules " + repo.rev);
if (ret.compare(0, 6, "fatal:") == 0) {
std::cout << "\n" << std::string{Colors::RED} + "" + Colors::RESET + " could not check out revision " + repo.rev + ": shell returned:\n" + ret;
return false;
}
}
if (!update) { if (!update) {
// check if git has updates // check if git has updates
std::string hash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD"); std::string hash = execAndGet("cd /tmp/hyprpm/update && git rev-parse HEAD");
@ -538,8 +556,8 @@ bool CPluginManager::updatePlugins(bool forceUpdateAll) {
continue; continue;
} }
if (!pManifest->m_sRepository.commitPins.empty()) { if (repo.rev.empty() && !pManifest->m_sRepository.commitPins.empty()) {
// check commit pins // check commit pins unless a revision is specified
progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking"); progress.printMessageAbove(std::string{Colors::RESET} + " → Manifest has " + std::to_string(pManifest->m_sRepository.commitPins.size()) + " pins, checking");

View file

@ -36,7 +36,7 @@ struct SHyprlandVersion {
class CPluginManager { class CPluginManager {
public: public:
bool addNewPluginRepo(const std::string& url); bool addNewPluginRepo(const std::string& url, const std::string& rev);
bool removePluginRepo(const std::string& urlOrName); bool removePluginRepo(const std::string& urlOrName);
eHeadersErrors headersValid(); eHeadersErrors headersValid();

View file

@ -75,7 +75,12 @@ int main(int argc, char** argv, char** envp) {
return 1; return 1;
} }
return g_pPluginManager->addNewPluginRepo(command[1]) ? 0 : 1; std::string rev = "";
if (command.size() >= 3) {
rev = command[2];
}
return g_pPluginManager->addNewPluginRepo(command[1], rev) ? 0 : 1;
} else if (command[0] == "remove") { } else if (command[0] == "remove") {
if (ARGS.size() < 2) { if (ARGS.size() < 2) {
std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for remove.\n"; std::cerr << Colors::RED << "" << Colors::RESET << " Not enough args for remove.\n";

View file

@ -8,6 +8,7 @@
binutils, binutils,
cairo, cairo,
git, git,
hyprcursor,
hyprland-protocols, hyprland-protocols,
hyprlang, hyprlang,
jq, jq,
@ -75,6 +76,7 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
[ [
cairo cairo
git git
hyprcursor.dev
hyprland-protocols hyprland-protocols
hyprlang hyprlang
libdrm libdrm
@ -132,6 +134,7 @@ assert lib.assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been remov
postInstall = '' postInstall = ''
ln -s ${wlroots}/include/wlr $dev/include/hyprland/wlroots ln -s ${wlroots}/include/wlr $dev/include/hyprland/wlroots
${lib.optionalString wrapRuntimeDeps '' ${lib.optionalString wrapRuntimeDeps ''
wrapProgram $out/bin/Hyprland \ wrapProgram $out/bin/Hyprland \
--suffix PATH : ${lib.makeBinPath [ --suffix PATH : ${lib.makeBinPath [

View file

@ -21,6 +21,7 @@ in {
# Packages for variations of Hyprland, dependencies included. # Packages for variations of Hyprland, dependencies included.
hyprland-packages = lib.composeManyExtensions [ hyprland-packages = lib.composeManyExtensions [
# Dependencies # Dependencies
inputs.hyprcursor.overlays.default
inputs.hyprland-protocols.overlays.default inputs.hyprland-protocols.overlays.default
inputs.hyprlang.overlays.default inputs.hyprlang.overlays.default
self.overlays.wlroots-hyprland self.overlays.wlroots-hyprland

View file

@ -37,15 +37,16 @@ diff --git a/src/meson.build b/src/meson.build
index 45701f5f..3505cefe 100644 index 45701f5f..3505cefe 100644
--- a/src/meson.build --- a/src/meson.build
+++ b/src/meson.build +++ b/src/meson.build
@@ -9,17 +9,17 @@ executable('Hyprland', src, @@ -9,7 +9,7 @@ executable('Hyprland', src,
server_protos, server_protos,
dependency('wayland-server'), dependency('wayland-server'),
dependency('wayland-client'), dependency('wayland-client'),
- wlroots.get_variable('wlroots'), - wlroots.get_variable('wlroots'),
+ dependency('wlroots'), + dependency('wlroots'),
dependency('cairo'), dependency('cairo'),
dependency('hyprcursor'),
dependency('hyprlang', version: '>= 0.3.2'), dependency('hyprlang', version: '>= 0.3.2'),
dependency('libdrm'), @@ -16,12 +16,12 @@ executable('Hyprland', src,
dependency('egl'), dependency('egl'),
dependency('xkbcommon'), dependency('xkbcommon'),
dependency('libinput'), dependency('libinput'),

View file

@ -1,3 +1,3 @@
{ {
"version": "0.36.0" "version": "0.37.1"
} }

View file

@ -0,0 +1,21 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 857e21de..122d6a78 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -101,7 +101,7 @@ message(STATUS "Checking deps...")
find_package(Threads REQUIRED)
find_package(PkgConfig REQUIRED)
find_package(OpenGL REQUIRED)
-pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2) # we do not check for wlroots, as we provide it ourselves
+pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-cursor wayland-protocols cairo libdrm xkbcommon libinput pango pangocairo pixman-1 hyprlang>=0.3.2 libffi) # we do not check for wlroots, as we provide it ourselves
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
@@ -121,6 +121,7 @@ if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
message(STATUS "Enabling ASan")
target_link_libraries(Hyprland asan)
+ target_link_libraries(Hyprland ${CMAKE_SOURCE_DIR}/libwayland-server.a)
target_compile_options(Hyprland PUBLIC -fsanitize=address)
endif()

View file

@ -0,0 +1,23 @@
diff --git a/src/meson.build b/src/meson.build
index 5d04334..6645eec 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -170,7 +170,7 @@ if get_option('libraries')
error('We probably need to bump the SONAME of libwayland-server and -client')
endif
- wayland_server = library(
+ wayland_server = static_library(
'wayland-server',
sources: [
wayland_server_protocol_core_h,
@@ -180,9 +180,6 @@ if get_option('libraries')
'wayland-shm.c',
'event-loop.c'
],
- # To avoid an unnecessary SONAME bump, wayland 1.x.y produces
- # libwayland-server.so.0.x.y.
- version: '.'.join(['0', wayland_version[1], wayland_version[2]]),
dependencies: [
epoll_dep,
ffi_dep,

View file

@ -1,5 +1,7 @@
#include "Compositor.hpp" #include "Compositor.hpp"
#include "helpers/Splashes.hpp" #include "helpers/Splashes.hpp"
#include "config/ConfigValue.hpp"
#include "managers/CursorManager.hpp"
#include <random> #include <random>
#include <unordered_set> #include <unordered_set>
#include "debug/HyprCtl.hpp" #include "debug/HyprCtl.hpp"
@ -125,6 +127,18 @@ void CCompositor::initServer() {
throwError("wlr_backend_autocreate() failed!"); throwError("wlr_backend_autocreate() failed!");
} }
bool isHeadlessOnly = true;
wlr_multi_for_each_backend(
m_sWLRBackend,
[](wlr_backend* backend, void* isHeadlessOnly) {
if (!wlr_backend_is_headless(backend))
*(bool*)isHeadlessOnly = false;
},
&isHeadlessOnly);
if (isHeadlessOnly) {
m_sWLRRenderer = wlr_renderer_autocreate(m_sWLRBackend);
} else {
m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend); m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend);
if (m_iDRMFD < 0) { if (m_iDRMFD < 0) {
Debug::log(CRIT, "Couldn't query the DRM FD!"); Debug::log(CRIT, "Couldn't query the DRM FD!");
@ -132,6 +146,7 @@ void CCompositor::initServer() {
} }
m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(m_iDRMFD); m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(m_iDRMFD);
}
if (!m_sWLRRenderer) { if (!m_sWLRRenderer) {
Debug::log(CRIT, "m_sWLRRenderer was NULL! This usually means wlroots could not find a GPU or enountered some issues."); Debug::log(CRIT, "m_sWLRRenderer was NULL! This usually means wlroots could not find a GPU or enountered some issues.");
@ -181,18 +196,6 @@ void CCompositor::initServer() {
m_sWLRCursor = wlr_cursor_create(); m_sWLRCursor = wlr_cursor_create();
wlr_cursor_attach_output_layout(m_sWLRCursor, m_sWLROutputLayout); wlr_cursor_attach_output_layout(m_sWLRCursor, m_sWLROutputLayout);
if (const auto XCURSORENV = getenv("XCURSOR_SIZE"); !XCURSORENV || std::string(XCURSORENV).empty())
setenv("XCURSOR_SIZE", "24", true);
const auto XCURSORENV = getenv("XCURSOR_SIZE");
int cursorSize = 24;
try {
cursorSize = std::stoi(XCURSORENV);
} catch (std::exception& e) { Debug::log(ERR, "XCURSOR_SIZE invalid in check #2? ({})", XCURSORENV); }
m_sWLRXCursorMgr = wlr_xcursor_manager_create(nullptr, cursorSize);
wlr_xcursor_manager_load(m_sWLRXCursorMgr, 1);
m_sSeat.seat = wlr_seat_create(m_sWLDisplay, "seat0"); m_sSeat.seat = wlr_seat_create(m_sWLDisplay, "seat0");
m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend); m_sWLRPresentation = wlr_presentation_create(m_sWLDisplay, m_sWLRBackend);
@ -421,6 +424,7 @@ void CCompositor::cleanup() {
wl_display_destroy_clients(g_pCompositor->m_sWLDisplay); wl_display_destroy_clients(g_pCompositor->m_sWLDisplay);
g_pDecorationPositioner.reset(); g_pDecorationPositioner.reset();
g_pCursorManager.reset();
g_pPluginSystem.reset(); g_pPluginSystem.reset();
g_pHyprNotificationOverlay.reset(); g_pHyprNotificationOverlay.reset();
g_pDebugOverlay.reset(); g_pDebugOverlay.reset();
@ -510,6 +514,9 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the DecorationPositioner!"); Debug::log(LOG, "Creating the DecorationPositioner!");
g_pDecorationPositioner = std::make_unique<CDecorationPositioner>(); g_pDecorationPositioner = std::make_unique<CDecorationPositioner>();
Debug::log(LOG, "Creating the CursorManager!");
g_pCursorManager = std::make_unique<CCursorManager>();
} break; } break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
@ -708,11 +715,11 @@ bool CCompositor::monitorExists(CMonitor* pMonitor) {
CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t properties, CWindow* pIgnoreWindow) { CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t properties, CWindow* pIgnoreWindow) {
const auto PMONITOR = getMonitorFromVector(pos); const auto PMONITOR = getMonitorFromVector(pos);
static auto* const PRESIZEONBORDER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:resize_on_border"); static auto PRESIZEONBORDER = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto* const PBORDERSIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:border_size"); static auto PBORDERSIZE = CConfigValue<Hyprlang::INT>("general:border_size");
static auto* const PBORDERGRABEXTEND = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:extend_border_grab_area"); static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
static auto* const PSPECIALFALLTHRU = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:special_fallthrough"); static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
const auto BORDER_GRAB_AREA = **PRESIZEONBORDER ? **PBORDERSIZE + **PBORDERGRABEXTEND : 0; const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0;
// pinned windows on top of floating regardless // pinned windows on top of floating regardless
if (properties & ALLOW_FLOATING) { if (properties & ALLOW_FLOATING) {
@ -740,6 +747,14 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert
continue; continue;
const auto BB = w->getWindowBoxUnified(properties); const auto BB = w->getWindowBoxUnified(properties);
const auto PWINDOWMONITOR = getMonitorFromID(w->m_iMonitorID);
// to avoid focusing windows behind special workspaces from other monitors
if (!*PSPECIALFALLTHRU && PWINDOWMONITOR && PWINDOWMONITOR->specialWorkspaceID && w->m_iWorkspaceID != PWINDOWMONITOR->specialWorkspaceID &&
BB.x >= PWINDOWMONITOR->vecPosition.x && BB.y >= PWINDOWMONITOR->vecPosition.y &&
BB.x + BB.width <= PWINDOWMONITOR->vecPosition.x + PWINDOWMONITOR->vecSize.x && BB.y + BB.height <= PWINDOWMONITOR->vecPosition.y + PWINDOWMONITOR->vecSize.y)
continue;
CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA}; CBox box = {BB.x - BORDER_GRAB_AREA, BB.y - BORDER_GRAB_AREA, BB.width + 2 * BORDER_GRAB_AREA, BB.height + 2 * BORDER_GRAB_AREA};
if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus && if (w->m_bIsFloating && w->m_bIsMapped && isWorkspaceVisible(w->m_iWorkspaceID) && !w->isHidden() && !w->m_bPinned && !w->m_sAdditionalConfigData.noFocus &&
w.get() != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) { w.get() != pIgnoreWindow && (!aboveFullscreen || w->m_bCreatedOverFullscreen)) {
@ -814,7 +829,7 @@ CWindow* CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t propert
}; };
// special workspace // special workspace
if (PMONITOR->specialWorkspaceID && !**PSPECIALFALLTHRU) if (PMONITOR->specialWorkspaceID && !*PSPECIALFALLTHRU)
return windowForWorkspace(true); return windowForWorkspace(true);
if (PMONITOR->specialWorkspaceID) { if (PMONITOR->specialWorkspaceID) {
@ -843,7 +858,8 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, geom.pWlr()); wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, geom.pWlr());
geom.applyFromWlr(); geom.applyFromWlr();
const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.vec().x + geom.x, pos.y - pWindow->m_vRealPosition.vec().y + geom.y, &subx, &suby); const auto PFOUND =
wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.value().x + geom.x, pos.y - pWindow->m_vRealPosition.value().y + geom.y, &subx, &suby);
if (PFOUND) { if (PFOUND) {
sl.x = subx; sl.x = subx;
@ -851,8 +867,8 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
return PFOUND; return PFOUND;
} }
sl.x = pos.x - pWindow->m_vRealPosition.vec().x; sl.x = pos.x - pWindow->m_vRealPosition.value().x;
sl.y = pos.y - pWindow->m_vRealPosition.vec().y; sl.y = pos.y - pWindow->m_vRealPosition.value().y;
sl.x += geom.x; sl.x += geom.x;
sl.y += geom.y; sl.y += geom.y;
@ -865,7 +881,7 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, CWindow* pWindow
return {}; return {};
if (pWindow->m_bIsX11) if (pWindow->m_bIsX11)
return vec - pWindow->m_vRealPosition.goalv(); return vec - pWindow->m_vRealPosition.goal();
const auto PSURFACE = pWindow->m_uSurface.xdg; const auto PSURFACE = pWindow->m_uSurface.xdg;
@ -887,9 +903,9 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, CWindow* pWindow
geom.applyFromWlr(); geom.applyFromWlr();
if (std::get<1>(iterData) == -1337 && std::get<2>(iterData) == -1337) if (std::get<1>(iterData) == -1337 && std::get<2>(iterData) == -1337)
return vec - pWindow->m_vRealPosition.goalv(); return vec - pWindow->m_vRealPosition.goal();
return vec - pWindow->m_vRealPosition.goalv() - Vector2D{std::get<1>(iterData), std::get<2>(iterData)} + Vector2D{geom.x, geom.y}; return vec - pWindow->m_vRealPosition.goal() - Vector2D{std::get<1>(iterData), std::get<2>(iterData)} + Vector2D{geom.x, geom.y};
} }
CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) { CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
@ -914,8 +930,8 @@ CMonitor* CCompositor::getRealMonitorFromOutput(wlr_output* out) {
void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) { void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
static auto* const PFOLLOWMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto* const PSPECIALFALLTHROUGH = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:special_fallthrough"); static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
if (g_pCompositor->m_sSeat.exclusiveClient) { if (g_pCompositor->m_sSeat.exclusiveClient) {
Debug::log(LOG, "Disallowing setting focus to a window due to there being an active input inhibitor layer."); Debug::log(LOG, "Disallowing setting focus to a window due to there being an active input inhibitor layer.");
@ -927,6 +943,9 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
return; return;
} }
if (pWindow && pWindow->m_bIsX11 && pWindow->m_iX11Type == 2 && !wlr_xwayland_or_surface_wants_focus(pWindow->m_uSurface.xwayland))
return;
g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow); g_pLayoutManager->getCurrentLayout()->bringWindowToTop(pWindow);
if (!pWindow || !windowValidMapped(pWindow)) { if (!pWindow || !windowValidMapped(pWindow)) {
@ -989,7 +1008,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
/* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which /* If special fallthrough is enabled, this behavior will be disabled, as I have no better idea of nicely tracking which
window focuses are "via keybinds" and which ones aren't. */ window focuses are "via keybinds" and which ones aren't. */
if (PMONITOR->specialWorkspaceID && PMONITOR->specialWorkspaceID != pWindow->m_iWorkspaceID && !pWindow->m_bPinned && !**PSPECIALFALLTHROUGH) if (PMONITOR->specialWorkspaceID && PMONITOR->specialWorkspaceID != pWindow->m_iWorkspaceID && !pWindow->m_bPinned && !*PSPECIALFALLTHROUGH)
PMONITOR->setSpecialWorkspace(nullptr); PMONITOR->setSpecialWorkspace(nullptr);
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window // we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
@ -1039,13 +1058,6 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
if (pWindow->m_phForeignToplevel) if (pWindow->m_phForeignToplevel)
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true); wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true);
if (!pWindow->m_bIsX11) {
const auto PCONSTRAINT = wlr_pointer_constraints_v1_constraint_for_surface(m_sWLRPointerConstraints, pWindow->m_uSurface.xdg->surface, m_sSeat.seat);
if (PCONSTRAINT)
g_pInputManager->constrainMouse(m_sSeat.mouse, PCONSTRAINT);
}
g_pInputManager->recheckIdleInhibitorStatus(); g_pInputManager->recheckIdleInhibitorStatus();
// move to front of the window history // move to front of the window history
@ -1056,7 +1068,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1); std::rotate(m_vWindowFocusHistory.begin(), HISTORYPIVOT, HISTORYPIVOT + 1);
} }
if (**PFOLLOWMOUSE == 0) if (*PFOLLOWMOUSE == 0)
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
} }
@ -1068,6 +1080,8 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface)) if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
return; return;
const auto PLASTSURF = m_pLastFocus;
// Unfocus last surface if should // Unfocus last surface if should
if (m_pLastFocus && !pWindowOwner) if (m_pLastFocus && !pWindowOwner)
g_pXWaylandManager->activateSurface(m_pLastFocus, false); g_pXWaylandManager->activateSurface(m_pLastFocus, false);
@ -1102,6 +1116,15 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
m_pLastFocus = pSurface; m_pLastFocus = pSurface;
EMIT_HOOK_EVENT("keyboardFocus", pSurface); EMIT_HOOK_EVENT("keyboardFocus", pSurface);
const auto SURF = CWLSurface::surfaceFromWlr(pSurface);
const auto OLDSURF = CWLSurface::surfaceFromWlr(PLASTSURF);
if (OLDSURF && OLDSURF->constraint())
OLDSURF->constraint()->deactivate();
if (SURF && SURF->constraint())
SURF->constraint()->activate();
} }
bool CCompositor::windowValidMapped(CWindow* pWindow) { bool CCompositor::windowValidMapped(CWindow* pWindow) {
@ -1120,19 +1143,10 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) {
return true; return true;
} }
CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) {
for (auto& p : m_vXDGPopups) {
if (p->popup == popup)
return p->parentWindow;
}
return nullptr;
}
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<std::unique_ptr<SLayerSurface>>* layerSurfaces, Vector2D* sCoords, wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<std::unique_ptr<SLayerSurface>>* layerSurfaces, Vector2D* sCoords,
SLayerSurface** ppLayerSurfaceFound) { SLayerSurface** ppLayerSurfaceFound) {
for (auto& ls : *layerSurfaces | std::views::reverse) { for (auto& ls : *layerSurfaces | std::views::reverse) {
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.fl() == 0.f) if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f)
continue; continue;
auto SURFACEAT = wlr_layer_surface_v1_surface_at(ls->layerSurface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y); auto SURFACEAT = wlr_layer_surface_v1_surface_at(ls->layerSurface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y);
@ -1250,7 +1264,7 @@ void CCompositor::sanityCheckWorkspaces() {
if (!isWorkspaceVisible(WORKSPACE->m_iID)) { if (!isWorkspaceVisible(WORKSPACE->m_iID)) {
if (WORKSPACE->m_bIsSpecialWorkspace) { if (WORKSPACE->m_bIsSpecialWorkspace) {
if (WORKSPACE->m_fAlpha.fl() > 0.f /* don't abruptly end the fadeout */) { if (WORKSPACE->m_fAlpha.value() > 0.f /* don't abruptly end the fadeout */) {
++it; ++it;
continue; continue;
} }
@ -1431,12 +1445,16 @@ void CCompositor::cleanupFadingOut(const int& monid) {
bool valid = windowExists(w); bool valid = windowExists(w);
if (!valid || !w->m_bFadingOut || w->m_fAlpha.fl() == 0.f) { if (!valid || !w->m_bFadingOut || w->m_fAlpha.value() == 0.f) {
if (valid && !w->m_bReadyToDelete) if (valid) {
w->m_bFadingOut = false;
if (!w->m_bReadyToDelete)
continue; continue;
w->m_bFadingOut = false;
removeWindowFromVectorSafe(w); removeWindowFromVectorSafe(w);
}
std::erase(m_vWindowsFadingOut, w); std::erase(m_vWindowsFadingOut, w);
Debug::log(LOG, "Cleanup: destroyed a window"); Debug::log(LOG, "Cleanup: destroyed a window");
@ -1480,7 +1498,7 @@ void CCompositor::cleanupFadingOut(const int& monid) {
if (ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) if (ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND || ls->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM)
g_pHyprOpenGL->markBlurDirtyForMonitor(getMonitorFromID(monid)); g_pHyprOpenGL->markBlurDirtyForMonitor(getMonitorFromID(monid));
if (ls->fadingOut && ls->readyToDelete && !ls->alpha.isBeingAnimated()) { if (ls->fadingOut && ls->readyToDelete && ls->isFadedOut()) {
for (auto& m : m_vMonitors) { for (auto& m : m_vMonitors) {
for (auto& lsl : m->m_aLayerSurfaceLayers) { for (auto& lsl : m->m_aLayerSurfaceLayers) {
if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](std::unique_ptr<SLayerSurface>& other) { return other.get() == ls; }) != lsl.end()) { if (!lsl.empty() && std::find_if(lsl.begin(), lsl.end(), [&](std::unique_ptr<SLayerSurface>& other) { return other.get() == ls; }) != lsl.end()) {
@ -1523,7 +1541,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
return nullptr; return nullptr;
// 0 -> history, 1 -> shared length // 0 -> history, 1 -> shared length
static auto* const PMETHOD = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:focus_preferred_method"); static auto PMETHOD = CConfigValue<Hyprlang::INT>("binds:focus_preferred_method");
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
@ -1585,7 +1603,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
break; break;
} }
if (**PMETHOD == 0 /* history */) { if (*PMETHOD == 0 /* history */) {
if (intersectLength > 0) { if (intersectLength > 0) {
// get idx // get idx
@ -1778,31 +1796,6 @@ void checkFocusSurfaceIter(wlr_surface* pSurface, int x, int y, void* data) {
pair->second = pair->second || pSurface == pair->first; pair->second = pair->second || pSurface == pair->first;
} }
CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
if (!pMouse->currentConstraint)
return nullptr;
const auto PSURFACE = pMouse->currentConstraint->surface;
for (auto& w : m_vWindows) {
if (w->isHidden() || !w->m_bIsMapped || !w->m_pWLSurface.exists())
continue;
if (w->m_bIsX11) {
if (PSURFACE == w->m_pWLSurface.wlr())
return w.get();
} else {
std::pair<wlr_surface*, bool> check = {PSURFACE, false};
wlr_surface_for_each_surface(w->m_uSurface.xdg->surface, checkFocusSurfaceIter, &check);
if (check.second)
return w.get();
}
}
return nullptr;
}
CMonitor* CCompositor::getMonitorInDirection(const char& dir) { CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
return this->getMonitorInDirection(m_pLastMonitor, dir); return this->getMonitorInDirection(m_pLastMonitor, dir);
} }
@ -1891,30 +1884,30 @@ void CCompositor::updateWorkspaceWindows(const int64_t& id) {
void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) { void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
// optimization // optimization
static auto* const PACTIVECOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:col.active_border"); static auto PACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.active_border");
static auto* const PINACTIVECOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:col.inactive_border"); static auto PINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.inactive_border");
static auto* const PNOGROUPACTIVECOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:col.nogroup_border_active"); static auto PNOGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border_active");
static auto* const PNOGROUPINACTIVECOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:col.nogroup_border"); static auto PNOGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("general:col.nogroup_border");
static auto* const PGROUPACTIVECOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("group:col.border_active"); static auto PGROUPACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_active");
static auto* const PGROUPINACTIVECOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("group:col.border_inactive"); static auto PGROUPINACTIVECOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_inactive");
static auto* const PGROUPACTIVELOCKEDCOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("group:col.border_locked_active"); static auto PGROUPACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_active");
static auto* const PGROUPINACTIVELOCKEDCOL = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("group:col.border_locked_inactive"); static auto PGROUPINACTIVELOCKEDCOL = CConfigValue<Hyprlang::CUSTOMTYPE>("group:col.border_locked_inactive");
static auto* const PINACTIVEALPHA = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity"); static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
static auto* const PACTIVEALPHA = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:active_opacity"); static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
static auto* const PFULLSCREENALPHA = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:fullscreen_opacity"); static auto PFULLSCREENALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:fullscreen_opacity");
static auto* const PSHADOWCOL = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:col.shadow"); static auto PSHADOWCOL = CConfigValue<Hyprlang::INT>("decoration:col.shadow");
static auto* const PSHADOWCOLINACTIVE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:col.shadow_inactive"); static auto PSHADOWCOLINACTIVE = CConfigValue<Hyprlang::INT>("decoration:col.shadow_inactive");
static auto* const PDIMSTRENGTH = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:dim_strength"); static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
static auto* const PDIMENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:dim_inactive"); static auto PDIMENABLED = CConfigValue<Hyprlang::INT>("decoration:dim_inactive");
auto* const ACTIVECOL = (CGradientValueData*)(*PACTIVECOL)->getData(); auto* const ACTIVECOL = (CGradientValueData*)(PACTIVECOL.ptr())->getData();
auto* const INACTIVECOL = (CGradientValueData*)(*PINACTIVECOL)->getData(); auto* const INACTIVECOL = (CGradientValueData*)(PINACTIVECOL.ptr())->getData();
auto* const NOGROUPACTIVECOL = (CGradientValueData*)(*PNOGROUPACTIVECOL)->getData(); auto* const NOGROUPACTIVECOL = (CGradientValueData*)(PNOGROUPACTIVECOL.ptr())->getData();
auto* const NOGROUPINACTIVECOL = (CGradientValueData*)(*PNOGROUPINACTIVECOL)->getData(); auto* const NOGROUPINACTIVECOL = (CGradientValueData*)(PNOGROUPINACTIVECOL.ptr())->getData();
auto* const GROUPACTIVECOL = (CGradientValueData*)(*PGROUPACTIVECOL)->getData(); auto* const GROUPACTIVECOL = (CGradientValueData*)(PGROUPACTIVECOL.ptr())->getData();
auto* const GROUPINACTIVECOL = (CGradientValueData*)(*PGROUPINACTIVECOL)->getData(); auto* const GROUPINACTIVECOL = (CGradientValueData*)(PGROUPINACTIVECOL.ptr())->getData();
auto* const GROUPACTIVELOCKEDCOL = (CGradientValueData*)(*PGROUPACTIVELOCKEDCOL)->getData(); auto* const GROUPACTIVELOCKEDCOL = (CGradientValueData*)(PGROUPACTIVELOCKEDCOL.ptr())->getData();
auto* const GROUPINACTIVELOCKEDCOL = (CGradientValueData*)(*PGROUPINACTIVELOCKEDCOL)->getData(); auto* const GROUPINACTIVELOCKEDCOL = (CGradientValueData*)(PGROUPINACTIVELOCKEDCOL.ptr())->getData();
auto setBorderColor = [&](CGradientValueData grad) -> void { auto setBorderColor = [&](CGradientValueData grad) -> void {
if (grad == pWindow->m_cRealBorderColor) if (grad == pWindow->m_cRealBorderColor)
@ -1952,31 +1945,31 @@ void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
// opacity // opacity
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
if (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) { if (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) {
pWindow->m_fActiveInactiveAlpha = **PFULLSCREENALPHA; pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA;
} else { } else {
if (pWindow == m_pLastWindow) if (pWindow == m_pLastWindow)
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaOverride.toUnderlying() ? pWindow->m_sSpecialRenderData.alpha.toUnderlying() : pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaOverride.toUnderlying() ? pWindow->m_sSpecialRenderData.alpha.toUnderlying() :
pWindow->m_sSpecialRenderData.alpha.toUnderlying() * **PACTIVEALPHA; pWindow->m_sSpecialRenderData.alpha.toUnderlying() * *PACTIVEALPHA;
else else
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() != -1 ? pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() != -1 ?
(pWindow->m_sSpecialRenderData.alphaInactiveOverride.toUnderlying() ? pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() : (pWindow->m_sSpecialRenderData.alphaInactiveOverride.toUnderlying() ? pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() :
pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() * **PINACTIVEALPHA) : pWindow->m_sSpecialRenderData.alphaInactive.toUnderlying() * *PINACTIVEALPHA) :
**PINACTIVEALPHA; *PINACTIVEALPHA;
} }
// dim // dim
if (pWindow == m_pLastWindow || pWindow->m_sAdditionalConfigData.forceNoDim || !**PDIMENABLED) { if (pWindow == m_pLastWindow || pWindow->m_sAdditionalConfigData.forceNoDim || !*PDIMENABLED) {
pWindow->m_fDimPercent = 0; pWindow->m_fDimPercent = 0;
} else { } else {
pWindow->m_fDimPercent = **PDIMSTRENGTH; pWindow->m_fDimPercent = *PDIMSTRENGTH;
} }
// shadow // shadow
if (pWindow->m_iX11Type != 2 && !pWindow->m_bX11DoesntWantBorders) { if (pWindow->m_iX11Type != 2 && !pWindow->m_bX11DoesntWantBorders) {
if (pWindow == m_pLastWindow) { if (pWindow == m_pLastWindow) {
pWindow->m_cRealShadowColor = CColor(**PSHADOWCOL); pWindow->m_cRealShadowColor = CColor(*PSHADOWCOL);
} else { } else {
pWindow->m_cRealShadowColor = CColor(**PSHADOWCOLINACTIVE != INT_MAX ? **PSHADOWCOLINACTIVE : **PSHADOWCOL); pWindow->m_cRealShadowColor = CColor(*PSHADOWCOLINACTIVE != INT_MAX ? *PSHADOWCOLINACTIVE : *PSHADOWCOL);
} }
} else { } else {
pWindow->m_cRealShadowColor.setValueAndWarp(CColor(0, 0, 0, 0)); // no shadow pWindow->m_cRealShadowColor.setValueAndWarp(CColor(0, 0, 0, 0)); // no shadow
@ -2023,7 +2016,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
// additionally, move floating and fs windows manually // additionally, move floating and fs windows manually
if (w->m_bIsFloating) if (w->m_bIsFloating)
w->m_vRealPosition = w->m_vRealPosition.vec() - pMonitorA->vecPosition + pMonitorB->vecPosition; w->m_vRealPosition = w->m_vRealPosition.value() - pMonitorA->vecPosition + pMonitorB->vecPosition;
if (w->m_bIsFullscreen) { if (w->m_bIsFullscreen) {
w->m_vRealPosition = pMonitorB->vecPosition; w->m_vRealPosition = pMonitorB->vecPosition;
@ -2048,7 +2041,7 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
// additionally, move floating and fs windows manually // additionally, move floating and fs windows manually
if (w->m_bIsFloating) if (w->m_bIsFloating)
w->m_vRealPosition = w->m_vRealPosition.vec() - pMonitorB->vecPosition + pMonitorA->vecPosition; w->m_vRealPosition = w->m_vRealPosition.value() - pMonitorB->vecPosition + pMonitorA->vecPosition;
if (w->m_bIsFullscreen) { if (w->m_bIsFullscreen) {
w->m_vRealPosition = pMonitorA->vecPosition; w->m_vRealPosition = pMonitorA->vecPosition;
@ -2062,6 +2055,9 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
pMonitorA->activeWorkspace = PWORKSPACEB->m_iID; pMonitorA->activeWorkspace = PWORKSPACEB->m_iID;
pMonitorB->activeWorkspace = PWORKSPACEA->m_iID; pMonitorB->activeWorkspace = PWORKSPACEA->m_iID;
PWORKSPACEA->rememberPrevWorkspace(PWORKSPACEB);
PWORKSPACEB->rememberPrevWorkspace(PWORKSPACEA);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorA->ID); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorA->ID);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorB->ID); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorB->ID);
@ -2076,8 +2072,10 @@ void CCompositor::swapActiveWorkspaces(CMonitor* pMonitorA, CMonitor* pMonitorB)
// event // event
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEA->m_szName + "," + pMonitorB->szName});
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEA->m_iID, PWORKSPACEA->m_szName, pMonitorB->szName)});
EMIT_HOOK_EVENT("moveWorkspace", (std::vector<void*>{PWORKSPACEA, pMonitorB})); EMIT_HOOK_EVENT("moveWorkspace", (std::vector<void*>{PWORKSPACEA, pMonitorB}));
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", PWORKSPACEB->m_szName + "," + pMonitorA->szName});
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", PWORKSPACEB->m_iID, PWORKSPACEB->m_szName, pMonitorA->szName)});
EMIT_HOOK_EVENT("moveWorkspace", (std::vector<void*>{PWORKSPACEB, pMonitorA})); EMIT_HOOK_EVENT("moveWorkspace", (std::vector<void*>{PWORKSPACEB, pMonitorA}));
} }
@ -2170,7 +2168,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
// fix old mon // fix old mon
int nextWorkspaceOnMonitorID = -1; int nextWorkspaceOnMonitorID = -1;
if (!SWITCHINGISACTIVE || !POLDMON) if (!SWITCHINGISACTIVE)
nextWorkspaceOnMonitorID = pWorkspace->m_iID; nextWorkspaceOnMonitorID = pWorkspace->m_iID;
else { else {
for (auto& w : m_vWorkspaces) { for (auto& w : m_vWorkspaces) {
@ -2215,14 +2213,14 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
if (w->m_bIsMapped && !w->isHidden()) { if (w->m_bIsMapped && !w->isHidden()) {
if (POLDMON) { if (POLDMON) {
if (w->m_bIsFloating) if (w->m_bIsFloating)
w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition; w->m_vRealPosition = w->m_vRealPosition.value() - POLDMON->vecPosition + pMonitor->vecPosition;
if (w->m_bIsFullscreen) { if (w->m_bIsFullscreen) {
w->m_vRealPosition = pMonitor->vecPosition; w->m_vRealPosition = pMonitor->vecPosition;
w->m_vRealSize = pMonitor->vecSize; w->m_vRealSize = pMonitor->vecSize;
} }
} else { } else {
w->m_vRealPosition = Vector2D{(int)w->m_vRealPosition.goalv().x % (int)pMonitor->vecSize.x, (int)w->m_vRealPosition.goalv().y % (int)pMonitor->vecSize.y}; w->m_vRealPosition = Vector2D{(int)w->m_vRealPosition.goal().x % (int)pMonitor->vecSize.x, (int)w->m_vRealPosition.goal().y % (int)pMonitor->vecSize.y};
} }
} }
@ -2258,6 +2256,7 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
// event // event
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspace", pWorkspace->m_szName + "," + pMonitor->szName});
g_pEventManager->postEvent(SHyprIPCEvent{"moveworkspacev2", std::format("{},{},{}", pWorkspace->m_iID, pWorkspace->m_szName, pMonitor->szName)});
EMIT_HOOK_EVENT("moveWorkspace", (std::vector<void*>{pWorkspace, pMonitor})); EMIT_HOOK_EVENT("moveWorkspace", (std::vector<void*>{pWorkspace, pMonitor}));
} }
@ -2298,7 +2297,7 @@ void CCompositor::updateFullscreenFadeOnWorkspace(CWorkspace* pWorkspace) {
const auto PMONITOR = getMonitorFromID(pWorkspace->m_iMonitorID); const auto PMONITOR = getMonitorFromID(pWorkspace->m_iMonitorID);
if (pWorkspace->m_iID == PMONITOR->activeWorkspace) { if (pWorkspace->m_iID == PMONITOR->activeWorkspace || pWorkspace->m_iID == PMONITOR->specialWorkspaceID) {
for (auto& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { for (auto& ls : PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
if (!ls->fadingOut) if (!ls->fadingOut)
ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL ? 0.f : 1.f; ls->alpha = FULLSCREEN && pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL ? 0.f : 1.f;
@ -2315,6 +2314,11 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
return; return;
} }
if (pWindow->m_bIsFullscreen == on) {
Debug::log(LOG, "Window is already in the required fullscreen state");
return;
}
const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = getMonitorFromID(pWindow->m_iMonitorID);
const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID); const auto PWORKSPACE = getWorkspaceByID(pWindow->m_iWorkspaceID);
@ -2339,7 +2343,7 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
} }
updateFullscreenFadeOnWorkspace(PWORKSPACE); updateFullscreenFadeOnWorkspace(PWORKSPACE);
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv(), true); g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal(), true);
forceReportSizesToWindowsOnWorkspace(pWindow->m_iWorkspaceID); forceReportSizesToWindowsOnWorkspace(pWindow->m_iWorkspaceID);
@ -2462,9 +2466,9 @@ void CCompositor::warpCursorTo(const Vector2D& pos, bool force) {
// warpCursorTo should only be used for warps that // warpCursorTo should only be used for warps that
// should be disabled with no_cursor_warps // should be disabled with no_cursor_warps
static auto* const PNOWARPS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:no_cursor_warps"); static auto PNOWARPS = CConfigValue<Hyprlang::INT>("general:no_cursor_warps");
if (**PNOWARPS && !force) if (*PNOWARPS && !force)
return; return;
if (!m_sSeat.mouse) if (!m_sSeat.mouse)
@ -2578,7 +2582,7 @@ Vector2D CCompositor::parseWindowVectorArgsRelative(const std::string& args, con
void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) { void CCompositor::forceReportSizesToWindowsOnWorkspace(const int& wid) {
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
if (w->m_iWorkspaceID == wid && w->m_bIsMapped && !w->isHidden()) { if (w->m_iWorkspaceID == wid && w->m_bIsMapped && !w->isHidden()) {
g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.vec(), true); g_pXWaylandManager->setWindowSize(w.get(), w->m_vRealSize.value(), true);
} }
} }
} }
@ -2594,10 +2598,7 @@ CWorkspace* CCompositor::createNewWorkspace(const int& id, const int& monid, con
const bool SPECIAL = id >= SPECIAL_WORKSPACE_START && id <= -2; const bool SPECIAL = id >= SPECIAL_WORKSPACE_START && id <= -2;
const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(monID, NAME, SPECIAL)).get(); const auto PWORKSPACE = m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(id, monID, NAME, SPECIAL)).get();
PWORKSPACE->m_iID = id;
PWORKSPACE->m_iMonitorID = monID;
PWORKSPACE->m_fAlpha.setValueAndWarp(0); PWORKSPACE->m_fAlpha.setValueAndWarp(0);
@ -2668,9 +2669,6 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks
setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
pWindow->moveToWorkspace(pWorkspace->m_iID); pWindow->moveToWorkspace(pWorkspace->m_iID);
pWindow->updateToplevel();
pWindow->updateDynamicRules();
pWindow->uncacheWindowDecos();
if (!pWindow->m_bIsFloating) { if (!pWindow->m_bIsFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowRemovedTiling(pWindow); g_pLayoutManager->getCurrentLayout()->onWindowRemovedTiling(pWindow);
@ -2679,7 +2677,7 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks
g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow); g_pLayoutManager->getCurrentLayout()->onWindowCreatedTiling(pWindow);
} else { } else {
const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PWINDOWMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
const auto POSTOMON = pWindow->m_vRealPosition.goalv() - PWINDOWMONITOR->vecPosition; const auto POSTOMON = pWindow->m_vRealPosition.goal() - PWINDOWMONITOR->vecPosition;
const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); const auto PWORKSPACEMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
@ -2689,6 +2687,10 @@ void CCompositor::moveWindowToWorkspaceSafe(CWindow* pWindow, CWorkspace* pWorks
pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition; pWindow->m_vRealPosition = POSTOMON + PWORKSPACEMONITOR->vecPosition;
} }
pWindow->updateToplevel();
pWindow->updateDynamicRules();
pWindow->uncacheWindowDecos();
if (pWindow->m_sGroupData.pNextWindow) { if (pWindow->m_sGroupData.pNextWindow) {
CWindow* next = pWindow->m_sGroupData.pNextWindow; CWindow* next = pWindow->m_sGroupData.pNextWindow;
while (next != pWindow) { while (next != pWindow) {
@ -2776,9 +2778,9 @@ void CCompositor::arrangeMonitors() {
for (auto& m : m_vMonitors) { for (auto& m : m_vMonitors) {
Debug::log(LOG, "arrangeMonitors: {} xwayland [{}, {:.2f}]", m->szName, maxOffset, 0.f); Debug::log(LOG, "arrangeMonitors: {} xwayland [{}, {:.2f}]", m->szName, maxOffset, 0.f);
m->vecXWaylandPosition = {maxOffset, 0}; m->vecXWaylandPosition = {maxOffset, 0};
maxOffset += (**PXWLFORCESCALEZERO ? m->vecTransformedSize.x : m->vecSize.x); maxOffset += (*PXWLFORCESCALEZERO ? m->vecTransformedSize.x : m->vecSize.x);
if (**PXWLFORCESCALEZERO) if (*PXWLFORCESCALEZERO)
m->xwaylandScale = m->scale; m->xwaylandScale = m->scale;
else else
m->xwaylandScale = 1.f; m->xwaylandScale = 1.f;

View file

@ -21,7 +21,7 @@
#include "debug/HyprDebugOverlay.hpp" #include "debug/HyprDebugOverlay.hpp"
#include "debug/HyprNotificationOverlay.hpp" #include "debug/HyprNotificationOverlay.hpp"
#include "helpers/Monitor.hpp" #include "helpers/Monitor.hpp"
#include "helpers/Workspace.hpp" #include "desktop/Workspace.hpp"
#include "Window.hpp" #include "Window.hpp"
#include "render/Renderer.hpp" #include "render/Renderer.hpp"
#include "render/OpenGL.hpp" #include "render/OpenGL.hpp"
@ -57,7 +57,6 @@ class CCompositor {
wlr_layer_shell_v1* m_sWLRLayerShell; wlr_layer_shell_v1* m_sWLRLayerShell;
wlr_xdg_shell* m_sWLRXDGShell; wlr_xdg_shell* m_sWLRXDGShell;
wlr_cursor* m_sWLRCursor; wlr_cursor* m_sWLRCursor;
wlr_xcursor_manager* m_sWLRXCursorMgr;
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr; wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
wlr_output_manager_v1* m_sWLROutputMgr; wlr_output_manager_v1* m_sWLROutputMgr;
wlr_presentation* m_sWLRPresentation; wlr_presentation* m_sWLRPresentation;
@ -93,9 +92,7 @@ class CCompositor {
std::vector<std::shared_ptr<CMonitor>> m_vMonitors; std::vector<std::shared_ptr<CMonitor>> m_vMonitors;
std::vector<std::shared_ptr<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off std::vector<std::shared_ptr<CMonitor>> m_vRealMonitors; // for all monitors, even those turned off
std::vector<std::unique_ptr<CWindow>> m_vWindows; std::vector<std::unique_ptr<CWindow>> m_vWindows;
std::vector<std::unique_ptr<SXDGPopup>> m_vXDGPopups;
std::vector<std::unique_ptr<CWorkspace>> m_vWorkspaces; std::vector<std::unique_ptr<CWorkspace>> m_vWorkspaces;
std::vector<std::unique_ptr<SSubsurface>> m_vSubsurfaces;
std::vector<CWindow*> m_vWindowsFadingOut; std::vector<CWindow*> m_vWindowsFadingOut;
std::vector<SLayerSurface*> m_vSurfacesFadingOut; std::vector<SLayerSurface*> m_vSurfacesFadingOut;
@ -143,7 +140,6 @@ class CCompositor {
Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*); Vector2D vectorToSurfaceLocal(const Vector2D&, CWindow*, wlr_surface*);
CMonitor* getMonitorFromOutput(wlr_output*); CMonitor* getMonitorFromOutput(wlr_output*);
CMonitor* getRealMonitorFromOutput(wlr_output*); CMonitor* getRealMonitorFromOutput(wlr_output*);
CWindow* getWindowForPopup(wlr_xdg_popup*);
CWindow* getWindowFromSurface(wlr_surface*); CWindow* getWindowFromSurface(wlr_surface*);
CWindow* getWindowFromHandle(uint32_t); CWindow* getWindowFromHandle(uint32_t);
CWindow* getWindowFromZWLRHandle(wl_resource*); CWindow* getWindowFromZWLRHandle(wl_resource*);
@ -169,7 +165,6 @@ class CCompositor {
int getNextAvailableNamedWorkspace(); int getNextAvailableNamedWorkspace();
bool isPointOnAnyMonitor(const Vector2D&); bool isPointOnAnyMonitor(const Vector2D&);
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr); bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
CWindow* getConstraintWindow(SMouse*);
CMonitor* getMonitorInDirection(const char&); CMonitor* getMonitorInDirection(const char&);
CMonitor* getMonitorInDirection(CMonitor*, const char&); CMonitor* getMonitorInDirection(CMonitor*, const char&);
void updateAllWindowsAnimatedDecorationValues(); void updateAllWindowsAnimatedDecorationValues();
@ -180,7 +175,7 @@ class CCompositor {
void swapActiveWorkspaces(CMonitor*, CMonitor*); void swapActiveWorkspaces(CMonitor*, CMonitor*);
CMonitor* getMonitorFromString(const std::string&); CMonitor* getMonitorFromString(const std::string&);
bool workspaceIDOutOfBounds(const int64_t&); bool workspaceIDOutOfBounds(const int64_t&);
void setWindowFullscreen(CWindow*, bool, eFullscreenMode); void setWindowFullscreen(CWindow*, bool, eFullscreenMode mode = FULLSCREEN_INVALID);
void updateFullscreenFadeOnWorkspace(CWorkspace*); void updateFullscreenFadeOnWorkspace(CWorkspace*);
CWindow* getX11Parent(CWindow*); CWindow* getX11Parent(CWindow*);
void scheduleFrameForMonitor(CMonitor*); void scheduleFrameForMonitor(CMonitor*);
@ -237,4 +232,7 @@ inline std::map<std::string, xcb_atom_t> HYPRATOMS = {HYPRATOM("_NET_WM_WINDOW_T
HYPRATOM("_NET_WM_WINDOW_TYPE_POPUP_MENU"), HYPRATOM("_NET_WM_WINDOW_TYPE_POPUP_MENU"),
HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLTIP"), HYPRATOM("_NET_WM_WINDOW_TYPE_TOOLTIP"),
HYPRATOM("_NET_WM_WINDOW_TYPE_NOTIFICATION"), HYPRATOM("_NET_WM_WINDOW_TYPE_NOTIFICATION"),
HYPRATOM("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE")}; HYPRATOM("_KDE_NET_WM_WINDOW_TYPE_OVERRIDE"),
HYPRATOM("_NET_SUPPORTING_WM_CHECK"),
HYPRATOM("_NET_WM_NAME"),
HYPRATOM("UTF8_STRING")};

View file

@ -3,16 +3,17 @@
#include "render/decorations/CHyprDropShadowDecoration.hpp" #include "render/decorations/CHyprDropShadowDecoration.hpp"
#include "render/decorations/CHyprGroupBarDecoration.hpp" #include "render/decorations/CHyprGroupBarDecoration.hpp"
#include "render/decorations/CHyprBorderDecoration.hpp" #include "render/decorations/CHyprBorderDecoration.hpp"
#include "config/ConfigValue.hpp"
CWindow::CWindow() { CWindow::CWindow() {
m_vRealPosition.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); m_vRealPosition.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE);
m_vRealSize.create(AVARTYPE_VECTOR, g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE); m_vRealSize.create(g_pConfigManager->getAnimationPropertyConfig("windowsIn"), (void*)this, AVARDAMAGE_ENTIRE);
m_fBorderFadeAnimationProgress.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("border"), (void*)this, AVARDAMAGE_BORDER); m_fBorderFadeAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("border"), (void*)this, AVARDAMAGE_BORDER);
m_fBorderAngleAnimationProgress.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("borderangle"), (void*)this, AVARDAMAGE_BORDER); m_fBorderAngleAnimationProgress.create(g_pConfigManager->getAnimationPropertyConfig("borderangle"), (void*)this, AVARDAMAGE_BORDER);
m_fAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE); m_fAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeIn"), (void*)this, AVARDAMAGE_ENTIRE);
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), (void*)this, AVARDAMAGE_ENTIRE); m_fActiveInactiveAlpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeSwitch"), (void*)this, AVARDAMAGE_ENTIRE);
m_cRealShadowColor.create(AVARTYPE_COLOR, g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW); m_cRealShadowColor.create(g_pConfigManager->getAnimationPropertyConfig("fadeShadow"), (void*)this, AVARDAMAGE_SHADOW);
m_fDimPercent.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeDim"), (void*)this, AVARDAMAGE_ENTIRE); m_fDimPercent.create(g_pConfigManager->getAnimationPropertyConfig("fadeDim"), (void*)this, AVARDAMAGE_ENTIRE);
addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(this)); addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(this));
addWindowDeco(std::make_unique<CHyprBorderDecoration>(this)); addWindowDeco(std::make_unique<CHyprBorderDecoration>(this));
@ -39,8 +40,8 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
if (m_sAdditionalConfigData.dimAround) { if (m_sAdditionalConfigData.dimAround) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
return {{m_vRealPosition.vec().x - PMONITOR->vecPosition.x, m_vRealPosition.vec().y - PMONITOR->vecPosition.y}, return {{m_vRealPosition.value().x - PMONITOR->vecPosition.x, m_vRealPosition.value().y - PMONITOR->vecPosition.y},
{PMONITOR->vecSize.x - (m_vRealPosition.vec().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition.vec().y - PMONITOR->vecPosition.y)}}; {PMONITOR->vecSize.x - (m_vRealPosition.value().x - PMONITOR->vecPosition.x), PMONITOR->vecSize.y - (m_vRealPosition.value().y - PMONITOR->vecPosition.y)}};
} }
SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}}; SWindowDecorationExtents maxExtents = {{BORDERSIZE + 2, BORDERSIZE + 2}, {BORDERSIZE + 2, BORDERSIZE + 2}};
@ -101,8 +102,8 @@ CBox CWindow::getFullWindowBoundingBox() {
auto maxExtents = getFullWindowExtents(); auto maxExtents = getFullWindowExtents();
CBox finalBox = {m_vRealPosition.vec().x - maxExtents.topLeft.x, m_vRealPosition.vec().y - maxExtents.topLeft.y, CBox finalBox = {m_vRealPosition.value().x - maxExtents.topLeft.x, m_vRealPosition.value().y - maxExtents.topLeft.y,
m_vRealSize.vec().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize.vec().y + maxExtents.topLeft.y + maxExtents.bottomRight.y}; m_vRealSize.value().x + maxExtents.topLeft.x + maxExtents.bottomRight.x, m_vRealSize.value().y + maxExtents.topLeft.y + maxExtents.bottomRight.y};
return finalBox; return finalBox;
} }
@ -154,14 +155,14 @@ CBox CWindow::getWindowBoxUnified(uint64_t properties) {
if (properties & FULL_EXTENTS) if (properties & FULL_EXTENTS)
EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(this, false)); EXTENTS.addExtents(g_pDecorationPositioner->getWindowDecorationExtents(this, false));
CBox box = {m_vRealPosition.vec().x, m_vRealPosition.vec().y, m_vRealSize.vec().x, m_vRealSize.vec().y}; CBox box = {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
box.addExtents(EXTENTS); box.addExtents(EXTENTS);
return box; return box;
} }
CBox CWindow::getWindowMainSurfaceBox() { CBox CWindow::getWindowMainSurfaceBox() {
return {m_vRealPosition.vec().x, m_vRealPosition.vec().y, m_vRealSize.vec().x, m_vRealSize.vec().y}; return {m_vRealPosition.value().x, m_vRealPosition.value().y, m_vRealSize.value().x, m_vRealSize.value().y};
} }
SWindowDecorationExtents CWindow::getFullWindowReservedArea() { SWindowDecorationExtents CWindow::getFullWindowReservedArea() {
@ -193,7 +194,14 @@ void CWindow::updateWindowDecos() {
m_vDecosToRemove.clear(); m_vDecosToRemove.clear();
// make a copy because updateWindow can remove decos.
std::vector<IHyprWindowDecoration*> decos;
for (auto& wd : m_dWindowDecorations) { for (auto& wd : m_dWindowDecorations) {
decos.push_back(wd.get());
}
for (auto& wd : decos) {
wd->updateWindow(this); wd->updateWindow(this);
} }
} }
@ -239,13 +247,12 @@ bool CWindow::checkInputOnDecos(const eInputType type, const Vector2D& mouseCoor
pid_t CWindow::getPID() { pid_t CWindow::getPID() {
pid_t PID = -1; pid_t PID = -1;
if (!m_bIsX11) { if (!m_bIsX11) {
if (!m_uSurface.xdg)
if (!m_bIsMapped)
return -1; return -1;
wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr); wl_client_get_credentials(wl_resource_get_client(m_uSurface.xdg->resource), &PID, nullptr, nullptr);
} else { } else {
if (!m_bIsMapped) if (!m_uSurface.xwayland)
return -1; return -1;
PID = m_uSurface.xwayland->pid; PID = m_uSurface.xwayland->pid;
@ -336,7 +343,7 @@ void sendLeaveIter(wlr_surface* pSurface, int x, int y, void* data) {
} }
void CWindow::updateSurfaceScaleTransformDetails() { void CWindow::updateSurfaceScaleTransformDetails() {
if (!m_bIsMapped || m_bHidden) if (!m_bIsMapped || m_bHidden || g_pCompositor->m_bUnsafeState)
return; return;
const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(m_iLastSurfaceMonitorID); const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(m_iLastSurfaceMonitorID);
@ -345,6 +352,9 @@ void CWindow::updateSurfaceScaleTransformDetails() {
const auto PNEWMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PNEWMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (!PNEWMONITOR)
return;
if (PNEWMONITOR != PLASTMONITOR) { if (PNEWMONITOR != PLASTMONITOR) {
if (PLASTMONITOR && PLASTMONITOR->m_bEnabled) if (PLASTMONITOR && PLASTMONITOR->m_bEnabled)
wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendLeaveIter, PLASTMONITOR->output); wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendLeaveIter, PLASTMONITOR->output);
@ -371,7 +381,7 @@ void CWindow::moveToWorkspace(int workspaceID) {
if (m_iWorkspaceID == workspaceID) if (m_iWorkspaceID == workspaceID)
return; return;
static auto* const PCLOSEONLASTSPECIAL = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:close_special_on_empty"); static auto PCLOSEONLASTSPECIAL = CConfigValue<Hyprlang::INT>("misc:close_special_on_empty");
const int OLDWORKSPACE = m_iWorkspaceID; const int OLDWORKSPACE = m_iWorkspaceID;
@ -383,6 +393,7 @@ void CWindow::moveToWorkspace(int workspaceID) {
if (PWORKSPACE) { if (PWORKSPACE) {
g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", std::format("{:x},{}", (uintptr_t)this, PWORKSPACE->m_szName)}); g_pEventManager->postEvent(SHyprIPCEvent{"movewindow", std::format("{:x},{}", (uintptr_t)this, PWORKSPACE->m_szName)});
g_pEventManager->postEvent(SHyprIPCEvent{"movewindowv2", std::format("{:x},{},{}", (uintptr_t)this, PWORKSPACE->m_iID, PWORKSPACE->m_szName)});
EMIT_HOOK_EVENT("moveWindow", (std::vector<void*>{this, PWORKSPACE})); EMIT_HOOK_EVENT("moveWindow", (std::vector<void*>{this, PWORKSPACE}));
} }
@ -392,9 +403,9 @@ void CWindow::moveToWorkspace(int workspaceID) {
} }
// update xwayland coords // update xwayland coords
g_pXWaylandManager->setWindowSize(this, m_vRealSize.vec()); g_pXWaylandManager->setWindowSize(this, m_vRealSize.value());
if (g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE) == 0 && **PCLOSEONLASTSPECIAL) { if (g_pCompositor->isWorkspaceSpecial(OLDWORKSPACE) && g_pCompositor->getWindowsOnWorkspace(OLDWORKSPACE) == 0 && *PCLOSEONLASTSPECIAL) {
const auto PWS = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); const auto PWS = g_pCompositor->getWorkspaceByID(OLDWORKSPACE);
if (PWS) { if (PWS) {
@ -433,11 +444,11 @@ void CWindow::removeDecorationByType(eDecorationType type) {
} }
void unregisterVar(void* ptr) { void unregisterVar(void* ptr) {
((CAnimatedVariable*)ptr)->unregister(); ((CBaseAnimatedVariable*)ptr)->unregister();
} }
void CWindow::onUnmap() { void CWindow::onUnmap() {
static auto* const PCLOSEONLASTSPECIAL = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:close_special_on_empty"); static auto PCLOSEONLASTSPECIAL = CConfigValue<Hyprlang::INT>("misc:close_special_on_empty");
if (g_pCompositor->m_pLastWindow == this) if (g_pCompositor->m_pLastWindow == this)
g_pCompositor->m_pLastWindow = nullptr; g_pCompositor->m_pLastWindow = nullptr;
@ -459,7 +470,7 @@ void CWindow::onUnmap() {
hyprListener_unmapWindow.removeCallback(); hyprListener_unmapWindow.removeCallback();
if (**PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(m_iWorkspaceID) == 0 && g_pCompositor->isWorkspaceSpecial(m_iWorkspaceID)) { if (*PCLOSEONLASTSPECIAL && g_pCompositor->getWindowsOnWorkspace(m_iWorkspaceID) == 0 && g_pCompositor->isWorkspaceSpecial(m_iWorkspaceID)) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
if (PMONITOR && PMONITOR->specialWorkspaceID == m_iWorkspaceID) if (PMONITOR && PMONITOR->specialWorkspaceID == m_iWorkspaceID)
PMONITOR->setSpecialWorkspace(nullptr); PMONITOR->setSpecialWorkspace(nullptr);
@ -471,12 +482,17 @@ void CWindow::onUnmap() {
PMONITOR->solitaryClient = nullptr; PMONITOR->solitaryClient = nullptr;
g_pCompositor->updateWorkspaceWindows(m_iWorkspaceID); g_pCompositor->updateWorkspaceWindows(m_iWorkspaceID);
if (m_bIsX11)
return;
m_pSubsurfaceHead.reset();
m_pPopupHead.reset();
} }
void CWindow::onMap() { void CWindow::onMap() {
m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(this)); m_pWLSurface.assign(g_pXWaylandManager->getWindowSurface(this), this);
m_pWLSurface.m_pOwner = this;
// JIC, reset the callbacks. If any are set, we'll make sure they are cleared so we don't accidentally unset them. (In case a window got remapped) // JIC, reset the callbacks. If any are set, we'll make sure they are cleared so we don't accidentally unset them. (In case a window got remapped)
m_vRealPosition.resetAllCallbacks(); m_vRealPosition.resetAllCallbacks();
@ -516,10 +532,16 @@ void CWindow::onMap() {
m_bTearingHint = ctrl->pWlrHint->current; m_bTearingHint = ctrl->pWlrHint->current;
break; break;
} }
if (m_bIsX11)
return;
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
m_pPopupHead = std::make_unique<CPopup>(this);
} }
void CWindow::onBorderAngleAnimEnd(void* ptr) { void CWindow::onBorderAngleAnimEnd(void* ptr) {
const auto PANIMVAR = (CAnimatedVariable*)ptr; const auto PANIMVAR = (CAnimatedVariable<float>*)ptr;
const std::string STYLE = PANIMVAR->getConfig()->pValues->internalStyle; const std::string STYLE = PANIMVAR->getConfig()->pValues->internalStyle;
@ -673,6 +695,38 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
m_eIdleInhibitMode = IDLEINHIBIT_FULLSCREEN; m_eIdleInhibitMode = IDLEINHIBIT_FULLSCREEN;
else else
Debug::log(ERR, "Rule idleinhibit: unknown mode {}", IDLERULE); Debug::log(ERR, "Rule idleinhibit: unknown mode {}", IDLERULE);
} else if (r.szRule.starts_with("maxsize")) {
try {
if (!m_bIsFloating)
return;
const auto VEC = configStringToVector2D(r.szRule.substr(8));
if (VEC.x < 1 || VEC.y < 1) {
Debug::log(ERR, "Invalid size for maxsize");
return;
}
m_sAdditionalConfigData.maxSize = VEC;
m_vRealSize = Vector2D(std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().x, m_vRealSize.goal().x),
std::min((double)m_sAdditionalConfigData.maxSize.toUnderlying().y, m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal());
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "maxsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
} else if (r.szRule.starts_with("minsize")) {
try {
if (!m_bIsFloating)
return;
const auto VEC = configStringToVector2D(r.szRule.substr(8));
if (VEC.x < 1 || VEC.y < 1) {
Debug::log(ERR, "Invalid size for minsize");
return;
}
m_sAdditionalConfigData.minSize = VEC;
m_vRealSize = Vector2D(std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().x, m_vRealSize.goal().x),
std::max((double)m_sAdditionalConfigData.minSize.toUnderlying().y, m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(this, m_vRealSize.goal());
setHidden(false);
} catch (std::exception& e) { Debug::log(ERR, "minsize rule \"{}\" failed with: {}", r.szRule, e.what()); }
} }
} }
@ -687,6 +741,8 @@ void CWindow::updateDynamicRules() {
m_sAdditionalConfigData.forceNoDim = false; m_sAdditionalConfigData.forceNoDim = false;
if (!m_sAdditionalConfigData.forceOpaqueOverridden) if (!m_sAdditionalConfigData.forceOpaqueOverridden)
m_sAdditionalConfigData.forceOpaque = false; m_sAdditionalConfigData.forceOpaque = false;
m_sAdditionalConfigData.maxSize = Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
m_sAdditionalConfigData.minSize = Vector2D(20, 20);
m_sAdditionalConfigData.forceNoAnims = false; m_sAdditionalConfigData.forceNoAnims = false;
m_sAdditionalConfigData.animationStyle = std::string(""); m_sAdditionalConfigData.animationStyle = std::string("");
m_sAdditionalConfigData.rounding = -1; m_sAdditionalConfigData.rounding = -1;
@ -716,10 +772,10 @@ bool CWindow::isInCurvedCorner(double x, double y) {
return false; return false;
// (x0, y0), (x0, y1), ... are the center point of rounding at each corner // (x0, y0), (x0, y1), ... are the center point of rounding at each corner
double x0 = m_vRealPosition.vec().x + ROUNDING; double x0 = m_vRealPosition.value().x + ROUNDING;
double y0 = m_vRealPosition.vec().y + ROUNDING; double y0 = m_vRealPosition.value().y + ROUNDING;
double x1 = m_vRealPosition.vec().x + m_vRealSize.vec().x - ROUNDING; double x1 = m_vRealPosition.value().x + m_vRealSize.value().x - ROUNDING;
double y1 = m_vRealPosition.vec().y + m_vRealSize.vec().y - ROUNDING; double y1 = m_vRealPosition.value().y + m_vRealSize.value().y - ROUNDING;
if (x < x0 && y < y0) { if (x < x0 && y < y0) {
return Vector2D{x0, y0}.distance(Vector2D{x, y}) > (double)ROUNDING; return Vector2D{x0, y0}.distance(Vector2D{x, y}) > (double)ROUNDING;
@ -752,7 +808,7 @@ bool CWindow::hasPopupAt(const Vector2D& pos) {
return false; return false;
wlr_surface* resultSurf = nullptr; wlr_surface* resultSurf = nullptr;
Vector2D origin = m_vRealPosition.vec(); Vector2D origin = m_vRealPosition.value();
SExtensionFindingData data = {origin, pos, &resultSurf}; SExtensionFindingData data = {origin, pos, &resultSurf};
wlr_xdg_surface_for_each_popup_surface(m_uSurface.xdg, findExtensionForVector2D, &data); wlr_xdg_surface_for_each_popup_surface(m_uSurface.xdg, findExtensionForVector2D, &data);
@ -891,8 +947,8 @@ void CWindow::setGroupCurrent(CWindow* pWindow) {
const bool FULLSCREEN = PCURRENT->m_bIsFullscreen; const bool FULLSCREEN = PCURRENT->m_bIsFullscreen;
const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PCURRENT->m_iWorkspaceID); const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PCURRENT->m_iWorkspaceID);
const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goalv(); const auto PWINDOWSIZE = PCURRENT->m_vRealSize.goal();
const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goalv(); const auto PWINDOWPOS = PCURRENT->m_vRealPosition.goal();
const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow; const auto CURRENTISFOCUS = PCURRENT == g_pCompositor->m_pLastWindow;
@ -986,19 +1042,19 @@ void CWindow::updateGroupOutputs() {
curr->m_iMonitorID = m_iMonitorID; curr->m_iMonitorID = m_iMonitorID;
curr->moveToWorkspace(m_iWorkspaceID); curr->moveToWorkspace(m_iWorkspaceID);
curr->m_vRealPosition = m_vRealPosition.goalv(); curr->m_vRealPosition = m_vRealPosition.goal();
curr->m_vRealSize = m_vRealSize.goalv(); curr->m_vRealSize = m_vRealSize.goal();
curr = curr->m_sGroupData.pNextWindow; curr = curr->m_sGroupData.pNextWindow;
} }
} }
Vector2D CWindow::middle() { Vector2D CWindow::middle() {
return m_vRealPosition.goalv() + m_vRealSize.goalv() / 2.f; return m_vRealPosition.goal() + m_vRealSize.goal() / 2.f;
} }
bool CWindow::opaque() { bool CWindow::opaque() {
if (m_fAlpha.fl() != 1.f || m_fActiveInactiveAlpha.fl() != 1.f) if (m_fAlpha.value() != 1.f || m_fActiveInactiveAlpha.value() != 1.f)
return false; return false;
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_iWorkspaceID);
@ -1006,7 +1062,7 @@ bool CWindow::opaque() {
if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall) if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall)
return false; return false;
if (PWORKSPACE->m_fAlpha.fl() != 1.f) if (PWORKSPACE->m_fAlpha.value() != 1.f)
return false; return false;
if (m_bIsX11) if (m_bIsX11)
@ -1023,9 +1079,9 @@ bool CWindow::opaque() {
} }
float CWindow::rounding() { float CWindow::rounding() {
static auto* const PROUNDING = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:rounding"); static auto PROUNDING = CConfigValue<Hyprlang::INT>("decoration:rounding");
float rounding = m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? **PROUNDING : m_sAdditionalConfigData.rounding.toUnderlying(); float rounding = m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_sAdditionalConfigData.rounding.toUnderlying();
return m_sSpecialRenderData.rounding ? rounding : 0; return m_sSpecialRenderData.rounding ? rounding : 0;
} }
@ -1035,9 +1091,9 @@ void CWindow::updateSpecialRenderData() {
const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{}; const auto WORKSPACERULE = PWORKSPACE ? g_pConfigManager->getWorkspaceRuleFor(PWORKSPACE) : SWorkspaceRule{};
bool border = true; bool border = true;
static auto* const* PNOBORDERONFLOATING = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:no_border_on_floating"); static auto PNOBORDERONFLOATING = CConfigValue<Hyprlang::INT>("general:no_border_on_floating");
if (m_bIsFloating && **PNOBORDERONFLOATING == 1) if (m_bIsFloating && *PNOBORDERONFLOATING == 1)
border = false; border = false;
m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(border); m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(border);
@ -1057,9 +1113,9 @@ int CWindow::getRealBorderSize() {
if (m_sSpecialRenderData.borderSize.toUnderlying() != -1) if (m_sSpecialRenderData.borderSize.toUnderlying() != -1)
return m_sSpecialRenderData.borderSize.toUnderlying(); return m_sSpecialRenderData.borderSize.toUnderlying();
static auto* const* PBORDERSIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:border_size"); static auto PBORDERSIZE = CConfigValue<Hyprlang::INT>("general:border_size");
return **PBORDERSIZE; return *PBORDERSIZE;
} }
bool CWindow::canBeTorn() { bool CWindow::canBeTorn() {
@ -1081,3 +1137,9 @@ void CWindow::setSuspended(bool suspend) {
wlr_xdg_toplevel_set_suspended(m_uSurface.xdg->toplevel, suspend); wlr_xdg_toplevel_set_suspended(m_uSurface.xdg->toplevel, suspend);
m_bSuspended = suspend; m_bSuspended = suspend;
} }
bool CWindow::visibleOnMonitor(CMonitor* pMonitor) {
CBox wbox = {m_vRealPosition.value(), m_vRealSize.value()};
return wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, wbox.pWlr());
}

View file

@ -1,13 +1,14 @@
#pragma once #pragma once
#include "defines.hpp" #include "defines.hpp"
#include "helpers/SubsurfaceTree.hpp" #include "desktop/Subsurface.hpp"
#include "helpers/AnimatedVariable.hpp" #include "helpers/AnimatedVariable.hpp"
#include "render/decorations/IHyprWindowDecoration.hpp" #include "render/decorations/IHyprWindowDecoration.hpp"
#include <deque> #include <deque>
#include "config/ConfigDataValues.hpp" #include "config/ConfigDataValues.hpp"
#include "helpers/Vector2D.hpp" #include "helpers/Vector2D.hpp"
#include "helpers/WLSurface.hpp" #include "desktop/WLSurface.hpp"
#include "desktop/Popup.hpp"
#include "macros.hpp" #include "macros.hpp"
#include "managers/XWaylandManager.hpp" #include "managers/XWaylandManager.hpp"
@ -154,6 +155,8 @@ struct SWindowAdditionalConfigData {
CWindowOverridableVar<bool> noFocus = false; CWindowOverridableVar<bool> noFocus = false;
CWindowOverridableVar<bool> windowDanceCompat = false; CWindowOverridableVar<bool> windowDanceCompat = false;
CWindowOverridableVar<bool> noMaxSize = false; CWindowOverridableVar<bool> noMaxSize = false;
CWindowOverridableVar<Vector2D> maxSize = Vector2D(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
CWindowOverridableVar<Vector2D> minSize = Vector2D(20, 20);
CWindowOverridableVar<bool> dimAround = false; CWindowOverridableVar<bool> dimAround = false;
CWindowOverridableVar<bool> forceRGBX = false; CWindowOverridableVar<bool> forceRGBX = false;
CWindowOverridableVar<bool> keepAspectRatio = false; CWindowOverridableVar<bool> keepAspectRatio = false;
@ -193,7 +196,6 @@ class CWindow {
DYNLISTENER(setTitleWindow); DYNLISTENER(setTitleWindow);
DYNLISTENER(setGeometryX11U); DYNLISTENER(setGeometryX11U);
DYNLISTENER(fullscreenWindow); DYNLISTENER(fullscreenWindow);
DYNLISTENER(newPopupXDG);
DYNLISTENER(requestMove); DYNLISTENER(requestMove);
DYNLISTENER(requestMinimize); DYNLISTENER(requestMinimize);
DYNLISTENER(requestMaximize); DYNLISTENER(requestMaximize);
@ -210,7 +212,6 @@ class CWindow {
// DYNLISTENER(newSubsurfaceWindow); // DYNLISTENER(newSubsurfaceWindow);
CWLSurface m_pWLSurface; CWLSurface m_pWLSurface;
std::list<CWLSurface> m_lPopupSurfaces;
union { union {
wlr_xdg_surface* xdg; wlr_xdg_surface* xdg;
@ -222,8 +223,8 @@ class CWindow {
Vector2D m_vSize = Vector2D(0, 0); Vector2D m_vSize = Vector2D(0, 0);
// this is the real position and size used to draw the thing // this is the real position and size used to draw the thing
CAnimatedVariable m_vRealPosition; CAnimatedVariable<Vector2D> m_vRealPosition;
CAnimatedVariable m_vRealSize; CAnimatedVariable<Vector2D> m_vRealSize;
// for not spamming the protocols // for not spamming the protocols
Vector2D m_vReportedPosition; Vector2D m_vReportedPosition;
@ -278,16 +279,18 @@ class CWindow {
// bitfield eSuppressEvents // bitfield eSuppressEvents
uint64_t m_eSuppressedEvents = SUPPRESS_NONE; uint64_t m_eSuppressedEvents = SUPPRESS_NONE;
SSurfaceTreeNode* m_pSurfaceTree = nullptr; // desktop components
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
std::unique_ptr<CPopup> m_pPopupHead;
// Animated border // Animated border
CGradientValueData m_cRealBorderColor = {0}; CGradientValueData m_cRealBorderColor = {0};
CGradientValueData m_cRealBorderColorPrevious = {0}; CGradientValueData m_cRealBorderColorPrevious = {0};
CAnimatedVariable m_fBorderFadeAnimationProgress; CAnimatedVariable<float> m_fBorderFadeAnimationProgress;
CAnimatedVariable m_fBorderAngleAnimationProgress; CAnimatedVariable<float> m_fBorderAngleAnimationProgress;
// Fade in-out // Fade in-out
CAnimatedVariable m_fAlpha; CAnimatedVariable<float> m_fAlpha;
bool m_bFadingOut = false; bool m_bFadingOut = false;
bool m_bReadyToDelete = false; bool m_bReadyToDelete = false;
Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in Vector2D m_vOriginalClosedPos; // these will be used for calculations later on in
@ -321,13 +324,13 @@ class CWindow {
std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers; std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers;
// for alpha // for alpha
CAnimatedVariable m_fActiveInactiveAlpha; CAnimatedVariable<float> m_fActiveInactiveAlpha;
// animated shadow color // animated shadow color
CAnimatedVariable m_cRealShadowColor; CAnimatedVariable<CColor> m_cRealShadowColor;
// animated tint // animated tint
CAnimatedVariable m_fDimPercent; CAnimatedVariable<float> m_fDimPercent;
// swallowing // swallowing
CWindow* m_pSwallowed = nullptr; CWindow* m_pSwallowed = nullptr;
@ -392,6 +395,7 @@ class CWindow {
bool canBeTorn(); bool canBeTorn();
bool shouldSendFullscreenState(); bool shouldSendFullscreenState();
void setSuspended(bool suspend); void setSuspended(bool suspend);
bool visibleOnMonitor(CMonitor* pMonitor);
int getRealBorderSize(); int getRealBorderSize();
void updateSpecialRenderData(); void updateSpecialRenderData();

View file

@ -14,6 +14,8 @@ class ICustomConfigValueData {
virtual ~ICustomConfigValueData() = 0; virtual ~ICustomConfigValueData() = 0;
virtual eConfigValueDataTypes getDataType() = 0; virtual eConfigValueDataTypes getDataType() = 0;
virtual std::string toString() = 0;
}; };
class CGradientValueData : public ICustomConfigValueData { class CGradientValueData : public ICustomConfigValueData {
@ -51,6 +53,15 @@ class CGradientValueData : public ICustomConfigValueData {
return true; return true;
} }
virtual std::string toString() {
std::string result;
for (auto& c : m_vColors) {
result += std::format("{:x} ", c.getAsHex());
}
result += std::format("{}deg", (int)(m_fAngle * 180.0 / M_PI));
}
}; };
class CCssGapData : public ICustomConfigValueData { class CCssGapData : public ICustomConfigValueData {
@ -103,4 +114,8 @@ class CCssGapData : public ICustomConfigValueData {
virtual eConfigValueDataTypes getDataType() { virtual eConfigValueDataTypes getDataType() {
return CVD_TYPE_CSS_VALUE; return CVD_TYPE_CSS_VALUE;
} }
virtual std::string toString() {
return std::format("{} {} {} {}", top, right, bottom, left);
}
}; };

View file

@ -302,140 +302,142 @@ CConfigManager::CConfigManager() {
m_pConfig = std::make_unique<Hyprlang::CConfig>(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true}); m_pConfig = std::make_unique<Hyprlang::CConfig>(configPaths.begin()->c_str(), Hyprlang::SConfigOptions{.throwAllErrors = true, .allowMissingConfig = true});
m_pConfig->addConfigValue("general:sensitivity", {1.0f}); m_pConfig->addConfigValue("general:sensitivity", {1.0f});
m_pConfig->addConfigValue("general:apply_sens_to_raw", {0L}); m_pConfig->addConfigValue("general:apply_sens_to_raw", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:border_size", {1L}); m_pConfig->addConfigValue("general:border_size", Hyprlang::INT{1});
m_pConfig->addConfigValue("general:no_border_on_floating", {0L}); m_pConfig->addConfigValue("general:no_border_on_floating", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:border_part_of_window", {1L}); m_pConfig->addConfigValue("general:border_part_of_window", Hyprlang::INT{1});
m_pConfig->addConfigValue("general:gaps_in", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "5"}); m_pConfig->addConfigValue("general:gaps_in", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "5"});
m_pConfig->addConfigValue("general:gaps_out", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "20"}); m_pConfig->addConfigValue("general:gaps_out", Hyprlang::CConfigCustomValueType{configHandleGapSet, configHandleGapDestroy, "20"});
m_pConfig->addConfigValue("general:gaps_workspaces", {0L}); m_pConfig->addConfigValue("general:gaps_workspaces", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:cursor_inactive_timeout", {0L}); m_pConfig->addConfigValue("general:cursor_inactive_timeout", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:no_cursor_warps", {0L}); m_pConfig->addConfigValue("general:no_cursor_warps", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:no_focus_fallback", {0L}); m_pConfig->addConfigValue("general:no_focus_fallback", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:resize_on_border", {0L}); m_pConfig->addConfigValue("general:resize_on_border", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:extend_border_grab_area", {15L}); m_pConfig->addConfigValue("general:extend_border_grab_area", Hyprlang::INT{15});
m_pConfig->addConfigValue("general:hover_icon_on_border", {1L}); m_pConfig->addConfigValue("general:hover_icon_on_border", Hyprlang::INT{1});
m_pConfig->addConfigValue("general:layout", {"dwindle"}); m_pConfig->addConfigValue("general:layout", {"dwindle"});
m_pConfig->addConfigValue("general:allow_tearing", {0L}); m_pConfig->addConfigValue("general:allow_tearing", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:resize_corner", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:disable_hyprland_logo", {0L}); m_pConfig->addConfigValue("misc:disable_hyprland_logo", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:disable_splash_rendering", {0L}); m_pConfig->addConfigValue("misc:disable_splash_rendering", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:col.splash", {0x55ffffffL}); m_pConfig->addConfigValue("misc:col.splash", Hyprlang::INT{0x55ffffff});
m_pConfig->addConfigValue("misc:splash_font_family", {"Sans"}); m_pConfig->addConfigValue("misc:splash_font_family", {"Sans"});
m_pConfig->addConfigValue("misc:force_default_wallpaper", {-1L}); m_pConfig->addConfigValue("misc:force_default_wallpaper", Hyprlang::INT{-1});
m_pConfig->addConfigValue("misc:vfr", {1L}); m_pConfig->addConfigValue("misc:vfr", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:vrr", {0L}); m_pConfig->addConfigValue("misc:vrr", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:mouse_move_enables_dpms", {0L}); m_pConfig->addConfigValue("misc:mouse_move_enables_dpms", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:key_press_enables_dpms", {0L}); m_pConfig->addConfigValue("misc:key_press_enables_dpms", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:always_follow_on_dnd", {1L}); m_pConfig->addConfigValue("misc:always_follow_on_dnd", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:layers_hog_keyboard_focus", {1L}); m_pConfig->addConfigValue("misc:layers_hog_keyboard_focus", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:animate_manual_resizes", {0L}); m_pConfig->addConfigValue("misc:animate_manual_resizes", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:animate_mouse_windowdragging", {0L}); m_pConfig->addConfigValue("misc:animate_mouse_windowdragging", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:disable_autoreload", {0L}); m_pConfig->addConfigValue("misc:disable_autoreload", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:enable_swallow", {0L}); m_pConfig->addConfigValue("misc:enable_swallow", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:swallow_regex", {STRVAL_EMPTY}); m_pConfig->addConfigValue("misc:swallow_regex", {STRVAL_EMPTY});
m_pConfig->addConfigValue("misc:swallow_exception_regex", {STRVAL_EMPTY}); m_pConfig->addConfigValue("misc:swallow_exception_regex", {STRVAL_EMPTY});
m_pConfig->addConfigValue("misc:focus_on_activate", {0L}); m_pConfig->addConfigValue("misc:focus_on_activate", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:no_direct_scanout", {1L}); m_pConfig->addConfigValue("misc:no_direct_scanout", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:hide_cursor_on_touch", {1L}); m_pConfig->addConfigValue("misc:hide_cursor_on_touch", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:mouse_move_focuses_monitor", {1L}); m_pConfig->addConfigValue("misc:mouse_move_focuses_monitor", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:render_ahead_of_time", {0L}); m_pConfig->addConfigValue("misc:render_ahead_of_time", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:render_ahead_safezone", {1L}); m_pConfig->addConfigValue("misc:render_ahead_safezone", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:cursor_zoom_factor", {1.f}); m_pConfig->addConfigValue("misc:cursor_zoom_factor", {1.f});
m_pConfig->addConfigValue("misc:cursor_zoom_rigid", {0L}); m_pConfig->addConfigValue("misc:cursor_zoom_rigid", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:allow_session_lock_restore", {0L}); m_pConfig->addConfigValue("misc:allow_session_lock_restore", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:close_special_on_empty", {1L}); m_pConfig->addConfigValue("misc:close_special_on_empty", Hyprlang::INT{1});
m_pConfig->addConfigValue("misc:background_color", {0xff111111L}); m_pConfig->addConfigValue("misc:background_color", Hyprlang::INT{0xff111111});
m_pConfig->addConfigValue("misc:new_window_takes_over_fullscreen", {0L}); m_pConfig->addConfigValue("misc:new_window_takes_over_fullscreen", Hyprlang::INT{0});
m_pConfig->addConfigValue("misc:enable_hyprcursor", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:insert_after_current", {1L}); m_pConfig->addConfigValue("group:insert_after_current", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:focus_removed_window", {1L}); m_pConfig->addConfigValue("group:focus_removed_window", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:enabled", {1L}); m_pConfig->addConfigValue("group:groupbar:enabled", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:font_family", {"Sans"}); m_pConfig->addConfigValue("group:groupbar:font_family", {"Sans"});
m_pConfig->addConfigValue("group:groupbar:font_size", {8L}); m_pConfig->addConfigValue("group:groupbar:font_size", Hyprlang::INT{8});
m_pConfig->addConfigValue("group:groupbar:gradients", {1L}); m_pConfig->addConfigValue("group:groupbar:gradients", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:height", {14L}); m_pConfig->addConfigValue("group:groupbar:height", Hyprlang::INT{14});
m_pConfig->addConfigValue("group:groupbar:priority", {3L}); m_pConfig->addConfigValue("group:groupbar:priority", Hyprlang::INT{3});
m_pConfig->addConfigValue("group:groupbar:render_titles", {1L}); m_pConfig->addConfigValue("group:groupbar:render_titles", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:scrolling", {1L}); m_pConfig->addConfigValue("group:groupbar:scrolling", Hyprlang::INT{1});
m_pConfig->addConfigValue("group:groupbar:text_color", {0xffffffffL}); m_pConfig->addConfigValue("group:groupbar:text_color", Hyprlang::INT{0xffffffff});
m_pConfig->addConfigValue("debug:int", {0L}); m_pConfig->addConfigValue("debug:int", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:log_damage", {0L}); m_pConfig->addConfigValue("debug:log_damage", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:overlay", {0L}); m_pConfig->addConfigValue("debug:overlay", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:damage_blink", {0L}); m_pConfig->addConfigValue("debug:damage_blink", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:disable_logs", {1L}); m_pConfig->addConfigValue("debug:disable_logs", Hyprlang::INT{1});
m_pConfig->addConfigValue("debug:disable_time", {1L}); m_pConfig->addConfigValue("debug:disable_time", Hyprlang::INT{1});
m_pConfig->addConfigValue("debug:enable_stdout_logs", {0L}); m_pConfig->addConfigValue("debug:enable_stdout_logs", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:damage_tracking", {(Hyprlang::INT)DAMAGE_TRACKING_FULL}); m_pConfig->addConfigValue("debug:damage_tracking", {(Hyprlang::INT)DAMAGE_TRACKING_FULL});
m_pConfig->addConfigValue("debug:manual_crash", {0L}); m_pConfig->addConfigValue("debug:manual_crash", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:suppress_errors", {0L}); m_pConfig->addConfigValue("debug:suppress_errors", Hyprlang::INT{0});
m_pConfig->addConfigValue("debug:watchdog_timeout", {5L}); m_pConfig->addConfigValue("debug:watchdog_timeout", Hyprlang::INT{5});
m_pConfig->addConfigValue("debug:disable_scale_checks", {0L}); m_pConfig->addConfigValue("debug:disable_scale_checks", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:rounding", {0L}); m_pConfig->addConfigValue("decoration:rounding", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:blur:enabled", {1L}); m_pConfig->addConfigValue("decoration:blur:enabled", Hyprlang::INT{1});
m_pConfig->addConfigValue("decoration:blur:size", {8L}); m_pConfig->addConfigValue("decoration:blur:size", Hyprlang::INT{8});
m_pConfig->addConfigValue("decoration:blur:passes", {1L}); m_pConfig->addConfigValue("decoration:blur:passes", Hyprlang::INT{1});
m_pConfig->addConfigValue("decoration:blur:ignore_opacity", {0L}); m_pConfig->addConfigValue("decoration:blur:ignore_opacity", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:blur:new_optimizations", {1L}); m_pConfig->addConfigValue("decoration:blur:new_optimizations", Hyprlang::INT{1});
m_pConfig->addConfigValue("decoration:blur:xray", {0L}); m_pConfig->addConfigValue("decoration:blur:xray", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:blur:contrast", {0.8916F}); m_pConfig->addConfigValue("decoration:blur:contrast", {0.8916F});
m_pConfig->addConfigValue("decoration:blur:brightness", {1.0F}); m_pConfig->addConfigValue("decoration:blur:brightness", {1.0F});
m_pConfig->addConfigValue("decoration:blur:vibrancy", {0.1696F}); m_pConfig->addConfigValue("decoration:blur:vibrancy", {0.1696F});
m_pConfig->addConfigValue("decoration:blur:vibrancy_darkness", {0.0F}); m_pConfig->addConfigValue("decoration:blur:vibrancy_darkness", {0.0F});
m_pConfig->addConfigValue("decoration:blur:noise", {0.0117F}); m_pConfig->addConfigValue("decoration:blur:noise", {0.0117F});
m_pConfig->addConfigValue("decoration:blur:special", {0L}); m_pConfig->addConfigValue("decoration:blur:special", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:blur:popups", {0L}); m_pConfig->addConfigValue("decoration:blur:popups", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:blur:popups_ignorealpha", {0.2F}); m_pConfig->addConfigValue("decoration:blur:popups_ignorealpha", {0.2F});
m_pConfig->addConfigValue("decoration:active_opacity", {1.F}); m_pConfig->addConfigValue("decoration:active_opacity", {1.F});
m_pConfig->addConfigValue("decoration:inactive_opacity", {1.F}); m_pConfig->addConfigValue("decoration:inactive_opacity", {1.F});
m_pConfig->addConfigValue("decoration:fullscreen_opacity", {1.F}); m_pConfig->addConfigValue("decoration:fullscreen_opacity", {1.F});
m_pConfig->addConfigValue("decoration:no_blur_on_oversized", {0L}); m_pConfig->addConfigValue("decoration:no_blur_on_oversized", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:drop_shadow", {1L}); m_pConfig->addConfigValue("decoration:drop_shadow", Hyprlang::INT{1});
m_pConfig->addConfigValue("decoration:shadow_range", {4L}); m_pConfig->addConfigValue("decoration:shadow_range", Hyprlang::INT{4});
m_pConfig->addConfigValue("decoration:shadow_render_power", {3L}); m_pConfig->addConfigValue("decoration:shadow_render_power", Hyprlang::INT{3});
m_pConfig->addConfigValue("decoration:shadow_ignore_window", {1L}); m_pConfig->addConfigValue("decoration:shadow_ignore_window", Hyprlang::INT{1});
m_pConfig->addConfigValue("decoration:shadow_offset", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("decoration:shadow_offset", Hyprlang::VEC2{0, 0});
m_pConfig->addConfigValue("decoration:shadow_scale", {1.f}); m_pConfig->addConfigValue("decoration:shadow_scale", {1.f});
m_pConfig->addConfigValue("decoration:col.shadow", {0xee1a1a1aL}); m_pConfig->addConfigValue("decoration:col.shadow", Hyprlang::INT{0xee1a1a1a});
m_pConfig->addConfigValue("decoration:col.shadow_inactive", {(Hyprlang::INT)INT_MAX}); m_pConfig->addConfigValue("decoration:col.shadow_inactive", {(Hyprlang::INT)INT_MAX});
m_pConfig->addConfigValue("decoration:dim_inactive", {0L}); m_pConfig->addConfigValue("decoration:dim_inactive", Hyprlang::INT{0});
m_pConfig->addConfigValue("decoration:dim_strength", {0.5f}); m_pConfig->addConfigValue("decoration:dim_strength", {0.5f});
m_pConfig->addConfigValue("decoration:dim_special", {0.2f}); m_pConfig->addConfigValue("decoration:dim_special", {0.2f});
m_pConfig->addConfigValue("decoration:dim_around", {0.4f}); m_pConfig->addConfigValue("decoration:dim_around", {0.4f});
m_pConfig->addConfigValue("decoration:screen_shader", {STRVAL_EMPTY}); m_pConfig->addConfigValue("decoration:screen_shader", {STRVAL_EMPTY});
m_pConfig->addConfigValue("dwindle:pseudotile", {0L}); m_pConfig->addConfigValue("dwindle:pseudotile", Hyprlang::INT{0});
m_pConfig->addConfigValue("dwindle:force_split", {0L}); m_pConfig->addConfigValue("dwindle:force_split", Hyprlang::INT{0});
m_pConfig->addConfigValue("dwindle:permanent_direction_override", {0L}); m_pConfig->addConfigValue("dwindle:permanent_direction_override", Hyprlang::INT{0});
m_pConfig->addConfigValue("dwindle:preserve_split", {0L}); m_pConfig->addConfigValue("dwindle:preserve_split", Hyprlang::INT{0});
m_pConfig->addConfigValue("dwindle:special_scale_factor", {1.f}); m_pConfig->addConfigValue("dwindle:special_scale_factor", {1.f});
m_pConfig->addConfigValue("dwindle:split_width_multiplier", {1.0f}); m_pConfig->addConfigValue("dwindle:split_width_multiplier", {1.0f});
m_pConfig->addConfigValue("dwindle:no_gaps_when_only", {0L}); m_pConfig->addConfigValue("dwindle:no_gaps_when_only", Hyprlang::INT{0});
m_pConfig->addConfigValue("dwindle:use_active_for_splits", {1L}); m_pConfig->addConfigValue("dwindle:use_active_for_splits", Hyprlang::INT{1});
m_pConfig->addConfigValue("dwindle:default_split_ratio", {1.f}); m_pConfig->addConfigValue("dwindle:default_split_ratio", {1.f});
m_pConfig->addConfigValue("dwindle:smart_split", {0L}); m_pConfig->addConfigValue("dwindle:smart_split", Hyprlang::INT{0});
m_pConfig->addConfigValue("dwindle:smart_resizing", {1L}); m_pConfig->addConfigValue("dwindle:smart_resizing", Hyprlang::INT{1});
m_pConfig->addConfigValue("master:special_scale_factor", {1.f}); m_pConfig->addConfigValue("master:special_scale_factor", {1.f});
m_pConfig->addConfigValue("master:mfact", {0.55f}); m_pConfig->addConfigValue("master:mfact", {0.55f});
m_pConfig->addConfigValue("master:new_is_master", {1L}); m_pConfig->addConfigValue("master:new_is_master", Hyprlang::INT{1});
m_pConfig->addConfigValue("master:always_center_master", {0L}); m_pConfig->addConfigValue("master:always_center_master", Hyprlang::INT{0});
m_pConfig->addConfigValue("master:new_on_top", {0L}); m_pConfig->addConfigValue("master:new_on_top", Hyprlang::INT{0});
m_pConfig->addConfigValue("master:no_gaps_when_only", {0L}); m_pConfig->addConfigValue("master:no_gaps_when_only", Hyprlang::INT{0});
m_pConfig->addConfigValue("master:orientation", {"left"}); m_pConfig->addConfigValue("master:orientation", {"left"});
m_pConfig->addConfigValue("master:inherit_fullscreen", {1L}); m_pConfig->addConfigValue("master:inherit_fullscreen", Hyprlang::INT{1});
m_pConfig->addConfigValue("master:allow_small_split", {0L}); m_pConfig->addConfigValue("master:allow_small_split", Hyprlang::INT{0});
m_pConfig->addConfigValue("master:smart_resizing", {1L}); m_pConfig->addConfigValue("master:smart_resizing", Hyprlang::INT{1});
m_pConfig->addConfigValue("master:drop_at_cursor", {1L}); m_pConfig->addConfigValue("master:drop_at_cursor", Hyprlang::INT{1});
m_pConfig->addConfigValue("animations:enabled", {1L}); m_pConfig->addConfigValue("animations:enabled", Hyprlang::INT{1});
m_pConfig->addConfigValue("animations:first_launch_animation", {1L}); m_pConfig->addConfigValue("animations:first_launch_animation", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:follow_mouse", {1L}); m_pConfig->addConfigValue("input:follow_mouse", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:mouse_refocus", {1L}); m_pConfig->addConfigValue("input:mouse_refocus", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:special_fallthrough", {0L}); m_pConfig->addConfigValue("input:special_fallthrough", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:sensitivity", {0.f}); m_pConfig->addConfigValue("input:sensitivity", {0.f});
m_pConfig->addConfigValue("input:accel_profile", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:accel_profile", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:kb_file", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:kb_file", {STRVAL_EMPTY});
@ -444,65 +446,66 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("input:kb_options", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:kb_options", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:kb_rules", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:kb_rules", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:kb_model", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:kb_model", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:repeat_rate", {25L}); m_pConfig->addConfigValue("input:repeat_rate", Hyprlang::INT{25});
m_pConfig->addConfigValue("input:repeat_delay", {600L}); m_pConfig->addConfigValue("input:repeat_delay", Hyprlang::INT{600});
m_pConfig->addConfigValue("input:natural_scroll", {0L}); m_pConfig->addConfigValue("input:natural_scroll", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:numlock_by_default", {0L}); m_pConfig->addConfigValue("input:numlock_by_default", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:resolve_binds_by_sym", {0L}); m_pConfig->addConfigValue("input:resolve_binds_by_sym", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:force_no_accel", {0L}); m_pConfig->addConfigValue("input:force_no_accel", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:float_switch_override_focus", {1L}); m_pConfig->addConfigValue("input:float_switch_override_focus", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:left_handed", {0L}); m_pConfig->addConfigValue("input:left_handed", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:scroll_method", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:scroll_method", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:scroll_button", {0L}); m_pConfig->addConfigValue("input:scroll_button", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:scroll_button_lock", {0L}); m_pConfig->addConfigValue("input:scroll_button_lock", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:scroll_factor", {1.f});
m_pConfig->addConfigValue("input:scroll_points", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:scroll_points", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:touchpad:natural_scroll", {0L}); m_pConfig->addConfigValue("input:touchpad:natural_scroll", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:touchpad:disable_while_typing", {1L}); m_pConfig->addConfigValue("input:touchpad:disable_while_typing", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:touchpad:clickfinger_behavior", {0L}); m_pConfig->addConfigValue("input:touchpad:clickfinger_behavior", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:touchpad:tap_button_map", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:touchpad:tap_button_map", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:touchpad:middle_button_emulation", {0L}); m_pConfig->addConfigValue("input:touchpad:middle_button_emulation", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:touchpad:tap-to-click", {1L}); m_pConfig->addConfigValue("input:touchpad:tap-to-click", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:touchpad:tap-and-drag", {1L}); m_pConfig->addConfigValue("input:touchpad:tap-and-drag", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:touchpad:drag_lock", {0L}); m_pConfig->addConfigValue("input:touchpad:drag_lock", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:touchpad:scroll_factor", {1.f}); m_pConfig->addConfigValue("input:touchpad:scroll_factor", {1.f});
m_pConfig->addConfigValue("input:touchdevice:transform", {0L}); m_pConfig->addConfigValue("input:touchdevice:transform", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:touchdevice:output", {"[[Auto]]"}); m_pConfig->addConfigValue("input:touchdevice:output", {"[[Auto]]"});
m_pConfig->addConfigValue("input:touchdevice:enabled", {1L}); m_pConfig->addConfigValue("input:touchdevice:enabled", Hyprlang::INT{1});
m_pConfig->addConfigValue("input:tablet:transform", {0L}); m_pConfig->addConfigValue("input:tablet:transform", Hyprlang::INT{0});
m_pConfig->addConfigValue("input:tablet:output", {STRVAL_EMPTY}); m_pConfig->addConfigValue("input:tablet:output", {STRVAL_EMPTY});
m_pConfig->addConfigValue("input:tablet:region_position", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("input:tablet:region_position", Hyprlang::VEC2{0, 0});
m_pConfig->addConfigValue("input:tablet:region_size", Hyprlang::VEC2{0, 0}); m_pConfig->addConfigValue("input:tablet:region_size", Hyprlang::VEC2{0, 0});
m_pConfig->addConfigValue("input:tablet:relative_input", {0L}); m_pConfig->addConfigValue("input:tablet:relative_input", Hyprlang::INT{0});
m_pConfig->addConfigValue("binds:pass_mouse_when_bound", {0L}); m_pConfig->addConfigValue("binds:pass_mouse_when_bound", Hyprlang::INT{0});
m_pConfig->addConfigValue("binds:scroll_event_delay", {300L}); m_pConfig->addConfigValue("binds:scroll_event_delay", Hyprlang::INT{300});
m_pConfig->addConfigValue("binds:workspace_back_and_forth", {0L}); m_pConfig->addConfigValue("binds:workspace_back_and_forth", Hyprlang::INT{0});
m_pConfig->addConfigValue("binds:allow_workspace_cycles", {0L}); m_pConfig->addConfigValue("binds:allow_workspace_cycles", Hyprlang::INT{0});
m_pConfig->addConfigValue("binds:workspace_center_on", {1L}); m_pConfig->addConfigValue("binds:workspace_center_on", Hyprlang::INT{1});
m_pConfig->addConfigValue("binds:focus_preferred_method", {0L}); m_pConfig->addConfigValue("binds:focus_preferred_method", Hyprlang::INT{0});
m_pConfig->addConfigValue("binds:ignore_group_lock", {0L}); m_pConfig->addConfigValue("binds:ignore_group_lock", Hyprlang::INT{0});
m_pConfig->addConfigValue("binds:movefocus_cycles_fullscreen", {1L}); m_pConfig->addConfigValue("binds:movefocus_cycles_fullscreen", Hyprlang::INT{1});
m_pConfig->addConfigValue("gestures:workspace_swipe", {0L}); m_pConfig->addConfigValue("gestures:workspace_swipe", Hyprlang::INT{0});
m_pConfig->addConfigValue("gestures:workspace_swipe_fingers", {3L}); m_pConfig->addConfigValue("gestures:workspace_swipe_fingers", Hyprlang::INT{3});
m_pConfig->addConfigValue("gestures:workspace_swipe_distance", {300L}); m_pConfig->addConfigValue("gestures:workspace_swipe_distance", Hyprlang::INT{300});
m_pConfig->addConfigValue("gestures:workspace_swipe_invert", {1L}); m_pConfig->addConfigValue("gestures:workspace_swipe_invert", Hyprlang::INT{1});
m_pConfig->addConfigValue("gestures:workspace_swipe_min_speed_to_force", {30L}); m_pConfig->addConfigValue("gestures:workspace_swipe_min_speed_to_force", Hyprlang::INT{30});
m_pConfig->addConfigValue("gestures:workspace_swipe_cancel_ratio", {0.5f}); m_pConfig->addConfigValue("gestures:workspace_swipe_cancel_ratio", {0.5f});
m_pConfig->addConfigValue("gestures:workspace_swipe_create_new", {1L}); m_pConfig->addConfigValue("gestures:workspace_swipe_create_new", Hyprlang::INT{1});
m_pConfig->addConfigValue("gestures:workspace_swipe_direction_lock", {1L}); m_pConfig->addConfigValue("gestures:workspace_swipe_direction_lock", Hyprlang::INT{1});
m_pConfig->addConfigValue("gestures:workspace_swipe_direction_lock_threshold", {10L}); m_pConfig->addConfigValue("gestures:workspace_swipe_direction_lock_threshold", Hyprlang::INT{10});
m_pConfig->addConfigValue("gestures:workspace_swipe_forever", {0L}); m_pConfig->addConfigValue("gestures:workspace_swipe_forever", Hyprlang::INT{0});
m_pConfig->addConfigValue("gestures:workspace_swipe_numbered", {0L}); m_pConfig->addConfigValue("gestures:workspace_swipe_numbered", Hyprlang::INT{0});
m_pConfig->addConfigValue("gestures:workspace_swipe_use_r", {0L}); m_pConfig->addConfigValue("gestures:workspace_swipe_use_r", Hyprlang::INT{0});
m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", {1L}); m_pConfig->addConfigValue("xwayland:use_nearest_neighbor", Hyprlang::INT{1});
m_pConfig->addConfigValue("xwayland:force_zero_scaling", {0L}); m_pConfig->addConfigValue("xwayland:force_zero_scaling", Hyprlang::INT{0});
m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", {1L}); m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1});
m_pConfig->addConfigValue("opengl:force_introspection", {2L}); m_pConfig->addConfigValue("opengl:force_introspection", Hyprlang::INT{2});
m_pConfig->addConfigValue("autogenerated", {0L}); m_pConfig->addConfigValue("autogenerated", Hyprlang::INT{0});
m_pConfig->addConfigValue("general:col.active_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffffffff"}); m_pConfig->addConfigValue("general:col.active_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xffffffff"});
m_pConfig->addConfigValue("general:col.inactive_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xff444444"}); m_pConfig->addConfigValue("general:col.inactive_border", Hyprlang::CConfigCustomValueType{&configHandleGradientSet, configHandleGradientDestroy, "0xff444444"});
@ -529,29 +532,29 @@ CConfigManager::CConfigManager() {
m_pConfig->addSpecialConfigValue("device", "kb_options", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "kb_options", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "kb_rules", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "kb_rules", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "kb_model", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "kb_model", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "repeat_rate", {25L}); m_pConfig->addSpecialConfigValue("device", "repeat_rate", Hyprlang::INT{25});
m_pConfig->addSpecialConfigValue("device", "repeat_delay", {600L}); m_pConfig->addSpecialConfigValue("device", "repeat_delay", Hyprlang::INT{600});
m_pConfig->addSpecialConfigValue("device", "natural_scroll", {0L}); m_pConfig->addSpecialConfigValue("device", "natural_scroll", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "tap_button_map", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "tap_button_map", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "numlock_by_default", {0L}); m_pConfig->addSpecialConfigValue("device", "numlock_by_default", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "resolve_binds_by_sym", {0L}); m_pConfig->addSpecialConfigValue("device", "resolve_binds_by_sym", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "disable_while_typing", {1L}); m_pConfig->addSpecialConfigValue("device", "disable_while_typing", Hyprlang::INT{1});
m_pConfig->addSpecialConfigValue("device", "clickfinger_behavior", {0L}); m_pConfig->addSpecialConfigValue("device", "clickfinger_behavior", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "middle_button_emulation", {0L}); m_pConfig->addSpecialConfigValue("device", "middle_button_emulation", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "tap-to-click", {1L}); m_pConfig->addSpecialConfigValue("device", "tap-to-click", Hyprlang::INT{1});
m_pConfig->addSpecialConfigValue("device", "tap-and-drag", {1L}); m_pConfig->addSpecialConfigValue("device", "tap-and-drag", Hyprlang::INT{1});
m_pConfig->addSpecialConfigValue("device", "drag_lock", {0L}); m_pConfig->addSpecialConfigValue("device", "drag_lock", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "left_handed", {0L}); m_pConfig->addSpecialConfigValue("device", "left_handed", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "scroll_method", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "scroll_method", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "scroll_button", {0L}); m_pConfig->addSpecialConfigValue("device", "scroll_button", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "scroll_button_lock", {0L}); m_pConfig->addSpecialConfigValue("device", "scroll_button_lock", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "scroll_points", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "scroll_points", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "transform", {0L}); m_pConfig->addSpecialConfigValue("device", "transform", Hyprlang::INT{0});
m_pConfig->addSpecialConfigValue("device", "output", {STRVAL_EMPTY}); m_pConfig->addSpecialConfigValue("device", "output", {STRVAL_EMPTY});
m_pConfig->addSpecialConfigValue("device", "enabled", {1L}); // only for mice, touchpads, and touchdevices m_pConfig->addSpecialConfigValue("device", "enabled", Hyprlang::INT{1}); // only for mice, touchpads, and touchdevices
m_pConfig->addSpecialConfigValue("device", "region_position", Hyprlang::VEC2{0, 0}); // only for tablets m_pConfig->addSpecialConfigValue("device", "region_position", Hyprlang::VEC2{0, 0}); // only for tablets
m_pConfig->addSpecialConfigValue("device", "region_size", Hyprlang::VEC2{0, 0}); // only for tablets m_pConfig->addSpecialConfigValue("device", "region_size", Hyprlang::VEC2{0, 0}); // only for tablets
m_pConfig->addSpecialConfigValue("device", "relative_input", {0L}); // only for tablets m_pConfig->addSpecialConfigValue("device", "relative_input", Hyprlang::INT{0}); // only for tablets
// keywords // keywords
m_pConfig->registerHandler(&::handleRawExec, "exec", {false}); m_pConfig->registerHandler(&::handleRawExec, "exec", {false});
@ -617,6 +620,7 @@ void CConfigManager::setDefaultAnimationVars() {
if (isFirstLaunch) { if (isFirstLaunch) {
INITANIMCFG("global"); INITANIMCFG("global");
INITANIMCFG("windows"); INITANIMCFG("windows");
INITANIMCFG("layers");
INITANIMCFG("fade"); INITANIMCFG("fade");
INITANIMCFG("border"); INITANIMCFG("border");
INITANIMCFG("borderangle"); INITANIMCFG("borderangle");
@ -644,6 +648,7 @@ void CConfigManager::setDefaultAnimationVars() {
animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr}; animationConfig["global"] = {false, "default", "", 8.f, 1, &animationConfig["general"], nullptr};
CREATEANIMCFG("windows", "global"); CREATEANIMCFG("windows", "global");
CREATEANIMCFG("layers", "global");
CREATEANIMCFG("fade", "global"); CREATEANIMCFG("fade", "global");
CREATEANIMCFG("border", "global"); CREATEANIMCFG("border", "global");
CREATEANIMCFG("borderangle", "global"); CREATEANIMCFG("borderangle", "global");
@ -658,6 +663,7 @@ void CConfigManager::setDefaultAnimationVars() {
CREATEANIMCFG("fadeSwitch", "fade"); CREATEANIMCFG("fadeSwitch", "fade");
CREATEANIMCFG("fadeShadow", "fade"); CREATEANIMCFG("fadeShadow", "fade");
CREATEANIMCFG("fadeDim", "fade"); CREATEANIMCFG("fadeDim", "fade");
CREATEANIMCFG("fadeLayers", "fade");
CREATEANIMCFG("specialWorkspace", "workspaces"); CREATEANIMCFG("specialWorkspace", "workspaces");
} }
@ -942,8 +948,8 @@ SWorkspaceRule CConfigManager::getWorkspaceRuleFor(CWorkspace* pWorkspace) {
return *IT; return *IT;
} }
std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow, bool dynamic) { std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow, bool dynamic, bool shadowExec) {
if (!g_pCompositor->windowValidMapped(pWindow)) if (!g_pCompositor->windowExists(pWindow))
return std::vector<SWindowRule>(); return std::vector<SWindowRule>();
std::vector<SWindowRule> returns; std::vector<SWindowRule> returns;
@ -1090,7 +1096,7 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow, bool
} }
} }
if (anyExecFound) // remove exec rules to unclog searches in the future, why have the garbage here. if (anyExecFound && !shadowExec) // remove exec rules to unclog searches in the future, why have the garbage here.
execRequestedRules.erase(std::remove_if(execRequestedRules.begin(), execRequestedRules.end(), execRequestedRules.erase(std::remove_if(execRequestedRules.begin(), execRequestedRules.end(),
[&](const SExecRequestedRule& other) { return std::ranges::any_of(PIDs, [&](const auto& pid) { return pid == other.iPid; }); })); [&](const SExecRequestedRule& other) { return std::ranges::any_of(PIDs, [&](const auto& pid) { return pid == other.iPid; }); }));
@ -1228,7 +1234,7 @@ void CConfigManager::ensureMonitorStatus() {
} }
void CConfigManager::ensureVRR(CMonitor* pMonitor) { void CConfigManager::ensureVRR(CMonitor* pMonitor) {
static auto* const PVRR = reinterpret_cast<Hyprlang::INT* const*>(getConfigValuePtr("misc:vrr")); static auto PVRR = reinterpret_cast<Hyprlang::INT* const*>(getConfigValuePtr("misc:vrr"));
static auto ensureVRRForDisplay = [&](CMonitor* m) -> void { static auto ensureVRRForDisplay = [&](CMonitor* m) -> void {
if (!m->output || m->createdByUser) if (!m->output || m->createdByUser)
@ -1547,6 +1553,8 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
return {}; return {};
} }
std::string error = "";
if (ARGS[1].starts_with("pref")) { if (ARGS[1].starts_with("pref")) {
newrule.resolution = Vector2D(); newrule.resolution = Vector2D();
} else if (ARGS[1].starts_with("highrr")) { } else if (ARGS[1].starts_with("highrr")) {
@ -1557,32 +1565,45 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
newrule.resolution = Vector2D(newrule.drmMode.hdisplay, newrule.drmMode.vdisplay); newrule.resolution = Vector2D(newrule.drmMode.hdisplay, newrule.drmMode.vdisplay);
newrule.refreshRate = newrule.drmMode.vrefresh / 1000; newrule.refreshRate = newrule.drmMode.vrefresh / 1000;
} else { } else {
if (!ARGS[1].contains("x")) {
error += "invalid resolution ";
newrule.resolution = Vector2D();
} else {
newrule.resolution.x = stoi(ARGS[1].substr(0, ARGS[1].find_first_of('x'))); newrule.resolution.x = stoi(ARGS[1].substr(0, ARGS[1].find_first_of('x')));
newrule.resolution.y = stoi(ARGS[1].substr(ARGS[1].find_first_of('x') + 1, ARGS[1].find_first_of('@'))); newrule.resolution.y = stoi(ARGS[1].substr(ARGS[1].find_first_of('x') + 1, ARGS[1].find_first_of('@')));
if (ARGS[1].contains("@")) if (ARGS[1].contains("@"))
newrule.refreshRate = stof(ARGS[1].substr(ARGS[1].find_first_of('@') + 1)); newrule.refreshRate = stof(ARGS[1].substr(ARGS[1].find_first_of('@') + 1));
} }
}
if (ARGS[2].starts_with("auto")) { if (ARGS[2].starts_with("auto")) {
newrule.offset = Vector2D(-INT32_MAX, -INT32_MAX); newrule.offset = Vector2D(-INT32_MAX, -INT32_MAX);
} else {
if (!ARGS[2].contains("x")) {
error += "invalid offset ";
newrule.offset = Vector2D(-INT32_MAX, -INT32_MAX);
} else { } else {
newrule.offset.x = stoi(ARGS[2].substr(0, ARGS[2].find_first_of('x'))); newrule.offset.x = stoi(ARGS[2].substr(0, ARGS[2].find_first_of('x')));
newrule.offset.y = stoi(ARGS[2].substr(ARGS[2].find_first_of('x') + 1)); newrule.offset.y = stoi(ARGS[2].substr(ARGS[2].find_first_of('x') + 1));
} }
}
std::string error = "";
if (ARGS[3].starts_with("auto")) { if (ARGS[3].starts_with("auto")) {
newrule.scale = -1; newrule.scale = -1;
} else { } else {
if (!isNumber(ARGS[3], true))
error += "invalid scale ";
else {
newrule.scale = stof(ARGS[3]); newrule.scale = stof(ARGS[3]);
if (newrule.scale < 0.25f) { if (newrule.scale < 0.25f) {
error = "invalid scale"; error += "invalid scale ";
newrule.scale = 1; newrule.scale = 1;
} }
} }
}
int argno = 4; int argno = 4;
@ -1594,9 +1615,29 @@ std::optional<std::string> CConfigManager::handleMonitor(const std::string& comm
newrule.enable10bit = ARGS[argno + 1] == "10"; newrule.enable10bit = ARGS[argno + 1] == "10";
argno++; argno++;
} else if (ARGS[argno] == "transform") { } else if (ARGS[argno] == "transform") {
if (!isNumber(ARGS[argno + 1])) {
error = "invalid transform ";
argno++;
continue;
}
const auto NUM = std::stoi(ARGS[argno + 1]);
if (NUM < 0 || NUM > 7) {
error = "invalid transform ";
argno++;
continue;
}
newrule.transform = (wl_output_transform)std::stoi(ARGS[argno + 1]); newrule.transform = (wl_output_transform)std::stoi(ARGS[argno + 1]);
argno++; argno++;
} else if (ARGS[argno] == "vrr") { } else if (ARGS[argno] == "vrr") {
if (!isNumber(ARGS[argno + 1])) {
error = "invalid vrr ";
argno++;
continue;
}
newrule.vrr = std::stoi(ARGS[argno + 1]); newrule.vrr = std::stoi(ARGS[argno + 1]);
argno++; argno++;
} else if (ARGS[argno] == "workspace") { } else if (ARGS[argno] == "workspace") {
@ -1729,6 +1770,17 @@ std::optional<std::string> CConfigManager::handleAnimation(const std::string& co
return {}; return {};
} }
SParsedKey parseKey(const std::string& key) {
if (isNumber(key) && std::stoi(key) > 9)
return {.keycode = std::stoi(key)};
else if (key.starts_with("code:") && isNumber(key.substr(5)))
return {.keycode = std::stoi(key.substr(5))};
else if (key == "catchall")
return {.catchAll = true};
else
return {.key = key};
}
std::optional<std::string> CConfigManager::handleBind(const std::string& command, const std::string& value) { std::optional<std::string> CConfigManager::handleBind(const std::string& command, const std::string& value) {
// example: // example:
// bind[fl]=SUPER,G,exec,dmenu_run <args> // bind[fl]=SUPER,G,exec,dmenu_run <args>
@ -1804,14 +1856,15 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
} }
if (KEY != "") { if (KEY != "") {
if (isNumber(KEY) && std::stoi(KEY) > 9) SParsedKey parsedKey = parseKey(KEY);
g_pKeybindManager->addKeybind(
SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods}); if (parsedKey.catchAll && m_szCurrentSubmap == "") {
else if (KEY.starts_with("code:") && isNumber(KEY.substr(5))) Debug::log(ERR, "Catchall not allowed outside of submap!");
g_pKeybindManager->addKeybind( return "Invalid catchall, catchall keybinds are only allowed in submaps.";
SKeybind{"", std::stoi(KEY.substr(5)), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods}); }
else
g_pKeybindManager->addKeybind(SKeybind{KEY, 0, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse, nonConsuming, transparent, ignoreMods}); g_pKeybindManager->addKeybind(SKeybind{parsedKey.key, parsedKey.keycode, parsedKey.catchAll, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap, release, repeat, mouse,
nonConsuming, transparent, ignoreMods});
} }
return {}; return {};
@ -1822,7 +1875,7 @@ std::optional<std::string> CConfigManager::handleUnbind(const std::string& comma
const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]); const auto MOD = g_pKeybindManager->stringToModMask(ARGS[0]);
const auto KEY = ARGS[1]; const auto KEY = parseKey(ARGS[1]);
g_pKeybindManager->removeKeybind(MOD, KEY); g_pKeybindManager->removeKeybind(MOD, KEY);
@ -1840,7 +1893,7 @@ bool windowRuleValid(const std::string& RULE) {
} }
bool layerRuleValid(const std::string& RULE) { bool layerRuleValid(const std::string& RULE) {
return RULE == "noanim" || RULE == "blur" || RULE.starts_with("ignorealpha") || RULE.starts_with("ignorezero") || RULE.starts_with("xray"); return RULE == "noanim" || RULE == "blur" || RULE.starts_with("ignorealpha") || RULE.starts_with("ignorezero") || RULE.starts_with("xray") || RULE.starts_with("animation");
} }
std::optional<std::string> CConfigManager::handleWindowRule(const std::string& command, const std::string& value) { std::optional<std::string> CConfigManager::handleWindowRule(const std::string& command, const std::string& value) {
@ -2226,6 +2279,8 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
return err; return err;
} }
std::string errorsFromParsing;
for (size_t i = 0; i < glob_buf->gl_pathc; i++) { for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
auto value = absolutePath(glob_buf->gl_pathv[i], configCurrentPath); auto value = absolutePath(glob_buf->gl_pathv[i], configCurrentPath);
@ -2251,12 +2306,17 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
auto configCurrentPathBackup = configCurrentPath; auto configCurrentPathBackup = configCurrentPath;
configCurrentPath = value; configCurrentPath = value;
m_pConfig->parseFile(value.c_str()); const auto THISRESULT = m_pConfig->parseFile(value.c_str());
configCurrentPath = configCurrentPathBackup; configCurrentPath = configCurrentPathBackup;
if (THISRESULT.error && errorsFromParsing.empty())
errorsFromParsing += THISRESULT.getError();
} }
if (errorsFromParsing.empty())
return {}; return {};
return errorsFromParsing;
} }
std::optional<std::string> CConfigManager::handleEnv(const std::string& command, const std::string& value) { std::optional<std::string> CConfigManager::handleEnv(const std::string& command, const std::string& value) {

View file

@ -111,7 +111,7 @@ class CConfigManager {
std::string getBoundMonitorStringForWS(const std::string&); std::string getBoundMonitorStringForWS(const std::string&);
const std::deque<SWorkspaceRule>& getAllWorkspaceRules(); const std::deque<SWorkspaceRule>& getAllWorkspaceRules();
std::vector<SWindowRule> getMatchingRules(CWindow*, bool dynamic = true); std::vector<SWindowRule> getMatchingRules(CWindow*, bool dynamic = true, bool shadowExec = false);
std::vector<SLayerRule> getMatchingRules(SLayerSurface*); std::vector<SLayerRule> getMatchingRules(SLayerSurface*);
std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas; std::unordered_map<std::string, SMonitorAdditionalReservedArea> m_mAdditionalReservedAreas;

View file

@ -0,0 +1,72 @@
#pragma once
#include <string>
#include <typeindex>
#include <hyprlang.hpp>
#include "../debug/Log.hpp"
#include "../macros.hpp"
template <typename T>
class CConfigValue {
public:
CConfigValue(const std::string& val) {
const auto PVHYPRLANG = g_pConfigManager->getHyprlangConfigValuePtr(val.c_str());
p_ = PVHYPRLANG->getDataStaticPtr();
#ifdef HYPRLAND_DEBUG
// verify type
const auto ANY = PVHYPRLANG->getValue();
const auto TYPE = std::type_index(ANY.type());
// exceptions
const bool STRINGEX = (typeid(T) == typeid(std::string) && TYPE == typeid(Hyprlang::STRING));
const bool CUSTOMEX = (typeid(T) == typeid(Hyprlang::CUSTOMTYPE) && (TYPE == typeid(Hyprlang::CUSTOMTYPE*) || TYPE == typeid(void*) /* dunno why it does this? */));
RASSERT(typeid(T) == TYPE || STRINGEX || CUSTOMEX, "Mismatched type in CConfigValue<T>, got {} but has {}", typeid(T).name(), TYPE.name());
#endif
}
T* ptr() const {
return *(T* const*)p_;
}
T operator*() const {
return *ptr();
}
private:
void* const* p_ = nullptr;
};
template <>
inline std::string* CConfigValue<std::string>::ptr() const {
RASSERT(false, "Impossible to implement ptr() of CConfigValue<std::string>");
return nullptr;
}
template <>
inline std::string CConfigValue<std::string>::operator*() const {
return std::string{*(Hyprlang::STRING*)p_};
}
template <>
inline Hyprlang::STRING* CConfigValue<Hyprlang::STRING>::ptr() const {
return (Hyprlang::STRING*)p_;
}
template <>
inline Hyprlang::STRING CConfigValue<Hyprlang::STRING>::operator*() const {
return *(Hyprlang::STRING*)p_;
}
template <>
inline Hyprlang::CUSTOMTYPE* CConfigValue<Hyprlang::CUSTOMTYPE>::ptr() const {
return *(Hyprlang::CUSTOMTYPE* const*)p_;
}
template <>
inline Hyprlang::CUSTOMTYPE CConfigValue<Hyprlang::CUSTOMTYPE>::operator*() const {
RASSERT(false, "Impossible to implement operator* of CConfigValue<Hyprlang::CUSTOMTYPE>, use ptr()");
return *ptr();
}

View file

@ -123,7 +123,7 @@ misc {
} }
# Example per-device config # Example per-device config
# See https://wiki.hyprland.org/Configuring/Keywords/#executing for more # See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
device { device {
name = epic-mouse-v1 name = epic-mouse-v1
sensitivity = -0.5 sensitivity = -0.5

View file

@ -108,11 +108,16 @@ void CrashReporter::createAndSaveCrash(int sig) {
std::string addrs = ""; std::string addrs = "";
for (size_t i = 0; i < CALLSTACK.size(); ++i) { for (size_t i = 0; i < CALLSTACK.size(); ++i) {
#ifdef __GLIBC__
// convert in memory address to VMA address // convert in memory address to VMA address
Dl_info info; Dl_info info;
struct link_map* linkMap; struct link_map* linkMap;
dladdr1((void*)CALLSTACK[i].adr, &info, (void**)&linkMap, RTLD_DL_LINKMAP); dladdr1((void*)CALLSTACK[i].adr, &info, (void**)&linkMap, RTLD_DL_LINKMAP);
size_t vmaAddr = (size_t)CALLSTACK[i].adr - linkMap->l_addr; size_t vmaAddr = (size_t)CALLSTACK[i].adr - linkMap->l_addr;
#else
// musl doesn't define dladdr1
size_t vmaAddr = (size_t)CALLSTACK[i].adr;
#endif
addrs += std::format("0x{:x} ", vmaAddr); addrs += std::format("0x{:x} ", vmaAddr);
} }

View file

@ -15,6 +15,9 @@
#include <string> #include <string>
#include <typeindex> #include <typeindex>
#include "../config/ConfigValue.hpp"
#include "../managers/CursorManager.hpp"
static void trimTrailingComma(std::string& str) { static void trimTrailingComma(std::string& str) {
if (!str.empty() && str.back() == ',') if (!str.empty() && str.back() == ',')
str.pop_back(); str.pop_back();
@ -29,6 +32,38 @@ static std::string getWorkspaceNameFromSpecialID(const int workspaceID) {
return workspace->m_szName; return workspace->m_szName;
} }
static std::string formatToString(uint32_t drmFormat) {
switch (drmFormat) {
case DRM_FORMAT_XRGB2101010: return "XRGB2101010";
case DRM_FORMAT_XBGR2101010: return "XBGR2101010";
case DRM_FORMAT_XRGB8888: return "XRGB8888";
case DRM_FORMAT_XBGR8888: return "XBGR8888";
default: break;
}
return "Invalid";
}
static std::string availableModesForOutput(CMonitor* pMonitor, eHyprCtlOutputFormat format) {
std::string result;
if (!wl_list_empty(&pMonitor->output->modes)) {
wlr_output_mode* mode;
wl_list_for_each(mode, &pMonitor->output->modes, link) {
if (format == FORMAT_NORMAL)
result += std::format("{}x{}@{:.2f}Hz ", mode->width, mode->height, mode->refresh / 1000.0);
else
result += std::format("\"{}x{}@{:.2f}Hz\",", mode->width, mode->height, mode->refresh / 1000.0);
}
result.pop_back();
}
return result;
}
std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) { std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
CVarList vars(request, 0, ' '); CVarList vars(request, 0, ' ');
auto allMonitors = false; auto allMonitors = false;
@ -74,7 +109,9 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
"focused": {}, "focused": {},
"dpmsStatus": {}, "dpmsStatus": {},
"vrr": {}, "vrr": {},
"activelyTearing": {} "activelyTearing": {},
"currentFormat": "{}",
"availableModes": [{}]
}},)#", }},)#",
m->ID, escapeJSONStrings(m->szName), escapeJSONStrings(m->szShortDescription), (m->output->make ? m->output->make : ""), (m->output->model ? m->output->model : ""), m->ID, escapeJSONStrings(m->szName), escapeJSONStrings(m->szShortDescription), (m->output->make ? m->output->make : ""), (m->output->model ? m->output->model : ""),
(m->output->serial ? m->output->serial : ""), (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, (m->output->serial ? m->output->serial : ""), (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y,
@ -82,7 +119,7 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
escapeJSONStrings(getWorkspaceNameFromSpecialID(m->specialWorkspaceID)), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, escapeJSONStrings(getWorkspaceNameFromSpecialID(m->specialWorkspaceID)), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y,
(int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "true" : "false"), (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "true" : "false"),
(m->dpmsStatus ? "true" : "false"), (m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED ? "true" : "false"), (m->dpmsStatus ? "true" : "false"), (m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED ? "true" : "false"),
m->tearingState.activelyTearing ? "true" : "false"); m->tearingState.activelyTearing ? "true" : "false", formatToString(m->drmFormat), availableModesForOutput(m.get(), format));
} }
trimTrailingComma(result); trimTrailingComma(result);
@ -97,13 +134,14 @@ std::string monitorsRequest(eHyprCtlOutputFormat format, std::string request) {
std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\tspecial " std::format("Monitor {} (ID {}):\n\t{}x{}@{:.5f} at {}x{}\n\tdescription: {}\n\tmake: {}\n\tmodel: {}\n\tserial: {}\n\tactive workspace: {} ({})\n\tspecial "
"workspace: {} ({})\n\treserved: {} " "workspace: {} ({})\n\treserved: {} "
"{} {} {}\n\tscale: {:.2f}\n\ttransform: " "{} {} {}\n\tscale: {:.2f}\n\ttransform: "
"{}\n\tfocused: {}\n\tdpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\n", "{}\n\tfocused: {}\n\tdpmsStatus: {}\n\tvrr: {}\n\tactivelyTearing: {}\n\tcurrentFormat: {}\n\tavailableModes: {}\n\n",
m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription, m->szName, m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->szShortDescription,
(m->output->make ? m->output->make : ""), (m->output->model ? m->output->model : ""), (m->output->serial ? m->output->serial : ""), m->activeWorkspace, (m->output->make ? m->output->make : ""), (m->output->model ? m->output->model : ""), (m->output->serial ? m->output->serial : ""), m->activeWorkspace,
(m->activeWorkspace == -1 ? "" : g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName), m->specialWorkspaceID, (m->activeWorkspace == -1 ? "" : g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName), m->specialWorkspaceID,
getWorkspaceNameFromSpecialID(m->specialWorkspaceID), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, getWorkspaceNameFromSpecialID(m->specialWorkspaceID), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x,
(int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, (m.get() == g_pCompositor->m_pLastMonitor ? "yes" : "no"), (int)m->dpmsStatus,
(int)(m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED), m->tearingState.activelyTearing); (int)(m->output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED), m->tearingState.activelyTearing, formatToString(m->drmFormat),
availableModesForOutput(m.get(), format));
} }
} }
@ -171,8 +209,8 @@ static std::string getWindowData(CWindow* w, eHyprCtlOutputFormat format) {
"swallowing": "0x{:x}", "swallowing": "0x{:x}",
"focusHistoryID": {} "focusHistoryID": {}
}},)#", }},)#",
(uintptr_t)w, (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition.goalv().x, (int)w->m_vRealPosition.goalv().y, (uintptr_t)w, (w->m_bIsMapped ? "true" : "false"), (w->isHidden() ? "true" : "false"), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y,
(int)w->m_vRealSize.goalv().x, (int)w->m_vRealSize.goalv().y, w->m_iWorkspaceID, (int)w->m_vRealSize.goal().x, (int)w->m_vRealSize.goal().y, w->m_iWorkspaceID,
escapeJSONStrings(w->m_iWorkspaceID == -1 ? "" : escapeJSONStrings(w->m_iWorkspaceID == -1 ? "" :
g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName :
std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))), std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))),
@ -187,8 +225,8 @@ static std::string getWindowData(CWindow* w, eHyprCtlOutputFormat format) {
"{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: " "{}\n\tinitialClass: {}\n\tinitialTitle: {}\n\tpid: "
"{}\n\txwayland: {}\n\tpinned: " "{}\n\txwayland: {}\n\tpinned: "
"{}\n\tfullscreen: {}\n\tfullscreenmode: {}\n\tfakefullscreen: {}\n\tgrouped: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n", "{}\n\tfullscreen: {}\n\tfullscreenmode: {}\n\tfakefullscreen: {}\n\tgrouped: {}\n\tswallowing: {:x}\n\tfocusHistoryID: {}\n\n",
(uintptr_t)w, w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goalv().x, (int)w->m_vRealPosition.goalv().y, (uintptr_t)w, w->m_szTitle, (int)w->m_bIsMapped, (int)w->isHidden(), (int)w->m_vRealPosition.goal().x, (int)w->m_vRealPosition.goal().y, (int)w->m_vRealSize.goal().x,
(int)w->m_vRealSize.goalv().x, (int)w->m_vRealSize.goalv().y, w->m_iWorkspaceID, (int)w->m_vRealSize.goal().y, w->m_iWorkspaceID,
(w->m_iWorkspaceID == -1 ? "" : (w->m_iWorkspaceID == -1 ? "" :
g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName :
std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))), std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))),
@ -205,6 +243,9 @@ std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
result += "["; result += "[";
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped && !g_pHyprCtl->m_sCurrentRequestParams.all)
continue;
result += getWindowData(w.get(), format); result += getWindowData(w.get(), format);
} }
@ -213,6 +254,9 @@ std::string clientsRequest(eHyprCtlOutputFormat format, std::string request) {
result += "]"; result += "]";
} else { } else {
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped && !g_pHyprCtl->m_sCurrentRequestParams.all)
continue;
result += getWindowData(w.get(), format); result += getWindowData(w.get(), format);
} }
} }
@ -718,8 +762,8 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
if (kb.nonConsuming) if (kb.nonConsuming)
ret += "n"; ret += "n";
ret += std::format("\n\tmodmask: {}\n\tsubmap: {}\n\tkey: {}\n\tkeycode: {}\n\tdispatcher: {}\n\targ: {}\n\n", kb.modmask, kb.submap, kb.key, kb.keycode, kb.handler, ret += std::format("\n\tmodmask: {}\n\tsubmap: {}\n\tkey: {}\n\tkeycode: {}\n\tcatchall: {}\n\tdispatcher: {}\n\targ: {}\n\n", kb.modmask, kb.submap, kb.key,
kb.arg); kb.keycode, kb.catchAll, kb.handler, kb.arg);
} }
} else { } else {
// json // json
@ -737,11 +781,13 @@ std::string bindsRequest(eHyprCtlOutputFormat format, std::string request) {
"submap": "{}", "submap": "{}",
"key": "{}", "key": "{}",
"keycode": {}, "keycode": {},
"catch_all": {},
"dispatcher": "{}", "dispatcher": "{}",
"arg": "{}" "arg": "{}"
}},)#", }},)#",
kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.nonConsuming ? "true" : "false", kb.locked ? "true" : "false", kb.mouse ? "true" : "false", kb.release ? "true" : "false", kb.repeat ? "true" : "false", kb.nonConsuming ? "true" : "false",
kb.modmask, escapeJSONStrings(kb.submap), escapeJSONStrings(kb.key), kb.keycode, escapeJSONStrings(kb.handler), escapeJSONStrings(kb.arg)); kb.modmask, escapeJSONStrings(kb.submap), escapeJSONStrings(kb.key), kb.keycode, kb.catchAll ? "true" : "false", escapeJSONStrings(kb.handler),
escapeJSONStrings(kb.arg));
} }
trimTrailingComma(ret); trimTrailingComma(ret);
ret += "]"; ret += "]";
@ -877,7 +923,7 @@ std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in) {
g_pInputManager->setTabletConfigs(); // update tablets g_pInputManager->setTabletConfigs(); // update tablets
} }
static auto* const PLAYOUT = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("general:layout"); static auto PLAYOUT = CConfigValue<std::string>("general:layout");
if (COMMAND.contains("general:layout")) if (COMMAND.contains("general:layout"))
g_pLayoutManager->switchToLayout(*PLAYOUT); // update layout g_pLayoutManager->switchToLayout(*PLAYOUT); // update layout
@ -1000,16 +1046,7 @@ std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request)
if (size <= 0) if (size <= 0)
return "size not positive"; return "size not positive";
wlr_xcursor_manager_destroy(g_pCompositor->m_sWLRXCursorMgr); g_pCursorManager->changeTheme(theme, size);
g_pCompositor->m_sWLRXCursorMgr = wlr_xcursor_manager_create(theme.c_str(), size);
setenv("XCURSOR_SIZE", SIZESTR.c_str(), true);
setenv("XCURSOR_THEME", theme.c_str(), true);
for (auto& m : g_pCompositor->m_vMonitors) {
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, m->scale);
}
return "ok"; return "ok";
} }
@ -1108,11 +1145,8 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
bool lock = false; bool lock = false;
if (vars.size() > 4) { if (request.ends_with("lock"))
if (vars[4].starts_with("lock")) {
lock = true; lock = true;
}
}
try { try {
if (PROP == "animationstyle") { if (PROP == "animationstyle") {
@ -1141,6 +1175,22 @@ std::string dispatchSetProp(eHyprCtlOutputFormat format, std::string request) {
PWINDOW->m_sAdditionalConfigData.windowDanceCompat.forceSetIgnoreLocked(configStringToInt(VAL), lock); PWINDOW->m_sAdditionalConfigData.windowDanceCompat.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "nomaxsize") { } else if (PROP == "nomaxsize") {
PWINDOW->m_sAdditionalConfigData.noMaxSize.forceSetIgnoreLocked(configStringToInt(VAL), lock); PWINDOW->m_sAdditionalConfigData.noMaxSize.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "maxsize") {
PWINDOW->m_sAdditionalConfigData.maxSize.forceSetIgnoreLocked(configStringToVector2D(VAL + " " + vars[4]), lock);
if (lock) {
PWINDOW->m_vRealSize = Vector2D(std::min((double)PWINDOW->m_sAdditionalConfigData.maxSize.toUnderlying().x, PWINDOW->m_vRealSize.goal().x),
std::min((double)PWINDOW->m_sAdditionalConfigData.maxSize.toUnderlying().y, PWINDOW->m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
}
} else if (PROP == "minsize") {
PWINDOW->m_sAdditionalConfigData.minSize.forceSetIgnoreLocked(configStringToVector2D(VAL + " " + vars[4]), lock);
if (lock) {
PWINDOW->m_vRealSize = Vector2D(std::max((double)PWINDOW->m_sAdditionalConfigData.minSize.toUnderlying().x, PWINDOW->m_vRealSize.goal().x),
std::max((double)PWINDOW->m_sAdditionalConfigData.minSize.toUnderlying().y, PWINDOW->m_vRealSize.goal().y));
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false);
}
} else if (PROP == "dimaround") { } else if (PROP == "dimaround") {
PWINDOW->m_sAdditionalConfigData.dimAround.forceSetIgnoreLocked(configStringToInt(VAL), lock); PWINDOW->m_sAdditionalConfigData.dimAround.forceSetIgnoreLocked(configStringToInt(VAL), lock);
} else if (PROP == "alphaoverride") { } else if (PROP == "alphaoverride") {
@ -1221,8 +1271,8 @@ std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request)
return std::format("vec2: [{}, {}]\nset: {}", std::any_cast<Hyprlang::VEC2>(VAL).x, std::any_cast<Hyprlang::VEC2>(VAL).y, VAR->m_bSetByUser); return std::format("vec2: [{}, {}]\nset: {}", std::any_cast<Hyprlang::VEC2>(VAL).x, std::any_cast<Hyprlang::VEC2>(VAL).y, VAR->m_bSetByUser);
else if (TYPE == typeid(Hyprlang::STRING)) else if (TYPE == typeid(Hyprlang::STRING))
return std::format("str: {}\nset: {}", std::any_cast<Hyprlang::STRING>(VAL), VAR->m_bSetByUser); return std::format("str: {}\nset: {}", std::any_cast<Hyprlang::STRING>(VAL), VAR->m_bSetByUser);
else if (TYPE == typeid(Hyprlang::CUSTOMTYPE*)) else if (TYPE == typeid(void*))
return std::format("custom type at: {:x}\nset: {}", (uintptr_t)std::any_cast<Hyprlang::CUSTOMTYPE*>(VAL), VAR->m_bSetByUser); return std::format("custom type: {}\nset: {}", ((ICustomConfigValueData*)std::any_cast<void*>(VAL))->toString(), VAR->m_bSetByUser);
} else { } else {
if (TYPE == typeid(Hyprlang::INT)) if (TYPE == typeid(Hyprlang::INT))
return std::format("{{\"option\": \"{}\", \"int\": {}, \"set\": {} }}", curitem, std::any_cast<Hyprlang::INT>(VAL), VAR->m_bSetByUser); return std::format("{{\"option\": \"{}\", \"int\": {}, \"set\": {} }}", curitem, std::any_cast<Hyprlang::INT>(VAL), VAR->m_bSetByUser);
@ -1233,8 +1283,9 @@ std::string dispatchGetOption(eHyprCtlOutputFormat format, std::string request)
VAR->m_bSetByUser); VAR->m_bSetByUser);
else if (TYPE == typeid(Hyprlang::STRING)) else if (TYPE == typeid(Hyprlang::STRING))
return std::format("{{\"option\": \"{}\", \"str\": \"{}\", \"set\": {} }}", curitem, escapeJSONStrings(std::any_cast<Hyprlang::STRING>(VAL)), VAR->m_bSetByUser); return std::format("{{\"option\": \"{}\", \"str\": \"{}\", \"set\": {} }}", curitem, escapeJSONStrings(std::any_cast<Hyprlang::STRING>(VAL)), VAR->m_bSetByUser);
else if (TYPE == typeid(Hyprlang::CUSTOMTYPE*)) else if (TYPE == typeid(void*))
return std::format("{{\"option\": \"{}\", \"custom\": \"{:x}\", \"set\": {} }}", curitem, (uintptr_t)std::any_cast<Hyprlang::CUSTOMTYPE*>(VAL), VAR->m_bSetByUser); return std::format("{{\"option\": \"{}\", \"custom\": \"{}\", \"set\": {} }}", curitem, ((ICustomConfigValueData*)std::any_cast<void*>(VAL))->toString(),
VAR->m_bSetByUser);
} }
return "invalid type (internal error)"; return "invalid type (internal error)";
@ -1417,15 +1468,47 @@ std::string dispatchNotify(eHyprCtlOutputFormat format, std::string request) {
CColor color = configStringToInt(vars[3]); CColor color = configStringToInt(vars[3]);
std::string message = ""; size_t msgidx = 4;
float fontsize = 13.f;
if (vars[msgidx].length() > 9 && vars[msgidx].compare(0, 9, "fontsize:") == 0) {
const auto FONTSIZE = vars[msgidx].substr(9);
for (size_t i = 4; i < vars.size(); ++i) { if (!isNumber(FONTSIZE, true))
message += vars[i] + " "; return "invalid fontsize kwarg";
try {
fontsize = std::stoi(FONTSIZE);
} catch (std::exception& e) { return "invalid fontsize karg"; }
++msgidx;
} }
message.pop_back(); if (vars.size() <= msgidx)
return "not enough args";
g_pHyprNotificationOverlay->addNotification(message, color, time, (eIcons)icon); const auto MESSAGE = vars.join(" ", msgidx);
g_pHyprNotificationOverlay->addNotification(MESSAGE, color, time, (eIcons)icon, fontsize);
return "ok";
}
std::string dispatchDismissNotify(eHyprCtlOutputFormat format, std::string request) {
CVarList vars(request, 0, ' ');
int amount = -1;
if (vars.size() > 1) {
const auto AMOUNT = vars[1];
if (!isNumber(AMOUNT))
return "invalid arg 1";
try {
amount = std::stoi(AMOUNT);
} catch (std::exception& e) { return "invalid arg 1"; }
}
g_pHyprNotificationOverlay->dismissNotifications(amount);
return "ok"; return "ok";
} }
@ -1453,6 +1536,7 @@ CHyprCtl::CHyprCtl() {
registerCommand(SHyprCtlCommand{"reload", false, reloadRequest}); registerCommand(SHyprCtlCommand{"reload", false, reloadRequest});
registerCommand(SHyprCtlCommand{"plugin", false, dispatchPlugin}); registerCommand(SHyprCtlCommand{"plugin", false, dispatchPlugin});
registerCommand(SHyprCtlCommand{"notify", false, dispatchNotify}); registerCommand(SHyprCtlCommand{"notify", false, dispatchNotify});
registerCommand(SHyprCtlCommand{"dismissnotify", false, dispatchDismissNotify});
registerCommand(SHyprCtlCommand{"setprop", false, dispatchSetProp}); registerCommand(SHyprCtlCommand{"setprop", false, dispatchSetProp});
registerCommand(SHyprCtlCommand{"seterror", false, dispatchSeterror}); registerCommand(SHyprCtlCommand{"seterror", false, dispatchSeterror});
registerCommand(SHyprCtlCommand{"switchxkblayout", false, switchXKBLayoutRequest}); registerCommand(SHyprCtlCommand{"switchxkblayout", false, switchXKBLayoutRequest});
@ -1478,6 +1562,7 @@ void CHyprCtl::unregisterCommand(const std::shared_ptr<SHyprCtlCommand>& cmd) {
std::string CHyprCtl::getReply(std::string request) { std::string CHyprCtl::getReply(std::string request) {
auto format = eHyprCtlOutputFormat::FORMAT_NORMAL; auto format = eHyprCtlOutputFormat::FORMAT_NORMAL;
bool reloadAll = false; bool reloadAll = false;
m_sCurrentRequestParams = {};
// process flags for non-batch requests // process flags for non-batch requests
if (!request.starts_with("[[BATCH]]") && request.contains("/")) { if (!request.starts_with("[[BATCH]]") && request.contains("/")) {
@ -1498,8 +1583,10 @@ std::string CHyprCtl::getReply(std::string request) {
if (c == 'j') if (c == 'j')
format = eHyprCtlOutputFormat::FORMAT_JSON; format = eHyprCtlOutputFormat::FORMAT_JSON;
if (c == 'r') else if (c == 'r')
reloadAll = true; reloadAll = true;
else if (c == 'a')
m_sCurrentRequestParams.all = true;
} }
if (sepIndex < request.size()) if (sepIndex < request.size())
@ -1541,7 +1628,7 @@ std::string CHyprCtl::getReply(std::string request) {
g_pInputManager->setTouchDeviceConfigs(); // update touch device cfgs g_pInputManager->setTouchDeviceConfigs(); // update touch device cfgs
g_pInputManager->setTabletConfigs(); // update tablets g_pInputManager->setTabletConfigs(); // update tablets
static auto* const PLAYOUT = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("general:layout"); static auto PLAYOUT = CConfigValue<std::string>("general:layout");
g_pLayoutManager->switchToLayout(*PLAYOUT); // update layout g_pLayoutManager->switchToLayout(*PLAYOUT); // update layout

View file

@ -16,6 +16,10 @@ class CHyprCtl {
int m_iSocketFD = -1; int m_iSocketFD = -1;
struct {
bool all = false;
} m_sCurrentRequestParams;
private: private:
void startHyprCtlSocket(); void startHyprCtlSocket();

View file

@ -36,7 +36,7 @@ CHyprNotificationOverlay::CHyprNotificationOverlay() {
m_szIconFontName = fonts.substr(COLON + 2, LASTCHAR - (COLON + 2)); m_szIconFontName = fonts.substr(COLON + 2, LASTCHAR - (COLON + 2));
} }
void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon) { void CHyprNotificationOverlay::addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon, const float fontSize) {
const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get(); const auto PNOTIF = m_dNotifications.emplace_back(std::make_unique<SNotification>()).get();
PNOTIF->text = text; PNOTIF->text = text;
@ -44,12 +44,25 @@ void CHyprNotificationOverlay::addNotification(const std::string& text, const CC
PNOTIF->started.reset(); PNOTIF->started.reset();
PNOTIF->timeMs = timeMs; PNOTIF->timeMs = timeMs;
PNOTIF->icon = icon; PNOTIF->icon = icon;
PNOTIF->fontSize = fontSize;
for (auto& m : g_pCompositor->m_vMonitors) { for (auto& m : g_pCompositor->m_vMonitors) {
g_pCompositor->scheduleFrameForMonitor(m.get()); g_pCompositor->scheduleFrameForMonitor(m.get());
} }
} }
void CHyprNotificationOverlay::dismissNotifications(const int amount) {
if (amount == -1)
m_dNotifications.clear();
else {
const int AMT = std::min(amount, static_cast<int>(m_dNotifications.size()));
for (int i = 0; i < AMT; ++i) {
m_dNotifications.pop_front();
}
}
}
CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) { CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
static constexpr auto ANIM_DURATION_MS = 600.0; static constexpr auto ANIM_DURATION_MS = 600.0;
static constexpr auto ANIM_LAG_MS = 100.0; static constexpr auto ANIM_LAG_MS = 100.0;
@ -62,27 +75,24 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
float maxWidth = 0; float maxWidth = 0;
const auto SCALE = pMonitor->scale; const auto SCALE = pMonitor->scale;
const auto FONTSIZE = std::clamp((int)(13.f * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
const auto MONSIZE = pMonitor->vecPixelSize; const auto MONSIZE = pMonitor->vecPixelSize;
cairo_text_extents_t cairoExtents; cairo_text_extents_t cairoExtents;
int iconW = 0, iconH = 0; int iconW = 0, iconH = 0;
PangoLayout* pangoLayout;
PangoFontDescription* pangoFD;
pangoLayout = pango_cairo_create_layout(m_pCairo);
pangoFD = pango_font_description_from_string(("Sans " + std::to_string(FONTSIZE * ICON_SCALE)).c_str());
pango_layout_set_font_description(pangoLayout, pangoFD);
cairo_select_font_face(m_pCairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_select_font_face(m_pCairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(m_pCairo, FONTSIZE);
const auto PBEZIER = g_pAnimationManager->getBezier("default"); const auto PBEZIER = g_pAnimationManager->getBezier("default");
for (auto& notif : m_dNotifications) { for (auto& notif : m_dNotifications) {
const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD; const auto ICONPADFORNOTIF = notif->icon == ICON_NONE ? 0 : ICON_PAD;
const auto FONTSIZE = std::clamp((int)(notif->fontSize * ((pMonitor->vecPixelSize.x * SCALE) / 1920.f)), 8, 40);
PangoLayout* pangoLayout = pango_cairo_create_layout(m_pCairo);
PangoFontDescription* pangoFD = pango_font_description_from_string(("Sans " + std::to_string(FONTSIZE * ICON_SCALE)).c_str());
pango_layout_set_font_description(pangoLayout, pangoFD);
cairo_set_font_size(m_pCairo, FONTSIZE);
// first rect (bg, col) // first rect (bg, col)
const float FIRSTRECTANIMP = const float FIRSTRECTANIMP =
@ -162,10 +172,10 @@ CBox CHyprNotificationOverlay::drawNotifications(CMonitor* pMonitor) {
if (maxWidth < NOTIFSIZE.x) if (maxWidth < NOTIFSIZE.x)
maxWidth = NOTIFSIZE.x; maxWidth = NOTIFSIZE.x;
}
pango_font_description_free(pangoFD); pango_font_description_free(pangoFD);
g_object_unref(pangoLayout); g_object_unref(pangoLayout);
}
// cleanup notifs // cleanup notifs
std::erase_if(m_dNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; }); std::erase_if(m_dNotifications, [](const auto& notif) { return notif->started.getMillis() > notif->timeMs; });

View file

@ -33,6 +33,7 @@ struct SNotification {
CTimer started; CTimer started;
float timeMs = 0; float timeMs = 0;
eIcons icon = ICON_NONE; eIcons icon = ICON_NONE;
float fontSize = 13.f;
}; };
class CHyprNotificationOverlay { class CHyprNotificationOverlay {
@ -40,7 +41,8 @@ class CHyprNotificationOverlay {
CHyprNotificationOverlay(); CHyprNotificationOverlay();
void draw(CMonitor* pMonitor); void draw(CMonitor* pMonitor);
void addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon = ICON_NONE); void addNotification(const std::string& text, const CColor& color, const float timeMs, const eIcons icon = ICON_NONE, const float fontSize = 13.f);
void dismissNotifications(const int amount);
bool hasAny(); bool hasAny();
private: private:

123
src/desktop/Constraint.cpp Normal file
View file

@ -0,0 +1,123 @@
#include "Constraint.hpp"
#include "WLSurface.hpp"
#include "../Compositor.hpp"
CConstraint::CConstraint(wlr_pointer_constraint_v1* constraint, CWLSurface* owner) : m_pOwner(owner), m_pConstraint(constraint) {
initSignals();
m_vCursorPosOnActivate = g_pInputManager->getMouseCoordsInternal();
g_pInputManager->m_vConstraints.push_back(this);
if (g_pCompositor->m_pLastFocus == m_pOwner->wlr())
activate();
}
CConstraint::~CConstraint() {
std::erase(g_pInputManager->m_vConstraints, this);
}
static void onConstraintDestroy(void* owner, void* data) {
const auto CONSTRAINT = (CConstraint*)owner;
CONSTRAINT->onDestroy();
}
static void onConstraintSetRegion(void* owner, void* data) {
const auto CONSTRAINT = (CConstraint*)owner;
CONSTRAINT->onSetRegion();
}
void CConstraint::initSignals() {
hyprListener_setConstraintRegion.initCallback(&m_pConstraint->events.set_region, ::onConstraintSetRegion, this, "CConstraint");
hyprListener_destroyConstraint.initCallback(&m_pConstraint->events.destroy, ::onConstraintDestroy, this, "CConstraint");
}
void CConstraint::onDestroy() {
if (active())
deactivate();
// this is us
m_pOwner->m_pConstraint.reset();
}
void CConstraint::onSetRegion() {
if (!m_bActive)
return;
m_rRegion.set(&m_pConstraint->region);
m_vPositionHint = m_rRegion.closestPoint(m_vPositionHint);
g_pInputManager->simulateMouseMovement(); // to warp the cursor if anything's amiss
}
void CConstraint::onCommit() {
if (!m_bActive)
return;
const auto COMMITTED = m_pConstraint->current.committed;
if (COMMITTED & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
m_bHintSet = true;
m_vPositionHint = {m_pConstraint->current.cursor_hint.x, m_pConstraint->current.cursor_hint.y};
g_pInputManager->simulateMouseMovement();
}
if (COMMITTED & WLR_POINTER_CONSTRAINT_V1_STATE_REGION)
onSetRegion();
}
CRegion CConstraint::logicConstraintRegion() {
CRegion rg = m_rRegion;
const auto SURFBOX = m_pOwner->getSurfaceBoxGlobal();
const auto CONSTRAINTPOS = SURFBOX.has_value() ? SURFBOX->pos() : Vector2D{};
rg.translate(CONSTRAINTPOS);
return rg;
}
CWLSurface* CConstraint::owner() {
return m_pOwner;
}
bool CConstraint::isLocked() {
return m_pConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED;
}
Vector2D CConstraint::logicPositionHint() {
const auto SURFBOX = m_pOwner->getSurfaceBoxGlobal();
const auto CONSTRAINTPOS = SURFBOX.has_value() ? SURFBOX->pos() : Vector2D{};
return m_bHintSet ? CONSTRAINTPOS + m_vPositionHint : m_vCursorPosOnActivate;
}
void CConstraint::deactivate() {
if (!m_bActive)
return;
wlr_pointer_constraint_v1_send_deactivated(m_pConstraint);
m_bActive = false;
if (isLocked())
g_pCompositor->warpCursorTo(logicPositionHint(), true);
if (m_pConstraint->lifetime == ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT)
m_bDead = true;
}
void CConstraint::activate() {
if (m_bActive || m_bDead)
return;
// TODO: hack, probably not a super duper great idea
if (g_pCompositor->m_sSeat.seat->pointer_state.focused_surface != m_pOwner->wlr()) {
const auto SURFBOX = m_pOwner->getSurfaceBoxGlobal();
const auto LOCAL = SURFBOX.has_value() ? logicPositionHint() - SURFBOX->pos() : Vector2D{};
wlr_seat_pointer_enter(g_pCompositor->m_sSeat.seat, m_pOwner->wlr(), LOCAL.x, LOCAL.y);
}
g_pCompositor->warpCursorTo(logicPositionHint(), true);
wlr_pointer_constraint_v1_send_activated(m_pConstraint);
m_bActive = true;
}
bool CConstraint::active() {
return m_bActive;
}

View file

@ -0,0 +1,44 @@
#pragma once
#include "../includes.hpp"
#include "../helpers/Region.hpp"
#include "../helpers/WLListener.hpp"
class CWLSurface;
class CConstraint {
public:
CConstraint(wlr_pointer_constraint_v1* constraint, CWLSurface* owner);
~CConstraint();
void onCommit();
void onDestroy();
void onSetRegion();
CRegion logicConstraintRegion();
bool isLocked();
Vector2D logicPositionHint();
void deactivate();
void activate();
bool active();
CWLSurface* owner();
private:
bool m_bActive = false;
CWLSurface* m_pOwner = nullptr;
wlr_pointer_constraint_v1* m_pConstraint;
CRegion m_rRegion;
bool m_bHintSet = false;
Vector2D m_vPositionHint = {-1, -1};
Vector2D m_vCursorPosOnActivate = {-1, -1};
// for oneshot constraints that have been activated once
bool m_bDead = false;
DYNLISTENER(destroyConstraint);
DYNLISTENER(setConstraintRegion);
void initSignals();
};

247
src/desktop/Popup.cpp Normal file
View file

@ -0,0 +1,247 @@
#include "Popup.hpp"
#include "../Compositor.hpp"
CPopup::CPopup(CWindow* pOwner) : m_pWindowOwner(pOwner) {
initAllSignals();
}
CPopup::CPopup(SLayerSurface* pOwner) : m_pLayerOwner(pOwner) {
initAllSignals();
}
CPopup::CPopup(wlr_xdg_popup* popup, CPopup* pOwner) : m_pParent(pOwner), m_pWLR(popup) {
m_pWLR->base->data = this;
m_sWLSurface.assign(popup->base->surface, this);
m_pLayerOwner = pOwner->m_pLayerOwner;
m_pWindowOwner = pOwner->m_pWindowOwner;
m_vLastSize = {m_pWLR->current.geometry.width, m_pWLR->current.geometry.height};
unconstrain();
initAllSignals();
}
CPopup::~CPopup() {
m_sWLSurface.unassign();
if (m_pWLR)
m_pWLR->base->data = nullptr;
hyprListener_commitPopup.removeCallback();
hyprListener_repositionPopup.removeCallback();
hyprListener_mapPopup.removeCallback();
hyprListener_unmapPopup.removeCallback();
hyprListener_newPopup.removeCallback();
hyprListener_destroyPopup.removeCallback();
}
static void onNewPopup(void* owner, void* data) {
const auto POPUP = (CPopup*)owner;
POPUP->onNewPopup((wlr_xdg_popup*)data);
}
static void onMapPopup(void* owner, void* data) {
const auto POPUP = (CPopup*)owner;
POPUP->onMap();
}
static void onDestroyPopup(void* owner, void* data) {
const auto POPUP = (CPopup*)owner;
POPUP->onDestroy();
}
static void onUnmapPopup(void* owner, void* data) {
const auto POPUP = (CPopup*)owner;
POPUP->onUnmap();
}
static void onCommitPopup(void* owner, void* data) {
const auto POPUP = (CPopup*)owner;
POPUP->onCommit();
}
static void onRepositionPopup(void* owner, void* data) {
const auto POPUP = (CPopup*)owner;
POPUP->onReposition();
}
void CPopup::initAllSignals() {
if (!m_pWLR) {
if (m_pWindowOwner)
hyprListener_newPopup.initCallback(&m_pWindowOwner->m_uSurface.xdg->events.new_popup, ::onNewPopup, this, "CPopup Head");
else if (m_pLayerOwner)
hyprListener_newPopup.initCallback(&m_pLayerOwner->layerSurface->events.new_popup, ::onNewPopup, this, "CPopup Head");
else
ASSERT(false);
return;
}
hyprListener_repositionPopup.initCallback(&m_pWLR->events.reposition, ::onRepositionPopup, this, "CPopup");
hyprListener_destroyPopup.initCallback(&m_pWLR->events.destroy, ::onDestroyPopup, this, "CPopup");
hyprListener_mapPopup.initCallback(&m_sWLSurface.wlr()->events.map, ::onMapPopup, this, "CPopup");
hyprListener_unmapPopup.initCallback(&m_sWLSurface.wlr()->events.unmap, ::onUnmapPopup, this, "CPopup");
hyprListener_commitPopup.initCallback(&m_sWLSurface.wlr()->events.commit, ::onCommitPopup, this, "CPopup");
hyprListener_newPopup.initCallback(&m_pWLR->base->events.new_popup, ::onNewPopup, this, "CPopup");
}
void CPopup::onNewPopup(wlr_xdg_popup* popup) {
const auto POPUP = m_vChildren.emplace_back(std::make_unique<CPopup>(popup, this)).get();
Debug::log(LOG, "New popup at wlr {:x} and hl {:x}", (uintptr_t)popup, (uintptr_t)POPUP);
}
void CPopup::onDestroy() {
m_bInert = true;
if (!m_pParent)
return; // head node
std::erase_if(m_pParent->m_vChildren, [this](const auto& other) { return other.get() == this; });
}
void CPopup::onMap() {
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
const auto COORDS = coordsGlobal();
CBox box;
wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr());
box.applyFromWlr().translate(COORDS).expand(4);
g_pHyprRenderer->damageBox(&box);
m_vLastPos = coordsRelativeToParent();
g_pInputManager->simulateMouseMovement();
m_pSubsurfaceHead = std::make_unique<CSubsurface>(this);
unconstrain();
sendScale();
}
void CPopup::onUnmap() {
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
const auto COORDS = coordsGlobal();
CBox box;
wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr());
box.applyFromWlr().translate(COORDS).expand(4);
g_pHyprRenderer->damageBox(&box);
m_pSubsurfaceHead.reset();
g_pInputManager->simulateMouseMovement();
}
void CPopup::onCommit(bool ignoreSiblings) {
if (m_pWLR->base->initial_commit) {
wlr_xdg_surface_schedule_configure(m_pWLR->base);
return;
}
const auto COORDS = coordsGlobal();
const auto COORDSLOCAL = coordsRelativeToParent();
if (m_vLastSize != Vector2D{m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height} || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
g_pHyprRenderer->damageBox(&box);
m_vLastSize = {m_pWLR->base->current.geometry.width, m_pWLR->base->current.geometry.height};
box = {COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box);
m_vLastPos = COORDSLOCAL;
}
if (!ignoreSiblings)
m_pSubsurfaceHead->recheckDamageForSubsurfaces();
g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
m_bRequestedReposition = false;
}
void CPopup::onReposition() {
Debug::log(LOG, "Popup {:x} requests reposition", (uintptr_t)this);
m_bRequestedReposition = true;
m_vLastPos = coordsRelativeToParent();
unconstrain();
}
void CPopup::unconstrain() {
const auto COORDS = t1ParentCoords();
const auto PMONITOR = g_pCompositor->getMonitorFromVector(COORDS);
if (!PMONITOR)
return;
CBox box = {PMONITOR->vecPosition.x - COORDS.x, PMONITOR->vecPosition.y - COORDS.y, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
wlr_xdg_popup_unconstrain_from_box(m_pWLR, box.pWlr());
}
Vector2D CPopup::coordsRelativeToParent() {
Vector2D offset;
CPopup* current = this;
offset -= {m_pWLR->base->current.geometry.x, m_pWLR->base->current.geometry.y};
while (current->m_pParent) {
offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
offset += {current->m_pWLR->current.geometry.x, current->m_pWLR->current.geometry.y};
current = current->m_pParent;
}
return offset;
}
Vector2D CPopup::coordsGlobal() {
return localToGlobal(coordsRelativeToParent());
}
Vector2D CPopup::localToGlobal(const Vector2D& rel) {
return t1ParentCoords() + rel;
}
Vector2D CPopup::t1ParentCoords() {
if (m_pWindowOwner)
return m_pWindowOwner->m_vRealPosition.value();
if (m_pLayerOwner)
return m_pLayerOwner->realPosition.value();
ASSERT(false);
return {};
}
void CPopup::recheckTree() {
CPopup* curr = this;
while (curr->m_pParent) {
curr = curr->m_pParent;
}
curr->recheckChildrenRecursive();
}
void CPopup::recheckChildrenRecursive() {
for (auto& c : m_vChildren) {
c->onCommit(true);
c->recheckChildrenRecursive();
}
}
Vector2D CPopup::size() {
return m_vLastSize;
}
void CPopup::sendScale() {
if (m_pWindowOwner)
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner->m_pWLSurface.m_fLastScale);
else if (m_pLayerOwner)
g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale);
else
UNREACHABLE();
}

72
src/desktop/Popup.hpp Normal file
View file

@ -0,0 +1,72 @@
#pragma once
#include <vector>
#include <memory>
#include "Subsurface.hpp"
struct SLayerSurface;
class CPopup {
public:
// dummy head nodes
CPopup(CWindow* pOwner);
CPopup(SLayerSurface* pOwner);
// real nodes
CPopup(wlr_xdg_popup* popup, CPopup* pOwner);
~CPopup();
Vector2D coordsRelativeToParent();
Vector2D coordsGlobal();
Vector2D size();
void onNewPopup(wlr_xdg_popup* popup);
void onDestroy();
void onMap();
void onUnmap();
void onCommit(bool ignoreSiblings = false);
void onReposition();
void recheckTree();
CWLSurface m_sWLSurface;
private:
// T1 owners, each popup has to have one of these
CWindow* m_pWindowOwner = nullptr;
SLayerSurface* m_pLayerOwner = nullptr;
// T2 owners
CPopup* m_pParent = nullptr;
wlr_xdg_popup* m_pWLR = nullptr;
Vector2D m_vLastSize = {};
Vector2D m_vLastPos = {};
bool m_bRequestedReposition = false;
bool m_bInert = false;
//
std::vector<std::unique_ptr<CPopup>> m_vChildren;
std::unique_ptr<CSubsurface> m_pSubsurfaceHead;
// signals
DYNLISTENER(newPopup);
DYNLISTENER(destroyPopup);
DYNLISTENER(mapPopup);
DYNLISTENER(unmapPopup);
DYNLISTENER(commitPopup);
DYNLISTENER(repositionPopup);
void initAllSignals();
void unconstrain();
void recheckChildrenRecursive();
void sendScale();
Vector2D localToGlobal(const Vector2D& rel);
Vector2D t1ParentCoords();
};

243
src/desktop/Subsurface.cpp Normal file
View file

@ -0,0 +1,243 @@
#include "Subsurface.hpp"
#include "../events/Events.hpp"
#include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
static void onNewSubsurface(void* owner, void* data);
CSubsurface::CSubsurface(CWindow* pOwner) : m_pWindowParent(pOwner) {
initSignals();
wlr_subsurface* wlrSubsurface;
wl_list_for_each(wlrSubsurface, &pOwner->m_pWLSurface.wlr()->current.subsurfaces_below, current.link) {
::onNewSubsurface(this, wlrSubsurface);
}
wl_list_for_each(wlrSubsurface, &pOwner->m_pWLSurface.wlr()->current.subsurfaces_above, current.link) {
::onNewSubsurface(this, wlrSubsurface);
}
}
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
initSignals();
wlr_subsurface* wlrSubsurface;
wl_list_for_each(wlrSubsurface, &pOwner->m_sWLSurface.wlr()->current.subsurfaces_below, current.link) {
::onNewSubsurface(this, wlrSubsurface);
}
wl_list_for_each(wlrSubsurface, &pOwner->m_sWLSurface.wlr()->current.subsurfaces_above, current.link) {
::onNewSubsurface(this, wlrSubsurface);
}
}
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
m_sWLSurface.assign(pSubsurface->surface, this);
initSignals();
initExistingSubsurfaces();
}
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
m_sWLSurface.assign(pSubsurface->surface, this);
initSignals();
initExistingSubsurfaces();
}
CSubsurface::~CSubsurface() {
hyprListener_newSubsurface.removeCallback();
if (!m_pSubsurface)
return;
hyprListener_commitSubsurface.removeCallback();
hyprListener_destroySubsurface.removeCallback();
}
static void onNewSubsurface(void* owner, void* data) {
const auto PSUBSURFACE = (CSubsurface*)owner;
PSUBSURFACE->onNewSubsurface((wlr_subsurface*)data);
}
static void onDestroySubsurface(void* owner, void* data) {
const auto PSUBSURFACE = (CSubsurface*)owner;
PSUBSURFACE->onDestroy();
}
static void onCommitSubsurface(void* owner, void* data) {
const auto PSUBSURFACE = (CSubsurface*)owner;
PSUBSURFACE->onCommit();
}
static void onMapSubsurface(void* owner, void* data) {
const auto PSUBSURFACE = (CSubsurface*)owner;
PSUBSURFACE->onMap();
}
static void onUnmapSubsurface(void* owner, void* data) {
const auto PSUBSURFACE = (CSubsurface*)owner;
PSUBSURFACE->onUnmap();
}
void CSubsurface::initSignals() {
if (m_pSubsurface) {
hyprListener_commitSubsurface.initCallback(&m_pSubsurface->surface->events.commit, &onCommitSubsurface, this, "CSubsurface");
hyprListener_destroySubsurface.initCallback(&m_pSubsurface->events.destroy, &onDestroySubsurface, this, "CSubsurface");
hyprListener_newSubsurface.initCallback(&m_pSubsurface->surface->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface");
hyprListener_mapSubsurface.initCallback(&m_pSubsurface->surface->events.map, &onMapSubsurface, this, "CSubsurface");
hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
} else {
if (m_pWindowParent)
hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
else if (m_pPopupParent)
hyprListener_newSubsurface.initCallback(&m_pPopupParent->m_sWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
else
RASSERT(false, "CSubsurface::initSignals empty subsurface");
}
}
void CSubsurface::checkSiblingDamage() {
if (!m_pParent)
return; // ??????????
const double SCALE = m_pWindowParent && m_pWindowParent->m_bIsX11 ? 1.0 / m_pWindowParent->m_fX11SurfaceScaledBy : 1.0;
for (auto& n : m_pParent->m_vChildren) {
if (n.get() == this)
continue;
const auto COORDS = n->coordsGlobal();
g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y, SCALE);
}
}
void CSubsurface::recheckDamageForSubsurfaces() {
for (auto& n : m_vChildren) {
const auto COORDS = n->coordsGlobal();
g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y);
}
}
void CSubsurface::onCommit() {
// no damaging if it's not visible
if (m_pWindowParent && !g_pHyprRenderer->shouldRenderWindow(m_pWindowParent)) {
m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
if (*PLOGDAMAGE)
Debug::log(LOG, "Refusing to commit damage from a subsurface of {} because it's invisible.", m_pWindowParent);
return;
}
const auto COORDS = coordsGlobal();
g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
if (m_pPopupParent)
m_pPopupParent->recheckTree();
if (m_pWindowParent) // I hate you firefox why are you doing this
m_pWindowParent->m_pPopupHead->recheckTree();
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
checkSiblingDamage();
if (m_vLastSize != Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}) {
CBox box{COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box);
m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
box = {COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box);
}
}
void CSubsurface::onDestroy() {
// destroy children
m_vChildren.clear();
m_bInert = true;
if (!m_pSubsurface)
return; // dummy node, nothing to do, it's the parent dying
// kill ourselves
std::erase_if(m_pParent->m_vChildren, [this](const auto& other) { return other.get() == this; });
}
void CSubsurface::onNewSubsurface(wlr_subsurface* pSubsurface) {
CSubsurface* PSUBSURFACE = nullptr;
if (m_pWindowParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent)).get();
else if (m_pPopupParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
PSUBSURFACE->m_pParent = this;
ASSERT(PSUBSURFACE);
}
void CSubsurface::onMap() {
m_vLastSize = {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
const auto COORDS = coordsGlobal();
CBox box{COORDS, m_vLastSize};
box.expand(4);
g_pHyprRenderer->damageBox(&box);
if (m_pWindowParent)
m_pWindowParent->updateSurfaceScaleTransformDetails();
}
void CSubsurface::onUnmap() {
const auto COORDS = coordsGlobal();
CBox box{COORDS, m_vLastSize};
box.expand(4);
g_pHyprRenderer->damageBox(&box);
if (m_sWLSurface.wlr() == g_pCompositor->m_pLastFocus)
g_pInputManager->releaseAllMouseButtons();
g_pInputManager->simulateMouseMovement();
// TODO: should this remove children? Currently it won't, only on .destroy
}
Vector2D CSubsurface::coordsRelativeToParent() {
Vector2D offset;
CSubsurface* current = this;
while (current->m_pParent) {
offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
offset += {current->m_pSubsurface->current.x, current->m_pSubsurface->current.y};
current = current->m_pParent;
}
return offset;
}
Vector2D CSubsurface::coordsGlobal() {
Vector2D coords = coordsRelativeToParent();
if (m_pWindowParent)
coords += m_pWindowParent->m_vRealPosition.value();
else if (m_pPopupParent)
coords += m_pPopupParent->coordsGlobal();
return coords;
}
void CSubsurface::initExistingSubsurfaces() {
if (m_pWindowParent)
return;
wlr_subsurface* wlrSubsurface;
wl_list_for_each(wlrSubsurface, &m_sWLSurface.wlr()->current.subsurfaces_below, current.link) {
::onNewSubsurface(this, wlrSubsurface);
}
wl_list_for_each(wlrSubsurface, &m_sWLSurface.wlr()->current.subsurfaces_above, current.link) {
::onNewSubsurface(this, wlrSubsurface);
}
}
Vector2D CSubsurface::size() {
return {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
}

View file

@ -0,0 +1,59 @@
#pragma once
#include "../defines.hpp"
#include <vector>
#include "WLSurface.hpp"
class CWindow;
class CPopup;
class CSubsurface {
public:
// root dummy nodes
CSubsurface(CWindow* pOwner);
CSubsurface(CPopup* pOwner);
// real nodes
CSubsurface(wlr_subsurface* pSubsurface, CWindow* pOwner);
CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner);
~CSubsurface();
Vector2D coordsRelativeToParent();
Vector2D coordsGlobal();
Vector2D size();
void onCommit();
void onDestroy();
void onNewSubsurface(wlr_subsurface* pSubsurface);
void onMap();
void onUnmap();
void recheckDamageForSubsurfaces();
private:
DYNLISTENER(destroySubsurface);
DYNLISTENER(commitSubsurface);
DYNLISTENER(newSubsurface);
DYNLISTENER(mapSubsurface);
DYNLISTENER(unmapSubsurface);
wlr_subsurface* m_pSubsurface = nullptr;
CWLSurface m_sWLSurface;
Vector2D m_vLastSize = {};
// if nullptr, means it's a dummy node
CSubsurface* m_pParent = nullptr;
CWindow* m_pWindowParent = nullptr;
CPopup* m_pPopupParent = nullptr;
std::vector<std::unique_ptr<CSubsurface>> m_vChildren;
bool m_bInert = false;
void initSignals();
void initExistingSubsurfaces();
void checkSiblingDamage();
};

View file

@ -1,14 +1,38 @@
#include "WLSurface.hpp" #include "WLSurface.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
CWLSurface::CWLSurface(wlr_surface* pSurface) {
m_pWLRSurface = pSurface;
init();
}
void CWLSurface::assign(wlr_surface* pSurface) { void CWLSurface::assign(wlr_surface* pSurface) {
m_pWLRSurface = pSurface; m_pWLRSurface = pSurface;
init(); init();
m_bInert = false;
}
void CWLSurface::assign(wlr_surface* pSurface, CWindow* pOwner) {
m_pWindowOwner = pOwner;
m_pWLRSurface = pSurface;
init();
m_bInert = false;
}
void CWLSurface::assign(wlr_surface* pSurface, SLayerSurface* pOwner) {
m_pLayerOwner = pOwner;
m_pWLRSurface = pSurface;
init();
m_bInert = false;
}
void CWLSurface::assign(wlr_surface* pSurface, CSubsurface* pOwner) {
m_pSubsurfaceOwner = pOwner;
m_pWLRSurface = pSurface;
init();
m_bInert = false;
}
void CWLSurface::assign(wlr_surface* pSurface, CPopup* pOwner) {
m_pPopupOwner = pOwner;
m_pWLRSurface = pSurface;
init();
m_bInert = false;
} }
void CWLSurface::unassign() { void CWLSurface::unassign() {
@ -28,20 +52,20 @@ wlr_surface* CWLSurface::wlr() const {
} }
bool CWLSurface::small() const { bool CWLSurface::small() const {
if (!m_pOwner || !exists()) if (!m_pWindowOwner || !exists())
return false; return false;
return m_pOwner->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || m_pOwner->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1; return m_pWindowOwner->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || m_pWindowOwner->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1;
} }
Vector2D CWLSurface::correctSmallVec() const { Vector2D CWLSurface::correctSmallVec() const {
if (!m_pOwner || !exists() || !small() || m_bFillIgnoreSmall) if (!m_pWindowOwner || !exists() || !small() || m_bFillIgnoreSmall)
return {}; return {};
const auto SIZE = getViewporterCorrectedSize(); const auto SIZE = getViewporterCorrectedSize();
return Vector2D{(m_pOwner->m_vReportedSize.x - SIZE.x) / 2, (m_pOwner->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) * return Vector2D{(m_pWindowOwner->m_vReportedSize.x - SIZE.x) / 2, (m_pWindowOwner->m_vReportedSize.y - SIZE.y) / 2}.clamp({}, {INFINITY, INFINITY}) *
(m_pOwner->m_vRealSize.vec() / m_pOwner->m_vReportedSize); (m_pWindowOwner->m_vRealSize.value() / m_pWindowOwner->m_vReportedSize);
} }
Vector2D CWLSurface::getViewporterCorrectedSize() const { Vector2D CWLSurface::getViewporterCorrectedSize() const {
@ -79,9 +103,16 @@ void CWLSurface::destroy() {
if (!m_pWLRSurface) if (!m_pWLRSurface)
return; return;
m_pConstraint.reset();
hyprListener_destroy.removeCallback(); hyprListener_destroy.removeCallback();
hyprListener_commit.removeCallback();
m_pWLRSurface->data = nullptr; m_pWLRSurface->data = nullptr;
m_pOwner = nullptr; m_pWindowOwner = nullptr;
m_pLayerOwner = nullptr;
m_pPopupOwner = nullptr;
m_pSubsurfaceOwner = nullptr;
m_bInert = true;
if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface) if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface)
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus = nullptr;
@ -95,6 +126,11 @@ void CWLSurface::destroy() {
Debug::log(LOG, "CWLSurface {:x} called destroy()", (uintptr_t)this); Debug::log(LOG, "CWLSurface {:x} called destroy()", (uintptr_t)this);
} }
static void onCommit(void* owner, void* data) {
const auto SURF = (CWLSurface*)owner;
SURF->onCommit();
}
void CWLSurface::init() { void CWLSurface::init() {
if (!m_pWLRSurface) if (!m_pWLRSurface)
return; return;
@ -105,6 +141,56 @@ void CWLSurface::init() {
hyprListener_destroy.initCallback( hyprListener_destroy.initCallback(
&m_pWLRSurface->events.destroy, [&](void* owner, void* data) { destroy(); }, this, "CWLSurface"); &m_pWLRSurface->events.destroy, [&](void* owner, void* data) { destroy(); }, this, "CWLSurface");
hyprListener_commit.initCallback(&m_pWLRSurface->events.commit, ::onCommit, this, "CWLSurface");
Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this); Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this);
} }
CWindow* CWLSurface::getWindow() {
return m_pWindowOwner;
}
SLayerSurface* CWLSurface::getLayer() {
return m_pLayerOwner;
}
CPopup* CWLSurface::getPopup() {
return m_pPopupOwner;
}
CSubsurface* CWLSurface::getSubsurface() {
return m_pSubsurfaceOwner;
}
bool CWLSurface::desktopComponent() {
return m_pLayerOwner || m_pWindowOwner || m_pSubsurfaceOwner || m_pPopupOwner;
}
std::optional<CBox> CWLSurface::getSurfaceBoxGlobal() {
if (!desktopComponent())
return {};
if (m_pWindowOwner)
return m_pWindowOwner->getWindowMainSurfaceBox();
if (m_pLayerOwner)
return m_pLayerOwner->geometry;
if (m_pPopupOwner)
return CBox{m_pPopupOwner->coordsGlobal(), m_pPopupOwner->size()};
if (m_pSubsurfaceOwner)
return CBox{m_pSubsurfaceOwner->coordsGlobal(), m_pSubsurfaceOwner->size()};
return {};
}
void CWLSurface::appendConstraint(wlr_pointer_constraint_v1* constraint) {
m_pConstraint = std::make_unique<CConstraint>(constraint, this);
}
void CWLSurface::onCommit() {
if (m_pConstraint)
m_pConstraint->onCommit();
}
CConstraint* CWLSurface::constraint() {
return m_pConstraint.get();
}

View file

@ -1,17 +1,25 @@
#pragma once #pragma once
#include "../defines.hpp" #include "../defines.hpp"
#include "Region.hpp" #include "../helpers/Region.hpp"
#include "Constraint.hpp"
class CWindow; class CWindow;
struct SLayerSurface;
class CSubsurface;
class CPopup;
class CWLSurface { class CWLSurface {
public: public:
CWLSurface() = default; CWLSurface() = default;
CWLSurface(wlr_surface* pSurface);
~CWLSurface(); ~CWLSurface();
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
void assign(wlr_surface* pSurface); void assign(wlr_surface* pSurface);
void assign(wlr_surface* pSurface, CWindow* pOwner);
void assign(wlr_surface* pSurface, SLayerSurface* pOwner);
void assign(wlr_surface* pSurface, CSubsurface* pOwner);
void assign(wlr_surface* pSurface, CPopup* pOwner);
void unassign(); void unassign();
CWLSurface(const CWLSurface&) = delete; CWLSurface(const CWLSurface&) = delete;
@ -25,13 +33,22 @@ class CWLSurface {
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
Vector2D getViewporterCorrectedSize() const; Vector2D getViewporterCorrectedSize() const;
CRegion logicalDamage() const; CRegion logicalDamage() const;
void onCommit();
// getters for owners.
CWindow* getWindow();
SLayerSurface* getLayer();
CPopup* getPopup();
CSubsurface* getSubsurface();
// desktop components misc utils
std::optional<CBox> getSurfaceBoxGlobal();
void appendConstraint(wlr_pointer_constraint_v1* constraint);
CConstraint* constraint();
// allow stretching. Useful for plugins. // allow stretching. Useful for plugins.
bool m_bFillIgnoreSmall = false; bool m_bFillIgnoreSmall = false;
// if present, means this is a base surface of a window. Cleaned on unassign()
CWindow* m_pOwner = nullptr;
// track surface data and avoid dupes // track surface data and avoid dupes
float m_fLastScale = 0; float m_fLastScale = 0;
int m_iLastScale = 0; int m_iLastScale = 0;
@ -59,14 +76,30 @@ class CWLSurface {
} }
static CWLSurface* surfaceFromWlr(wlr_surface* pSurface) { static CWLSurface* surfaceFromWlr(wlr_surface* pSurface) {
if (!pSurface)
return nullptr;
return (CWLSurface*)pSurface->data; return (CWLSurface*)pSurface->data;
} }
private: private:
bool m_bInert = true;
wlr_surface* m_pWLRSurface = nullptr; wlr_surface* m_pWLRSurface = nullptr;
CWindow* m_pWindowOwner = nullptr;
SLayerSurface* m_pLayerOwner = nullptr;
CPopup* m_pPopupOwner = nullptr;
CSubsurface* m_pSubsurfaceOwner = nullptr;
//
std::unique_ptr<CConstraint> m_pConstraint;
void destroy(); void destroy();
void init(); void init();
bool desktopComponent();
DYNLISTENER(destroy); DYNLISTENER(destroy);
DYNLISTENER(commit);
friend class CConstraint;
}; };

View file

@ -1,7 +1,8 @@
#include "Workspace.hpp" #include "Workspace.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
CWorkspace::CWorkspace(int monitorID, std::string name, bool special) { CWorkspace::CWorkspace(int id, int monitorID, std::string name, bool special) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
if (!PMONITOR) { if (!PMONITOR) {
@ -10,12 +11,13 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
} }
m_iMonitorID = monitorID; m_iMonitorID = monitorID;
m_iID = id;
m_szName = name; m_szName = name;
m_bIsSpecialWorkspace = special; m_bIsSpecialWorkspace = special;
m_vRenderOffset.m_pWorkspace = this; m_vRenderOffset.m_pWorkspace = this;
m_vRenderOffset.create(AVARTYPE_VECTOR, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), m_vRenderOffset.create(special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), nullptr,
nullptr, AVARDAMAGE_ENTIRE); AVARDAMAGE_ENTIRE);
m_fAlpha.m_pWorkspace = this; m_fAlpha.m_pWorkspace = this;
m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"), m_fAlpha.create(AVARTYPE_FLOAT, special ? g_pConfigManager->getAnimationPropertyConfig("specialWorkspace") : g_pConfigManager->getAnimationPropertyConfig("workspaces"),
nullptr, AVARDAMAGE_ENTIRE); nullptr, AVARDAMAGE_ENTIRE);
@ -29,6 +31,7 @@ CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
m_szName = RULEFORTHIS.defaultName.value(); m_szName = RULEFORTHIS.defaultName.value();
g_pEventManager->postEvent({"createworkspace", m_szName}); g_pEventManager->postEvent({"createworkspace", m_szName});
g_pEventManager->postEvent({"createworkspacev2", std::format("{},{}", m_iID, m_szName)});
EMIT_HOOK_EVENT("createWorkspace", this); EMIT_HOOK_EVENT("createWorkspace", this);
} }
@ -38,12 +41,13 @@ CWorkspace::~CWorkspace() {
Debug::log(LOG, "Destroying workspace ID {}", m_iID); Debug::log(LOG, "Destroying workspace ID {}", m_iID);
g_pEventManager->postEvent({"destroyworkspace", m_szName}); g_pEventManager->postEvent({"destroyworkspace", m_szName});
g_pEventManager->postEvent({"destroyworkspacev2", std::format("{},{}", m_iID, m_szName)});
EMIT_HOOK_EVENT("destroyWorkspace", this); EMIT_HOOK_EVENT("destroyWorkspace", this);
} }
void CWorkspace::startAnim(bool in, bool left, bool instant) { void CWorkspace::startAnim(bool in, bool left, bool instant) {
const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle; const auto ANIMSTYLE = m_fAlpha.m_pConfig->pValues->internalStyle;
static auto* const PWORKSPACEGAP = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_workspaces"); static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
if (ANIMSTYLE.starts_with("slidefade")) { if (ANIMSTYLE.starts_with("slidefade")) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
@ -95,7 +99,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
} else if (ANIMSTYLE == "slidevert") { } else if (ANIMSTYLE == "slidevert") {
// fallback is slide // fallback is slide
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
const auto YDISTANCE = PMONITOR->vecSize.y + **PWORKSPACEGAP; const auto YDISTANCE = PMONITOR->vecSize.y + *PWORKSPACEGAP;
m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
@ -108,7 +112,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
} else { } else {
// fallback is slide // fallback is slide
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
const auto XDISTANCE = PMONITOR->vecSize.x + **PWORKSPACEGAP; const auto XDISTANCE = PMONITOR->vecSize.x + *PWORKSPACEGAP;
m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide. m_fAlpha.setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "AnimatedVariable.hpp" #include "../helpers/AnimatedVariable.hpp"
#include <string> #include <string>
#include "../defines.hpp" #include "../defines.hpp"
@ -14,7 +14,7 @@ class CWindow;
class CWorkspace { class CWorkspace {
public: public:
CWorkspace(int monitorID, std::string name, bool special = false); CWorkspace(int id, int monitorID, std::string name, bool special = false);
~CWorkspace(); ~CWorkspace();
// Workspaces ID-based have IDs > 0 // Workspaces ID-based have IDs > 0
@ -35,8 +35,8 @@ class CWorkspace {
wl_array m_wlrCoordinateArr; wl_array m_wlrCoordinateArr;
// for animations // for animations
CAnimatedVariable m_vRenderOffset; CAnimatedVariable<Vector2D> m_vRenderOffset;
CAnimatedVariable m_fAlpha; CAnimatedVariable<float> m_fAlpha;
bool m_bForceRendering = false; bool m_bForceRendering = false;
// "scratchpad" // "scratchpad"

View file

@ -74,7 +74,7 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
Debug::log(LOG, "Attached a touch device with name {}", DEVICE->name); Debug::log(LOG, "Attached a touch device with name {}", DEVICE->name);
g_pInputManager->newTouchDevice(DEVICE); g_pInputManager->newTouchDevice(DEVICE);
break; break;
case WLR_INPUT_DEVICE_TABLET_TOOL: case WLR_INPUT_DEVICE_TABLET:
Debug::log(LOG, "Attached a tablet tool with name {}", DEVICE->name); Debug::log(LOG, "Attached a tablet tool with name {}", DEVICE->name);
g_pInputManager->newTabletTool(DEVICE); g_pInputManager->newTabletTool(DEVICE);
break; break;
@ -97,44 +97,14 @@ void Events::listener_newConstraint(wl_listener* listener, void* data) {
Debug::log(LOG, "New mouse constraint at {:x}", (uintptr_t)PCONSTRAINT); Debug::log(LOG, "New mouse constraint at {:x}", (uintptr_t)PCONSTRAINT);
g_pInputManager->m_lConstraints.emplace_back(); const auto SURFACE = CWLSurface::surfaceFromWlr(PCONSTRAINT->surface);
const auto CONSTRAINT = &g_pInputManager->m_lConstraints.back();
CONSTRAINT->pMouse = g_pCompositor->m_sSeat.mouse; if (!SURFACE) {
CONSTRAINT->constraint = PCONSTRAINT; Debug::log(ERR, "Refusing a constraint from an unassigned wl_surface {:x}", (uintptr_t)PCONSTRAINT->surface);
return;
CONSTRAINT->hyprListener_destroyConstraint.initCallback(&PCONSTRAINT->events.destroy, &Events::listener_destroyConstraint, CONSTRAINT, "Constraint");
CONSTRAINT->hyprListener_setConstraintRegion.initCallback(&PCONSTRAINT->events.set_region, &Events::listener_setConstraintRegion, CONSTRAINT, "Constraint");
if (g_pCompositor->m_pLastFocus == PCONSTRAINT->surface) {
g_pInputManager->constrainMouse(CONSTRAINT->pMouse, PCONSTRAINT);
if (!CONSTRAINT->hintSet)
CONSTRAINT->positionHint = Vector2D{-1, -1};
}
}
void Events::listener_destroyConstraint(void* owner, void* data) {
const auto PCONSTRAINT = (SConstraint*)owner;
if (PCONSTRAINT->pMouse->currentConstraint == PCONSTRAINT->constraint) {
PCONSTRAINT->pMouse->hyprListener_commitConstraint.removeCallback();
const auto PWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
if (PWINDOW && PCONSTRAINT->active && PCONSTRAINT->constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED)
g_pInputManager->warpMouseToConstraintMiddle(PCONSTRAINT);
PCONSTRAINT->pMouse->currentConstraint = nullptr;
} }
Debug::log(LOG, "Unconstrained mouse from {:x}", (uintptr_t)PCONSTRAINT->constraint); SURFACE->appendConstraint(PCONSTRAINT);
g_pInputManager->m_lConstraints.remove(*PCONSTRAINT);
}
void Events::listener_setConstraintRegion(void* owner, void* data) {
// no
} }
void Events::listener_newVirtPtr(wl_listener* listener, void* data) { void Events::listener_newVirtPtr(wl_listener* listener, void* data) {

View file

@ -22,25 +22,6 @@ namespace Events {
DYNLISTENFUNC(unmapLayerSurface); DYNLISTENFUNC(unmapLayerSurface);
DYNLISTENFUNC(commitLayerSurface); DYNLISTENFUNC(commitLayerSurface);
// Subsurfaces
DYNLISTENFUNC(newSubsurfaceNode);
DYNLISTENFUNC(destroySubsurfaceNode);
DYNLISTENFUNC(mapSubsurface);
DYNLISTENFUNC(unmapSubsurface);
DYNLISTENFUNC(destroySubsurface);
DYNLISTENFUNC(commitSubsurface);
// Popups
DYNLISTENFUNC(newPopup); // LayerSurface
DYNLISTENFUNC(newPopupXDG);
DYNLISTENFUNC(mapPopupXDG);
DYNLISTENFUNC(unmapPopupXDG);
DYNLISTENFUNC(destroyPopupXDG);
DYNLISTENFUNC(commitPopupXDG);
DYNLISTENFUNC(newPopupFromPopupXDG);
DYNLISTENFUNC(repositionPopupXDG);
// Surface XDG (window) // Surface XDG (window)
LISTENER(newXDGToplevel); LISTENER(newXDGToplevel);
LISTENER(activateXDG); LISTENER(activateXDG);
@ -84,10 +65,7 @@ namespace Events {
DYNLISTENFUNC(keyboardMod); DYNLISTENFUNC(keyboardMod);
DYNLISTENFUNC(keyboardDestroy); DYNLISTENFUNC(keyboardDestroy);
DYNLISTENFUNC(commitConstraint);
LISTENER(newConstraint); LISTENER(newConstraint);
DYNLISTENFUNC(setConstraintRegion);
DYNLISTENFUNC(destroyConstraint);
// Various // Various
LISTENER(requestMouse); LISTENER(requestMouse);

View file

@ -46,12 +46,12 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
layerSurface->hyprListener_destroyLayerSurface.initCallback(&WLRLAYERSURFACE->events.destroy, &Events::listener_destroyLayerSurface, layerSurface, "layerSurface"); layerSurface->hyprListener_destroyLayerSurface.initCallback(&WLRLAYERSURFACE->events.destroy, &Events::listener_destroyLayerSurface, layerSurface, "layerSurface");
layerSurface->hyprListener_mapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.map, &Events::listener_mapLayerSurface, layerSurface, "layerSurface"); layerSurface->hyprListener_mapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.map, &Events::listener_mapLayerSurface, layerSurface, "layerSurface");
layerSurface->hyprListener_unmapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.unmap, &Events::listener_unmapLayerSurface, layerSurface, "layerSurface"); layerSurface->hyprListener_unmapLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.unmap, &Events::listener_unmapLayerSurface, layerSurface, "layerSurface");
layerSurface->hyprListener_newPopup.initCallback(&WLRLAYERSURFACE->events.new_popup, &Events::listener_newPopup, layerSurface, "layerSurface");
layerSurface->layerSurface = WLRLAYERSURFACE; layerSurface->layerSurface = WLRLAYERSURFACE;
layerSurface->layer = WLRLAYERSURFACE->current.layer; layerSurface->layer = WLRLAYERSURFACE->current.layer;
WLRLAYERSURFACE->data = layerSurface; WLRLAYERSURFACE->data = layerSurface;
layerSurface->monitorID = PMONITOR->ID; layerSurface->monitorID = PMONITOR->ID;
layerSurface->popupHead = std::make_unique<CPopup>(layerSurface);
layerSurface->forceBlur = g_pConfigManager->shouldBlurLS(layerSurface->szNamespace); layerSurface->forceBlur = g_pConfigManager->shouldBlurLS(layerSurface->szNamespace);
@ -66,6 +66,8 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
layersurface->popupHead.reset();
if (!g_pCompositor->getMonitorFromID(layersurface->monitorID)) if (!g_pCompositor->getMonitorFromID(layersurface->monitorID))
Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)"); Debug::log(WARN, "Layersurface destroyed on an invalid monitor (removed?)");
@ -87,7 +89,6 @@ void Events::listener_destroyLayerSurface(void* owner, void* data) {
layersurface->hyprListener_destroyLayerSurface.removeCallback(); layersurface->hyprListener_destroyLayerSurface.removeCallback();
layersurface->hyprListener_mapLayerSurface.removeCallback(); layersurface->hyprListener_mapLayerSurface.removeCallback();
layersurface->hyprListener_unmapLayerSurface.removeCallback(); layersurface->hyprListener_unmapLayerSurface.removeCallback();
layersurface->hyprListener_newPopup.removeCallback();
// rearrange to fix the reserved areas // rearrange to fix the reserved areas
if (PMONITOR) { if (PMONITOR) {
@ -113,9 +114,6 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
layersurface->keyboardExclusive = layersurface->layerSurface->current.keyboard_interactive; layersurface->keyboardExclusive = layersurface->layerSurface->current.keyboard_interactive;
layersurface->surface = layersurface->layerSurface->surface; layersurface->surface = layersurface->layerSurface->surface;
// anim
layersurface->alpha.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
// fix if it changed its mon // fix if it changed its mon
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output); const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
@ -147,7 +145,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
const bool GRABSFOCUS = layersurface->layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && const bool GRABSFOCUS = layersurface->layerSurface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
// don't focus if constrained // don't focus if constrained
(!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint); (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained());
if (GRABSFOCUS) { if (GRABSFOCUS) {
g_pCompositor->focusSurface(layersurface->layerSurface->surface); g_pCompositor->focusSurface(layersurface->layerSurface->surface);
@ -156,6 +154,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y); g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y); wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
g_pInputManager->m_bEmptyFocusCursorSet = false;
} }
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y); layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
@ -166,8 +165,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); const auto WORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL; const bool FULLSCREEN = WORKSPACE->m_bHasFullscreenWindow && WORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
layersurface->alpha.setValue(0); layersurface->startAnimation(!(layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
layersurface->alpha = ((layersurface->layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS) ? 0.f : 1.f);
layersurface->readyToDelete = false; layersurface->readyToDelete = false;
layersurface->fadingOut = false; layersurface->fadingOut = false;
@ -198,23 +196,17 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
layersurface->mapped = false; layersurface->mapped = false;
layersurface->fadingOut = true; layersurface->startAnimation(false);
layersurface->alpha.setValueAndWarp(0.f);
return; return;
} }
// anim
layersurface->alpha.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
// make a snapshot and start fade // make a snapshot and start fade
g_pHyprOpenGL->makeLayerSnapshot(layersurface); g_pHyprOpenGL->makeLayerSnapshot(layersurface);
layersurface->alpha = 0.f;
layersurface->startAnimation(false);
layersurface->mapped = false; layersurface->mapped = false;
layersurface->fadingOut = true;
g_pCompositor->addToFadingOutSafe(layersurface); g_pCompositor->addToFadingOutSafe(layersurface);
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output); const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
@ -244,7 +236,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
&surfaceCoords, &pFoundLayerSurface); &surfaceCoords, &pFoundLayerSurface);
if (!foundSurface) { if (!foundSurface && g_pCompositor->m_pLastWindow) {
// if there isn't any, focus the last window // if there isn't any, focus the last window
const auto PLASTWINDOW = g_pCompositor->m_pLastWindow; const auto PLASTWINDOW = g_pCompositor->m_pLastWindow;
g_pCompositor->focusWindow(nullptr); g_pCompositor->focusWindow(nullptr);
@ -335,8 +327,20 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
} }
} }
if (layersurface->layerSurface->current.keyboard_interactive && if (layersurface->realPosition.goal() != layersurface->geometry.pos()) {
(!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) // don't focus if constrained if (layersurface->realPosition.isBeingAnimated())
layersurface->realPosition = layersurface->geometry.pos();
else
layersurface->realPosition.setValueAndWarp(layersurface->geometry.pos());
}
if (layersurface->realSize.goal() != layersurface->geometry.size()) {
if (layersurface->realSize.isBeingAnimated())
layersurface->realSize = layersurface->geometry.size();
else
layersurface->realSize.setValueAndWarp(layersurface->geometry.size());
}
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) // don't focus if constrained
&& !layersurface->keyboardExclusive && layersurface->mapped) { && !layersurface->keyboardExclusive && layersurface->mapped) {
g_pCompositor->focusSurface(layersurface->layerSurface->surface); g_pCompositor->focusSurface(layersurface->layerSurface->surface);
@ -344,7 +348,8 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y); g_pInputManager->getMouseCoordsInternal() - Vector2D(layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, layersurface->layerSurface->surface, LOCAL.x, LOCAL.y);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y); wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
} else if (!layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) && g_pInputManager->m_bEmptyFocusCursorSet = false;
} else if (!layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained()) &&
layersurface->keyboardExclusive) { layersurface->keyboardExclusive) {
g_pInputManager->refocus(); g_pInputManager->refocus();
} }

View file

@ -4,6 +4,7 @@
#include "../helpers/WLClasses.hpp" #include "../helpers/WLClasses.hpp"
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../managers/CursorManager.hpp"
// ------------------------------ // // ------------------------------ //
// __ __ _____ _____ _____ // // __ __ _____ _____ _____ //
@ -63,15 +64,26 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) {
} }
ATOM.second = reply->atom; ATOM.second = reply->atom;
free(reply);
} }
wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sSeat.seat); wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sSeat.seat);
const auto XCURSOR = wlr_xcursor_manager_get_xcursor(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", 1); g_pCursorManager->setXWaylandCursor(g_pXWaylandManager->m_sWLRXWayland);
if (XCURSOR) {
wlr_xwayland_set_cursor(g_pXWaylandManager->m_sWLRXWayland, XCURSOR->images[0]->buffer, XCURSOR->images[0]->width * 4, XCURSOR->images[0]->width, const auto ROOT = xcb_setup_roots_iterator(xcb_get_setup(XCBCONNECTION)).data->root;
XCURSOR->images[0]->height, XCURSOR->images[0]->hotspot_x, XCURSOR->images[0]->hotspot_y); auto cookie = xcb_get_property(XCBCONNECTION, 0, ROOT, HYPRATOMS["_NET_SUPPORTING_WM_CHECK"], XCB_ATOM_ANY, 0, 2048);
} auto reply = xcb_get_property_reply(XCBCONNECTION, cookie, nullptr);
const auto XWMWINDOW = *(xcb_window_t*)xcb_get_property_value(reply);
const char* name = "Hyprland";
xcb_change_property(wlr_xwayland_get_xwm_connection(g_pXWaylandManager->m_sWLRXWayland), XCB_PROP_MODE_REPLACE, XWMWINDOW, HYPRATOMS["_NET_WM_NAME"], HYPRATOMS["UTF8_STRING"],
8, // format
strlen(name), name);
free(reply);
xcb_disconnect(XCBCONNECTION); xcb_disconnect(XCBCONNECTION);
#endif #endif
@ -169,6 +181,7 @@ void Events::listener_sessionActive(wl_listener* listener, void* data) {
for (auto& m : g_pCompositor->m_vMonitors) { for (auto& m : g_pCompositor->m_vMonitors) {
g_pCompositor->scheduleFrameForMonitor(m.get()); g_pCompositor->scheduleFrameForMonitor(m.get());
g_pHyprRenderer->applyMonitorRule(m.get(), &m->activeMonitorRule, true);
} }
g_pConfigManager->m_bWantsMonitorReload = true; g_pConfigManager->m_bWantsMonitorReload = true;

View file

@ -4,6 +4,7 @@
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "Events.hpp" #include "Events.hpp"
#include "../debug/HyprCtl.hpp" #include "../debug/HyprCtl.hpp"
#include "../config/ConfigValue.hpp"
// --------------------------------------------------------- // // --------------------------------------------------------- //
// __ __ ____ _ _ _____ _______ ____ _____ _____ // // __ __ ____ _ _ _____ _______ ____ _____ _____ //
@ -147,12 +148,12 @@ void Events::listener_monitorFrame(void* owner, void* data) {
PMONITOR->tearingState.frameScheduledWhileBusy = false; PMONITOR->tearingState.frameScheduledWhileBusy = false;
} }
static auto* const PENABLERAT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:render_ahead_of_time"); static auto PENABLERAT = CConfigValue<Hyprlang::INT>("misc:render_ahead_of_time");
static auto* const PRATSAFE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:render_ahead_safezone"); static auto PRATSAFE = CConfigValue<Hyprlang::INT>("misc:render_ahead_safezone");
PMONITOR->lastPresentationTimer.reset(); PMONITOR->lastPresentationTimer.reset();
if (**PENABLERAT && !PMONITOR->tearingState.nextRenderTorn) { if (*PENABLERAT && !PMONITOR->tearingState.nextRenderTorn) {
if (!PMONITOR->RATScheduled) { if (!PMONITOR->RATScheduled) {
// render // render
g_pHyprRenderer->renderMonitor(PMONITOR); g_pHyprRenderer->renderMonitor(PMONITOR);
@ -162,14 +163,14 @@ void Events::listener_monitorFrame(void* owner, void* data) {
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(PMONITOR); const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(PMONITOR);
if (max + **PRATSAFE > 1000.0 / PMONITOR->refreshRate) if (max + *PRATSAFE > 1000.0 / PMONITOR->refreshRate)
return; return;
const auto MSLEFT = 1000.0 / PMONITOR->refreshRate - PMONITOR->lastPresentationTimer.getMillis(); const auto MSLEFT = 1000.0 / PMONITOR->refreshRate - PMONITOR->lastPresentationTimer.getMillis();
PMONITOR->RATScheduled = true; PMONITOR->RATScheduled = true;
const auto ESTRENDERTIME = std::ceil(avg + **PRATSAFE); const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME); const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1) if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)

View file

@ -1,269 +0,0 @@
#include "Events.hpp"
#include "../Compositor.hpp"
#include "../helpers/WLClasses.hpp"
#include "../managers/input/InputManager.hpp"
#include "../render/Renderer.hpp"
// --------------------------------------------- //
// _____ ____ _____ _ _ _____ _____ //
// | __ \ / __ \| __ \| | | | __ \ / ____| //
// | |__) | | | | |__) | | | | |__) | (___ //
// | ___/| | | | ___/| | | | ___/ \___ \ //
// | | | |__| | | | |__| | | ____) | //
// |_| \____/|_| \____/|_| |_____/ //
// //
// --------------------------------------------- //
void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
SXDGPopup* const PPOPUP = (SXDGPopup*)pPopup;
auto curPopup = PPOPUP;
int px = 0;
int py = 0;
while (true) {
px += curPopup->popup->current.geometry.x;
py += curPopup->popup->current.geometry.y;
if (curPopup == PPOPUP && PPOPUP->parentWindow) {
px -= curPopup->popup->base->current.geometry.x;
py -= curPopup->popup->base->current.geometry.y;
}
if (curPopup->popup && !curPopup->parentPopup && !curPopup->parentWindow) {
const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->popup->base->surface->input_region);
px -= EXTENTSSURFACE->x1;
py -= EXTENTSSURFACE->y1;
}
if (curPopup->parentPopup) {
curPopup = curPopup->parentPopup;
} else {
break;
}
}
px += PPOPUP->lx;
py += PPOPUP->ly;
*x += px;
*y += py;
}
void createNewPopup(wlr_xdg_popup* popup, SXDGPopup* pHyprPopup) {
pHyprPopup->popup = popup;
pHyprPopup->hyprListener_destroyPopupXDG.initCallback(&popup->events.destroy, &Events::listener_destroyPopupXDG, pHyprPopup, "HyprPopup");
pHyprPopup->hyprListener_mapPopupXDG.initCallback(&popup->base->surface->events.map, &Events::listener_mapPopupXDG, pHyprPopup, "HyprPopup");
pHyprPopup->hyprListener_unmapPopupXDG.initCallback(&popup->base->surface->events.unmap, &Events::listener_unmapPopupXDG, pHyprPopup, "HyprPopup");
pHyprPopup->hyprListener_newPopupFromPopupXDG.initCallback(&popup->base->events.new_popup, &Events::listener_newPopupFromPopupXDG, pHyprPopup, "HyprPopup");
pHyprPopup->hyprListener_commitPopupXDG.initCallback(&popup->base->surface->events.commit, &Events::listener_commitPopupXDG, pHyprPopup, "HyprPopup");
pHyprPopup->hyprListener_repositionPopupXDG.initCallback(&popup->events.reposition, &Events::listener_repositionPopupXDG, pHyprPopup, "HyprPopup");
const auto PMONITOR = g_pCompositor->m_pLastMonitor;
CBox box = {PMONITOR->vecPosition.x - pHyprPopup->lx, PMONITOR->vecPosition.y - pHyprPopup->ly, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
wlr_xdg_popup_unconstrain_from_box(popup, box.pWlr());
pHyprPopup->monitor = PMONITOR;
Debug::log(LOG, "Popup: Unconstrained from lx ly: {:j5}, pHyprPopup lx ly: {:.5f} {:.5f}", PMONITOR->vecPosition, (float)pHyprPopup->lx, (float)pHyprPopup->ly);
}
void Events::listener_newPopup(void* owner, void* data) {
SLayerSurface* layersurface = (SLayerSurface*)owner;
ASSERT(layersurface);
Debug::log(LOG, "New layer popup created from surface {:x}", (uintptr_t)layersurface);
const auto WLRPOPUP = (wlr_xdg_popup*)data;
const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
PNEWPOPUP->popup = WLRPOPUP;
PNEWPOPUP->lx = layersurface->position.x;
PNEWPOPUP->ly = layersurface->position.y;
PNEWPOPUP->monitor = PMONITOR;
PNEWPOPUP->parentLS = layersurface;
createNewPopup(WLRPOPUP, PNEWPOPUP);
}
void Events::listener_newPopupXDG(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner;
ASSERT(PWINDOW);
if (!PWINDOW->m_bIsMapped)
return;
Debug::log(LOG, "New layer popup created from XDG window {}", PWINDOW);
const auto WLRPOPUP = (wlr_xdg_popup*)data;
const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
PNEWPOPUP->popup = WLRPOPUP;
PNEWPOPUP->lx = PWINDOW->m_vRealPosition.goalv().x;
PNEWPOPUP->ly = PWINDOW->m_vRealPosition.goalv().y;
PNEWPOPUP->parentWindow = PWINDOW;
PNEWPOPUP->monitor = PMONITOR;
createNewPopup(WLRPOPUP, PNEWPOPUP);
}
void Events::listener_newPopupFromPopupXDG(void* owner, void* data) {
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
ASSERT(PPOPUP);
if (PPOPUP->parentWindow)
Debug::log(LOG, "New popup created from XDG Window popup {:x} -> {}", (uintptr_t)PPOPUP, PPOPUP->parentWindow);
else
Debug::log(LOG, "New popup created from Non-Window popup {:x}", (uintptr_t)PPOPUP);
const auto WLRPOPUP = (wlr_xdg_popup*)data;
const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
PNEWPOPUP->popup = WLRPOPUP;
PNEWPOPUP->parentPopup = PPOPUP;
PNEWPOPUP->lx = PPOPUP->lx;
PNEWPOPUP->ly = PPOPUP->ly;
PNEWPOPUP->parentWindow = PPOPUP->parentWindow;
PNEWPOPUP->monitor = PPOPUP->monitor;
createNewPopup(WLRPOPUP, PNEWPOPUP);
}
void Events::listener_mapPopupXDG(void* owner, void* data) {
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
ASSERT(PPOPUP);
Debug::log(LOG, "New XDG Popup mapped at {} {}", (int)PPOPUP->lx, (int)PPOPUP->ly);
if (PPOPUP->parentWindow)
PPOPUP->parentWindow->m_lPopupSurfaces.emplace_back(PPOPUP->popup->base->surface);
else if (PPOPUP->parentLS)
PPOPUP->parentLS->popupSurfaces.emplace_back(PPOPUP->popup->base->surface);
PPOPUP->pSurfaceTree = SubsurfaceTree::createTreeRoot(PPOPUP->popup->base->surface, addPopupGlobalCoords, PPOPUP, PPOPUP->parentWindow);
int lx = 0, ly = 0;
addPopupGlobalCoords(PPOPUP, &lx, &ly);
CBox extents;
wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
extents.applyFromWlr();
g_pHyprRenderer->damageBox(lx - extents.x, ly - extents.y, extents.width + 2, extents.height + 2);
if (PPOPUP->monitor) {
g_pCompositor->setPreferredScaleForSurface(PPOPUP->popup->base->surface, PPOPUP->monitor->scale);
g_pCompositor->setPreferredTransformForSurface(PPOPUP->popup->base->surface, PPOPUP->monitor->transform);
}
Debug::log(LOG, "XDG Popup got assigned a surfaceTreeNode {:x}", (uintptr_t)PPOPUP->pSurfaceTree);
}
void Events::listener_repositionPopupXDG(void* owner, void* data) {
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
Debug::log(LOG, "XDG Popup {:x} asks for a reposition", (uintptr_t)PPOPUP);
int lx = 0, ly = 0;
addPopupGlobalCoords(PPOPUP, &lx, &ly);
CBox extents;
wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
extents.applyFromWlr();
PPOPUP->lastPos = {lx - extents.x, ly - extents.y};
PPOPUP->repositionRequested = true;
const auto PMONITOR = g_pCompositor->m_pLastMonitor;
CBox box = {PMONITOR->vecPosition.x - lx + PPOPUP->popup->current.geometry.x, PMONITOR->vecPosition.y - ly + PPOPUP->popup->current.geometry.y, PMONITOR->vecSize.x,
PMONITOR->vecSize.y};
wlr_xdg_popup_unconstrain_from_box(PPOPUP->popup, box.pWlr());
}
void Events::listener_unmapPopupXDG(void* owner, void* data) {
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
Debug::log(LOG, "XDG Popup unmapped");
ASSERT(PPOPUP);
if (PPOPUP->popup->base->surface == g_pCompositor->m_pLastFocus)
g_pInputManager->releaseAllMouseButtons();
SubsurfaceTree::destroySurfaceTree(PPOPUP->pSurfaceTree);
int lx = 0, ly = 0;
addPopupGlobalCoords(PPOPUP, &lx, &ly);
CBox extents;
wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
extents.applyFromWlr();
g_pHyprRenderer->damageBox(lx - extents.x, ly - extents.y, extents.width + 2, extents.height + 2);
if (PPOPUP->parentWindow)
std::erase(PPOPUP->parentWindow->m_lPopupSurfaces, PPOPUP->popup->base->surface);
else if (PPOPUP->parentLS)
std::erase(PPOPUP->parentLS->popupSurfaces, PPOPUP->popup->base->surface);
PPOPUP->pSurfaceTree = nullptr;
g_pInputManager->simulateMouseMovement(); // to focus and return back to an appropriate surface
}
void Events::listener_commitPopupXDG(void* owner, void* data) {
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
if (PPOPUP->popup->base->initial_commit) {
wlr_xdg_surface_schedule_configure(PPOPUP->popup->base);
return;
}
if (g_pCompositor->windowValidMapped(PPOPUP->parentWindow)) {
PPOPUP->lx = PPOPUP->parentWindow->m_vRealPosition.vec().x;
PPOPUP->ly = PPOPUP->parentWindow->m_vRealPosition.vec().y;
}
int lx = 0, ly = 0;
addPopupGlobalCoords(PPOPUP, &lx, &ly);
CBox extents;
wlr_surface_get_extends(PPOPUP->popup->base->surface, extents.pWlr());
extents.applyFromWlr();
if (PPOPUP->repositionRequested)
g_pHyprRenderer->damageBox(PPOPUP->lastPos.x, PPOPUP->lastPos.y, extents.width + 2, extents.height + 2);
PPOPUP->repositionRequested = false;
g_pHyprRenderer->damageSurface(PPOPUP->popup->base->surface, lx, ly);
}
void Events::listener_destroyPopupXDG(void* owner, void* data) {
SXDGPopup* PPOPUP = (SXDGPopup*)owner;
ASSERT(PPOPUP);
Debug::log(LOG, "Destroyed popup XDG {:x}", (uintptr_t)PPOPUP);
if (PPOPUP->pSurfaceTree) {
SubsurfaceTree::destroySurfaceTree(PPOPUP->pSurfaceTree);
PPOPUP->pSurfaceTree = nullptr;
}
std::erase_if(g_pCompositor->m_vXDGPopups, [&](std::unique_ptr<SXDGPopup>& el) { return el.get() == PPOPUP; });
}

View file

@ -4,6 +4,7 @@
#include "../helpers/WLClasses.hpp" #include "../helpers/WLClasses.hpp"
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "../config/ConfigValue.hpp"
// ------------------------------------------------------------ // // ------------------------------------------------------------ //
// __ _______ _ _ _____ ______ _______ // // __ _______ _ _ _____ ______ _______ //
@ -17,8 +18,8 @@
void addViewCoords(void* pWindow, int* x, int* y) { void addViewCoords(void* pWindow, int* x, int* y) {
const auto PWINDOW = (CWindow*)pWindow; const auto PWINDOW = (CWindow*)pWindow;
*x += PWINDOW->m_vRealPosition.goalv().x; *x += PWINDOW->m_vRealPosition.goal().x;
*y += PWINDOW->m_vRealPosition.goalv().y; *y += PWINDOW->m_vRealPosition.goal().y;
if (!PWINDOW->m_bIsX11 && PWINDOW->m_bIsMapped) { if (!PWINDOW->m_bIsX11 && PWINDOW->m_bIsMapped) {
wlr_box geom; wlr_box geom;
@ -32,7 +33,7 @@ void addViewCoords(void* pWindow, int* x, int* y) {
void setAnimToMove(void* data) { void setAnimToMove(void* data) {
auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove"); auto* const PANIMCFG = g_pConfigManager->getAnimationPropertyConfig("windowsMove");
CAnimatedVariable* animvar = (CAnimatedVariable*)data; CBaseAnimatedVariable* animvar = (CBaseAnimatedVariable*)data;
animvar->setConfig(PANIMCFG); animvar->setConfig(PANIMCFG);
} }
@ -40,13 +41,13 @@ void setAnimToMove(void* data) {
void Events::listener_mapWindow(void* owner, void* data) { void Events::listener_mapWindow(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner; CWindow* PWINDOW = (CWindow*)owner;
static auto* const PINACTIVEALPHA = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity"); static auto PINACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:inactive_opacity");
static auto* const PACTIVEALPHA = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:active_opacity"); static auto PACTIVEALPHA = CConfigValue<Hyprlang::FLOAT>("decoration:active_opacity");
static auto* const PDIMSTRENGTH = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:dim_strength"); static auto PDIMSTRENGTH = CConfigValue<Hyprlang::FLOAT>("decoration:dim_strength");
static auto* const PSWALLOW = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:enable_swallow"); static auto PSWALLOW = CConfigValue<Hyprlang::INT>("misc:enable_swallow");
static auto* const PSWALLOWREGEX = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("misc:swallow_regex"); static auto PSWALLOWREGEX = CConfigValue<std::string>("misc:swallow_regex");
static auto* const PSWALLOWEXREGEX = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("misc:swallow_exception_regex"); static auto PSWALLOWEXREGEX = CConfigValue<std::string>("misc:swallow_exception_regex");
static auto* const PNEWTAKESOVERFS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:new_window_takes_over_fullscreen"); static auto PNEWTAKESOVERFS = CConfigValue<Hyprlang::INT>("misc:new_window_takes_over_fullscreen");
auto PMONITOR = g_pCompositor->m_pLastMonitor; auto PMONITOR = g_pCompositor->m_pLastMonitor;
auto PWORKSPACE = PMONITOR->specialWorkspaceID ? g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace); auto PWORKSPACE = PMONITOR->specialWorkspaceID ? g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
@ -258,8 +259,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->applyDynamicRule(r); PWINDOW->applyDynamicRule(r);
} }
PWINDOW->updateSpecialRenderData();
// disallow tiled pinned // disallow tiled pinned
if (PWINDOW->m_bPinned && !PWINDOW->m_bIsFloating) if (PWINDOW->m_bPinned && !PWINDOW->m_bIsFloating)
PWINDOW->m_bPinned = false; PWINDOW->m_bPinned = false;
@ -290,7 +289,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (!workspaceSilent) { if (!workspaceSilent) {
if (pWorkspace->m_bIsSpecialWorkspace) if (pWorkspace->m_bIsSpecialWorkspace)
g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID)->setSpecialWorkspace(pWorkspace); g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID)->setSpecialWorkspace(pWorkspace);
else else if (PMONITOR->activeWorkspace != REQUESTEDWORKSPACEID)
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspaceName); g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspaceName);
PMONITOR = g_pCompositor->m_pLastMonitor; PMONITOR = g_pCompositor->m_pLastMonitor;
@ -299,6 +298,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
workspaceSilent = false; workspaceSilent = false;
} }
PWINDOW->updateSpecialRenderData();
if (PWINDOW->m_bIsFloating) { if (PWINDOW->m_bIsFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW); g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
PWINDOW->m_bCreatedOverFullscreen = true; PWINDOW->m_bCreatedOverFullscreen = true;
@ -323,38 +324,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
Debug::log(LOG, "Rule size, applying to {}", PWINDOW); Debug::log(LOG, "Rule size, applying to {}", PWINDOW);
PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY); PWINDOW->m_vRealSize = Vector2D(SIZEX, SIZEY);
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
PWINDOW->setHidden(false); PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); } } catch (...) { Debug::log(LOG, "Rule size failed, rule: {} -> {}", r.szRule, r.szValue); }
} else if (r.szRule.starts_with("minsize")) {
try {
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' '));
const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1);
const auto SIZE =
Vector2D(std::max((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goalv().x), std::max((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goalv().y));
PWINDOW->m_vRealSize = SIZE;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule minsize failed, rule: {} -> {}", r.szRule, r.szValue); }
} else if (r.szRule.starts_with("maxsize")) {
try {
const auto VALUE = r.szRule.substr(r.szRule.find(' ') + 1);
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(' '));
const auto SIZEYSTR = VALUE.substr(VALUE.find(' ') + 1);
const auto SIZE =
Vector2D(std::min((double)std::stoll(SIZEXSTR), PWINDOW->m_vRealSize.goalv().x), std::min((double)std::stoll(SIZEYSTR), PWINDOW->m_vRealSize.goalv().y));
PWINDOW->m_vRealSize = SIZE;
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
PWINDOW->setHidden(false);
} catch (...) { Debug::log(LOG, "Rule maxsize failed, rule: {} -> {}", r.szRule, r.szValue); }
} else if (r.szRule.starts_with("move")) { } else if (r.szRule.starts_with("move")) {
try { try {
auto value = r.szRule.substr(r.szRule.find(' ') + 1); auto value = r.szRule.substr(r.szRule.find(' ') + 1);
@ -390,7 +363,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x; posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x;
} else { } else {
posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x + posX = g_pInputManager->getMouseCoordsInternal().x - PMONITOR->vecPosition.x +
(!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stof(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goalv().x); (!POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stof(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goal().x);
} }
} }
@ -409,7 +382,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y; posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y;
} else { } else {
posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y + posY = g_pInputManager->getMouseCoordsInternal().y - PMONITOR->vecPosition.y +
(!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stof(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goalv().y); (!POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stof(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01 * PWINDOW->m_vRealSize.goal().y);
} }
} }
@ -417,10 +390,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
int borderSize = PWINDOW->getRealBorderSize(); int borderSize = PWINDOW->getRealBorderSize();
posX = std::clamp(posX, (int)(PMONITOR->vecReservedTopLeft.x + borderSize), posX = std::clamp(posX, (int)(PMONITOR->vecReservedTopLeft.x + borderSize),
(int)(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PWINDOW->m_vRealSize.goalv().x - borderSize)); (int)(PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PWINDOW->m_vRealSize.goal().x - borderSize));
posY = std::clamp(posY, (int)(PMONITOR->vecReservedTopLeft.y + borderSize), posY = std::clamp(posY, (int)(PMONITOR->vecReservedTopLeft.y + borderSize),
(int)(PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PWINDOW->m_vRealSize.goalv().y - borderSize)); (int)(PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PWINDOW->m_vRealSize.goal().y - borderSize));
} }
Debug::log(LOG, "Rule move, applying to {}", PWINDOW); Debug::log(LOG, "Rule move, applying to {}", PWINDOW);
@ -435,20 +408,20 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (ARGS[1] == "1") if (ARGS[1] == "1")
RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f; RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f;
PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goalv() / 2.f + RESERVEDOFFSET; PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goal() / 2.f + RESERVEDOFFSET;
} }
} }
// set the pseudo size to the GOAL of our current size // set the pseudo size to the GOAL of our current size
// because the windows are animated on RealSize // because the windows are animated on RealSize
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv(); PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal();
g_pCompositor->changeWindowZOrder(PWINDOW, true); g_pCompositor->changeWindowZOrder(PWINDOW, true);
} else { } else {
g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW); g_pLayoutManager->getCurrentLayout()->onWindowCreated(PWINDOW);
// Set the pseudo size here too so that it doesnt end up being 0x0 // Set the pseudo size here too so that it doesnt end up being 0x0
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10, 10); PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goal() - Vector2D(10, 10);
} }
const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow; const auto PFOCUSEDWINDOWPREV = g_pCompositor->m_pLastWindow;
@ -465,9 +438,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (PLSFROMFOCUS && PLSFROMFOCUS->layerSurface->current.keyboard_interactive) if (PLSFROMFOCUS && PLSFROMFOCUS->layerSurface->current.keyboard_interactive)
PWINDOW->m_bNoInitialFocus = true; PWINDOW->m_bNoInitialFocus = true;
if (PWORKSPACE->m_bHasFullscreenWindow && !requestsFullscreen && !PWINDOW->m_bIsFloating) { if (PWORKSPACE->m_bHasFullscreenWindow && !requestsFullscreen && !PWINDOW->m_bIsFloating) {
if (**PNEWTAKESOVERFS == 0) if (*PNEWTAKESOVERFS == 0)
PWINDOW->m_bNoInitialFocus = true; PWINDOW->m_bNoInitialFocus = true;
else if (**PNEWTAKESOVERFS == 2) else if (*PNEWTAKESOVERFS == 2)
g_pCompositor->setWindowFullscreen(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), false, FULLSCREEN_INVALID); g_pCompositor->setWindowFullscreen(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), false, FULLSCREEN_INVALID);
else if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) else if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED)
requestsMaximize = true; requestsMaximize = true;
@ -476,21 +449,19 @@ void Events::listener_mapWindow(void* owner, void* data) {
} }
if (!PWINDOW->m_sAdditionalConfigData.noFocus && !PWINDOW->m_bNoInitialFocus && if (!PWINDOW->m_sAdditionalConfigData.noFocus && !PWINDOW->m_bNoInitialFocus &&
(PWINDOW->m_iX11Type != 2 || (PWINDOW->m_bIsX11 && wlr_xwayland_or_surface_wants_focus(PWINDOW->m_uSurface.xwayland))) && !workspaceSilent && (PWINDOW->m_iX11Type != 2 ||
(!PFORCEFOCUS || PFORCEFOCUS == PWINDOW)) { (PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xwayland->window_type_len > 0 && wlr_xwayland_or_surface_wants_focus(PWINDOW->m_uSurface.xwayland))) &&
!workspaceSilent && (!PFORCEFOCUS || PFORCEFOCUS == PWINDOW) && !g_pInputManager->isConstrained()) {
g_pCompositor->focusWindow(PWINDOW); g_pCompositor->focusWindow(PWINDOW);
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(**PACTIVEALPHA); PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
PWINDOW->m_fDimPercent.setValueAndWarp(PWINDOW->m_sAdditionalConfigData.forceNoDim ? 0.f : **PDIMSTRENGTH); PWINDOW->m_fDimPercent.setValueAndWarp(PWINDOW->m_sAdditionalConfigData.forceNoDim ? 0.f : *PDIMSTRENGTH);
} else { } else {
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(**PINACTIVEALPHA); PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
PWINDOW->m_fDimPercent.setValueAndWarp(0); PWINDOW->m_fDimPercent.setValueAndWarp(0);
} }
Debug::log(LOG, "Window got assigned a surfaceTreeNode {:x}", (uintptr_t)PWINDOW->m_pSurfaceTree);
if (!PWINDOW->m_bIsX11) { if (!PWINDOW->m_bIsX11) {
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late"); PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XDG Window Late");
PWINDOW->hyprListener_newPopupXDG.initCallback(&PWINDOW->m_uSurface.xdg->events.new_popup, &Events::listener_newPopupXDG, PWINDOW, "XDG Window Late");
PWINDOW->hyprListener_requestMaximize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_maximize, &Events::listener_requestMaximize, PWINDOW, PWINDOW->hyprListener_requestMaximize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_maximize, &Events::listener_requestMaximize, PWINDOW,
"XDG Window Late"); "XDG Window Late");
PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_minimize, &Events::listener_requestMinimize, PWINDOW, PWINDOW->hyprListener_requestMinimize.initCallback(&PWINDOW->m_uSurface.xdg->toplevel->events.request_minimize, &Events::listener_requestMinimize, PWINDOW,
@ -538,8 +509,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
// recheck idle inhibitors // recheck idle inhibitors
g_pInputManager->recheckIdleInhibitorStatus(); g_pInputManager->recheckIdleInhibitorStatus();
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(PWINDOW->m_pWLSurface.wlr(), addViewCoords, PWINDOW, PWINDOW);
PWINDOW->updateToplevel(); PWINDOW->updateToplevel();
if (workspaceSilent) { if (workspaceSilent) {
@ -551,7 +520,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
} }
// verify swallowing // verify swallowing
if (**PSWALLOW && std::string{*PSWALLOWREGEX} != STRVAL_EMPTY) { if (*PSWALLOW && std::string{*PSWALLOWREGEX} != STRVAL_EMPTY) {
// don't swallow ourselves // don't swallow ourselves
std::regex rgx(*PSWALLOWREGEX); std::regex rgx(*PSWALLOWREGEX);
if (!std::regex_match(g_pXWaylandManager->getAppIDClass(PWINDOW), rgx)) { if (!std::regex_match(g_pXWaylandManager->getAppIDClass(PWINDOW), rgx)) {
@ -622,7 +591,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_bFirstMap = false; PWINDOW->m_bFirstMap = false;
Debug::log(LOG, "Map request dispatched, monitor {}, window pos: {:5j}, window size: {:5j}", PMONITOR->szName, PWINDOW->m_vRealPosition.goalv(), PWINDOW->m_vRealSize.goalv()); Debug::log(LOG, "Map request dispatched, monitor {}, window pos: {:5j}, window size: {:5j}", PMONITOR->szName, PWINDOW->m_vRealPosition.goal(), PWINDOW->m_vRealSize.goal());
auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName; auto workspaceID = requestedWorkspace != "" ? requestedWorkspace : PWORKSPACE->m_szName;
g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", PWINDOW, workspaceID, g_pXWaylandManager->getAppIDClass(PWINDOW), PWINDOW->m_szTitle)}); g_pEventManager->postEvent(SHyprIPCEvent{"openwindow", std::format("{:x},{},{},{}", PWINDOW, workspaceID, g_pXWaylandManager->getAppIDClass(PWINDOW), PWINDOW->m_szTitle)});
@ -650,13 +619,16 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale); g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform); g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform);
if (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->constraintActive) if (!g_pCompositor->m_sSeat.mouse || !g_pInputManager->isConstrained())
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
// fix some xwayland apps that don't behave nicely // fix some xwayland apps that don't behave nicely
PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize; PWINDOW->m_vReportedSize = PWINDOW->m_vPendingReportedSize;
g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID); g_pCompositor->updateWorkspaceWindows(PWINDOW->m_iWorkspaceID);
if (PMONITOR && PWINDOW->m_iX11Type == 2)
PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale;
} }
void Events::listener_unmapWindow(void* owner, void* data) { void Events::listener_unmapWindow(void* owner, void* data) {
@ -672,8 +644,8 @@ void Events::listener_unmapWindow(void* owner, void* data) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (PMONITOR) { if (PMONITOR) {
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec() - PMONITOR->vecPosition; PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.value() - PMONITOR->vecPosition;
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec(); PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.value();
PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents(); PWINDOW->m_eOriginalClosedExtents = PWINDOW->getFullWindowExtents();
} }
@ -685,7 +657,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
if (!PWINDOW->m_bIsX11) { if (!PWINDOW->m_bIsX11) {
Debug::log(LOG, "Unregistered late callbacks XDG"); Debug::log(LOG, "Unregistered late callbacks XDG");
PWINDOW->hyprListener_setTitleWindow.removeCallback(); PWINDOW->hyprListener_setTitleWindow.removeCallback();
PWINDOW->hyprListener_newPopupXDG.removeCallback();
PWINDOW->hyprListener_requestMaximize.removeCallback(); PWINDOW->hyprListener_requestMaximize.removeCallback();
PWINDOW->hyprListener_requestMinimize.removeCallback(); PWINDOW->hyprListener_requestMinimize.removeCallback();
PWINDOW->hyprListener_requestMove.removeCallback(); PWINDOW->hyprListener_requestMove.removeCallback();
@ -745,6 +716,9 @@ void Events::listener_unmapWindow(void* owner, void* data) {
if (PWINDOWCANDIDATE != g_pCompositor->m_pLastWindow && PWINDOWCANDIDATE) if (PWINDOWCANDIDATE != g_pCompositor->m_pLastWindow && PWINDOWCANDIDATE)
g_pCompositor->focusWindow(PWINDOWCANDIDATE); g_pCompositor->focusWindow(PWINDOWCANDIDATE);
if (!PWINDOWCANDIDATE && g_pCompositor->getWindowsOnWorkspace(PWINDOW->m_iWorkspaceID) == 0)
g_pInputManager->refocus();
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
// CWindow::onUnmap will remove this window's active status, but we can't really do it above. // CWindow::onUnmap will remove this window's active status, but we can't really do it above.
@ -757,11 +731,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
Debug::log(LOG, "Unmapped was not focused, ignoring a refocus."); Debug::log(LOG, "Unmapped was not focused, ignoring a refocus.");
} }
Debug::log(LOG, "Destroying the SubSurface tree of unmapped window {}", PWINDOW);
SubsurfaceTree::destroySurfaceTree(PWINDOW->m_pSurfaceTree);
PWINDOW->m_pSurfaceTree = nullptr;
PWINDOW->m_bFadingOut = true; PWINDOW->m_bFadingOut = true;
g_pCompositor->addToFadingOutSafe(PWINDOW); g_pCompositor->addToFadingOutSafe(PWINDOW);
@ -769,7 +738,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)); g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID));
if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in. if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in.
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.vec() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
// anims // anims
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true); g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
@ -806,7 +775,26 @@ void Events::listener_commitWindow(void* owner, void* data) {
CWindow* PWINDOW = (CWindow*)owner; CWindow* PWINDOW = (CWindow*)owner;
if (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->initial_commit) { if (!PWINDOW->m_bIsX11 && PWINDOW->m_uSurface.xdg->initial_commit) {
wlr_xdg_toplevel_set_size(PWINDOW->m_uSurface.xdg->toplevel, 0, 0); Vector2D predSize = g_pLayoutManager->getCurrentLayout()->predictSizeForNewWindow();
if (g_pXWaylandManager->shouldBeFloated(PWINDOW, true))
predSize = {};
Vector2D maxSize = Vector2D{PWINDOW->m_uSurface.xdg->toplevel->pending.max_width, PWINDOW->m_uSurface.xdg->toplevel->pending.max_height};
if ((maxSize.x > 0 && maxSize.x < predSize.x) || (maxSize.y > 0 && maxSize.y < predSize.y))
predSize = {};
for (auto& r : g_pConfigManager->getMatchingRules(PWINDOW, true, true)) {
if (r.szRule.starts_with("float")) {
predSize = {};
break;
}
}
Debug::log(LOG, "Layout predicts size {} for {}", predSize, PWINDOW);
wlr_xdg_toplevel_set_size(PWINDOW->m_uSurface.xdg->toplevel, predSize.x, predSize.y);
return; return;
} }
@ -820,9 +808,30 @@ void Events::listener_commitWindow(void* owner, void* data) {
PWINDOW->m_pPendingSizeAck.reset(); PWINDOW->m_pPendingSizeAck.reset();
} }
g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0); PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
if (!PWINDOW->m_bIsX11) {
PWINDOW->m_pSubsurfaceHead->recheckDamageForSubsurfaces();
PWINDOW->m_pPopupHead->recheckTree();
}
// tearing: if solitary, redraw it. This still might be a single surface window
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (PMONITOR && PMONITOR->solitaryClient == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear &&
PWINDOW->m_pWLSurface.wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) {
CRegion damageBox{&PWINDOW->m_pWLSurface.wlr()->buffer_damage};
if (!damageBox.empty()) {
if (PMONITOR->tearingState.busy) {
PMONITOR->tearingState.frameScheduledWhileBusy = true;
} else {
PMONITOR->tearingState.nextRenderTorn = true;
g_pHyprRenderer->renderMonitor(PMONITOR);
}
}
}
if (PWINDOW->m_bIsX11 || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen) if (PWINDOW->m_bIsX11 || !PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen)
return; return;
@ -832,7 +841,7 @@ void Events::listener_commitWindow(void* owner, void* data) {
if (MAXSIZE < Vector2D{1, 1}) if (MAXSIZE < Vector2D{1, 1})
return; return;
const auto REALSIZE = PWINDOW->m_vRealSize.goalv(); const auto REALSIZE = PWINDOW->m_vRealSize.goal();
Vector2D newSize = REALSIZE; Vector2D newSize = REALSIZE;
if (MAXSIZE.x < newSize.x) if (MAXSIZE.x < newSize.x)
@ -846,7 +855,7 @@ void Events::listener_commitWindow(void* owner, void* data) {
const Vector2D DELTA = REALSIZE - newSize; const Vector2D DELTA = REALSIZE - newSize;
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goalv() + DELTA / 2.0; PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + DELTA / 2.0;
PWINDOW->m_vRealSize = newSize; PWINDOW->m_vRealSize = newSize;
g_pXWaylandManager->setWindowSize(PWINDOW, newSize, true); g_pXWaylandManager->setWindowSize(PWINDOW, newSize, true);
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
@ -876,14 +885,10 @@ void Events::listener_destroyWindow(void* owner, void* data) {
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW); g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
if (PWINDOW->m_pSurfaceTree) {
Debug::log(LOG, "Destroying Subsurface tree of {} in destroyWindow", PWINDOW);
SubsurfaceTree::destroySurfaceTree(PWINDOW->m_pSurfaceTree);
PWINDOW->m_pSurfaceTree = nullptr;
}
PWINDOW->m_bReadyToDelete = true; PWINDOW->m_bReadyToDelete = true;
PWINDOW->m_uSurface.xdg = nullptr;
if (!PWINDOW->m_bFadingOut) { if (!PWINDOW->m_bFadingOut) {
Debug::log(LOG, "Unmapped {} removed instantly", PWINDOW); Debug::log(LOG, "Unmapped {} removed instantly", PWINDOW);
g_pCompositor->removeWindowFromVectorSafe(PWINDOW); // most likely X11 unmanaged or sumn g_pCompositor->removeWindowFromVectorSafe(PWINDOW); // most likely X11 unmanaged or sumn
@ -896,7 +901,12 @@ void Events::listener_setTitleWindow(void* owner, void* data) {
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!g_pCompositor->windowValidMapped(PWINDOW))
return; return;
PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW); const auto NEWTITLE = g_pXWaylandManager->getTitle(PWINDOW);
if (NEWTITLE == PWINDOW->m_szTitle)
return;
PWINDOW->m_szTitle = NEWTITLE;
g_pEventManager->postEvent(SHyprIPCEvent{"windowtitle", std::format("{:x}", (uintptr_t)PWINDOW)}); g_pEventManager->postEvent(SHyprIPCEvent{"windowtitle", std::format("{:x}", (uintptr_t)PWINDOW)});
EMIT_HOOK_EVENT("windowTitle", PWINDOW); EMIT_HOOK_EVENT("windowTitle", PWINDOW);
@ -975,7 +985,7 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
void Events::listener_activateXDG(wl_listener* listener, void* data) { void Events::listener_activateXDG(wl_listener* listener, void* data) {
const auto E = (wlr_xdg_activation_v1_request_activate_event*)data; const auto E = (wlr_xdg_activation_v1_request_activate_event*)data;
static auto* const PFOCUSONACTIVATE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:focus_on_activate"); static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
Debug::log(LOG, "Activate request for surface at {:x}", (uintptr_t)E->surface); Debug::log(LOG, "Activate request for surface at {:x}", (uintptr_t)E->surface);
@ -992,7 +1002,7 @@ void Events::listener_activateXDG(wl_listener* listener, void* data) {
PWINDOW->m_bIsUrgent = true; PWINDOW->m_bIsUrgent = true;
if (!**PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY)) if (!*PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
return; return;
if (PWINDOW->m_bIsFloating) if (PWINDOW->m_bIsFloating)
@ -1005,7 +1015,7 @@ void Events::listener_activateXDG(wl_listener* listener, void* data) {
void Events::listener_activateX11(void* owner, void* data) { void Events::listener_activateX11(void* owner, void* data) {
const auto PWINDOW = (CWindow*)owner; const auto PWINDOW = (CWindow*)owner;
static auto* const PFOCUSONACTIVATE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:focus_on_activate"); static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
Debug::log(LOG, "X11 Activate request for window {}", PWINDOW); Debug::log(LOG, "X11 Activate request for window {}", PWINDOW);
@ -1029,7 +1039,7 @@ void Events::listener_activateX11(void* owner, void* data) {
g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)PWINDOW)}); g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)PWINDOW)});
EMIT_HOOK_EVENT("urgent", PWINDOW); EMIT_HOOK_EVENT("urgent", PWINDOW);
if (!**PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY)) if (!*PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
return; return;
if (PWINDOW->m_bIsFloating) if (PWINDOW->m_bIsFloating)
@ -1048,13 +1058,15 @@ void Events::listener_configureX11(void* owner, void* data) {
wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height); wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height);
PWINDOW->m_vPendingReportedSize = {E->width, E->height}; PWINDOW->m_vPendingReportedSize = {E->width, E->height};
PWINDOW->m_vReportedSize = {E->width, E->height}; PWINDOW->m_vReportedSize = {E->width, E->height};
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR)
PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale;
return; return;
} }
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
if (!PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen || g_pInputManager->currentlyDraggedWindow == PWINDOW) { if (!PWINDOW->m_bIsFloating || PWINDOW->m_bIsFullscreen || g_pInputManager->currentlyDraggedWindow == PWINDOW) {
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv(), true); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal(), true);
g_pInputManager->refocus(); g_pInputManager->refocus();
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
return; return;
@ -1070,14 +1082,16 @@ void Events::listener_configureX11(void* owner, void* data) {
PWINDOW->m_vRealPosition.setValueAndWarp(LOGICALPOS); PWINDOW->m_vRealPosition.setValueAndWarp(LOGICALPOS);
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height)); PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height));
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
if (**PXWLFORCESCALEZERO) { if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) {
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale); PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goal() / PMONITOR->scale);
PWINDOW->m_fX11SurfaceScaledBy = PMONITOR->scale;
}
} }
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec(); PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.value();
PWINDOW->m_vSize = PWINDOW->m_vRealSize.vec(); PWINDOW->m_vSize = PWINDOW->m_vRealSize.value();
wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height); wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height);
@ -1089,7 +1103,7 @@ void Events::listener_configureX11(void* owner, void* data) {
if (!g_pCompositor->isWorkspaceVisible(PWINDOW->m_iWorkspaceID)) if (!g_pCompositor->isWorkspaceVisible(PWINDOW->m_iWorkspaceID))
return; // further things are only for visible windows return; // further things are only for visible windows
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.vec() + PWINDOW->m_vRealSize.vec() / 2.f)->activeWorkspace; PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace;
g_pCompositor->changeWindowZOrder(PWINDOW, true); g_pCompositor->changeWindowZOrder(PWINDOW, true);
@ -1107,8 +1121,8 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
if (!PWINDOW->m_bIsMapped) if (!PWINDOW->m_bIsMapped)
return; return;
const auto POS = PWINDOW->m_vRealPosition.goalv(); const auto POS = PWINDOW->m_vRealPosition.goal();
const auto SIZ = PWINDOW->m_vRealSize.goalv(); const auto SIZ = PWINDOW->m_vRealSize.goal();
if (PWINDOW->m_uSurface.xwayland->width > 1 && PWINDOW->m_uSurface.xwayland->height > 1) if (PWINDOW->m_uSurface.xwayland->width > 1 && PWINDOW->m_uSurface.xwayland->height > 1)
PWINDOW->setHidden(false); PWINDOW->setHidden(false);
@ -1116,12 +1130,12 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
PWINDOW->setHidden(true); PWINDOW->setHidden(true);
if (PWINDOW->m_bIsFullscreen || !PWINDOW->m_bIsFloating) { if (PWINDOW->m_bIsFullscreen || !PWINDOW->m_bIsFloating) {
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv(), true); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal(), true);
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
return; return;
} }
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y}); const auto LOGICALPOS = g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y});
@ -1136,25 +1150,25 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
if (abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) if (abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2)
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height)); PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
if (**PXWLFORCESCALEZERO) { if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) { if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) {
const Vector2D DELTA = PWINDOW->m_vRealSize.goalv() - PWINDOW->m_vRealSize.goalv() / PMONITOR->scale; const Vector2D DELTA = PWINDOW->m_vRealSize.goal() - PWINDOW->m_vRealSize.goal() / PMONITOR->scale;
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale); PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goal() / PMONITOR->scale);
PWINDOW->m_vRealPosition.setValueAndWarp(PWINDOW->m_vRealPosition.goalv() + DELTA / 2.0); PWINDOW->m_vRealPosition.setValueAndWarp(PWINDOW->m_vRealPosition.goal() + DELTA / 2.0);
} }
} }
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv(); PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goal();
PWINDOW->m_vSize = PWINDOW->m_vRealSize.goalv(); PWINDOW->m_vSize = PWINDOW->m_vRealSize.goal();
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.vec() + PWINDOW->m_vRealSize.vec() / 2.f)->activeWorkspace; PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.value() + PWINDOW->m_vRealSize.value() / 2.f)->activeWorkspace;
g_pCompositor->changeWindowZOrder(PWINDOW, true); g_pCompositor->changeWindowZOrder(PWINDOW, true);
PWINDOW->updateWindowDecos(); PWINDOW->updateWindowDecos();
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
PWINDOW->m_vReportedPosition = PWINDOW->m_vRealPosition.goalv(); PWINDOW->m_vReportedPosition = PWINDOW->m_vRealPosition.goal();
PWINDOW->m_vPendingReportedSize = PWINDOW->m_vRealSize.goalv(); PWINDOW->m_vPendingReportedSize = PWINDOW->m_vRealSize.goal();
} }
} }

View file

@ -2,12 +2,11 @@
#include "../managers/AnimationManager.hpp" #include "../managers/AnimationManager.hpp"
#include "../config/ConfigManager.hpp" #include "../config/ConfigManager.hpp"
CAnimatedVariable::CAnimatedVariable() { CBaseAnimatedVariable::CBaseAnimatedVariable(ANIMATEDVARTYPE type) : m_Type(type) {
; // dummy var ; // dummy var
} }
void CAnimatedVariable::create(ANIMATEDVARTYPE type, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) { void CBaseAnimatedVariable::create(SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) {
m_eVarType = type;
m_eDamagePolicy = policy; m_eDamagePolicy = policy;
m_pConfig = pAnimConfig; m_pConfig = pAnimConfig;
m_pWindow = pWindow; m_pWindow = pWindow;
@ -15,42 +14,11 @@ void CAnimatedVariable::create(ANIMATEDVARTYPE type, SAnimationPropertyConfig* p
m_bDummy = false; m_bDummy = false;
} }
void CAnimatedVariable::create(ANIMATEDVARTYPE type, std::any val, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) { CBaseAnimatedVariable::~CBaseAnimatedVariable() {
create(type, pAnimConfig, pWindow, policy);
try {
switch (type) {
case AVARTYPE_FLOAT: {
const auto V = std::any_cast<float>(val);
m_fValue = V;
m_fGoal = V;
break;
}
case AVARTYPE_VECTOR: {
const auto V = std::any_cast<Vector2D>(val);
m_vValue = V;
m_vGoal = V;
break;
}
case AVARTYPE_COLOR: {
const auto V = std::any_cast<CColor>(val);
m_cValue = V;
m_cGoal = V;
break;
}
default: ASSERT(false); break;
}
} catch (std::exception& e) {
Debug::log(ERR, "CAnimatedVariable create error: {}", e.what());
RASSERT(false, "CAnimatedVariable create error: {}", e.what());
}
}
CAnimatedVariable::~CAnimatedVariable() {
unregister(); unregister();
} }
void CAnimatedVariable::unregister() { void CBaseAnimatedVariable::unregister() {
if (!g_pAnimationManager) if (!g_pAnimationManager)
return; return;
std::erase_if(g_pAnimationManager->m_vAnimatedVariables, [&](const auto& other) { return other == this; }); std::erase_if(g_pAnimationManager->m_vAnimatedVariables, [&](const auto& other) { return other == this; });
@ -58,23 +26,23 @@ void CAnimatedVariable::unregister() {
disconnectFromActive(); disconnectFromActive();
} }
void CAnimatedVariable::registerVar() { void CBaseAnimatedVariable::registerVar() {
if (!m_bIsRegistered) if (!m_bIsRegistered)
g_pAnimationManager->m_vAnimatedVariables.push_back(this); g_pAnimationManager->m_vAnimatedVariables.push_back(this);
m_bIsRegistered = true; m_bIsRegistered = true;
} }
int CAnimatedVariable::getDurationLeftMs() { int CBaseAnimatedVariable::getDurationLeftMs() {
return std::max( return std::max(
(int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0); (int)(m_pConfig->pValues->internalSpeed * 100) - (int)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(), 0);
} }
float CAnimatedVariable::getPercent() { float CBaseAnimatedVariable::getPercent() {
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count(); const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - animationBegin).count();
return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f); return std::clamp((DURATIONPASSED / 100.f) / m_pConfig->pValues->internalSpeed, 0.f, 1.f);
} }
float CAnimatedVariable::getCurveValue() { float CBaseAnimatedVariable::getCurveValue() {
if (!m_bIsBeingAnimated) if (!m_bIsBeingAnimated)
return 1.f; return 1.f;
@ -86,7 +54,7 @@ float CAnimatedVariable::getCurveValue() {
return g_pAnimationManager->getBezier(m_pConfig->pValues->internalBezier)->getYForPoint(SPENT); return g_pAnimationManager->getBezier(m_pConfig->pValues->internalBezier)->getYForPoint(SPENT);
} }
void CAnimatedVariable::connectToActive() { void CBaseAnimatedVariable::connectToActive() {
g_pAnimationManager->scheduleTick(); // otherwise the animation manager will never pick this up g_pAnimationManager->scheduleTick(); // otherwise the animation manager will never pick this up
if (!m_bIsConnectedToActive) if (!m_bIsConnectedToActive)
@ -95,7 +63,7 @@ void CAnimatedVariable::connectToActive() {
m_bIsConnectedToActive = true; m_bIsConnectedToActive = true;
} }
void CAnimatedVariable::disconnectFromActive() { void CBaseAnimatedVariable::disconnectFromActive() {
std::erase_if(g_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == this; }); std::erase_if(g_pAnimationManager->m_vActiveAnimatedVariables, [&](const auto& other) { return other == this; });
m_bIsConnectedToActive = false; m_bIsConnectedToActive = false;
} }

View file

@ -3,6 +3,7 @@
#include <functional> #include <functional>
#include <any> #include <any>
#include <chrono> #include <chrono>
#include <type_traits>
#include "Vector2D.hpp" #include "Vector2D.hpp"
#include "Color.hpp" #include "Color.hpp"
#include "../macros.hpp" #include "../macros.hpp"
@ -15,6 +16,30 @@ enum ANIMATEDVARTYPE {
AVARTYPE_COLOR AVARTYPE_COLOR
}; };
// Utility to bind a type with its corresponding ANIMATEDVARTYPE
template <class T>
struct typeToANIMATEDVARTYPE_t {
static constexpr ANIMATEDVARTYPE value = AVARTYPE_INVALID;
};
template <>
struct typeToANIMATEDVARTYPE_t<float> {
static constexpr ANIMATEDVARTYPE value = AVARTYPE_FLOAT;
};
template <>
struct typeToANIMATEDVARTYPE_t<Vector2D> {
static constexpr ANIMATEDVARTYPE value = AVARTYPE_VECTOR;
};
template <>
struct typeToANIMATEDVARTYPE_t<CColor> {
static constexpr ANIMATEDVARTYPE value = AVARTYPE_COLOR;
};
template <class T>
inline constexpr ANIMATEDVARTYPE typeToANIMATEDVARTYPE = typeToANIMATEDVARTYPE_t<T>::value;
enum AVARDAMAGEPOLICY { enum AVARDAMAGEPOLICY {
AVARDAMAGE_NONE = -1, AVARDAMAGE_NONE = -1,
AVARDAMAGE_ENTIRE = 0, AVARDAMAGE_ENTIRE = 0,
@ -28,174 +53,34 @@ struct SLayerSurface;
struct SAnimationPropertyConfig; struct SAnimationPropertyConfig;
class CHyprRenderer; class CHyprRenderer;
class CAnimatedVariable { // Utility to define a concept as a list of possible type
template <class T, class... U>
concept OneOf = (... or std::same_as<T, U>);
// Concept to describe which type can be placed into CAnimatedVariable
// This is mainly to get better errors if we put a type that's not supported
// Otherwise template errors are ugly
template <class T>
concept Animable = OneOf<T, Vector2D, float, CColor>;
class CBaseAnimatedVariable {
public: public:
CAnimatedVariable(); // dummy var CBaseAnimatedVariable(ANIMATEDVARTYPE type);
void create(SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy);
void create(ANIMATEDVARTYPE, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY); CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete;
void create(ANIMATEDVARTYPE, std::any val, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY); CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete;
CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete;
CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete;
CAnimatedVariable(const CAnimatedVariable&) = delete; virtual ~CBaseAnimatedVariable();
CAnimatedVariable(CAnimatedVariable&&) = delete;
CAnimatedVariable& operator=(const CAnimatedVariable&) = delete;
CAnimatedVariable& operator=(CAnimatedVariable&&) = delete;
~CAnimatedVariable();
void unregister(); void unregister();
void registerVar(); void registerVar();
// gets the current vector value (real time) virtual void warp(bool endCallback = true) = 0;
const Vector2D& vec() const {
return m_vValue;
}
// gets the current float value (real time)
const float& fl() const {
return m_fValue;
}
// gets the current color value (real time)
const CColor& col() const {
return m_cValue;
}
// gets the goal vector value
const Vector2D& goalv() const {
return m_vGoal;
}
// gets the goal float value
const float& goalf() const {
return m_fGoal;
}
// gets the goal color value
const CColor& goalc() const {
return m_cGoal;
}
CAnimatedVariable& operator=(const Vector2D& v) {
if (v == m_vGoal)
return *this;
m_vGoal = v;
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
onAnimationBegin();
return *this;
}
CAnimatedVariable& operator=(const float& v) {
if (v == m_fGoal)
return *this;
m_fGoal = v;
animationBegin = std::chrono::system_clock::now();
m_fBegun = m_fValue;
onAnimationBegin();
return *this;
}
CAnimatedVariable& operator=(const CColor& v) {
if (v == m_cGoal)
return *this;
m_cGoal = v;
animationBegin = std::chrono::system_clock::now();
m_cBegun = m_cValue;
onAnimationBegin();
return *this;
}
// Sets the actual stored value, without affecting the goal, but resets the timer
void setValue(const Vector2D& v) {
if (v == m_vValue)
return;
m_vValue = v;
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
onAnimationBegin();
}
// Sets the actual stored value, without affecting the goal, but resets the timer
void setValue(const float& v) {
if (v == m_fValue)
return;
m_fValue = v;
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
onAnimationBegin();
}
// Sets the actual stored value, without affecting the goal, but resets the timer
void setValue(const CColor& v) {
if (v == m_cValue)
return;
m_cValue = v;
animationBegin = std::chrono::system_clock::now();
m_vBegun = m_vValue;
onAnimationBegin();
}
// Sets the actual value and goal
void setValueAndWarp(const Vector2D& v) {
m_vGoal = v;
warp();
}
// Sets the actual value and goal
void setValueAndWarp(const float& v) {
m_fGoal = v;
warp();
}
// Sets the actual value and goal
void setValueAndWarp(const CColor& v) {
m_cGoal = v;
warp();
}
// checks if an animation is in progress
inline bool isBeingAnimated() {
return m_bIsBeingAnimated;
}
void warp(bool endCallback = true) {
switch (m_eVarType) {
case AVARTYPE_FLOAT: {
m_fValue = m_fGoal;
break;
}
case AVARTYPE_VECTOR: {
m_vValue = m_vGoal;
break;
}
case AVARTYPE_COLOR: {
m_cValue = m_cGoal;
break;
}
default: UNREACHABLE();
}
m_bIsBeingAnimated = false;
if (endCallback)
onAnimationEnd();
}
//
void setConfig(SAnimationPropertyConfig* pConfig) { void setConfig(SAnimationPropertyConfig* pConfig) {
m_pConfig = pConfig; m_pConfig = pConfig;
} }
@ -212,6 +97,11 @@ class CAnimatedVariable {
/* returns the current curve value */ /* returns the current curve value */
float getCurveValue(); float getCurveValue();
// checks if an animation is in progress
inline bool isBeingAnimated() {
return m_bIsBeingAnimated;
}
/* sets a function to be ran when the animation finishes. /* sets a function to be ran when the animation finishes.
if an animation is not running, runs instantly. if an animation is not running, runs instantly.
if "remove" is set to true, will remove the callback when ran. */ if "remove" is set to true, will remove the callback when ran. */
@ -245,20 +135,7 @@ class CAnimatedVariable {
m_bRemoveEndAfterRan = false; m_bRemoveEndAfterRan = false;
} }
private: protected:
Vector2D m_vValue = Vector2D(0, 0);
float m_fValue = 0;
CColor m_cValue;
Vector2D m_vGoal = Vector2D(0, 0);
float m_fGoal = 0;
CColor m_cGoal;
Vector2D m_vBegun = Vector2D(0, 0);
float m_fBegun = 0;
CColor m_cBegun;
// owners
void* m_pWindow = nullptr; void* m_pWindow = nullptr;
void* m_pWorkspace = nullptr; void* m_pWorkspace = nullptr;
void* m_pLayer = nullptr; void* m_pLayer = nullptr;
@ -271,8 +148,8 @@ class CAnimatedVariable {
std::chrono::system_clock::time_point animationBegin; std::chrono::system_clock::time_point animationBegin;
ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID;
AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_NONE; AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_NONE;
ANIMATEDVARTYPE m_Type;
bool m_bRemoveEndAfterRan = true; bool m_bRemoveEndAfterRan = true;
bool m_bRemoveBeginAfterRan = true; bool m_bRemoveBeginAfterRan = true;
@ -281,7 +158,9 @@ class CAnimatedVariable {
std::function<void(void* thisptr)> m_fUpdateCallback; std::function<void(void* thisptr)> m_fUpdateCallback;
bool m_bIsConnectedToActive = false; bool m_bIsConnectedToActive = false;
void connectToActive(); void connectToActive();
void disconnectFromActive(); void disconnectFromActive();
// methods // methods
@ -314,3 +193,86 @@ class CAnimatedVariable {
friend struct SLayerSurface; friend struct SLayerSurface;
friend class CHyprRenderer; friend class CHyprRenderer;
}; };
template <Animable VarType>
class CAnimatedVariable : public CBaseAnimatedVariable {
public:
CAnimatedVariable() : CBaseAnimatedVariable(typeToANIMATEDVARTYPE<VarType>) {} // dummy var
void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) {
create(pAnimConfig, pWindow, policy);
m_Value = value;
m_Goal = value;
}
using CBaseAnimatedVariable::create;
CAnimatedVariable(const CAnimatedVariable&) = delete;
CAnimatedVariable(CAnimatedVariable&&) = delete;
CAnimatedVariable& operator=(const CAnimatedVariable&) = delete;
CAnimatedVariable& operator=(CAnimatedVariable&&) = delete;
~CAnimatedVariable() = default;
// gets the current vector value (real time)
const VarType& value() const {
return m_Value;
}
// gets the goal vector value
const VarType& goal() const {
return m_Goal;
}
CAnimatedVariable& operator=(const VarType& v) {
if (v == m_Goal)
return *this;
m_Goal = v;
animationBegin = std::chrono::system_clock::now();
m_Begun = m_Value;
onAnimationBegin();
return *this;
}
// Sets the actual stored value, without affecting the goal, but resets the timer
void setValue(const VarType& v) {
if (v == m_Value)
return;
m_Value = v;
animationBegin = std::chrono::system_clock::now();
m_Begun = m_Value;
onAnimationBegin();
}
// Sets the actual value and goal
void setValueAndWarp(const VarType& v) {
m_Goal = v;
warp();
}
void warp(bool endCallback = true) override {
m_Value = m_Goal;
m_bIsBeingAnimated = false;
if (endCallback)
onAnimationEnd();
}
private:
VarType m_Value{};
VarType m_Goal{};
VarType m_Begun{};
// owners
friend class CAnimationManager;
friend class CWorkspace;
friend struct SLayerSurface;
friend class CHyprRenderer;
};

View file

@ -116,6 +116,24 @@ CBox& CBox::noNegativeSize() {
return *this; return *this;
} }
CBox& CBox::intersection(const CBox other) {
const float newTop = std::max(y, other.y);
const float newBottom = std::min(y + h, other.y + other.h);
const float newLeft = std::max(x, other.x);
const float newRight = std::min(x + w, other.x + other.w);
y = newTop;
x = newLeft;
w = newRight - newLeft;
h = newBottom - newTop;
if (w <= 0 || h <= 0) {
w = 0;
h = 0;
}
return *this;
}
CBox CBox::roundInternal() { CBox CBox::roundInternal() {
float newW = x + w - std::floor(x); float newW = x + w - std::floor(x);
float newH = y + h - std::floor(y); float newH = y + h - std::floor(y);

View file

@ -52,6 +52,7 @@ class CBox {
CBox& addExtents(const SWindowDecorationExtents& e); CBox& addExtents(const SWindowDecorationExtents& e);
CBox& expand(const double& value); CBox& expand(const double& value);
CBox& noNegativeSize(); CBox& noNegativeSize();
CBox& intersection(const CBox other);
CBox copy() const; CBox copy() const;

View file

@ -722,6 +722,32 @@ int64_t configStringToInt(const std::string& VALUE) {
return std::stoll(VALUE); return std::stoll(VALUE);
} }
Vector2D configStringToVector2D(const std::string& VALUE) {
std::istringstream iss(VALUE);
std::string token;
if (!std::getline(iss, token, ' ') && !std::getline(iss, token, ','))
throw std::invalid_argument("Invalid string format");
if (!isNumber(token))
throw std::invalid_argument("Invalid x value");
long long x = std::stoll(token);
if (!std::getline(iss, token))
throw std::invalid_argument("Invalid string format");
if (!isNumber(token))
throw std::invalid_argument("Invalid y value");
long long y = std::stoll(token);
if (std::getline(iss, token))
throw std::invalid_argument("Invalid string format");
return Vector2D(x, y);
}
double normalizeAngleRad(double ang) { double normalizeAngleRad(double ang) {
if (ang > M_PI * 2) { if (ang > M_PI * 2) {
while (ang > M_PI * 2) while (ang > M_PI * 2)

View file

@ -28,6 +28,7 @@ void logSystemInfo();
std::string execAndGet(const char*); std::string execAndGet(const char*);
int64_t getPPIDof(int64_t pid); int64_t getPPIDof(int64_t pid);
int64_t configStringToInt(const std::string&); int64_t configStringToInt(const std::string&);
Vector2D configStringToVector2D(const std::string&);
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative); std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr); void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
double normalizeAngleRad(double ang); double normalizeAngleRad(double ang);

View file

@ -4,6 +4,8 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
int ratHandler(void* data) { int ratHandler(void* data) {
g_pHyprRenderer->renderMonitor((CMonitor*)data); g_pHyprRenderer->renderMonitor((CMonitor*)data);
@ -54,11 +56,12 @@ void CMonitor::onConnect(bool noRule) {
szDescription = output->description ? output->description : ""; szDescription = output->description ? output->description : "";
// remove comma character from description. This allow monitor specific rules to work on monitor with comma on their description // remove comma character from description. This allow monitor specific rules to work on monitor with comma on their description
szDescription.erase(std::remove(szDescription.begin(), szDescription.end(), ','), szDescription.end()); std::erase(szDescription, ',');
// field is backwards-compatible with intended usage of `szDescription` but excludes the parenthesized DRM node name suffix // field is backwards-compatible with intended usage of `szDescription` but excludes the parenthesized DRM node name suffix
szShortDescription = szShortDescription =
removeBeginEndSpacesTabs(std::format("{} {} {}", output->make ? output->make : "", output->model ? output->model : "", output->serial ? output->serial : "")); removeBeginEndSpacesTabs(std::format("{} {} {}", output->make ? output->make : "", output->model ? output->model : "", output->serial ? output->serial : ""));
std::erase(szShortDescription, ',');
if (!wlr_backend_is_drm(output->backend)) if (!wlr_backend_is_drm(output->backend))
createdByUser = true; // should be true. WL, X11 and Headless backends should be addable / removable createdByUser = true; // should be true. WL, X11 and Headless backends should be addable / removable
@ -161,8 +164,6 @@ void CMonitor::onConnect(bool noRule) {
wlr_damage_ring_set_bounds(&damage, vecTransformedSize.x, vecTransformedSize.y); wlr_damage_ring_set_bounds(&damage, vecTransformedSize.x, vecTransformedSize.y);
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, scale);
Debug::log(LOG, "Added new monitor with name {} at {:j0} with size {:j0}, pointer {:x}", output->name, vecPosition, vecPixelSize, (uintptr_t)output); Debug::log(LOG, "Added new monitor with name {} at {:j0} with size {:j0}, pointer {:x}", output->name, vecPosition, vecPixelSize, (uintptr_t)output);
setupDefaultWS(monitorRule); setupDefaultWS(monitorRule);
@ -189,8 +190,6 @@ void CMonitor::onConnect(bool noRule) {
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
g_pCompositor->setActiveMonitor(this); g_pCompositor->setActiveMonitor(this);
wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, scale);
g_pHyprRenderer->arrangeLayersForMonitor(ID); g_pHyprRenderer->arrangeLayersForMonitor(ID);
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
@ -330,8 +329,8 @@ void CMonitor::onDisconnect(bool destroy) {
} }
void CMonitor::addDamage(const pixman_region32_t* rg) { void CMonitor::addDamage(const pixman_region32_t* rg) {
static auto* const PZOOMFACTOR = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("misc:cursor_zoom_factor"); static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("misc:cursor_zoom_factor");
if (**PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) { if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
wlr_damage_ring_add_whole(&damage); wlr_damage_ring_add_whole(&damage);
g_pCompositor->scheduleFrameForMonitor(this); g_pCompositor->scheduleFrameForMonitor(this);
} else if (wlr_damage_ring_add(&damage, rg)) } else if (wlr_damage_ring_add(&damage, rg))
@ -343,8 +342,8 @@ void CMonitor::addDamage(const CRegion* rg) {
} }
void CMonitor::addDamage(const CBox* box) { void CMonitor::addDamage(const CBox* box) {
static auto* const PZOOMFACTOR = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("misc:cursor_zoom_factor"); static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("misc:cursor_zoom_factor");
if (**PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) { if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {
wlr_damage_ring_add_whole(&damage); wlr_damage_ring_add_whole(&damage);
g_pCompositor->scheduleFrameForMonitor(this); g_pCompositor->scheduleFrameForMonitor(this);
} }
@ -361,9 +360,8 @@ bool CMonitor::matchesStaticSelector(const std::string& selector) const {
if (selector.starts_with("desc:")) { if (selector.starts_with("desc:")) {
// match by description // match by description
const auto DESCRIPTIONSELECTOR = selector.substr(5); const auto DESCRIPTIONSELECTOR = selector.substr(5);
const auto DESCRIPTION = removeBeginEndSpacesTabs(szDescription.substr(0, szDescription.find_first_of('(')));
return DESCRIPTIONSELECTOR == szDescription || DESCRIPTIONSELECTOR == DESCRIPTION; return DESCRIPTIONSELECTOR == szShortDescription || DESCRIPTIONSELECTOR == szDescription;
} else { } else {
// match by selector // match by selector
return szName == selector; return szName == selector;
@ -412,9 +410,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
if (newDefaultWorkspaceName == "") if (newDefaultWorkspaceName == "")
newDefaultWorkspaceName = std::to_string(WORKSPACEID); newDefaultWorkspaceName = std::to_string(WORKSPACEID);
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(ID, newDefaultWorkspaceName)).get(); PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(WORKSPACEID, ID, newDefaultWorkspaceName)).get();
PNEWWORKSPACE->m_iID = WORKSPACEID;
} }
activeWorkspace = PNEWWORKSPACE->m_iID; activeWorkspace = PNEWWORKSPACE->m_iID;
@ -568,11 +564,11 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool
} }
if (!noFocus && !g_pCompositor->m_pLastMonitor->specialWorkspaceID) { if (!noFocus && !g_pCompositor->m_pLastMonitor->specialWorkspaceID) {
static auto* const PFOLLOWMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
CWindow* pWindow = pWorkspace->getLastFocusedWindow(); CWindow* pWindow = pWorkspace->getLastFocusedWindow();
if (!pWindow) { if (!pWindow) {
if (**PFOLLOWMOUSE == 1) if (*PFOLLOWMOUSE == 1)
pWindow = g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING); pWindow = g_pCompositor->vectorToWindowUnified(g_pInputManager->getMouseCoordsInternal(), RESERVED_EXTENTS | INPUT_EXTENTS | ALLOW_FLOATING);
if (!pWindow) if (!pWindow)
@ -591,6 +587,7 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID);
g_pEventManager->postEvent(SHyprIPCEvent{"workspace", pWorkspace->m_szName}); g_pEventManager->postEvent(SHyprIPCEvent{"workspace", pWorkspace->m_szName});
g_pEventManager->postEvent(SHyprIPCEvent{"workspacev2", std::format("{},{}", pWorkspace->m_iID, pWorkspace->m_szName)});
EMIT_HOOK_EVENT("workspace", pWorkspace); EMIT_HOOK_EVENT("workspace", pWorkspace);
} }
@ -601,6 +598,12 @@ void CMonitor::changeWorkspace(CWorkspace* const pWorkspace, bool internal, bool
g_pConfigManager->ensureVRR(this); g_pConfigManager->ensureVRR(this);
g_pCompositor->updateSuspendedStates(); g_pCompositor->updateSuspendedStates();
if (specialWorkspaceID) {
const auto PSPECIALWS = g_pCompositor->getWorkspaceByID(specialWorkspaceID);
if (PSPECIALWS->m_bHasFullscreenWindow)
g_pCompositor->updateFullscreenFadeOnWorkspace(PSPECIALWS);
}
} }
void CMonitor::changeWorkspace(const int& id, bool internal, bool noMouseMove, bool noFocus) { void CMonitor::changeWorkspace(const int& id, bool internal, bool noMouseMove, bool noFocus) {
@ -626,6 +629,10 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) {
else else
g_pInputManager->refocus(); g_pInputManager->refocus();
g_pCompositor->updateFullscreenFadeOnWorkspace(PWORKSPACE);
g_pConfigManager->ensureVRR(this);
g_pCompositor->updateSuspendedStates(); g_pCompositor->updateSuspendedStates();
return; return;
@ -643,6 +650,10 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) {
PMONITORWORKSPACEOWNER->specialWorkspaceID = 0; PMONITORWORKSPACEOWNER->specialWorkspaceID = 0;
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITORWORKSPACEOWNER->ID); g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITORWORKSPACEOWNER->ID);
g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + PMONITORWORKSPACEOWNER->szName}); g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + PMONITORWORKSPACEOWNER->szName});
const auto PACTIVEWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITORWORKSPACEOWNER->activeWorkspace);
g_pCompositor->updateFullscreenFadeOnWorkspace(PACTIVEWORKSPACE);
animate = false; animate = false;
} }
@ -661,11 +672,11 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) {
if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && w->m_iX11Type != 2) { if (w->m_bIsFloating && !VECINRECT(MIDDLE, vecPosition.x, vecPosition.y, vecPosition.x + vecSize.x, vecPosition.y + vecSize.y) && w->m_iX11Type != 2) {
// if it's floating and the middle isnt on the current mon, move it to the center // if it's floating and the middle isnt on the current mon, move it to the center
const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE); const auto PMONFROMMIDDLE = g_pCompositor->getMonitorFromVector(MIDDLE);
Vector2D pos = w->m_vRealPosition.goalv(); Vector2D pos = w->m_vRealPosition.goal();
if (!VECINRECT(MIDDLE, PMONFROMMIDDLE->vecPosition.x, PMONFROMMIDDLE->vecPosition.y, PMONFROMMIDDLE->vecPosition.x + PMONFROMMIDDLE->vecSize.x, if (!VECINRECT(MIDDLE, PMONFROMMIDDLE->vecPosition.x, PMONFROMMIDDLE->vecPosition.y, PMONFROMMIDDLE->vecPosition.x + PMONFROMMIDDLE->vecSize.x,
PMONFROMMIDDLE->vecPosition.y + PMONFROMMIDDLE->vecSize.y)) { PMONFROMMIDDLE->vecPosition.y + PMONFROMMIDDLE->vecSize.y)) {
// not on any monitor, center // not on any monitor, center
pos = middle() / 2.f - w->m_vRealSize.goalv() / 2.f; pos = middle() / 2.f - w->m_vRealSize.goal() / 2.f;
} else } else
pos = pos - PMONFROMMIDDLE->vecPosition + vecPosition; pos = pos - PMONFROMMIDDLE->vecPosition + vecPosition;
@ -686,6 +697,10 @@ void CMonitor::setSpecialWorkspace(CWorkspace* const pWorkspace) {
g_pHyprRenderer->damageMonitor(this); g_pHyprRenderer->damageMonitor(this);
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
g_pConfigManager->ensureVRR(this);
g_pCompositor->updateSuspendedStates(); g_pCompositor->updateSuspendedStates();
} }

View file

@ -75,6 +75,8 @@ inline const std::vector<std::string> SPLASHES = {
"Join the discord server!", "Join the discord server!",
"Thanks ThatOneCalculator!", "Thanks ThatOneCalculator!",
"The AUR packages always work, except for the times they don't.", "The AUR packages always work, except for the times they don't.",
"Funny animation compositor woo" "Funny animation compositor woo",
//
"2 years!"
// clang-format on // clang-format on
}; };

View file

@ -1,312 +0,0 @@
#include "SubsurfaceTree.hpp"
#include "../events/Events.hpp"
#include "../Compositor.hpp"
void addSurfaceGlobalOffset(SSurfaceTreeNode* node, int* lx, int* ly) {
if (!node->pSurface || !node->pSurface->exists())
return;
*lx += node->pSurface->wlr()->current.dx;
*ly += node->pSurface->wlr()->current.dy;
if (node->offsetfn) {
// This is the root node
RASSERT(!node->pSubsurface, "Node had no subsurface!");
node->offsetfn(node->globalOffsetData, lx, ly);
} else {
RASSERT(node->pSubsurface, "Node had no subsurface!");
*lx += node->pSubsurface->pSubsurface->current.x;
*ly += node->pSubsurface->pSubsurface->current.y;
addSurfaceGlobalOffset(node->pParent, lx, ly);
}
}
SSurfaceTreeNode* createTree(wlr_surface* pSurface, CWindow* pWindow) {
const auto PNODE = &SubsurfaceTree::surfaceTreeNodes.emplace_back();
if (pSurface->data)
PNODE->pSurface = (CWLSurface*)pSurface->data;
else {
PNODE->pInternalSurface = pSurface;
PNODE->pSurface = &PNODE->pInternalSurface;
}
PNODE->pWindowOwner = pWindow;
PNODE->hyprListener_newSubsurface.initCallback(&pSurface->events.new_subsurface, &Events::listener_newSubsurfaceNode, PNODE, "SurfaceTreeNode");
PNODE->hyprListener_commit.initCallback(&pSurface->events.commit, &Events::listener_commitSubsurface, PNODE, "SurfaceTreeNode");
PNODE->hyprListener_destroy.initCallback(&pSurface->events.destroy, &Events::listener_destroySubsurfaceNode, PNODE, "SurfaceTreeNode");
wlr_subsurface* wlrSubsurface;
wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_below, current.link) {
Events::listener_newSubsurfaceNode(PNODE, wlrSubsurface);
}
wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_above, current.link) {
Events::listener_newSubsurfaceNode(PNODE, wlrSubsurface);
}
return PNODE;
}
SSurfaceTreeNode* createSubsurfaceNode(SSurfaceTreeNode* pParent, SSubsurface* pSubsurface, wlr_surface* surface, CWindow* pWindow) {
const auto PNODE = createTree(surface, pWindow);
PNODE->pParent = pParent;
PNODE->pSubsurface = pSubsurface;
Debug::log(LOG, "Creating a subsurface Node! {}", pWindow);
return PNODE;
}
SSurfaceTreeNode* SubsurfaceTree::createTreeRoot(wlr_surface* pSurface, applyGlobalOffsetFn fn, void* data, CWindow* pWindow) {
const auto PNODE = createTree(pSurface, pWindow);
Debug::log(LOG, "Creating a surfaceTree Root! {}", pWindow);
PNODE->offsetfn = fn;
PNODE->globalOffsetData = data;
return PNODE;
}
void destroySubsurface(SSubsurface* pSubsurface);
void SubsurfaceTree::destroySurfaceTree(SSurfaceTreeNode* pNode) {
bool exists = false;
for (auto& n : surfaceTreeNodes) {
if (&n == pNode) {
exists = true;
break;
}
}
if (!exists) {
Debug::log(ERR, "Tried to remove a SurfaceTreeNode that doesn't exist?? (Node {:x})", (uintptr_t)pNode);
return;
}
for (auto& c : pNode->childSubsurfaces)
destroySubsurface(&c);
pNode->childSubsurfaces.clear();
pNode->hyprListener_commit.removeCallback();
pNode->hyprListener_destroy.removeCallback();
pNode->hyprListener_newSubsurface.removeCallback();
// damage
if (pNode->pSurface && pNode->pSurface->exists()) {
CBox extents = {};
wlr_surface_get_extends(pNode->pSurface->wlr(), extents.pWlr());
extents.applyFromWlr();
int lx = 0, ly = 0;
addSurfaceGlobalOffset(pNode, &lx, &ly);
extents.x += lx;
extents.y += ly;
g_pHyprRenderer->damageBox(&extents);
}
// remove references to this node
for (auto& tn : surfaceTreeNodes) {
for (auto& cs : tn.childSubsurfaces) {
if (cs.pChild == pNode)
cs.pChild = nullptr;
}
}
surfaceTreeNodes.remove(*pNode);
Debug::log(LOG, "SurfaceTree Node removed");
}
void destroySubsurface(SSubsurface* pSubsurface) {
if (pSubsurface->pChild) {
SubsurfaceTree::destroySurfaceTree(pSubsurface->pChild);
pSubsurface->pChild = nullptr;
}
pSubsurface->hyprListener_destroy.removeCallback();
pSubsurface->hyprListener_map.removeCallback();
pSubsurface->hyprListener_unmap.removeCallback();
}
//
// Subsurface listeners
//
void Events::listener_newSubsurfaceNode(void* owner, void* data) {
SSurfaceTreeNode* pNode = (SSurfaceTreeNode*)owner;
const auto PSUBSURFACE = (wlr_subsurface*)data;
const auto PNEWSUBSURFACE = &pNode->childSubsurfaces.emplace_back();
Debug::log(LOG, "Added a new subsurface {:x}", (uintptr_t)PSUBSURFACE);
PNEWSUBSURFACE->pSubsurface = PSUBSURFACE;
PNEWSUBSURFACE->pParent = pNode;
PNEWSUBSURFACE->hyprListener_map.initCallback(&PSUBSURFACE->surface->events.map, &Events::listener_mapSubsurface, PNEWSUBSURFACE, "Subsurface");
PNEWSUBSURFACE->hyprListener_unmap.initCallback(&PSUBSURFACE->surface->events.unmap, &Events::listener_unmapSubsurface, PNEWSUBSURFACE, "Subsurface");
PNEWSUBSURFACE->hyprListener_destroy.initCallback(&PSUBSURFACE->events.destroy, &Events::listener_destroySubsurface, PNEWSUBSURFACE, "Subsurface");
PNEWSUBSURFACE->pWindowOwner = pNode->pWindowOwner;
if (PSUBSURFACE->surface->mapped)
listener_mapSubsurface(PNEWSUBSURFACE, nullptr);
wlr_subsurface* existingWlrSubsurface;
wl_list_for_each(existingWlrSubsurface, &PSUBSURFACE->surface->current.subsurfaces_below, current.link) {
listener_newSubsurfaceNode(pNode, existingWlrSubsurface);
}
wl_list_for_each(existingWlrSubsurface, &PSUBSURFACE->surface->current.subsurfaces_above, current.link) {
listener_newSubsurfaceNode(pNode, existingWlrSubsurface);
}
}
void Events::listener_mapSubsurface(void* owner, void* data) {
SSubsurface* subsurface = (SSubsurface*)owner;
if (subsurface->pChild)
return;
Debug::log(LOG, "Subsurface {:x} mapped", (uintptr_t)subsurface->pSubsurface);
subsurface->pChild = createSubsurfaceNode(subsurface->pParent, subsurface, subsurface->pSubsurface->surface, subsurface->pWindowOwner);
if (subsurface->pWindowOwner)
subsurface->pWindowOwner->updateSurfaceScaleTransformDetails();
}
void Events::listener_unmapSubsurface(void* owner, void* data) {
SSubsurface* subsurface = (SSubsurface*)owner;
Debug::log(LOG, "Subsurface {:x} unmapped", (uintptr_t)subsurface);
if (subsurface->pSubsurface->surface == g_pCompositor->m_pLastFocus)
g_pInputManager->releaseAllMouseButtons();
if (subsurface->pChild) {
const auto PNODE = subsurface->pChild;
const auto IT =
std::find_if(SubsurfaceTree::surfaceTreeNodes.begin(), SubsurfaceTree::surfaceTreeNodes.end(), [&](const SSurfaceTreeNode& other) { return &other == PNODE; });
if (IT != SubsurfaceTree::surfaceTreeNodes.end()) {
if (PNODE->pSurface && PNODE->pSurface->exists()) {
int lx = 0, ly = 0;
addSurfaceGlobalOffset(PNODE, &lx, &ly);
CBox extents = {lx, ly, 0, 0};
extents.width = PNODE->pSurface->wlr()->current.width;
extents.height = PNODE->pSurface->wlr()->current.height;
g_pHyprRenderer->damageBox(&extents);
}
// SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
// subsurface->pChild = nullptr;
}
}
g_pInputManager->simulateMouseMovement(); // to focus and return back to an appropriate surface
}
void Events::listener_commitSubsurface(void* owner, void* data) {
SSurfaceTreeNode* pNode = (SSurfaceTreeNode*)owner;
// no damaging if it's not visible
if (!g_pHyprRenderer->shouldRenderWindow(pNode->pWindowOwner)) {
pNode->lastSize = pNode->pSurface->exists() ? Vector2D{pNode->pSurface->wlr()->current.width, pNode->pSurface->wlr()->current.height} : Vector2D{};
static auto* const PLOGDAMAGE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("debug:log_damage");
if (**PLOGDAMAGE)
Debug::log(LOG, "Refusing to commit damage from {} because it's invisible.", pNode->pWindowOwner);
return;
}
int lx = 0, ly = 0;
addSurfaceGlobalOffset(pNode, &lx, &ly);
const double SCALE = pNode->pWindowOwner && pNode->pWindowOwner->m_bIsX11 ? 1.0 / pNode->pWindowOwner->m_fX11SurfaceScaledBy : 1.0;
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
// What this does is that basically, if the pNode is a child of some other node, on commit,
// it will also damage (check & damage if needed) all its siblings.
if (pNode->pParent)
for (auto& cs : pNode->pParent->childSubsurfaces) {
const auto NODECOORDS = pNode->pSubsurface ? Vector2D(pNode->pSubsurface->pSubsurface->current.x, pNode->pSubsurface->pSubsurface->current.y) : Vector2D();
if (&cs != pNode->pSubsurface && cs.pSubsurface) {
g_pHyprRenderer->damageSurface(cs.pSubsurface->surface, lx - NODECOORDS.x + cs.pSubsurface->current.x, ly - NODECOORDS.y + cs.pSubsurface->current.y, SCALE);
}
}
if (pNode->pSurface && pNode->pSurface->exists()) {
g_pHyprRenderer->damageSurface(pNode->pSurface->wlr(), lx, ly, SCALE);
if (pNode->lastSize != Vector2D{pNode->pSurface->wlr()->current.width, pNode->pSurface->wlr()->current.height} && pNode->pWindowOwner)
g_pHyprRenderer->damageWindow(pNode->pWindowOwner);
}
if (pNode->pWindowOwner) {
if (pNode->pWindowOwner->m_bIsX11)
pNode->pWindowOwner->m_vReportedSize = pNode->pWindowOwner->m_vPendingReportedSize; // apply pending size. We pinged, the window ponged.
// tearing: if solitary, redraw it. This still might be a single surface window
const auto PMONITOR = g_pCompositor->getMonitorFromID(pNode->pWindowOwner->m_iMonitorID);
if (PMONITOR && PMONITOR->solitaryClient == pNode->pWindowOwner && pNode->pWindowOwner->canBeTorn() && PMONITOR->tearingState.canTear &&
pNode->pSurface->wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) {
CRegion damageBox{&pNode->pSurface->wlr()->buffer_damage};
if (!damageBox.empty()) {
if (PMONITOR->tearingState.busy) {
PMONITOR->tearingState.frameScheduledWhileBusy = true;
} else {
PMONITOR->tearingState.nextRenderTorn = true;
g_pHyprRenderer->renderMonitor(PMONITOR);
}
}
}
}
pNode->lastSize = pNode->pSurface->exists() ? Vector2D{pNode->pSurface->wlr()->current.width, pNode->pSurface->wlr()->current.height} : Vector2D{};
}
void Events::listener_destroySubsurface(void* owner, void* data) {
SSubsurface* subsurface = (SSubsurface*)owner;
if (subsurface->pChild) {
SubsurfaceTree::destroySurfaceTree(subsurface->pChild);
}
Debug::log(LOG, "Subsurface {:x} destroyed", (uintptr_t)subsurface);
subsurface->hyprListener_destroy.removeCallback();
subsurface->hyprListener_map.removeCallback();
subsurface->hyprListener_unmap.removeCallback();
subsurface->pParent->childSubsurfaces.remove(*subsurface);
}
void Events::listener_destroySubsurfaceNode(void* owner, void* data) {
SSurfaceTreeNode* pNode = (SSurfaceTreeNode*)owner;
Debug::log(LOG, "Subsurface Node {:x} destroyed", (uintptr_t)pNode);
for (auto& c : pNode->childSubsurfaces)
destroySubsurface(&c);
pNode->hyprListener_commit.removeCallback();
pNode->hyprListener_newSubsurface.removeCallback();
pNode->hyprListener_destroy.removeCallback();
SubsurfaceTree::surfaceTreeNodes.remove(*pNode);
}

View file

@ -1,60 +0,0 @@
#pragma once
#include "../defines.hpp"
#include <list>
#include "WLSurface.hpp"
struct SSubsurface;
class CWindow;
typedef void (*applyGlobalOffsetFn)(void*, int*, int*);
struct SSurfaceTreeNode {
CWLSurface* pSurface = nullptr; // actual surface
CWLSurface pInternalSurface; // not present for head nodes to not dupe wlr_surface ownership
DYNLISTENER(newSubsurface);
DYNLISTENER(commit);
DYNLISTENER(destroy);
SSurfaceTreeNode* pParent = nullptr;
SSubsurface* pSubsurface = nullptr;
std::list<SSubsurface> childSubsurfaces;
applyGlobalOffsetFn offsetfn;
void* globalOffsetData;
CWindow* pWindowOwner = nullptr;
Vector2D lastSize;
//
bool operator==(const SSurfaceTreeNode& rhs) const {
return pSurface == rhs.pSurface;
}
};
struct SSubsurface {
wlr_subsurface* pSubsurface = nullptr;
SSurfaceTreeNode* pParent = nullptr;
SSurfaceTreeNode* pChild = nullptr;
DYNLISTENER(map);
DYNLISTENER(unmap);
DYNLISTENER(destroy);
CWindow* pWindowOwner = nullptr;
//
bool operator==(const SSubsurface& rhs) const {
return pSubsurface == rhs.pSubsurface;
}
};
namespace SubsurfaceTree {
SSurfaceTreeNode* createTreeRoot(wlr_surface*, applyGlobalOffsetFn, void*, CWindow* pWindow = nullptr);
void destroySurfaceTree(SSurfaceTreeNode*);
inline std::list<SSurfaceTreeNode> surfaceTreeNodes;
};

View file

@ -3,9 +3,17 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
SLayerSurface::SLayerSurface() { SLayerSurface::SLayerSurface() {
alpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_ENTIRE); alpha.create(g_pConfigManager->getAnimationPropertyConfig("fadeLayers"), nullptr, AVARDAMAGE_ENTIRE);
realPosition.create(g_pConfigManager->getAnimationPropertyConfig("layers"), nullptr, AVARDAMAGE_ENTIRE);
realSize.create(g_pConfigManager->getAnimationPropertyConfig("layers"), nullptr, AVARDAMAGE_ENTIRE);
alpha.m_pLayer = this; alpha.m_pLayer = this;
realPosition.m_pLayer = this;
realSize.m_pLayer = this;
alpha.registerVar(); alpha.registerVar();
realPosition.registerVar();
realSize.registerVar();
alpha.setValueAndWarp(0.f);
} }
SLayerSurface::~SLayerSurface() { SLayerSurface::~SLayerSurface() {
@ -22,6 +30,7 @@ void SLayerSurface::applyRules() {
ignoreAlpha = false; ignoreAlpha = false;
ignoreAlphaValue = 0.f; ignoreAlphaValue = 0.f;
xray = -1; xray = -1;
animationStyle.reset();
for (auto& rule : g_pConfigManager->getMatchingRules(this)) { for (auto& rule : g_pConfigManager->getMatchingRules(this)) {
if (rule.rule == "noanim") if (rule.rule == "noanim")
@ -44,82 +53,193 @@ void SLayerSurface::applyRules() {
try { try {
xray = configStringToInt(vars[1]); xray = configStringToInt(vars[1]);
} catch (...) {} } catch (...) {}
} else if (rule.rule.starts_with("animation")) {
CVarList vars{rule.rule, 2, 's'};
animationStyle = vars[1];
} }
} }
} }
CRegion SConstraint::getLogicCoordsRegion() { void SLayerSurface::startAnimation(bool in, bool instant) {
CRegion result; const auto ANIMSTYLE = animationStyle.value_or(realPosition.m_pConfig->pValues->internalStyle);
if (!constraint) if (ANIMSTYLE == "slide") {
return result; // get closest edge
const auto MIDDLE = geometry.middle();
const auto PWINDOWOWNER = g_pCompositor->getWindowFromSurface(constraint->surface); const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE);
if (!PWINDOWOWNER) const std::array<Vector2D, 4> edgePoints = {
return result; PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, 0},
PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x / 2, PMONITOR->vecSize.y},
PMONITOR->vecPosition + Vector2D{0, PMONITOR->vecSize.y},
PMONITOR->vecPosition + Vector2D{PMONITOR->vecSize.x, PMONITOR->vecSize.y / 2},
};
result.add(&constraint->region); // surface-local coords float closest = std::numeric_limits<float>::max();
size_t leader = 0;
if (!PWINDOWOWNER->m_bIsX11) { for (size_t i = 0; i < 4; ++i) {
result.translate(PWINDOWOWNER->m_vRealPosition.goalv()); float dist = MIDDLE.distance(edgePoints[i]);
return result; if (dist < closest) {
leader = i;
closest = dist;
}
} }
const auto COORDS = PWINDOWOWNER->m_bIsMapped ? PWINDOWOWNER->m_vRealPosition.goalv() : realSize.setValueAndWarp(geometry.size());
g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOWOWNER->m_uSurface.xwayland->x, PWINDOWOWNER->m_uSurface.xwayland->y}); alpha.setValueAndWarp(1.f);
const auto PMONITOR = PWINDOWOWNER->m_bIsMapped ? g_pCompositor->getMonitorFromID(PWINDOWOWNER->m_iMonitorID) : g_pCompositor->getMonitorFromVector(COORDS); Vector2D prePos;
if (!PMONITOR) switch (leader) {
return CRegion{}; case 0:
// TOP
prePos = {geometry.x, PMONITOR->vecPosition.y - geometry.h};
break;
case 1:
// BOTTOM
prePos = {geometry.x, PMONITOR->vecPosition.y + PMONITOR->vecPosition.y};
break;
case 2:
// LEFT
prePos = {PMONITOR->vecPosition.x - geometry.w, geometry.y};
break;
case 3:
// RIGHT
prePos = {PMONITOR->vecPosition.x + PMONITOR->vecSize.x, geometry.y};
break;
default: UNREACHABLE();
}
result.scale(PMONITOR->xwaylandScale); if (in) {
realPosition.setValueAndWarp(prePos);
realPosition = geometry.pos();
} else {
realPosition.setValueAndWarp(geometry.pos());
realPosition = prePos;
}
result.translate(COORDS); } else if (ANIMSTYLE.starts_with("popin")) {
float minPerc = 0.f;
if (ANIMSTYLE.find("%") != std::string::npos) {
try {
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' '));
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
} catch (std::exception& e) {
; // oops
}
}
return result; minPerc *= 0.01;
const auto GOALSIZE = (geometry.size() * minPerc).clamp({5, 5});
const auto GOALPOS = geometry.pos() + (geometry.size() - GOALSIZE) / 2.f;
alpha.setValueAndWarp(in ? 0.f : 1.f);
alpha = in ? 1.f : 0.f;
if (in) {
realSize.setValueAndWarp(GOALSIZE);
realPosition.setValueAndWarp(GOALPOS);
realSize = geometry.size();
realPosition = geometry.pos();
} else {
realSize.setValueAndWarp(geometry.size());
realPosition.setValueAndWarp(geometry.pos());
realSize = GOALSIZE;
realPosition = GOALPOS;
}
} else {
// fade
realPosition.setValueAndWarp(geometry.pos());
realSize.setValueAndWarp(geometry.size());
alpha = in ? 1.f : 0.f;
}
if (!in)
fadingOut = true;
} }
Vector2D SConstraint::getLogicConstraintPos() { bool SLayerSurface::isFadedOut() {
if (!constraint) if (!fadingOut)
return {}; return false;
const auto PWINDOWOWNER = g_pCompositor->getWindowFromSurface(constraint->surface); return !realPosition.isBeingAnimated() && !realSize.isBeingAnimated() && !alpha.isBeingAnimated();
if (!PWINDOWOWNER)
return {};
if (!PWINDOWOWNER->m_bIsX11)
return PWINDOWOWNER->m_vRealPosition.goalv();
const auto COORDS = PWINDOWOWNER->m_bIsMapped ? PWINDOWOWNER->m_vRealPosition.goalv() :
g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOWOWNER->m_uSurface.xwayland->x, PWINDOWOWNER->m_uSurface.xwayland->y});
return COORDS;
} }
Vector2D SConstraint::getLogicConstraintSize() { void SKeyboard::updateXKBTranslationState(xkb_keymap* const keymap) {
if (!constraint) xkb_state_unref(xkbTranslationState);
return {};
const auto PWINDOWOWNER = g_pCompositor->getWindowFromSurface(constraint->surface); if (keymap) {
Debug::log(LOG, "Updating keyboard {:x}'s translation state from a provided keymap", (uintptr_t)this);
xkbTranslationState = xkb_state_new(keymap);
return;
}
if (!PWINDOWOWNER) const auto WLRKB = wlr_keyboard_from_input_device(keyboard);
return {}; const auto KEYMAP = WLRKB->keymap;
const auto STATE = WLRKB->xkb_state;
const auto LAYOUTSNUM = xkb_keymap_num_layouts(KEYMAP);
if (!PWINDOWOWNER->m_bIsX11) const auto PCONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
return PWINDOWOWNER->m_vRealSize.goalv();
const auto PMONITOR = PWINDOWOWNER->m_bIsMapped ? for (uint32_t i = 0; i < LAYOUTSNUM; ++i) {
g_pCompositor->getMonitorFromID(PWINDOWOWNER->m_iMonitorID) : if (xkb_state_layout_index_is_active(STATE, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
g_pCompositor->getMonitorFromVector(g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOWOWNER->m_uSurface.xwayland->x, PWINDOWOWNER->m_uSurface.xwayland->y})); Debug::log(LOG, "Updating keyboard {:x}'s translation state from an active index {}", (uintptr_t)this, i);
if (!PMONITOR) CVarList keyboardLayouts(currentRules.layout, 0, ',');
return {}; CVarList keyboardModels(currentRules.model, 0, ',');
CVarList keyboardVariants(currentRules.variant, 0, ',');
const auto SIZE = PWINDOWOWNER->m_bIsMapped ? PWINDOWOWNER->m_vRealSize.goalv() : xkb_rule_names rules = {.rules = "", .model = "", .layout = "", .variant = "", .options = ""};
Vector2D{PWINDOWOWNER->m_uSurface.xwayland->width, PWINDOWOWNER->m_uSurface.xwayland->height} * PMONITOR->xwaylandScale;
return SIZE; std::string layout, model, variant;
layout = keyboardLayouts[i % keyboardLayouts.size()];
model = keyboardModels[i % keyboardModels.size()];
variant = keyboardVariants[i % keyboardVariants.size()];
rules.layout = layout.c_str();
rules.model = model.c_str();
rules.variant = variant.c_str();
auto KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!KEYMAP) {
Debug::log(ERR, "updateXKBTranslationState: keymap failed 1, fallback without model/variant");
rules.model = "";
rules.variant = "";
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
if (!KEYMAP) {
Debug::log(ERR, "updateXKBTranslationState: keymap failed 2, fallback to us");
rules.layout = "us";
KEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
}
xkbTranslationState = xkb_state_new(KEYMAP);
xkb_keymap_unref(KEYMAP);
xkb_context_unref(PCONTEXT);
return;
}
}
Debug::log(LOG, "Updating keyboard {:x}'s translation state from an unknown index", (uintptr_t)this);
xkb_rule_names rules = {
.rules = currentRules.rules.c_str(),
.model = currentRules.model.c_str(),
.layout = currentRules.layout.c_str(),
.variant = currentRules.variant.c_str(),
.options = currentRules.options.c_str(),
};
const auto NEWKEYMAP = xkb_keymap_new_from_names(PCONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
xkbTranslationState = xkb_state_new(NEWKEYMAP);
xkb_keymap_unref(NEWKEYMAP);
xkb_context_unref(PCONTEXT);
} }

View file

@ -4,9 +4,10 @@
#include "../defines.hpp" #include "../defines.hpp"
#include "wlr-layer-shell-unstable-v1-protocol.h" #include "wlr-layer-shell-unstable-v1-protocol.h"
#include "../Window.hpp" #include "../Window.hpp"
#include "SubsurfaceTree.hpp" #include "../desktop/Subsurface.hpp"
#include "../desktop/Popup.hpp"
#include "AnimatedVariable.hpp" #include "AnimatedVariable.hpp"
#include "WLSurface.hpp" #include "../desktop/WLSurface.hpp"
#include "Region.hpp" #include "Region.hpp"
struct SLayerRule { struct SLayerRule {
@ -19,6 +20,11 @@ struct SLayerSurface {
~SLayerSurface(); ~SLayerSurface();
void applyRules(); void applyRules();
void startAnimation(bool in, bool instant = false);
bool isFadedOut();
CAnimatedVariable<Vector2D> realPosition;
CAnimatedVariable<Vector2D> realSize;
wlr_layer_surface_v1* layerSurface; wlr_layer_surface_v1* layerSurface;
wl_list link; wl_list link;
@ -26,13 +32,14 @@ struct SLayerSurface {
bool keyboardExclusive = false; bool keyboardExclusive = false;
CWLSurface surface; CWLSurface surface;
std::list<CWLSurface> popupSurfaces;
// desktop components
std::unique_ptr<CPopup> popupHead;
DYNLISTENER(destroyLayerSurface); DYNLISTENER(destroyLayerSurface);
DYNLISTENER(mapLayerSurface); DYNLISTENER(mapLayerSurface);
DYNLISTENER(unmapLayerSurface); DYNLISTENER(unmapLayerSurface);
DYNLISTENER(commitLayerSurface); DYNLISTENER(commitLayerSurface);
DYNLISTENER(newPopup);
CBox geometry = {0, 0, 0, 0}; CBox geometry = {0, 0, 0, 0};
Vector2D position; Vector2D position;
@ -44,7 +51,7 @@ struct SLayerSurface {
std::string szNamespace = ""; std::string szNamespace = "";
CAnimatedVariable alpha; CAnimatedVariable<float> alpha;
bool fadingOut = false; bool fadingOut = false;
bool readyToDelete = false; bool readyToDelete = false;
bool noProcess = false; bool noProcess = false;
@ -55,6 +62,8 @@ struct SLayerSurface {
bool ignoreAlpha = false; bool ignoreAlpha = false;
float ignoreAlphaValue = 0.f; float ignoreAlphaValue = 0.f;
std::optional<std::string> animationStyle;
// For the list lookup // For the list lookup
bool operator==(const SLayerSurface& rhs) const { bool operator==(const SLayerSurface& rhs) const {
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID; return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
@ -139,6 +148,8 @@ struct SKeyboard {
int numlockOn = -1; int numlockOn = -1;
bool resolveBindsBySym = false; bool resolveBindsBySym = false;
void updateXKBTranslationState(xkb_keymap* const keymap = nullptr);
// For the list lookup // For the list lookup
bool operator==(const SKeyboard& rhs) const { bool operator==(const SKeyboard& rhs) const {
return keyboard == rhs.keyboard; return keyboard == rhs.keyboard;
@ -148,18 +159,12 @@ struct SKeyboard {
struct SMouse { struct SMouse {
wlr_input_device* mouse = nullptr; wlr_input_device* mouse = nullptr;
wlr_pointer_constraint_v1* currentConstraint = nullptr;
bool constraintActive = false;
CRegion confinedTo;
std::string name = ""; std::string name = "";
bool virt = false; bool virt = false;
bool connected = false; // means connected to the cursor bool connected = false; // means connected to the cursor
DYNLISTENER(commitConstraint);
DYNLISTENER(destroyMouse); DYNLISTENER(destroyMouse);
bool operator==(const SMouse& b) const { bool operator==(const SMouse& b) const {
@ -167,59 +172,8 @@ struct SMouse {
} }
}; };
struct SConstraint {
SMouse* pMouse = nullptr;
wlr_pointer_constraint_v1* constraint = nullptr;
bool active = false;
bool hintSet = false;
Vector2D positionHint = {-1, -1}; // the position hint, but will use cursorPosOnActivate if unset
Vector2D cursorPosOnActivate = {-1, -1};
DYNLISTENER(setConstraintRegion);
DYNLISTENER(destroyConstraint);
CRegion getLogicCoordsRegion();
Vector2D getLogicConstraintPos();
Vector2D getLogicConstraintSize();
//
bool operator==(const SConstraint& b) const {
return constraint == b.constraint;
}
};
class CMonitor; class CMonitor;
struct SXDGPopup {
CWindow* parentWindow = nullptr;
SLayerSurface* parentLS = nullptr;
SXDGPopup* parentPopup = nullptr;
wlr_xdg_popup* popup = nullptr;
CMonitor* monitor = nullptr;
DYNLISTENER(newPopupFromPopupXDG);
DYNLISTENER(destroyPopupXDG);
DYNLISTENER(mapPopupXDG);
DYNLISTENER(unmapPopupXDG);
DYNLISTENER(commitPopupXDG);
DYNLISTENER(repositionPopupXDG);
double lx;
double ly;
Vector2D lastPos = {};
bool repositionRequested = false;
SSurfaceTreeNode* pSurfaceTree = nullptr;
// For the list lookup
bool operator==(const SXDGPopup& rhs) const {
return popup == rhs.popup;
}
};
struct SSeat { struct SSeat {
wlr_seat* seat = nullptr; wlr_seat* seat = nullptr;
wl_client* exclusiveClient = nullptr; wl_client* exclusiveClient = nullptr;
@ -410,7 +364,7 @@ struct STearingController {
DYNLISTENER(set); DYNLISTENER(set);
DYNLISTENER(destroy); DYNLISTENER(destroy);
bool operator==(const STearingController& other) { bool operator==(const STearingController& other) const {
return pWlrHint == other.pWlrHint; return pWlrHint == other.pWlrHint;
} }
}; };
@ -420,7 +374,7 @@ struct SShortcutInhibitor {
DYNLISTENER(destroy); DYNLISTENER(destroy);
bool operator==(const SShortcutInhibitor& other) { bool operator==(const SShortcutInhibitor& other) const {
return pWlrInhibitor == other.pWlrInhibitor; return pWlrInhibitor == other.pWlrInhibitor;
} }
}; };

View file

@ -1,6 +1,7 @@
#include "Watchdog.hpp" #include "Watchdog.hpp"
#include <signal.h> #include <signal.h>
#include "config/ConfigManager.hpp" #include "config/ConfigManager.hpp"
#include "../config/ConfigValue.hpp"
CWatchdog::~CWatchdog() { CWatchdog::~CWatchdog() {
m_bExitThread = true; m_bExitThread = true;
@ -13,7 +14,7 @@ CWatchdog::CWatchdog() {
m_iMainThreadPID = pthread_self(); m_iMainThreadPID = pthread_self();
m_pWatchdog = std::make_unique<std::thread>([this] { m_pWatchdog = std::make_unique<std::thread>([this] {
static auto* const PTIMEOUT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("debug:watchdog_timeout"); static auto PTIMEOUT = CConfigValue<Hyprlang::INT>("debug:watchdog_timeout");
while (1337) { while (1337) {
std::unique_lock lk(m_mWatchdogMutex); std::unique_lock lk(m_mWatchdogMutex);
@ -21,7 +22,7 @@ CWatchdog::CWatchdog() {
if (!m_bWillWatch) if (!m_bWillWatch)
m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified; }); m_cvWatchdogCondition.wait(lk, [this] { return m_bNotified; });
else { else {
if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(**PTIMEOUT * 1000.0)), [this] { return m_bNotified; }) == false) if (m_cvWatchdogCondition.wait_for(lk, std::chrono::milliseconds((int)(*PTIMEOUT * 1000.0)), [this] { return m_bNotified; }) == false)
pthread_kill(m_iMainThreadPID, SIGUSR1); pthread_kill(m_iMainThreadPID, SIGUSR1);
} }
@ -37,9 +38,9 @@ CWatchdog::CWatchdog() {
} }
void CWatchdog::startWatching() { void CWatchdog::startWatching() {
static auto* const PTIMEOUT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("debug:watchdog_timeout"); static auto PTIMEOUT = CConfigValue<Hyprlang::INT>("debug:watchdog_timeout");
if (**PTIMEOUT == 0) if (*PTIMEOUT == 0)
return; return;
m_tTriggered = std::chrono::high_resolution_clock::now(); m_tTriggered = std::chrono::high_resolution_clock::now();

View file

@ -168,3 +168,5 @@ inline wlr_xwayland_surface* wlr_xwayland_surface_try_from_wlr_surface(wlr_surfa
inline bool wlr_xwayland_or_surface_wants_focus(const wlr_xwayland_surface*) { inline bool wlr_xwayland_or_surface_wants_focus(const wlr_xwayland_surface*) {
return false; return false;
} }
inline void wlr_xwayland_set_cursor(wlr_xwayland* wlr_xwayland, uint8_t* pixels, uint32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y) {}

View file

@ -139,7 +139,7 @@ void CHyprError::draw() {
if (m_bQueuedDestroy) { if (m_bQueuedDestroy) {
if (!m_fFadeOpacity.isBeingAnimated()) { if (!m_fFadeOpacity.isBeingAnimated()) {
if (m_fFadeOpacity.fl() == 0.f) { if (m_fFadeOpacity.value() == 0.f) {
m_bQueuedDestroy = false; m_bQueuedDestroy = false;
m_tTexture.destroyTexture(); m_tTexture.destroyTexture();
m_bIsCreated = false; m_bIsCreated = false;
@ -164,7 +164,7 @@ void CHyprError::draw() {
m_bMonitorChanged = false; m_bMonitorChanged = false;
g_pHyprOpenGL->renderTexture(m_tTexture, &monbox, m_fFadeOpacity.fl(), 0); g_pHyprOpenGL->renderTexture(m_tTexture, &monbox, m_fFadeOpacity.value(), 0);
} }
void CHyprError::destroy() { void CHyprError::destroy() {

View file

@ -22,7 +22,7 @@ class CHyprError {
bool m_bQueuedDestroy = false; bool m_bQueuedDestroy = false;
bool m_bIsCreated = false; bool m_bIsCreated = false;
CTexture m_tTexture; CTexture m_tTexture;
CAnimatedVariable m_fFadeOpacity; CAnimatedVariable<float> m_fFadeOpacity;
CBox m_bDamageBox = {0, 0, 0, 0}; CBox m_bDamageBox = {0, 0, 0, 0};
bool m_bMonitorChanged = false; bool m_bMonitorChanged = false;

View file

@ -63,7 +63,6 @@ extern "C" {
#include <wlr/types/wlr_server_decoration.h> #include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_viewporter.h> #include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h> #include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_activation_v1.h> #include <wlr/types/wlr_xdg_activation_v1.h>
#include <wlr/types/wlr_xdg_decoration_v1.h> #include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h> #include <wlr/types/wlr_xdg_output_v1.h>
@ -76,6 +75,7 @@ extern "C" {
#include <wlr/types/wlr_idle_inhibit_v1.h> #include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include <wlr/util/region.h> #include <wlr/util/region.h>
#include <wlr/util/edges.h>
#include <wlr/types/wlr_tablet_pad.h> #include <wlr/types/wlr_tablet_pad.h>
#include <wlr/types/wlr_tablet_tool.h> #include <wlr/types/wlr_tablet_tool.h>
#include <wlr/types/wlr_tablet_v2.h> #include <wlr/types/wlr_tablet_v2.h>

View file

@ -1,15 +1,16 @@
#include "DwindleLayout.hpp" #include "DwindleLayout.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) { void SDwindleNodeData::recalcSizePosRecursive(bool force, bool horizontalOverride, bool verticalOverride) {
if (children[0]) { if (children[0]) {
static auto* const PSMARTSPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:smart_split"); static auto PSMARTSPLIT = CConfigValue<Hyprlang::INT>("dwindle:smart_split");
static auto* const PPRESERVESPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:preserve_split"); static auto PPRESERVESPLIT = CConfigValue<Hyprlang::INT>("dwindle:preserve_split");
static auto* const PFLMULT = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("dwindle:split_width_multiplier"); static auto PFLMULT = CConfigValue<Hyprlang::FLOAT>("dwindle:split_width_multiplier");
if (**PPRESERVESPLIT == 0 && **PSMARTSPLIT == 0) if (*PPRESERVESPLIT == 0 && *PSMARTSPLIT == 0)
splitTop = box.h * **PFLMULT > box.w; splitTop = box.h * *PFLMULT > box.w;
if (verticalOverride == true) if (verticalOverride == true)
splitTop = true; splitTop = true;
@ -127,28 +128,28 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
const auto PWINDOW = pNode->pWindow; const auto PWINDOW = pNode->pWindow;
// get specific gaps and rules for this workspace, // get specific gaps and rules for this workspace,
// if user specified them in config // if user specified them in config
const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)); const auto WORKSPACERULE = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(pNode->workspaceID));
if (!g_pCompositor->windowExists(PWINDOW)) {
Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW);
onWindowRemovedTiling(PWINDOW);
return;
}
if (PWINDOW->m_bIsFullscreen && !pNode->ignoreFullscreenChecks) if (PWINDOW->m_bIsFullscreen && !pNode->ignoreFullscreenChecks)
return; return;
PWINDOW->updateSpecialRenderData(); PWINDOW->updateSpecialRenderData();
static auto* const PNOGAPSWHENONLY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:no_gaps_when_only"); static auto PNOGAPSWHENONLY = CConfigValue<Hyprlang::INT>("dwindle:no_gaps_when_only");
static auto* const PGAPSINDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_in"); static auto PGAPSINDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_in");
static auto* const PGAPSOUTDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_out"); static auto PGAPSOUTDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_out");
auto* const PGAPSIN = (CCssGapData*)(*PGAPSINDATA)->getData(); auto* const PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData();
auto* const PGAPSOUT = (CCssGapData*)(*PGAPSOUTDATA)->getData(); auto* const PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData();
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN); auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT); auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
if (!g_pCompositor->windowExists(PWINDOW) || !PWINDOW->m_bIsMapped) {
Debug::log(ERR, "Node {} holding invalid {}!!", pNode, PWINDOW);
onWindowRemovedTiling(PWINDOW);
return;
}
CBox nodeBox = pNode->box; CBox nodeBox = pNode->box;
nodeBox.round(); nodeBox.round();
@ -157,10 +158,10 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->m_iWorkspaceID); const auto NODESONWORKSPACE = getNodesOnWorkspace(PWINDOW->m_iWorkspaceID);
if (**PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) &&
(NODESONWORKSPACE == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { (NODESONWORKSPACE == 1 || (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) {
PWINDOW->m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(**PNOGAPSWHENONLY == 2); PWINDOW->m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(*PNOGAPSWHENONLY == 2);
PWINDOW->m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true); PWINDOW->m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true);
PWINDOW->m_sSpecialRenderData.rounding = false; PWINDOW->m_sSpecialRenderData.rounding = false;
PWINDOW->m_sSpecialRenderData.shadow = false; PWINDOW->m_sSpecialRenderData.shadow = false;
@ -172,7 +173,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + RESERVED.topLeft; PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + RESERVED.topLeft;
PWINDOW->m_vRealSize = PWINDOW->m_vSize - (RESERVED.topLeft + RESERVED.bottomRight); PWINDOW->m_vRealSize = PWINDOW->m_vSize - (RESERVED.topLeft + RESERVED.bottomRight);
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
return; return;
} }
@ -215,11 +216,11 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode, bool for
calcPos = calcPos + RESERVED.topLeft; calcPos = calcPos + RESERVED.topLeft;
calcSize = calcSize - (RESERVED.topLeft + RESERVED.bottomRight); calcSize = calcSize - (RESERVED.topLeft + RESERVED.bottomRight);
if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID)) { if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && !PWINDOW->m_bIsFullscreen) {
// if special, we adjust the coords a bit // if special, we adjust the coords a bit
static auto* const PSCALEFACTOR = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("dwindle:special_scale_factor"); static auto PSCALEFACTOR = CConfigValue<Hyprlang::FLOAT>("dwindle:special_scale_factor");
CBox wb = {calcPos + (calcSize - calcSize * **PSCALEFACTOR) / 2.f, calcSize * **PSCALEFACTOR}; CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR};
wb.round(); // avoid rounding mess wb.round(); // avoid rounding mess
PWINDOW->m_vRealPosition = wb.pos(); PWINDOW->m_vRealPosition = wb.pos();
@ -257,8 +258,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
static auto* const PUSEACTIVE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:use_active_for_splits"); static auto PUSEACTIVE = CConfigValue<Hyprlang::INT>("dwindle:use_active_for_splits");
static auto* const PDEFAULTSPLIT = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("dwindle:default_split_ratio"); static auto PDEFAULTSPLIT = CConfigValue<Hyprlang::FLOAT>("dwindle:default_split_ratio");
if (direction != DIRECTION_DEFAULT && overrideDirection == DIRECTION_DEFAULT) if (direction != DIRECTION_DEFAULT && overrideDirection == DIRECTION_DEFAULT)
overrideDirection = direction; overrideDirection = direction;
@ -275,13 +276,13 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
const auto MONFROMCURSOR = g_pCompositor->getMonitorFromVector(MOUSECOORDS); const auto MONFROMCURSOR = g_pCompositor->getMonitorFromVector(MOUSECOORDS);
if (PMONITOR->ID == MONFROMCURSOR->ID && if (PMONITOR->ID == MONFROMCURSOR->ID &&
(PNODE->workspaceID == PMONITOR->activeWorkspace || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->specialWorkspaceID)) && !**PUSEACTIVE) { (PNODE->workspaceID == PMONITOR->activeWorkspace || (g_pCompositor->isWorkspaceSpecial(PNODE->workspaceID) && PMONITOR->specialWorkspaceID)) && !*PUSEACTIVE) {
OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS)); OPENINGON = getNodeFromWindow(g_pCompositor->vectorToWindowUnified(MOUSECOORDS, RESERVED_EXTENTS | INPUT_EXTENTS));
if (!OPENINGON && g_pCompositor->isPointOnReservedArea(MOUSECOORDS, PMONITOR)) if (!OPENINGON && g_pCompositor->isPointOnReservedArea(MOUSECOORDS, PMONITOR))
OPENINGON = getClosestNodeOnWorkspace(PNODE->workspaceID, MOUSECOORDS); OPENINGON = getClosestNodeOnWorkspace(PNODE->workspaceID, MOUSECOORDS);
} else if (**PUSEACTIVE) { } else if (*PUSEACTIVE) {
if (g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow && if (g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsFloating && g_pCompositor->m_pLastWindow != pWindow &&
g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) { g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID && g_pCompositor->m_pLastWindow->m_bIsMapped) {
OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow); OPENINGON = getNodeFromWindow(g_pCompositor->m_pLastWindow);
@ -343,8 +344,8 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
&& pWindow->canBeGroupedInto(OPENINGON->pWindow) && !m_vOverrideFocalPoint) { // we are not moving window && pWindow->canBeGroupedInto(OPENINGON->pWindow) && !m_vOverrideFocalPoint) { // we are not moving window
m_lDwindleNodesData.remove(*PNODE); m_lDwindleNodesData.remove(*PNODE);
static const auto* USECURRPOS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("group:insert_after_current"); static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(**USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow); (*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow);
OPENINGON->pWindow->setGroupCurrent(pWindow); OPENINGON->pWindow->setGroupCurrent(pWindow);
pWindow->applyGroupRules(); pWindow->applyGroupRules();
@ -367,17 +368,17 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
NEWPARENT->workspaceID = OPENINGON->workspaceID; NEWPARENT->workspaceID = OPENINGON->workspaceID;
NEWPARENT->pParent = OPENINGON->pParent; NEWPARENT->pParent = OPENINGON->pParent;
NEWPARENT->isNode = true; // it is a node NEWPARENT->isNode = true; // it is a node
NEWPARENT->splitRatio = std::clamp(**PDEFAULTSPLIT, 0.1f, 1.9f); NEWPARENT->splitRatio = std::clamp(*PDEFAULTSPLIT, 0.1f, 1.9f);
const auto PWIDTHMULTIPLIER = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("dwindle:split_width_multiplier"); static auto PWIDTHMULTIPLIER = CConfigValue<Hyprlang::FLOAT>("dwindle:split_width_multiplier");
// if cursor over first child, make it first, etc // if cursor over first child, make it first, etc
const auto SIDEBYSIDE = NEWPARENT->box.w > NEWPARENT->box.h * **PWIDTHMULTIPLIER; const auto SIDEBYSIDE = NEWPARENT->box.w > NEWPARENT->box.h * *PWIDTHMULTIPLIER;
NEWPARENT->splitTop = !SIDEBYSIDE; NEWPARENT->splitTop = !SIDEBYSIDE;
static auto* const PFORCESPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:force_split"); static auto PFORCESPLIT = CConfigValue<Hyprlang::INT>("dwindle:force_split");
static auto* const PERMANENTDIRECTIONOVERRIDE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:permanent_direction_override"); static auto PERMANENTDIRECTIONOVERRIDE = CConfigValue<Hyprlang::INT>("dwindle:permanent_direction_override");
static auto* const PSMARTSPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:smart_split"); static auto PSMARTSPLIT = CConfigValue<Hyprlang::INT>("dwindle:smart_split");
bool horizontalOverride = false; bool horizontalOverride = false;
bool verticalOverride = false; bool verticalOverride = false;
@ -401,9 +402,9 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
} }
// whether or not the override persists after opening one window // whether or not the override persists after opening one window
if (**PERMANENTDIRECTIONOVERRIDE == 0) if (*PERMANENTDIRECTIONOVERRIDE == 0)
overrideDirection = DIRECTION_DEFAULT; overrideDirection = DIRECTION_DEFAULT;
} else if (**PSMARTSPLIT == 1) { } else if (*PSMARTSPLIT == 1) {
const auto PARENT_CENTER = NEWPARENT->box.pos() + NEWPARENT->box.size() / 2; const auto PARENT_CENTER = NEWPARENT->box.pos() + NEWPARENT->box.size() / 2;
const auto PARENT_PROPORTIONS = NEWPARENT->box.h / NEWPARENT->box.w; const auto PARENT_PROPORTIONS = NEWPARENT->box.h / NEWPARENT->box.w;
const auto DELTA = MOUSECOORDS - PARENT_CENTER; const auto DELTA = MOUSECOORDS - PARENT_CENTER;
@ -434,11 +435,11 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
NEWPARENT->children[1] = OPENINGON; NEWPARENT->children[1] = OPENINGON;
} }
} }
} else if (**PFORCESPLIT == 0 || !pWindow->m_bFirstMap) { } else if (*PFORCESPLIT == 0 || !pWindow->m_bFirstMap) {
if ((SIDEBYSIDE && if ((SIDEBYSIDE &&
VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / **PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w / 2.f, NEWPARENT->box.y + NEWPARENT->box.h)) || VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / *PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w / 2.f, NEWPARENT->box.y + NEWPARENT->box.h)) ||
(!SIDEBYSIDE && (!SIDEBYSIDE &&
VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / **PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w, NEWPARENT->box.y + NEWPARENT->box.h / 2.f))) { VECINRECT(MOUSECOORDS, NEWPARENT->box.x, NEWPARENT->box.y / *PWIDTHMULTIPLIER, NEWPARENT->box.x + NEWPARENT->box.w, NEWPARENT->box.y + NEWPARENT->box.h / 2.f))) {
// we are hovering over the first node, make PNODE first. // we are hovering over the first node, make PNODE first.
NEWPARENT->children[1] = OPENINGON; NEWPARENT->children[1] = OPENINGON;
NEWPARENT->children[0] = PNODE; NEWPARENT->children[0] = PNODE;
@ -448,7 +449,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
NEWPARENT->children[1] = PNODE; NEWPARENT->children[1] = PNODE;
} }
} else { } else {
if (**PFORCESPLIT == 1) { if (*PFORCESPLIT == 1) {
NEWPARENT->children[1] = OPENINGON; NEWPARENT->children[1] = OPENINGON;
NEWPARENT->children[0] = PNODE; NEWPARENT->children[0] = PNODE;
} else { } else {
@ -467,7 +468,7 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection dire
} }
// Update the children // Update the children
if (!verticalOverride && (NEWPARENT->box.w * **PWIDTHMULTIPLIER > NEWPARENT->box.h || horizontalOverride)) { if (!verticalOverride && (NEWPARENT->box.w * *PWIDTHMULTIPLIER > NEWPARENT->box.h || horizontalOverride)) {
// split left/right -> forced // split left/right -> forced
OPENINGON->box = {NEWPARENT->box.pos(), Vector2D(NEWPARENT->box.w / 2.f, NEWPARENT->box.h)}; OPENINGON->box = {NEWPARENT->box.pos(), Vector2D(NEWPARENT->box.w / 2.f, NEWPARENT->box.h)};
PNODE->box = {Vector2D(NEWPARENT->box.x + NEWPARENT->box.w / 2.f, NEWPARENT->box.y), Vector2D(NEWPARENT->box.w / 2.f, NEWPARENT->box.h)}; PNODE->box = {Vector2D(NEWPARENT->box.x + NEWPARENT->box.w / 2.f, NEWPARENT->box.y), Vector2D(NEWPARENT->box.w / 2.f, NEWPARENT->box.h)};
@ -548,6 +549,27 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
g_pHyprRenderer->damageMonitor(PMONITOR); g_pHyprRenderer->damageMonitor(PMONITOR);
if (PMONITOR->specialWorkspaceID) { if (PMONITOR->specialWorkspaceID) {
const auto PSPECIALWS = g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID);
if (PSPECIALWS->m_bHasFullscreenWindow) {
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PSPECIALWS->m_iID);
if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_FULL) {
PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition;
PFULLWINDOW->m_vRealSize = PMONITOR->vecSize;
} else if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
SDwindleNodeData fakeNode;
fakeNode.pWindow = PFULLWINDOW;
fakeNode.box = {PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft, PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight};
fakeNode.workspaceID = PSPECIALWS->m_iID;
PFULLWINDOW->m_vPosition = fakeNode.box.pos();
PFULLWINDOW->m_vSize = fakeNode.box.size();
fakeNode.ignoreFullscreenChecks = true;
applyNodeDataToWindow(&fakeNode);
}
}
const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->specialWorkspaceID); const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->specialWorkspaceID);
if (TOPNODE && PMONITOR) { if (TOPNODE && PMONITOR) {
@ -606,13 +628,13 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
const auto PNODE = getNodeFromWindow(PWINDOW); const auto PNODE = getNodeFromWindow(PWINDOW);
if (!PNODE) { if (!PNODE) {
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goalv() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goalv() + pixResize).y, 20.0)); PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0));
PWINDOW->updateWindowDecos(); PWINDOW->updateWindowDecos();
return; return;
} }
const auto PANIMATE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes"); static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
const auto PSMARTRESIZING = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("dwindle:smart_resizing"); static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("dwindle:smart_resizing");
// get some data about our window // get some data about our window
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
@ -625,7 +647,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (!m_PseudoDragFlags.started) { if (!m_PseudoDragFlags.started) {
m_PseudoDragFlags.started = true; m_PseudoDragFlags.started = true;
const auto pseudoSize = PWINDOW->m_vRealSize.goalv(); const auto pseudoSize = PWINDOW->m_vRealSize.goal();
const auto mouseOffset = g_pInputManager->getMouseCoordsInternal() - (PNODE->box.pos() + ((PNODE->box.size() / 2) - (pseudoSize / 2))); const auto mouseOffset = g_pInputManager->getMouseCoordsInternal() - (PNODE->box.pos() + ((PNODE->box.size() / 2) - (pseudoSize / 2)));
if (mouseOffset.x > 0 && mouseOffset.x < pseudoSize.x && mouseOffset.y > 0 && mouseOffset.y < pseudoSize.y) { if (mouseOffset.x > 0 && mouseOffset.x < pseudoSize.x && mouseOffset.y > 0 && mouseOffset.y < pseudoSize.y) {
@ -655,7 +677,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
PWINDOW->m_vPseudoSize = {std::clamp(PWINDOW->m_vPseudoSize.x, 30.0, wbox.w), std::clamp(PWINDOW->m_vPseudoSize.y, 30.0, wbox.h)}; PWINDOW->m_vPseudoSize = {std::clamp(PWINDOW->m_vPseudoSize.x, 30.0, wbox.w), std::clamp(PWINDOW->m_vPseudoSize.y, 30.0, wbox.h)};
PWINDOW->m_vLastFloatingSize = PWINDOW->m_vPseudoSize; PWINDOW->m_vLastFloatingSize = PWINDOW->m_vPseudoSize;
PNODE->recalcSizePosRecursive(**PANIMATE == 0); PNODE->recalcSizePosRecursive(*PANIMATE == 0);
return; return;
} }
@ -669,7 +691,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (DISPLAYBOTTOM && DISPLAYTOP) if (DISPLAYBOTTOM && DISPLAYTOP)
allowedMovement.y = 0; allowedMovement.y = 0;
if (**PSMARTRESIZING == 1) { if (*PSMARTRESIZING == 1) {
// Identify inner and outer nodes for both directions // Identify inner and outer nodes for both directions
SDwindleNodeData* PVOUTER = nullptr; SDwindleNodeData* PVOUTER = nullptr;
SDwindleNodeData* PVINNER = nullptr; SDwindleNodeData* PVINNER = nullptr;
@ -703,14 +725,14 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (PHINNER) { if (PHINNER) {
const auto ORIGINAL = PHINNER->box.w; const auto ORIGINAL = PHINNER->box.w;
PHOUTER->pParent->recalcSizePosRecursive(**PANIMATE == 0); PHOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
if (PHINNER->pParent->children[0] == PHINNER) if (PHINNER->pParent->children[0] == PHINNER)
PHINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.x) / PHINNER->pParent->box.w * 2.f, 0.1, 1.9); PHINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.x) / PHINNER->pParent->box.w * 2.f, 0.1, 1.9);
else else
PHINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.x) / PHINNER->pParent->box.w * 2.f, 0.1, 1.9); PHINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.x) / PHINNER->pParent->box.w * 2.f, 0.1, 1.9);
PHINNER->pParent->recalcSizePosRecursive(**PANIMATE == 0); PHINNER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
} else } else
PHOUTER->pParent->recalcSizePosRecursive(**PANIMATE == 0); PHOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
} }
if (PVOUTER) { if (PVOUTER) {
@ -718,14 +740,14 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (PVINNER) { if (PVINNER) {
const auto ORIGINAL = PVINNER->box.h; const auto ORIGINAL = PVINNER->box.h;
PVOUTER->pParent->recalcSizePosRecursive(**PANIMATE == 0); PVOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
if (PVINNER->pParent->children[0] == PVINNER) if (PVINNER->pParent->children[0] == PVINNER)
PVINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.y) / PVINNER->pParent->box.h * 2.f, 0.1, 1.9); PVINNER->pParent->splitRatio = std::clamp((ORIGINAL - allowedMovement.y) / PVINNER->pParent->box.h * 2.f, 0.1, 1.9);
else else
PVINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.y) / PVINNER->pParent->box.h * 2.f, 0.1, 1.9); PVINNER->pParent->splitRatio = std::clamp(2 - (ORIGINAL + allowedMovement.y) / PVINNER->pParent->box.h * 2.f, 0.1, 1.9);
PVINNER->pParent->recalcSizePosRecursive(**PANIMATE == 0); PVINNER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
} else } else
PVOUTER->pParent->recalcSizePosRecursive(**PANIMATE == 0); PVOUTER->pParent->recalcSizePosRecursive(*PANIMATE == 0);
} }
} else { } else {
// get the correct containers to apply splitratio to // get the correct containers to apply splitratio to
@ -744,11 +766,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (PARENTSIDEBYSIDE) { if (PARENTSIDEBYSIDE) {
allowedMovement.x *= 2.f / PPARENT->box.w; allowedMovement.x *= 2.f / PPARENT->box.w;
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9); PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9);
PPARENT->recalcSizePosRecursive(**PANIMATE == 0); PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
} else { } else {
allowedMovement.y *= 2.f / PPARENT->box.h; allowedMovement.y *= 2.f / PPARENT->box.h;
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9); PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
PPARENT->recalcSizePosRecursive(**PANIMATE == 0); PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
} }
return; return;
@ -763,11 +785,11 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
if (PARENTSIDEBYSIDE) { if (PARENTSIDEBYSIDE) {
allowedMovement.x *= 2.f / PPARENT->box.w; allowedMovement.x *= 2.f / PPARENT->box.w;
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9); PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.x, 0.1, 1.9);
PPARENT->recalcSizePosRecursive(**PANIMATE == 0); PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
} else { } else {
allowedMovement.y *= 2.f / PPARENT->box.h; allowedMovement.y *= 2.f / PPARENT->box.h;
PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9); PPARENT->splitRatio = std::clamp(PPARENT->splitRatio + allowedMovement.y, 0.1, 1.9);
PPARENT->recalcSizePosRecursive(**PANIMATE == 0); PPARENT->recalcSizePosRecursive(*PANIMATE == 0);
} }
return; return;
@ -782,8 +804,8 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorn
SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, 0.1, 1.9); SIDECONTAINER->splitRatio = std::clamp(SIDECONTAINER->splitRatio + allowedMovement.x, 0.1, 1.9);
TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, 0.1, 1.9); TOPCONTAINER->splitRatio = std::clamp(TOPCONTAINER->splitRatio + allowedMovement.y, 0.1, 1.9);
SIDECONTAINER->recalcSizePosRecursive(**PANIMATE == 0); SIDECONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
TOPCONTAINER->recalcSizePosRecursive(**PANIMATE == 0); TOPCONTAINER->recalcSizePosRecursive(*PANIMATE == 0);
} }
} }
@ -791,7 +813,7 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
if (!g_pCompositor->windowValidMapped(pWindow)) if (!g_pCompositor->windowValidMapped(pWindow))
return; return;
if (on == pWindow->m_bIsFullscreen || g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) if (on == pWindow->m_bIsFullscreen)
return; // ignore return; // ignore
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
@ -805,10 +827,10 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
// save position and size if floating // save position and size if floating
if (pWindow->m_bIsFloating && on) { if (pWindow->m_bIsFloating && on) {
pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goalv(); pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goal();
pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goalv(); pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goal();
pWindow->m_vPosition = pWindow->m_vRealPosition.goalv(); pWindow->m_vPosition = pWindow->m_vRealPosition.goal();
pWindow->m_vSize = pWindow->m_vRealSize.goalv(); pWindow->m_vSize = pWindow->m_vRealSize.goal();
} }
// otherwise, accept it. // otherwise, accept it.
@ -853,14 +875,15 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
fakeNode.workspaceID = pWindow->m_iWorkspaceID; fakeNode.workspaceID = pWindow->m_iWorkspaceID;
pWindow->m_vPosition = fakeNode.box.pos(); pWindow->m_vPosition = fakeNode.box.pos();
pWindow->m_vSize = fakeNode.box.size(); pWindow->m_vSize = fakeNode.box.size();
fakeNode.ignoreFullscreenChecks = true;
applyNodeDataToWindow(&fakeNode, true); applyNodeDataToWindow(&fakeNode);
} }
} }
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal());
g_pCompositor->changeWindowZOrder(pWindow, true); g_pCompositor->changeWindowZOrder(pWindow, true);
@ -940,9 +963,16 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
auto PNODE = getNodeFromWindow(pWindow); auto PNODE = getNodeFromWindow(pWindow);
auto PNODE2 = getNodeFromWindow(pWindow2); auto PNODE2 = getNodeFromWindow(pWindow2);
if (!PNODE2 || !PNODE) { if (!PNODE2 || !PNODE)
return; return;
}
const bool FS1 = pWindow->m_bIsFullscreen;
const bool FS2 = pWindow2->m_bIsFullscreen;
if (FS1)
g_pCompositor->setWindowFullscreen(pWindow, false);
if (FS2)
g_pCompositor->setWindowFullscreen(pWindow2, false);
SDwindleNodeData* ACTIVE1 = nullptr; SDwindleNodeData* ACTIVE1 = nullptr;
SDwindleNodeData* ACTIVE2 = nullptr; SDwindleNodeData* ACTIVE2 = nullptr;
@ -959,9 +989,8 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
// recalc the workspace // recalc the workspace
getMasterNodeOnWorkspace(PNODE->workspaceID)->recalcSizePosRecursive(); getMasterNodeOnWorkspace(PNODE->workspaceID)->recalcSizePosRecursive();
if (PNODE2->workspaceID != PNODE->workspaceID) { if (PNODE2->workspaceID != PNODE->workspaceID)
getMasterNodeOnWorkspace(PNODE2->workspaceID)->recalcSizePosRecursive(); getMasterNodeOnWorkspace(PNODE2->workspaceID)->recalcSizePosRecursive();
}
if (ACTIVE1) { if (ACTIVE1) {
ACTIVE1->box = PNODE->box; ACTIVE1->box = PNODE->box;
@ -977,6 +1006,11 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
g_pHyprRenderer->damageWindow(pWindow); g_pHyprRenderer->damageWindow(pWindow);
g_pHyprRenderer->damageWindow(pWindow2); g_pHyprRenderer->damageWindow(pWindow2);
if (FS1)
g_pCompositor->setWindowFullscreen(pWindow2, true);
if (FS2)
g_pCompositor->setWindowFullscreen(pWindow, true);
} }
void CHyprDwindleLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) { void CHyprDwindleLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) {
@ -1093,3 +1127,48 @@ void CHyprDwindleLayout::onEnable() {
void CHyprDwindleLayout::onDisable() { void CHyprDwindleLayout::onDisable() {
m_lDwindleNodesData.clear(); m_lDwindleNodesData.clear();
} }
Vector2D CHyprDwindleLayout::predictSizeForNewWindow() {
if (!g_pCompositor->m_pLastMonitor)
return {};
// get window candidate
CWindow* candidate = g_pCompositor->m_pLastWindow;
if (!candidate)
candidate = g_pCompositor->getFirstWindowOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
// create a fake node
SDwindleNodeData node;
if (!candidate)
return g_pCompositor->m_pLastMonitor->vecSize;
else {
const auto PNODE = getNodeFromWindow(candidate);
if (!PNODE)
return {};
node = *PNODE;
node.pWindow = nullptr;
CBox box = PNODE->box;
static auto PFLMULT = CConfigValue<Hyprlang::FLOAT>("dwindle:split_width_multiplier");
bool splitTop = box.h * *PFLMULT > box.w;
const auto SPLITSIDE = !splitTop;
if (SPLITSIDE)
node.box = {{}, {box.w / 2.0, box.h}};
else
node.box = {{}, {box.w, box.h / 2.0}};
// TODO: make this better and more accurate
return node.box.size();
}
return {};
}

View file

@ -59,6 +59,7 @@ class CHyprDwindleLayout : public IHyprLayout {
virtual void alterSplitRatio(CWindow*, float, bool); virtual void alterSplitRatio(CWindow*, float, bool);
virtual std::string getLayoutName(); virtual std::string getLayoutName();
virtual void replaceWindowDataWith(CWindow* from, CWindow* to); virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
virtual Vector2D predictSizeForNewWindow();
virtual void onEnable(); virtual void onEnable();
virtual void onDisable(); virtual void onDisable();

View file

@ -2,6 +2,7 @@
#include "../defines.hpp" #include "../defines.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "../config/ConfigValue.hpp"
void IHyprLayout::onWindowCreated(CWindow* pWindow, eDirection direction) { void IHyprLayout::onWindowCreated(CWindow* pWindow, eDirection direction) {
if (pWindow->m_bIsFloating) { if (pWindow->m_bIsFloating) {
@ -87,7 +88,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
desiredGeometry.y = xy.y; desiredGeometry.y = xy.y;
} }
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
if (!PMONITOR) { if (!PMONITOR) {
Debug::log(ERR, "{:m} has an invalid monitor in onWindowCreatedFloating!!!", pWindow); Debug::log(ERR, "{:m} has an invalid monitor in onWindowCreatedFloating!!!", pWindow);
@ -105,7 +106,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
} }
// reject any windows with size <= 5x5 // reject any windows with size <= 5x5
if (pWindow->m_vRealSize.goalv().x <= 5 || pWindow->m_vRealSize.goalv().y <= 5) if (pWindow->m_vRealSize.goal().x <= 5 || pWindow->m_vRealSize.goal().y <= 5)
pWindow->m_vRealSize = PMONITOR->vecSize / 2.f; pWindow->m_vRealSize = PMONITOR->vecSize / 2.f;
if (pWindow->m_bIsX11 && pWindow->m_uSurface.xwayland->override_redirect) { if (pWindow->m_bIsX11 && pWindow->m_uSurface.xwayland->override_redirect) {
@ -113,11 +114,11 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
if (pWindow->m_uSurface.xwayland->x != 0 && pWindow->m_uSurface.xwayland->y != 0) if (pWindow->m_uSurface.xwayland->x != 0 && pWindow->m_uSurface.xwayland->y != 0)
pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords({pWindow->m_uSurface.xwayland->x, pWindow->m_uSurface.xwayland->y}); pWindow->m_vRealPosition = g_pXWaylandManager->xwaylandToWaylandCoords({pWindow->m_uSurface.xwayland->x, pWindow->m_uSurface.xwayland->y});
else else
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goalv().x) / 2.f, pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f,
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goalv().y) / 2.f); PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f);
} else { } else {
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goalv().x) / 2.f, pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.goal().x) / 2.f,
PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goalv().y) / 2.f); PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.goal().y) / 2.f);
} }
} else { } else {
// we respect the size. // we respect the size.
@ -151,8 +152,8 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
} }
} }
if (**PXWLFORCESCALEZERO && pWindow->m_bIsX11) if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11)
pWindow->m_vRealSize = pWindow->m_vRealSize.goalv() / PMONITOR->scale; pWindow->m_vRealSize = pWindow->m_vRealSize.goal() / PMONITOR->scale;
if (pWindow->m_bX11DoesntWantBorders || (pWindow->m_bIsX11 && pWindow->m_uSurface.xwayland->override_redirect)) { if (pWindow->m_bX11DoesntWantBorders || (pWindow->m_bIsX11 && pWindow->m_uSurface.xwayland->override_redirect)) {
pWindow->m_vRealPosition.warp(); pWindow->m_vRealPosition.warp();
@ -160,11 +161,11 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
} }
if (pWindow->m_iX11Type != 2) { if (pWindow->m_iX11Type != 2) {
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal());
g_pCompositor->changeWindowZOrder(pWindow, true); g_pCompositor->changeWindowZOrder(pWindow, true);
} else { } else {
pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goalv(); pWindow->m_vPendingReportedSize = pWindow->m_vRealSize.goal();
pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize; pWindow->m_vReportedSize = pWindow->m_vPendingReportedSize;
} }
} }
@ -172,6 +173,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
void IHyprLayout::onBeginDragWindow() { void IHyprLayout::onBeginDragWindow() {
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow; const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
m_iMouseMoveEventCount = 1;
m_vBeginDragSizeXY = Vector2D(); m_vBeginDragSizeXY = Vector2D();
// Window will be floating. Let's check if it's valid. It should be, but I don't like crashing. // Window will be floating. Let's check if it's valid. It should be, but I don't like crashing.
@ -200,22 +202,42 @@ void IHyprLayout::onBeginDragWindow() {
if (!DRAGGINGWINDOW->m_bIsFloating) { if (!DRAGGINGWINDOW->m_bIsFloating) {
if (g_pInputManager->dragMode == MBIND_MOVE) { if (g_pInputManager->dragMode == MBIND_MOVE) {
DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize.goalv() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor(); DRAGGINGWINDOW->m_vLastFloatingSize = (DRAGGINGWINDOW->m_vRealSize.goal() * 0.8489).clamp(Vector2D{5, 5}, Vector2D{}).floor();
changeWindowFloatingMode(DRAGGINGWINDOW); changeWindowFloatingMode(DRAGGINGWINDOW);
DRAGGINGWINDOW->m_bIsFloating = true; DRAGGINGWINDOW->m_bIsFloating = true;
DRAGGINGWINDOW->m_bDraggingTiled = true; DRAGGINGWINDOW->m_bDraggingTiled = true;
DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize.goalv() / 2.f; DRAGGINGWINDOW->m_vRealPosition = g_pInputManager->getMouseCoordsInternal() - DRAGGINGWINDOW->m_vRealSize.goal() / 2.f;
} }
} }
m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal(); m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal();
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.goalv(); m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.goal();
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goalv(); m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.goal();
m_vLastDragXY = m_vBeginDragXY; m_vLastDragXY = m_vBeginDragXY;
// get the grab corner // get the grab corner
if (m_vBeginDragXY.x < m_vBeginDragPositionXY.x + m_vBeginDragSizeXY.x / 2.0) { static auto RESIZECORNER = CConfigValue<Hyprlang::INT>("general:resize_corner");
if (*RESIZECORNER != 0 && *RESIZECORNER <= 4 && DRAGGINGWINDOW->m_bIsFloating) {
switch (*RESIZECORNER) {
case 1:
m_eGrabbedCorner = CORNER_TOPLEFT;
g_pInputManager->setCursorImageUntilUnset("nw-resize");
break;
case 2:
m_eGrabbedCorner = CORNER_TOPRIGHT;
g_pInputManager->setCursorImageUntilUnset("ne-resize");
break;
case 3:
m_eGrabbedCorner = CORNER_BOTTOMRIGHT;
g_pInputManager->setCursorImageUntilUnset("se-resize");
break;
case 4:
m_eGrabbedCorner = CORNER_BOTTOMLEFT;
g_pInputManager->setCursorImageUntilUnset("sw-resize");
break;
}
} else if (m_vBeginDragXY.x < m_vBeginDragPositionXY.x + m_vBeginDragSizeXY.x / 2.0) {
if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0) { if (m_vBeginDragXY.y < m_vBeginDragPositionXY.y + m_vBeginDragSizeXY.y / 2.0) {
m_eGrabbedCorner = CORNER_TOPLEFT; m_eGrabbedCorner = CORNER_TOPLEFT;
g_pInputManager->setCursorImageUntilUnset("nw-resize"); g_pInputManager->setCursorImageUntilUnset("nw-resize");
@ -247,6 +269,8 @@ void IHyprLayout::onBeginDragWindow() {
void IHyprLayout::onEndDragWindow() { void IHyprLayout::onEndDragWindow() {
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow; const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
m_iMouseMoveEventCount = 1;
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW)) { if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW)) {
if (DRAGGINGWINDOW) { if (DRAGGINGWINDOW) {
g_pInputManager->unsetCursorImage(); g_pInputManager->unsetCursorImage();
@ -275,8 +299,8 @@ void IHyprLayout::onEndDragWindow() {
return; return;
if (pWindow->m_sGroupData.pNextWindow && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) { if (pWindow->m_sGroupData.pNextWindow && DRAGGINGWINDOW->canBeGroupedInto(pWindow)) {
static const auto* USECURRPOS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("group:insert_after_current"); static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(**USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW); (*USECURRPOS ? pWindow : pWindow->getGroupTail())->insertWindowToGroup(DRAGGINGWINDOW);
pWindow->setGroupCurrent(DRAGGINGWINDOW); pWindow->setGroupCurrent(DRAGGINGWINDOW);
DRAGGINGWINDOW->updateWindowDecos(); DRAGGINGWINDOW->updateWindowDecos();
@ -302,19 +326,36 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
return; return;
} }
static auto TIMER = std::chrono::high_resolution_clock::now(); static auto TIMER = std::chrono::high_resolution_clock::now(), MSTIMER = TIMER;
const auto SPECIAL = g_pCompositor->isWorkspaceSpecial(DRAGGINGWINDOW->m_iWorkspaceID); const auto SPECIAL = g_pCompositor->isWorkspaceSpecial(DRAGGINGWINDOW->m_iWorkspaceID);
const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y); const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y);
const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y); const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y);
static auto* const PANIMATEMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:animate_mouse_windowdragging"); static auto PANIMATEMOUSE = CConfigValue<Hyprlang::INT>("misc:animate_mouse_windowdragging");
static auto* const PANIMATE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes"); static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
if ((abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f) || const auto TIMERDELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - TIMER).count();
(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - TIMER).count() < const auto MSDELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - MSTIMER).count();
1000.0 / g_pHyprRenderer->m_pMostHzMonitor->refreshRate)) const auto MSMONITOR = 1000.0 / g_pHyprRenderer->m_pMostHzMonitor->refreshRate;
static int totalMs = 0;
bool canSkipUpdate = true;
MSTIMER = std::chrono::high_resolution_clock::now();
if (m_iMouseMoveEventCount == 1)
totalMs = 0;
if (MSMONITOR > 16.0) {
totalMs += MSDELTA < MSMONITOR ? MSDELTA : std::round(totalMs * 1.0 / m_iMouseMoveEventCount);
m_iMouseMoveEventCount += 1;
// check if time-window is enough to skip update on 60hz monitor
canSkipUpdate = std::clamp(MSMONITOR - TIMERDELTA, 0.0, MSMONITOR) > totalMs * 1.0 / m_iMouseMoveEventCount;
}
if ((abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f) || (TIMERDELTA < MSMONITOR && canSkipUpdate))
return; return;
TIMER = std::chrono::high_resolution_clock::now(); TIMER = std::chrono::high_resolution_clock::now();
@ -325,20 +366,20 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
if (g_pInputManager->dragMode == MBIND_MOVE) { if (g_pInputManager->dragMode == MBIND_MOVE) {
CBox wb = {m_vBeginDragPositionXY + DELTA, DRAGGINGWINDOW->m_vRealSize.goalv()}; CBox wb = {m_vBeginDragPositionXY + DELTA, DRAGGINGWINDOW->m_vRealSize.goal()};
wb.round(); wb.round();
if (**PANIMATEMOUSE) if (*PANIMATEMOUSE)
DRAGGINGWINDOW->m_vRealPosition = wb.pos(); DRAGGINGWINDOW->m_vRealPosition = wb.pos();
else else
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos()); DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
} else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) { } else if (g_pInputManager->dragMode == MBIND_RESIZE || g_pInputManager->dragMode == MBIND_RESIZE_FORCE_RATIO || g_pInputManager->dragMode == MBIND_RESIZE_BLOCK_RATIO) {
if (DRAGGINGWINDOW->m_bIsFloating) { if (DRAGGINGWINDOW->m_bIsFloating) {
Vector2D MINSIZE = Vector2D(20, 20); Vector2D MINSIZE = g_pXWaylandManager->getMinSizeForWindow(DRAGGINGWINDOW).clamp(DRAGGINGWINDOW->m_sAdditionalConfigData.minSize.toUnderlying());
Vector2D MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW); Vector2D MAXSIZE = g_pXWaylandManager->getMaxSizeForWindow(DRAGGINGWINDOW).clamp({}, DRAGGINGWINDOW->m_sAdditionalConfigData.maxSize.toUnderlying());
Vector2D newSize = m_vBeginDragSizeXY; Vector2D newSize = m_vBeginDragSizeXY;
Vector2D newPos = m_vBeginDragPositionXY; Vector2D newPos = m_vBeginDragPositionXY;
@ -386,7 +427,7 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
CBox wb = {newPos, newSize}; CBox wb = {newPos, newSize};
wb.round(); wb.round();
if (**PANIMATE) { if (*PANIMATE) {
DRAGGINGWINDOW->m_vRealSize = wb.size(); DRAGGINGWINDOW->m_vRealSize = wb.size();
DRAGGINGWINDOW->m_vRealPosition = wb.pos(); DRAGGINGWINDOW->m_vRealPosition = wb.pos();
} else { } else {
@ -394,14 +435,14 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos()); DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(wb.pos());
} }
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goal());
} else { } else {
resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW); resizeActiveWindow(TICKDELTA, m_eGrabbedCorner, DRAGGINGWINDOW);
} }
} }
// get middle point // get middle point
Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.vec() + DRAGGINGWINDOW->m_vRealSize.vec() / 2.f; Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.value() + DRAGGINGWINDOW->m_vRealSize.value() / 2.f;
// and check its monitor // and check its monitor
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle); const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
@ -435,18 +476,23 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
EMIT_HOOK_EVENT("changeFloatingMode", pWindow); EMIT_HOOK_EVENT("changeFloatingMode", pWindow);
if (!TILED) { if (!TILED) {
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f); const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.value() + pWindow->m_vRealSize.value() / 2.f);
pWindow->m_iMonitorID = PNEWMON->ID; pWindow->m_iMonitorID = PNEWMON->ID;
pWindow->moveToWorkspace(PNEWMON->specialWorkspaceID != 0 ? PNEWMON->specialWorkspaceID : PNEWMON->activeWorkspace); pWindow->moveToWorkspace(PNEWMON->specialWorkspaceID != 0 ? PNEWMON->specialWorkspaceID : PNEWMON->activeWorkspace);
pWindow->updateGroupOutputs(); pWindow->updateGroupOutputs();
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PNEWMON->specialWorkspaceID != 0 ? PNEWMON->specialWorkspaceID : PNEWMON->activeWorkspace);
if (PWORKSPACE->m_bHasFullscreenWindow)
g_pCompositor->setWindowFullscreen(g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID), false);
// save real pos cuz the func applies the default 5,5 mid // save real pos cuz the func applies the default 5,5 mid
const auto PSAVEDPOS = pWindow->m_vRealPosition.goalv(); const auto PSAVEDPOS = pWindow->m_vRealPosition.goal();
const auto PSAVEDSIZE = pWindow->m_vRealSize.goalv(); const auto PSAVEDSIZE = pWindow->m_vRealSize.goal();
// if the window is pseudo, update its size // if the window is pseudo, update its size
if (!pWindow->m_bDraggingTiled) if (!pWindow->m_bDraggingTiled)
pWindow->m_vPseudoSize = pWindow->m_vRealSize.goalv(); pWindow->m_vPseudoSize = pWindow->m_vRealSize.goal();
pWindow->m_vLastFloatingSize = PSAVEDSIZE; pWindow->m_vLastFloatingSize = PSAVEDSIZE;
@ -468,10 +514,11 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
g_pCompositor->changeWindowZOrder(pWindow, true); g_pCompositor->changeWindowZOrder(pWindow, true);
CBox wb = {pWindow->m_vRealPosition.goalv() + (pWindow->m_vRealSize.goalv() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize}; CBox wb = {pWindow->m_vRealPosition.goal() + (pWindow->m_vRealSize.goal() - pWindow->m_vLastFloatingSize) / 2.f, pWindow->m_vLastFloatingSize};
wb.round(); wb.round();
if (DELTALESSTHAN(pWindow->m_vRealSize.vec().x, pWindow->m_vLastFloatingSize.x, 10) && DELTALESSTHAN(pWindow->m_vRealSize.vec().y, pWindow->m_vLastFloatingSize.y, 10)) { if (DELTALESSTHAN(pWindow->m_vRealSize.value().x, pWindow->m_vLastFloatingSize.x, 10) &&
DELTALESSTHAN(pWindow->m_vRealSize.value().y, pWindow->m_vLastFloatingSize.y, 10)) {
wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}}; wb = {wb.pos() + Vector2D{10, 10}, wb.size() - Vector2D{20, 20}};
} }
@ -505,7 +552,7 @@ void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
return; return;
} }
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goalv() + delta; PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goal() + delta;
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
} }
@ -591,6 +638,11 @@ void IHyprLayout::bringWindowToTop(CWindow* pWindow) {
void IHyprLayout::requestFocusForWindow(CWindow* pWindow) { void IHyprLayout::requestFocusForWindow(CWindow* pWindow) {
bringWindowToTop(pWindow); bringWindowToTop(pWindow);
g_pCompositor->focusWindow(pWindow); g_pCompositor->focusWindow(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle());
}
Vector2D IHyprLayout::predictSizeForNewWindow() {
return Vector2D{};
} }
IHyprLayout::~IHyprLayout() {} IHyprLayout::~IHyprLayout() {}

View file

@ -181,7 +181,14 @@ class IHyprLayout {
*/ */
virtual void requestFocusForWindow(CWindow*); virtual void requestFocusForWindow(CWindow*);
/*
Called to predict the size of a newly opened window to send it a configure.
Return 0,0 if unpredictable
*/
virtual Vector2D predictSizeForNewWindow();
private: private:
int m_iMouseMoveEventCount;
Vector2D m_vBeginDragXY; Vector2D m_vBeginDragXY;
Vector2D m_vLastDragXY; Vector2D m_vLastDragXY;
Vector2D m_vBeginDragPositionXY; Vector2D m_vBeginDragPositionXY;

View file

@ -3,6 +3,7 @@
#include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "config/ConfigDataValues.hpp" #include "config/ConfigDataValues.hpp"
#include <ranges> #include <ranges>
#include "../config/ConfigValue.hpp"
SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(CWindow* pWindow) { SMasterNodeData* CHyprMasterLayout::getNodeFromWindow(CWindow* pWindow) {
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
@ -42,9 +43,9 @@ SMasterWorkspaceData* CHyprMasterLayout::getMasterWorkspaceData(const int& ws) {
//create on the fly if it doesn't exist yet //create on the fly if it doesn't exist yet
const auto PWORKSPACEDATA = &m_lMasterWorkspacesData.emplace_back(); const auto PWORKSPACEDATA = &m_lMasterWorkspacesData.emplace_back();
PWORKSPACEDATA->workspaceID = ws; PWORKSPACEDATA->workspaceID = ws;
const auto orientation = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("master:orientation"); static auto PORIENTATION = CConfigValue<std::string>("master:orientation");
const auto layoutoptsForWs = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(ws)).layoutopts; const auto layoutoptsForWs = g_pConfigManager->getWorkspaceRuleFor(g_pCompositor->getWorkspaceByID(ws)).layoutopts;
std::string orientationForWs = *orientation; std::string orientationForWs = *PORIENTATION;
if (layoutoptsForWs.contains("orientation")) if (layoutoptsForWs.contains("orientation"))
orientationForWs = layoutoptsForWs.at("orientation"); orientationForWs = layoutoptsForWs.at("orientation");
@ -81,20 +82,20 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
if (pWindow->m_bIsFloating) if (pWindow->m_bIsFloating)
return; return;
static auto* const PNEWTOP = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:new_on_top"); static auto PNEWTOP = CConfigValue<Hyprlang::INT>("master:new_on_top");
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
const auto PNODE = **PNEWTOP ? &m_lMasterNodesData.emplace_front() : &m_lMasterNodesData.emplace_back(); const auto PNODE = *PNEWTOP ? &m_lMasterNodesData.emplace_front() : &m_lMasterNodesData.emplace_back();
PNODE->workspaceID = pWindow->m_iWorkspaceID; PNODE->workspaceID = pWindow->m_iWorkspaceID;
PNODE->pWindow = pWindow; PNODE->pWindow = pWindow;
static auto* const PNEWISMASTER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:new_is_master"); static auto PNEWISMASTER = CConfigValue<Hyprlang::INT>("master:new_is_master");
const auto WINDOWSONWORKSPACE = getNodesOnWorkspace(PNODE->workspaceID); const auto WINDOWSONWORKSPACE = getNodesOnWorkspace(PNODE->workspaceID);
static auto* const PMFACT = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("master:mfact"); static auto PMFACT = CConfigValue<Hyprlang::FLOAT>("master:mfact");
float lastSplitPercent = **PMFACT; float lastSplitPercent = *PMFACT;
auto OPENINGON = isWindowTiled(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID ? auto OPENINGON = isWindowTiled(g_pCompositor->m_pLastWindow) && g_pCompositor->m_pLastWindow->m_iWorkspaceID == pWindow->m_iWorkspaceID ?
getNodeFromWindow(g_pCompositor->m_pLastWindow) : getNodeFromWindow(g_pCompositor->m_pLastWindow) :
@ -113,8 +114,8 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
m_lMasterNodesData.remove(*PNODE); m_lMasterNodesData.remove(*PNODE);
static const auto* USECURRPOS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("group:insert_after_current"); static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
(**USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow); (*USECURRPOS ? OPENINGON->pWindow : OPENINGON->pWindow->getGroupTail())->insertWindowToGroup(pWindow);
OPENINGON->pWindow->setGroupCurrent(pWindow); OPENINGON->pWindow->setGroupCurrent(pWindow);
pWindow->applyGroupRules(); pWindow->applyGroupRules();
@ -129,14 +130,14 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
pWindow->applyGroupRules(); pWindow->applyGroupRules();
static auto* const PDROPATCURSOR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:drop_at_cursor"); static auto PDROPATCURSOR = CConfigValue<Hyprlang::INT>("master:drop_at_cursor");
const auto PWORKSPACEDATA = getMasterWorkspaceData(pWindow->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(pWindow->m_iWorkspaceID);
eOrientation orientation = PWORKSPACEDATA->orientation; eOrientation orientation = PWORKSPACEDATA->orientation;
const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE); const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE);
bool forceDropAsMaster = false; bool forceDropAsMaster = false;
// if dragging window to move, drop it at the cursor position instead of bottom/top of stack // if dragging window to move, drop it at the cursor position instead of bottom/top of stack
if (**PDROPATCURSOR && g_pInputManager->dragMode == MBIND_MOVE) { if (*PDROPATCURSOR && g_pInputManager->dragMode == MBIND_MOVE) {
if (WINDOWSONWORKSPACE > 2) { if (WINDOWSONWORKSPACE > 2) {
for (auto it = m_lMasterNodesData.begin(); it != m_lMasterNodesData.end(); ++it) { for (auto it = m_lMasterNodesData.begin(); it != m_lMasterNodesData.end(); ++it) {
if (it->workspaceID != pWindow->m_iWorkspaceID) if (it->workspaceID != pWindow->m_iWorkspaceID)
@ -192,7 +193,7 @@ void CHyprMasterLayout::onWindowCreatedTiling(CWindow* pWindow, eDirection direc
} }
} }
if ((**PNEWISMASTER && g_pInputManager->dragMode != MBIND_MOVE) || WINDOWSONWORKSPACE == 1 || (WINDOWSONWORKSPACE > 2 && !pWindow->m_bFirstMap && OPENINGON->isMaster) || if ((*PNEWISMASTER && g_pInputManager->dragMode != MBIND_MOVE) || WINDOWSONWORKSPACE == 1 || (WINDOWSONWORKSPACE > 2 && !pWindow->m_bFirstMap && OPENINGON->isMaster) ||
forceDropAsMaster) { forceDropAsMaster) {
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
if (nd.isMaster && nd.workspaceID == PNODE->workspaceID) { if (nd.isMaster && nd.workspaceID == PNODE->workspaceID) {
@ -240,14 +241,13 @@ void CHyprMasterLayout::onWindowRemovedTiling(CWindow* pWindow) {
const auto WORKSPACEID = PNODE->workspaceID; const auto WORKSPACEID = PNODE->workspaceID;
const auto MASTERSLEFT = getMastersOnWorkspace(WORKSPACEID); const auto MASTERSLEFT = getMastersOnWorkspace(WORKSPACEID);
static const auto* SMALLSPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:allow_small_split"); static auto SMALLSPLIT = CConfigValue<Hyprlang::INT>("master:allow_small_split");
pWindow->updateSpecialRenderData(); pWindow->updateSpecialRenderData();
if (pWindow->m_bIsFullscreen)
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL); g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
if (PNODE->isMaster && (MASTERSLEFT <= 1 || **SMALLSPLIT == 1)) { if (PNODE->isMaster && (MASTERSLEFT <= 1 || *SMALLSPLIT == 1)) {
// find a new master from top of the list // find a new master from top of the list
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
if (!nd.isMaster && nd.workspaceID == WORKSPACEID) { if (!nd.isMaster && nd.workspaceID == WORKSPACEID) {
@ -295,6 +295,28 @@ void CHyprMasterLayout::recalculateMonitor(const int& monid) {
g_pHyprRenderer->damageMonitor(PMONITOR); g_pHyprRenderer->damageMonitor(PMONITOR);
if (PMONITOR->specialWorkspaceID) { if (PMONITOR->specialWorkspaceID) {
const auto PSPECIALWS = g_pCompositor->getWorkspaceByID(PMONITOR->specialWorkspaceID);
if (PSPECIALWS->m_bHasFullscreenWindow) {
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PSPECIALWS->m_iID);
if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_FULL) {
PFULLWINDOW->m_vRealPosition = PMONITOR->vecPosition;
PFULLWINDOW->m_vRealSize = PMONITOR->vecSize;
} else if (PSPECIALWS->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
SMasterNodeData fakeNode;
fakeNode.pWindow = PFULLWINDOW;
fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight;
fakeNode.workspaceID = PSPECIALWS->m_iID;
PFULLWINDOW->m_vPosition = fakeNode.position;
PFULLWINDOW->m_vSize = fakeNode.size;
fakeNode.ignoreFullscreenChecks = true;
applyNodeDataToWindow(&fakeNode);
}
}
calculateWorkspace(PMONITOR->specialWorkspaceID); calculateWorkspace(PMONITOR->specialWorkspaceID);
} }
@ -339,8 +361,8 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
eOrientation orientation = PWORKSPACEDATA->orientation; eOrientation orientation = PWORKSPACEDATA->orientation;
bool centerMasterWindow = false; bool centerMasterWindow = false;
static auto* const ALWAYSCENTER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:always_center_master"); static auto ALWAYSCENTER = CConfigValue<Hyprlang::INT>("master:always_center_master");
static auto* const PSMARTRESIZING = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:smart_resizing"); static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("master:smart_resizing");
const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID); const auto MASTERS = getMastersOnWorkspace(PWORKSPACE->m_iID);
const auto WINDOWS = getNodesOnWorkspace(PWORKSPACE->m_iID); const auto WINDOWS = getNodesOnWorkspace(PWORKSPACE->m_iID);
@ -349,7 +371,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
const auto WSPOS = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft; const auto WSPOS = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
if (orientation == ORIENTATION_CENTER) { if (orientation == ORIENTATION_CENTER) {
if (STACKWINDOWS >= 2 || (**ALWAYSCENTER == 1)) { if (STACKWINDOWS >= 2 || (*ALWAYSCENTER == 1)) {
centerMasterWindow = true; centerMasterWindow = true;
} else { } else {
orientation = ORIENTATION_LEFT; orientation = ORIENTATION_LEFT;
@ -362,7 +384,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
float masterAccumulatedSize = 0; float masterAccumulatedSize = 0;
float slaveAccumulatedSize = 0; float slaveAccumulatedSize = 0;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
// check the total width and height so that later // check the total width and height so that later
// if larger/smaller than screen size them down/up // if larger/smaller than screen size them down/up
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
@ -400,7 +422,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (WIDTH > widthLeft * 0.9f && mastersLeft > 1) if (WIDTH > widthLeft * 0.9f && mastersLeft > 1)
WIDTH = widthLeft * 0.9f; WIDTH = widthLeft * 0.9f;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
nd.percSize *= WSSIZE.x / masterAccumulatedSize; nd.percSize *= WSSIZE.x / masterAccumulatedSize;
WIDTH = masterAverageSize * nd.percSize; WIDTH = masterAverageSize * nd.percSize;
} }
@ -437,7 +459,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (HEIGHT > heightLeft * 0.9f && mastersLeft > 1) if (HEIGHT > heightLeft * 0.9f && mastersLeft > 1)
HEIGHT = heightLeft * 0.9f; HEIGHT = heightLeft * 0.9f;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
nd.percSize *= WSSIZE.y / masterAccumulatedSize; nd.percSize *= WSSIZE.y / masterAccumulatedSize;
HEIGHT = masterAverageSize * nd.percSize; HEIGHT = masterAverageSize * nd.percSize;
} }
@ -474,7 +496,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (WIDTH > widthLeft * 0.9f && slavesLeft > 1) if (WIDTH > widthLeft * 0.9f && slavesLeft > 1)
WIDTH = widthLeft * 0.9f; WIDTH = widthLeft * 0.9f;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
nd.percSize *= WSSIZE.x / slaveAccumulatedSize; nd.percSize *= WSSIZE.x / slaveAccumulatedSize;
WIDTH = slaveAverageSize * nd.percSize; WIDTH = slaveAverageSize * nd.percSize;
} }
@ -504,7 +526,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1) if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
HEIGHT = heightLeft * 0.9f; HEIGHT = heightLeft * 0.9f;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
nd.percSize *= WSSIZE.y / slaveAccumulatedSize; nd.percSize *= WSSIZE.y / slaveAccumulatedSize;
HEIGHT = slaveAverageSize * nd.percSize; HEIGHT = slaveAverageSize * nd.percSize;
} }
@ -535,7 +557,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
const float slaveAverageHeightR = WSSIZE.y / slavesLeftR; const float slaveAverageHeightR = WSSIZE.y / slavesLeftR;
float slaveAccumulatedHeightL = 0; float slaveAccumulatedHeightL = 0;
float slaveAccumulatedHeightR = 0; float slaveAccumulatedHeightR = 0;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
for (auto& nd : m_lMasterNodesData) { for (auto& nd : m_lMasterNodesData) {
if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster) if (nd.workspaceID != PWORKSPACE->m_iID || nd.isMaster)
continue; continue;
@ -570,7 +592,7 @@ void CHyprMasterLayout::calculateWorkspace(const int& ws) {
if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1) if (HEIGHT > heightLeft * 0.9f && slavesLeft > 1)
HEIGHT = heightLeft * 0.9f; HEIGHT = heightLeft * 0.9f;
if (**PSMARTRESIZING) { if (*PSMARTRESIZING) {
if (onRight) { if (onRight) {
nd.percSize *= WSSIZE.y / slaveAccumulatedHeightR; nd.percSize *= WSSIZE.y / slaveAccumulatedHeightR;
HEIGHT = slaveAverageHeightR * nd.percSize; HEIGHT = slaveAverageHeightR * nd.percSize;
@ -634,12 +656,12 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
PWINDOW->updateSpecialRenderData(); PWINDOW->updateSpecialRenderData();
static auto* const PNOGAPSWHENONLY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:no_gaps_when_only"); static auto PNOGAPSWHENONLY = CConfigValue<Hyprlang::INT>("master:no_gaps_when_only");
static auto* const PANIMATE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:animate_manual_resizes"); static auto PANIMATE = CConfigValue<Hyprlang::INT>("misc:animate_manual_resizes");
static auto* const PGAPSINDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_in"); static auto PGAPSINDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_in");
static auto* const PGAPSOUTDATA = (Hyprlang::CUSTOMTYPE* const*)g_pConfigManager->getConfigValuePtr("general:gaps_out"); static auto PGAPSOUTDATA = CConfigValue<Hyprlang::CUSTOMTYPE>("general:gaps_out");
auto* const PGAPSIN = (CCssGapData*)(*PGAPSINDATA)->getData(); auto* PGAPSIN = (CCssGapData*)(PGAPSINDATA.ptr())->getData();
auto* const PGAPSOUT = (CCssGapData*)(*PGAPSOUTDATA)->getData(); auto* PGAPSOUT = (CCssGapData*)(PGAPSOUTDATA.ptr())->getData();
auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN); auto gapsIn = WORKSPACERULE.gapsIn.value_or(*PGAPSIN);
auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT); auto gapsOut = WORKSPACERULE.gapsOut.value_or(*PGAPSOUT);
@ -652,11 +674,11 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
PWINDOW->m_vSize = pNode->size; PWINDOW->m_vSize = pNode->size;
PWINDOW->m_vPosition = pNode->position; PWINDOW->m_vPosition = pNode->position;
if (**PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && if (*PNOGAPSWHENONLY && !g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) &&
(getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 || (getNodesOnWorkspace(PWINDOW->m_iWorkspaceID) == 1 ||
(PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) { (PWINDOW->m_bIsFullscreen && g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_efFullscreenMode == FULLSCREEN_MAXIMIZED))) {
PWINDOW->m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(**PNOGAPSWHENONLY == 2); PWINDOW->m_sSpecialRenderData.border = WORKSPACERULE.border.value_or(*PNOGAPSWHENONLY == 2);
PWINDOW->m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true); PWINDOW->m_sSpecialRenderData.decorate = WORKSPACERULE.decorate.value_or(true);
PWINDOW->m_sSpecialRenderData.rounding = false; PWINDOW->m_sSpecialRenderData.rounding = false;
PWINDOW->m_sSpecialRenderData.shadow = false; PWINDOW->m_sSpecialRenderData.shadow = false;
@ -668,7 +690,7 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + RESERVED.topLeft; PWINDOW->m_vRealPosition = PWINDOW->m_vPosition + RESERVED.topLeft;
PWINDOW->m_vRealSize = PWINDOW->m_vSize - (RESERVED.topLeft + RESERVED.bottomRight); PWINDOW->m_vRealSize = PWINDOW->m_vSize - (RESERVED.topLeft + RESERVED.bottomRight);
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
return; return;
} }
@ -687,10 +709,10 @@ void CHyprMasterLayout::applyNodeDataToWindow(SMasterNodeData* pNode) {
calcPos = calcPos + RESERVED.topLeft; calcPos = calcPos + RESERVED.topLeft;
calcSize = calcSize - (RESERVED.topLeft + RESERVED.bottomRight); calcSize = calcSize - (RESERVED.topLeft + RESERVED.bottomRight);
if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID)) { if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID) && !PWINDOW->m_bIsFullscreen) {
static auto* const PSCALEFACTOR = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("master:special_scale_factor"); static auto PSCALEFACTOR = CConfigValue<Hyprlang::FLOAT>("master:special_scale_factor");
CBox wb = {calcPos + (calcSize - calcSize * **PSCALEFACTOR) / 2.f, calcSize * **PSCALEFACTOR}; CBox wb = {calcPos + (calcSize - calcSize * *PSCALEFACTOR) / 2.f, calcSize * *PSCALEFACTOR};
wb.round(); // avoid rounding mess wb.round(); // avoid rounding mess
PWINDOW->m_vRealPosition = wb.pos(); PWINDOW->m_vRealPosition = wb.pos();
@ -732,18 +754,18 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
const auto PNODE = getNodeFromWindow(PWINDOW); const auto PNODE = getNodeFromWindow(PWINDOW);
if (!PNODE) { if (!PNODE) {
PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goalv() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goalv() + pixResize).y, 20.0)); PWINDOW->m_vRealSize = Vector2D(std::max((PWINDOW->m_vRealSize.goal() + pixResize).x, 20.0), std::max((PWINDOW->m_vRealSize.goal() + pixResize).y, 20.0));
PWINDOW->updateWindowDecos(); PWINDOW->updateWindowDecos();
return; return;
} }
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
const auto PWORKSPACEDATA = getMasterWorkspaceData(PMONITOR->activeWorkspace); const auto PWORKSPACEDATA = getMasterWorkspaceData(PMONITOR->activeWorkspace);
static auto* const ALWAYSCENTER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:always_center_master"); static auto ALWAYSCENTER = CConfigValue<Hyprlang::INT>("master:always_center_master");
static auto* const PSMARTRESIZING = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:smart_resizing"); static auto PSMARTRESIZING = CConfigValue<Hyprlang::INT>("master:smart_resizing");
eOrientation orientation = PWORKSPACEDATA->orientation; eOrientation orientation = PWORKSPACEDATA->orientation;
bool centered = orientation == ORIENTATION_CENTER && (**ALWAYSCENTER == 1); bool centered = orientation == ORIENTATION_CENTER && (*ALWAYSCENTER == 1);
double delta = 0; double delta = 0;
const bool DISPLAYBOTTOM = STICKS(PWINDOW->m_vPosition.y + PWINDOW->m_vSize.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y); const bool DISPLAYBOTTOM = STICKS(PWINDOW->m_vPosition.y + PWINDOW->m_vSize.y, PMONITOR->vecPosition.y + PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y);
@ -800,7 +822,7 @@ void CHyprMasterLayout::resizeActiveWindow(const Vector2D& pixResize, eRectCorne
const auto SIZE = isStackVertical ? WSSIZE.y / nodesInSameColumn : WSSIZE.x / nodesInSameColumn; const auto SIZE = isStackVertical ? WSSIZE.y / nodesInSameColumn : WSSIZE.x / nodesInSameColumn;
if (RESIZEDELTA != 0 && nodesInSameColumn > 1) { if (RESIZEDELTA != 0 && nodesInSameColumn > 1) {
if (!**PSMARTRESIZING) { if (!*PSMARTRESIZING) {
PNODE->percSize = std::clamp(PNODE->percSize + RESIZEDELTA / SIZE, 0.05, 1.95); PNODE->percSize = std::clamp(PNODE->percSize + RESIZEDELTA / SIZE, 0.05, 1.95);
} else { } else {
const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE); const auto NODEIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), *PNODE);
@ -870,7 +892,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen
if (!g_pCompositor->windowValidMapped(pWindow)) if (!g_pCompositor->windowValidMapped(pWindow))
return; return;
if (on == pWindow->m_bIsFullscreen || g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) if (on == pWindow->m_bIsFullscreen)
return; // ignore return; // ignore
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
@ -884,10 +906,10 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen
// save position and size if floating // save position and size if floating
if (pWindow->m_bIsFloating && on) { if (pWindow->m_bIsFloating && on) {
pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goalv(); pWindow->m_vLastFloatingSize = pWindow->m_vRealSize.goal();
pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goalv(); pWindow->m_vLastFloatingPosition = pWindow->m_vRealPosition.goal();
pWindow->m_vPosition = pWindow->m_vRealPosition.goalv(); pWindow->m_vPosition = pWindow->m_vRealPosition.goal();
pWindow->m_vSize = pWindow->m_vRealSize.goalv(); pWindow->m_vSize = pWindow->m_vRealSize.goal();
} }
// otherwise, accept it. // otherwise, accept it.
@ -941,7 +963,7 @@ void CHyprMasterLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreen
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow); g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goal());
g_pCompositor->changeWindowZOrder(pWindow, true); g_pCompositor->changeWindowZOrder(pWindow, true);
@ -976,6 +998,8 @@ void CHyprMasterLayout::moveWindowTo(CWindow* pWindow, const std::string& dir) {
onWindowRemovedTiling(pWindow); onWindowRemovedTiling(pWindow);
pWindow->moveToWorkspace(PWINDOW2->m_iWorkspaceID); pWindow->moveToWorkspace(PWINDOW2->m_iWorkspaceID);
pWindow->m_iMonitorID = PWINDOW2->m_iMonitorID; pWindow->m_iMonitorID = PWINDOW2->m_iMonitorID;
const auto pMonitor = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
g_pCompositor->setActiveMonitor(pMonitor);
onWindowCreatedTiling(pWindow); onWindowCreatedTiling(pWindow);
} else { } else {
// if same monitor, switch windows // if same monitor, switch windows
@ -992,8 +1016,6 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
if (!PNODE2 || !PNODE) if (!PNODE2 || !PNODE)
return; return;
const auto inheritFullscreen = prepareLoseFocus(pWindow);
if (PNODE->workspaceID != PNODE2->workspaceID) { if (PNODE->workspaceID != PNODE2->workspaceID) {
std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID); std::swap(pWindow2->m_iMonitorID, pWindow->m_iMonitorID);
std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID); std::swap(pWindow2->m_iWorkspaceID, pWindow->m_iWorkspaceID);
@ -1009,8 +1031,6 @@ void CHyprMasterLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
g_pHyprRenderer->damageWindow(pWindow); g_pHyprRenderer->damageWindow(pWindow);
g_pHyprRenderer->damageWindow(pWindow2); g_pHyprRenderer->damageWindow(pWindow2);
prepareNewFocus(pWindow2, inheritFullscreen);
} }
void CHyprMasterLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) { void CHyprMasterLayout::alterSplitRatio(CWindow* pWindow, float ratio, bool exact) {
@ -1051,35 +1071,27 @@ CWindow* CHyprMasterLayout::getNextWindow(CWindow* pWindow, bool next) {
return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow; return CANDIDATE == nodes.end() ? nullptr : CANDIDATE->pWindow;
} }
bool CHyprMasterLayout::prepareLoseFocus(CWindow* pWindow) {
if (!pWindow)
return false;
//if the current window is fullscreen, make it normal again if we are about to lose focus
if (pWindow->m_bIsFullscreen) {
g_pCompositor->setWindowFullscreen(pWindow, false, FULLSCREEN_FULL);
static auto* const INHERIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:inherit_fullscreen");
return **INHERIT == 1;
}
return false;
}
void CHyprMasterLayout::prepareNewFocus(CWindow* pWindow, bool inheritFullscreen) {
if (!pWindow)
return;
if (inheritFullscreen)
g_pCompositor->setWindowFullscreen(pWindow, true, g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID)->m_efFullscreenMode);
}
std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) { std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::string message) {
auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) { auto switchToWindow = [&](CWindow* PWINDOWTOCHANGETO) {
if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO)) if (!g_pCompositor->windowValidMapped(PWINDOWTOCHANGETO))
return; return;
if (header.pWindow->m_bIsFullscreen) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(header.pWindow->m_iWorkspaceID);
const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
static auto INHERITFULLSCREEN = CConfigValue<Hyprlang::INT>("master:inherit_fullscreen");
g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
if (*INHERITFULLSCREEN)
g_pCompositor->setWindowFullscreen(PWINDOWTOCHANGETO, true, FSMODE);
} else {
g_pCompositor->focusWindow(PWINDOWTOCHANGETO); g_pCompositor->focusWindow(PWINDOWTOCHANGETO);
g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle()); g_pCompositor->warpCursorTo(PWINDOWTOCHANGETO->middle());
}
g_pInputManager->m_pForcedFocus = PWINDOWTOCHANGETO;
g_pInputManager->simulateMouseMovement();
g_pInputManager->m_pForcedFocus = nullptr;
}; };
CVarList vars(message, 0, ' '); CVarList vars(message, 0, ' ');
@ -1115,21 +1127,17 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (PMASTER->pWindow != PWINDOW) { if (PMASTER->pWindow != PWINDOW) {
const auto NEWMASTER = PWINDOW; const auto NEWMASTER = PWINDOW;
const bool newFocusToChild = vars.size() >= 2 && vars[1] == "child"; const bool newFocusToChild = vars.size() >= 2 && vars[1] == "child";
const bool inheritFullscreen = prepareLoseFocus(NEWMASTER);
switchWindows(NEWMASTER, NEWCHILD); switchWindows(NEWMASTER, NEWCHILD);
const auto NEWFOCUS = newFocusToChild ? NEWCHILD : NEWMASTER; const auto NEWFOCUS = newFocusToChild ? NEWCHILD : NEWMASTER;
switchToWindow(NEWFOCUS); switchToWindow(NEWFOCUS);
prepareNewFocus(NEWFOCUS, inheritFullscreen);
} else { } else {
for (auto& n : m_lMasterNodesData) { for (auto& n : m_lMasterNodesData) {
if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) {
const auto NEWMASTER = n.pWindow; const auto NEWMASTER = n.pWindow;
const bool inheritFullscreen = prepareLoseFocus(NEWCHILD);
switchWindows(NEWMASTER, NEWCHILD); switchWindows(NEWMASTER, NEWCHILD);
const bool newFocusToMaster = vars.size() >= 2 && vars[1] == "master"; const bool newFocusToMaster = vars.size() >= 2 && vars[1] == "master";
const auto NEWFOCUS = newFocusToMaster ? NEWMASTER : NEWCHILD; const auto NEWFOCUS = newFocusToMaster ? NEWMASTER : NEWCHILD;
switchToWindow(NEWFOCUS); switchToWindow(NEWFOCUS);
prepareNewFocus(NEWFOCUS, inheritFullscreen);
break; break;
} }
} }
@ -1147,8 +1155,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID); const auto PMASTER = getMasterNodeOnWorkspace(PWINDOW->m_iWorkspaceID);
if (!PMASTER) if (!PMASTER)
@ -1156,7 +1162,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (PMASTER->pWindow != PWINDOW) { if (PMASTER->pWindow != PWINDOW) {
switchToWindow(PMASTER->pWindow); switchToWindow(PMASTER->pWindow);
prepareNewFocus(PMASTER->pWindow, inheritFullscreen);
} else if (vars.size() >= 2 && vars[1] == "master") { } else if (vars.size() >= 2 && vars[1] == "master") {
return 0; return 0;
} else { } else {
@ -1164,7 +1169,6 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
for (auto& n : m_lMasterNodesData) { for (auto& n : m_lMasterNodesData) {
if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) { if (n.workspaceID == PMASTER->workspaceID && !n.isMaster) {
switchToWindow(n.pWindow); switchToWindow(n.pWindow);
prepareNewFocus(n.pWindow, inheritFullscreen);
break; break;
} }
} }
@ -1177,22 +1181,16 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
const auto PNEXTWINDOW = getNextWindow(PWINDOW, true); const auto PNEXTWINDOW = getNextWindow(PWINDOW, true);
switchToWindow(PNEXTWINDOW); switchToWindow(PNEXTWINDOW);
prepareNewFocus(PNEXTWINDOW, inheritFullscreen);
} else if (command == "cycleprev") { } else if (command == "cycleprev") {
const auto PWINDOW = header.pWindow; const auto PWINDOW = header.pWindow;
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
const auto PPREVWINDOW = getNextWindow(PWINDOW, false); const auto PPREVWINDOW = getNextWindow(PWINDOW, false);
switchToWindow(PPREVWINDOW); switchToWindow(PPREVWINDOW);
prepareNewFocus(PPREVWINDOW, inheritFullscreen);
} else if (command == "swapnext") { } else if (command == "swapnext") {
if (!g_pCompositor->windowValidMapped(header.pWindow)) if (!g_pCompositor->windowValidMapped(header.pWindow))
return 0; return 0;
@ -1205,9 +1203,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true); const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, true);
if (PWINDOWTOSWAPWITH) { if (PWINDOWTOSWAPWITH) {
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
switchWindows(header.pWindow, PWINDOWTOSWAPWITH); switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
g_pCompositor->focusWindow(header.pWindow); switchToWindow(header.pWindow);
} }
} else if (command == "swapprev") { } else if (command == "swapprev") {
if (!g_pCompositor->windowValidMapped(header.pWindow)) if (!g_pCompositor->windowValidMapped(header.pWindow))
@ -1221,9 +1219,9 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false); const auto PWINDOWTOSWAPWITH = getNextWindow(header.pWindow, false);
if (PWINDOWTOSWAPWITH) { if (PWINDOWTOSWAPWITH) {
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
switchWindows(header.pWindow, PWINDOWTOSWAPWITH); switchWindows(header.pWindow, PWINDOWTOSWAPWITH);
g_pCompositor->focusWindow(header.pWindow); switchToWindow(header.pWindow);
} }
} else if (command == "addmaster") { } else if (command == "addmaster") {
if (!g_pCompositor->windowValidMapped(header.pWindow)) if (!g_pCompositor->windowValidMapped(header.pWindow))
@ -1236,11 +1234,11 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID); const auto WINDOWS = getNodesOnWorkspace(header.pWindow->m_iWorkspaceID);
const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID); const auto MASTERS = getMastersOnWorkspace(header.pWindow->m_iWorkspaceID);
static const auto* SMALLSPLIT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("master:allow_small_split"); static auto SMALLSPLIT = CConfigValue<Hyprlang::INT>("master:allow_small_split");
if (MASTERS + 2 > WINDOWS && **SMALLSPLIT == 0) if (MASTERS + 2 > WINDOWS && *SMALLSPLIT == 0)
return 0; return 0;
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
if (!PNODE || PNODE->isMaster) { if (!PNODE || PNODE->isMaster) {
// first non-master node // first non-master node
@ -1272,7 +1270,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (WINDOWS < 2 || MASTERS < 2) if (WINDOWS < 2 || MASTERS < 2)
return 0; return 0;
prepareLoseFocus(header.pWindow); g_pCompositor->setWindowFullscreen(header.pWindow, false, FULLSCREEN_FULL);
if (!PNODE || !PNODE->isMaster) { if (!PNODE || !PNODE->isMaster) {
// first non-master node // first non-master node
@ -1293,7 +1291,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
if (!PWINDOW) if (!PWINDOW)
return 0; return 0;
prepareLoseFocus(PWINDOW); g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
@ -1348,9 +1346,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
nd.isMaster = true; nd.isMaster = true;
const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd); const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd);
m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT); m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT);
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
switchToWindow(nd.pWindow); switchToWindow(nd.pWindow);
prepareNewFocus(nd.pWindow, inheritFullscreen);
OLDMASTER->isMaster = false; OLDMASTER->isMaster = false;
m_lMasterNodesData.splice(m_lMasterNodesData.end(), m_lMasterNodesData, OLDMASTERIT); m_lMasterNodesData.splice(m_lMasterNodesData.end(), m_lMasterNodesData, OLDMASTERIT);
break; break;
@ -1376,9 +1372,7 @@ std::any CHyprMasterLayout::layoutMessage(SLayoutMessageHeader header, std::stri
nd.isMaster = true; nd.isMaster = true;
const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd); const auto NEWMASTERIT = std::find(m_lMasterNodesData.begin(), m_lMasterNodesData.end(), nd);
m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT); m_lMasterNodesData.splice(OLDMASTERIT, m_lMasterNodesData, NEWMASTERIT);
const bool inheritFullscreen = prepareLoseFocus(PWINDOW);
switchToWindow(nd.pWindow); switchToWindow(nd.pWindow);
prepareNewFocus(nd.pWindow, inheritFullscreen);
OLDMASTER->isMaster = false; OLDMASTER->isMaster = false;
m_lMasterNodesData.splice(m_lMasterNodesData.begin(), m_lMasterNodesData, OLDMASTERIT); m_lMasterNodesData.splice(m_lMasterNodesData.begin(), m_lMasterNodesData, OLDMASTERIT);
break; break;
@ -1405,7 +1399,7 @@ void CHyprMasterLayout::runOrientationCycle(SLayoutMessageHeader& header, CVarLi
if (!PWINDOW) if (!PWINDOW)
return; return;
prepareLoseFocus(PWINDOW); g_pCompositor->setWindowFullscreen(PWINDOW, false, FULLSCREEN_FULL);
const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID); const auto PWORKSPACEDATA = getMasterWorkspaceData(PWINDOW->m_iWorkspaceID);
@ -1459,6 +1453,33 @@ void CHyprMasterLayout::replaceWindowDataWith(CWindow* from, CWindow* to) {
applyNodeDataToWindow(PNODE); applyNodeDataToWindow(PNODE);
} }
Vector2D CHyprMasterLayout::predictSizeForNewWindow() {
static auto PNEWISMASTER = CConfigValue<Hyprlang::INT>("master:new_is_master");
if (!g_pCompositor->m_pLastMonitor)
return {};
const int NODES = getNodesOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
if (NODES <= 0)
return g_pCompositor->m_pLastMonitor->vecSize;
const auto MASTER = getMasterNodeOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
if (!MASTER) // wtf
return {};
if (*PNEWISMASTER) {
return MASTER->size;
} else {
const auto SLAVES = NODES - getMastersOnWorkspace(g_pCompositor->m_pLastMonitor->activeWorkspace);
// TODO: make this better
return {g_pCompositor->m_pLastMonitor->vecSize.x - MASTER->size.x, g_pCompositor->m_pLastMonitor->vecSize.y / (SLAVES + 1)};
}
return {};
}
void CHyprMasterLayout::onEnable() { void CHyprMasterLayout::onEnable() {
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_bIsFloating || !w->m_bIsMapped || w->isHidden()) if (w->m_bIsFloating || !w->m_bIsMapped || w->isHidden())

View file

@ -65,6 +65,7 @@ class CHyprMasterLayout : public IHyprLayout {
virtual void alterSplitRatio(CWindow*, float, bool); virtual void alterSplitRatio(CWindow*, float, bool);
virtual std::string getLayoutName(); virtual std::string getLayoutName();
virtual void replaceWindowDataWith(CWindow* from, CWindow* to); virtual void replaceWindowDataWith(CWindow* from, CWindow* to);
virtual Vector2D predictSizeForNewWindow();
virtual void onEnable(); virtual void onEnable();
virtual void onDisable(); virtual void onDisable();
@ -86,8 +87,6 @@ class CHyprMasterLayout : public IHyprLayout {
void calculateWorkspace(const int&); void calculateWorkspace(const int&);
CWindow* getNextWindow(CWindow*, bool); CWindow* getNextWindow(CWindow*, bool);
int getMastersOnWorkspace(const int&); int getMastersOnWorkspace(const int&);
bool prepareLoseFocus(CWindow*);
void prepareNewFocus(CWindow*, bool inherit_fullscreen);
friend struct SMasterNodeData; friend struct SMasterNodeData;
friend struct SMasterWorkspaceData; friend struct SMasterWorkspaceData;

View file

@ -6,6 +6,7 @@
#ifndef NDEBUG #ifndef NDEBUG
#ifdef HYPRLAND_DEBUG #ifdef HYPRLAND_DEBUG
#define HYPRLAND_DEBUG
#define ISDEBUG true #define ISDEBUG true
#else #else
#define ISDEBUG false #define ISDEBUG false

View file

@ -1,6 +1,8 @@
#include "AnimationManager.hpp" #include "AnimationManager.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "HookSystemManager.hpp" #include "HookSystemManager.hpp"
#include "macros.hpp"
#include "../config/ConfigValue.hpp"
int wlTick(void* data) { int wlTick(void* data) {
if (g_pAnimationManager) if (g_pAnimationManager)
@ -53,20 +55,20 @@ void CAnimationManager::tick() {
bool animGlobalDisabled = false; bool animGlobalDisabled = false;
static auto* const PANIMENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("animations:enabled"); static auto PANIMENABLED = CConfigValue<Hyprlang::INT>("animations:enabled");
if (!**PANIMENABLED) if (!*PANIMENABLED)
animGlobalDisabled = true; animGlobalDisabled = true;
static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:drop_shadow"); static auto* const PSHADOWSENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:drop_shadow");
const auto DEFAULTBEZIER = m_mBezierCurves.find("default"); const auto DEFAULTBEZIER = m_mBezierCurves.find("default");
std::vector<CAnimatedVariable*> animationEndedVars; std::vector<CBaseAnimatedVariable*> animationEndedVars;
for (auto& av : m_vActiveAnimatedVariables) { for (auto& av : m_vActiveAnimatedVariables) {
if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !**PSHADOWSENABLED) { if (av->m_eDamagePolicy == AVARDAMAGE_SHADOW && !*PSHADOWSENABLED) {
av->warp(false); av->warp(false);
animationEndedVars.push_back(av); animationEndedVars.push_back(av);
continue; continue;
@ -84,7 +86,12 @@ void CAnimationManager::tick() {
CBox WLRBOXPREV = {0, 0, 0, 0}; CBox WLRBOXPREV = {0, 0, 0, 0};
if (PWINDOW) { if (PWINDOW) {
WLRBOXPREV = PWINDOW->getFullWindowBoundingBox(); CBox bb = PWINDOW->getFullWindowBoundingBox();
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
if (PWINDOWWORKSPACE)
bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
WLRBOXPREV = bb;
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (!PMONITOR) if (!PMONITOR)
continue; continue;
@ -93,15 +100,29 @@ void CAnimationManager::tick() {
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID); PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
if (!PMONITOR) if (!PMONITOR)
continue; continue;
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y}; WLRBOXPREV = {PMONITOR->vecPosition, PMONITOR->vecSize};
// TODO: just make this into a damn callback already vax... // TODO: just make this into a damn callback already vax...
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->isHidden() && w->m_bIsMapped && w->m_bIsFloating) if (!w->isHidden() && w->m_bIsMapped && w->m_bIsFloating)
g_pHyprRenderer->damageWindow(w.get()); g_pHyprRenderer->damageWindow(w.get());
} }
// if a workspace window is on any monitor, damage it
for (auto& w : g_pCompositor->m_vWindows) {
for (auto& m : g_pCompositor->m_vMonitors) {
if (w->m_iWorkspaceID == PWORKSPACE->m_iID && g_pCompositor->windowValidMapped(w.get()) && g_pHyprRenderer->shouldRenderWindow(w.get(), m.get(), PWORKSPACE)) {
CBox bb = w->getFullWindowBoundingBox();
bb.translate(PWORKSPACE->m_vRenderOffset.value());
if (PWORKSPACE->m_bIsSpecialWorkspace)
bb.scaleFromCenter(1.1); // for some reason special ws windows getting border artifacts if you close it too quickly...
bb.intersection({m->vecPosition, m->vecSize});
g_pHyprRenderer->damageBox(&bb);
}
}
}
} else if (PLAYER) { } else if (PLAYER) {
WLRBOXPREV = PLAYER->geometry; WLRBOXPREV = CBox{PLAYER->realPosition.value(), PLAYER->realSize.value()};
PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f); PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f);
if (!PMONITOR) if (!PMONITOR)
continue; continue;
@ -113,78 +134,48 @@ void CAnimationManager::tick() {
// beziers are with a switch unforto // beziers are with a switch unforto
// TODO: maybe do something cleaner // TODO: maybe do something cleaner
switch (av->m_eVarType) { auto updateVariable = [&]<Animable T>(CAnimatedVariable<T>& av) {
case AVARTYPE_FLOAT: {
// for disabled anims just warp // for disabled anims just warp
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) { if (av.m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) {
av->warp(false); av.warp(false);
break; return;
} }
if (SPENT >= 1.f || av->m_fBegun == av->m_fGoal) { if (SPENT >= 1.f || av.m_Begun == av.m_Goal) {
av->warp(false); av.warp(false);
break; return;
} }
const auto DELTA = av->m_fGoal - av->m_fBegun; const auto DELTA = av.m_Goal - av.m_Begun;
const auto BEZIER = m_mBezierCurves.find(av->m_pConfig->pValues->internalBezier); const auto BEZIER = m_mBezierCurves.find(av.m_pConfig->pValues->internalBezier);
if (BEZIER != m_mBezierCurves.end()) if (BEZIER != m_mBezierCurves.end())
av->m_fValue = av->m_fBegun + BEZIER->second.getYForPoint(SPENT) * DELTA; av.m_Value = av.m_Begun + DELTA * BEZIER->second.getYForPoint(SPENT);
else else
av->m_fValue = av->m_fBegun + DEFAULTBEZIER->second.getYForPoint(SPENT) * DELTA; av.m_Value = av.m_Begun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
};
switch (av->m_Type) {
case AVARTYPE_FLOAT: {
auto typedAv = static_cast<CAnimatedVariable<float>*>(av);
updateVariable(*typedAv);
break; break;
} }
case AVARTYPE_VECTOR: { case AVARTYPE_VECTOR: {
// for disabled anims just warp auto typedAv = static_cast<CAnimatedVariable<Vector2D>*>(av);
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) { updateVariable(*typedAv);
av->warp(false);
break;
}
if (SPENT >= 1.f || av->m_vBegun == av->m_vGoal) {
av->warp(false);
break;
}
const auto DELTA = av->m_vGoal - av->m_vBegun;
const auto BEZIER = m_mBezierCurves.find(av->m_pConfig->pValues->internalBezier);
if (BEZIER != m_mBezierCurves.end())
av->m_vValue = av->m_vBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
else
av->m_vValue = av->m_vBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
break; break;
} }
case AVARTYPE_COLOR: { case AVARTYPE_COLOR: {
// for disabled anims just warp auto typedAv = static_cast<CAnimatedVariable<CColor>*>(av);
if (av->m_pConfig->pValues->internalEnabled == 0 || animationsDisabled) { updateVariable(*typedAv);
av->warp(false);
break; break;
} }
default: UNREACHABLE();
if (SPENT >= 1.f || av->m_cBegun == av->m_cGoal) {
av->warp(false);
break;
} }
const auto DELTA = av->m_cGoal - av->m_cBegun;
const auto BEZIER = m_mBezierCurves.find(av->m_pConfig->pValues->internalBezier);
if (BEZIER != m_mBezierCurves.end())
av->m_cValue = av->m_cBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
else
av->m_cValue = av->m_cBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
break;
}
default: {
;
}
}
// set size and pos if valid, but only if damage policy entire (dont if border for example) // set size and pos if valid, but only if damage policy entire (dont if border for example)
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2) if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2)
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv()); g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goal());
// check if we did not finish animating. If so, trigger onAnimationEnd. // check if we did not finish animating. If so, trigger onAnimationEnd.
if (!av->isBeingAnimated()) if (!av->isBeingAnimated())
@ -203,7 +194,10 @@ void CAnimationManager::tick() {
if (PWINDOW) { if (PWINDOW) {
PWINDOW->updateWindowDecos(); PWINDOW->updateWindowDecos();
g_pHyprRenderer->damageWindow(PWINDOW); auto bb = PWINDOW->getFullWindowBoundingBox();
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
bb.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
g_pHyprRenderer->damageBox(&bb);
} else if (PWORKSPACE) { } else if (PWORKSPACE) {
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped || w->isHidden()) if (!w->m_bIsMapped || w->isHidden())
@ -216,7 +210,7 @@ void CAnimationManager::tick() {
if (w->m_bIsFloating) { if (w->m_bIsFloating) {
auto bb = w->getFullWindowBoundingBox(); auto bb = w->getFullWindowBoundingBox();
bb.translate(PWORKSPACE->m_vRenderOffset.vec()); bb.translate(PWORKSPACE->m_vRenderOffset.value());
g_pHyprRenderer->damageBox(&bb); g_pHyprRenderer->damageBox(&bb);
} }
} }
@ -250,7 +244,10 @@ void CAnimationManager::tick() {
BORDERSIZE + ROUNDINGSIZE); // bottom BORDERSIZE + ROUNDINGSIZE); // bottom
// damage for new box // damage for new box
const CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.vec().x, PWINDOW->m_vRealPosition.vec().y, PWINDOW->m_vRealSize.vec().x, PWINDOW->m_vRealSize.vec().y}; CBox WLRBOXNEW = {PWINDOW->m_vRealPosition.value(), PWINDOW->m_vRealSize.value()};
const auto PWINDOWWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
if (PWINDOWWORKSPACE)
WLRBOXNEW.translate(PWINDOWWORKSPACE->m_vRenderOffset.value());
g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, WLRBOXNEW.width + 2 * BORDERSIZE, BORDERSIZE + ROUNDINGSIZE); // top
g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // left g_pHyprRenderer->damageBox(WLRBOXNEW.x - BORDERSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, WLRBOXNEW.height + 2 * BORDERSIZE); // left
g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE, g_pHyprRenderer->damageBox(WLRBOXNEW.x + WLRBOXNEW.width - ROUNDINGSIZE, WLRBOXNEW.y - BORDERSIZE, BORDERSIZE + ROUNDINGSIZE,
@ -323,23 +320,23 @@ bool CAnimationManager::bezierExists(const std::string& bezier) {
// //
void CAnimationManager::animationPopin(CWindow* pWindow, bool close, float minPerc) { void CAnimationManager::animationPopin(CWindow* pWindow, bool close, float minPerc) {
const auto GOALPOS = pWindow->m_vRealPosition.goalv(); const auto GOALPOS = pWindow->m_vRealPosition.goal();
const auto GOALSIZE = pWindow->m_vRealSize.goalv(); const auto GOALSIZE = pWindow->m_vRealSize.goal();
if (!close) { if (!close) {
pWindow->m_vRealSize.setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y})); pWindow->m_vRealSize.setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}));
pWindow->m_vRealPosition.setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_vValue / 2.f); pWindow->m_vRealPosition.setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_Value / 2.f);
} else { } else {
pWindow->m_vRealSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}); pWindow->m_vRealSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y});
pWindow->m_vRealPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_vGoal / 2.f; pWindow->m_vRealPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_vRealSize.m_Goal / 2.f;
} }
} }
void CAnimationManager::animationSlide(CWindow* pWindow, std::string force, bool close) { void CAnimationManager::animationSlide(CWindow* pWindow, std::string force, bool close) {
pWindow->m_vRealSize.warp(false); // size we preserve in slide pWindow->m_vRealSize.warp(false); // size we preserve in slide
const auto GOALPOS = pWindow->m_vRealPosition.goalv(); const auto GOALPOS = pWindow->m_vRealPosition.goal();
const auto GOALSIZE = pWindow->m_vRealSize.goalv(); const auto GOALSIZE = pWindow->m_vRealSize.goal();
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
@ -513,6 +510,27 @@ std::string CAnimationManager::styleValidInConfigVar(const std::string& config,
if (style == "loop" || style == "once") if (style == "loop" || style == "once")
return ""; return "";
return "unknown style"; return "unknown style";
} else if (config.starts_with("layers")) {
if (style == "fade" || style == "" || style == "slide")
return "";
else if (style.starts_with("popin")) {
// try parsing
float minPerc = 0.f;
if (style.find("%") != std::string::npos) {
try {
auto percstr = style.substr(style.find_last_of(' '));
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
} catch (std::exception& e) { return "invalid minperc"; }
return "";
}
minPerc; // fix warning
return "";
}
return "";
return "unknown style";
} else { } else {
return "animation has no styles"; return "animation has no styles";
} }

View file

@ -28,8 +28,8 @@ class CAnimationManager {
std::unordered_map<std::string, CBezierCurve> getAllBeziers(); std::unordered_map<std::string, CBezierCurve> getAllBeziers();
std::vector<CAnimatedVariable*> m_vAnimatedVariables; std::vector<CBaseAnimatedVariable*> m_vAnimatedVariables;
std::vector<CAnimatedVariable*> m_vActiveAnimatedVariables; std::vector<CBaseAnimatedVariable*> m_vActiveAnimatedVariables;
wl_event_source* m_pAnimationTick; wl_event_source* m_pAnimationTick;

View file

@ -0,0 +1,231 @@
#include "CursorManager.hpp"
#include "Compositor.hpp"
#include "../config/ConfigValue.hpp"
extern "C" {
#include <wlr/interfaces/wlr_buffer.h>
#include <wlr/types/wlr_xcursor_manager.h>
}
static int cursorAnimTimer(void* data) {
g_pCursorManager->tickAnimatedCursor();
return 1;
}
CCursorManager::CCursorManager() {
m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(m_szTheme.empty() ? nullptr : m_szTheme.c_str());
// find default size. First, HYPRCURSOR_SIZE, then XCURSOR_SIZE, then 24
auto SIZE = getenv("HYPRCURSOR_SIZE");
if (SIZE) {
try {
m_iSize = std::stoi(SIZE);
} catch (...) { ; }
}
SIZE = getenv("XCURSOR_SIZE");
if (SIZE && m_iSize == 0) {
try {
m_iSize = std::stoi(SIZE);
} catch (...) { ; }
}
if (m_iSize == 0)
m_iSize = 24;
m_pWLRXCursorMgr = wlr_xcursor_manager_create(getenv("XCURSOR_THEME"), m_iSize);
wlr_xcursor_manager_load(m_pWLRXCursorMgr, 1.0);
m_pAnimationTimer = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, ::cursorAnimTimer, nullptr);
updateTheme();
g_pHookSystem->hookDynamic("monitorLayoutChanged", [this](void* self, SCallbackInfo& info, std::any param) { this->updateTheme(); });
}
void CCursorManager::dropBufferRef(CCursorManager::CCursorBuffer* ref) {
std::erase_if(m_vCursorBuffers, [ref](const auto& buf) { return buf.get() == ref; });
}
static void cursorBufferDestroy(struct wlr_buffer* wlr_buffer) {
CCursorManager::CCursorBuffer::SCursorWlrBuffer* buffer = wl_container_of(wlr_buffer, buffer, base);
g_pCursorManager->dropBufferRef(buffer->parent);
}
static bool cursorBufferBeginDataPtr(struct wlr_buffer* wlr_buffer, uint32_t flags, void** data, uint32_t* format, size_t* stride) {
CCursorManager::CCursorBuffer::SCursorWlrBuffer* buffer = wl_container_of(wlr_buffer, buffer, base);
if (flags & WLR_BUFFER_DATA_PTR_ACCESS_WRITE)
return false;
*data = cairo_image_surface_get_data(buffer->surface);
*stride = cairo_image_surface_get_stride(buffer->surface);
*format = DRM_FORMAT_ARGB8888;
return true;
}
static void cursorBufferEndDataPtr(struct wlr_buffer* wlr_buffer) {
;
}
//
static const wlr_buffer_impl bufferImpl = {
.destroy = cursorBufferDestroy,
.begin_data_ptr_access = cursorBufferBeginDataPtr,
.end_data_ptr_access = cursorBufferEndDataPtr,
};
CCursorManager::CCursorBuffer::CCursorBuffer(cairo_surface_t* surf, const Vector2D& size_, const Vector2D& hot_) : size(size_), hotspot(hot_) {
wlrBuffer.surface = surf;
wlr_buffer_init(&wlrBuffer.base, &bufferImpl, size.x, size.y);
wlrBuffer.parent = this;
}
CCursorManager::CCursorBuffer::~CCursorBuffer() {
; // will be freed in .destroy
}
wlr_buffer* CCursorManager::getCursorBuffer() {
return !m_vCursorBuffers.empty() ? &m_vCursorBuffers.back()->wlrBuffer.base : nullptr;
}
void CCursorManager::setCursorSurface(wlr_surface* surf, const Vector2D& hotspot) {
wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, surf, hotspot.x, hotspot.y);
m_bOurBufferConnected = false;
}
void CCursorManager::setCursorFromName(const std::string& name) {
static auto PUSEHYPRCURSOR = CConfigValue<Hyprlang::INT>("misc:enable_hyprcursor");
if (!m_pHyprcursor->valid() || !*PUSEHYPRCURSOR) {
wlr_cursor_set_xcursor(g_pCompositor->m_sWLRCursor, m_pWLRXCursorMgr, name.c_str());
return;
}
m_sCurrentCursorShapeData = m_pHyprcursor->getShape(name.c_str(), m_sCurrentStyleInfo);
if (m_sCurrentCursorShapeData.images.size() < 1) {
// fallback to a default if available
constexpr const std::array<const char*, 2> fallbackShapes = {"default", "left_ptr"};
for (auto& s : fallbackShapes) {
m_sCurrentCursorShapeData = m_pHyprcursor->getShape(s, m_sCurrentStyleInfo);
if (m_sCurrentCursorShapeData.images.size() > 0)
break;
}
if (m_sCurrentCursorShapeData.images.size() < 1) {
Debug::log(ERR, "BUG THIS: No fallback found for a cursor in setCursorFromName");
return;
}
}
m_vCursorBuffers.emplace_back(std::make_unique<CCursorBuffer>(m_sCurrentCursorShapeData.images[0].surface,
Vector2D{m_sCurrentCursorShapeData.images[0].size, m_sCurrentCursorShapeData.images[0].size},
Vector2D{m_sCurrentCursorShapeData.images[0].hotspotX, m_sCurrentCursorShapeData.images[0].hotspotY}));
if (g_pCompositor->m_sWLRCursor) {
wlr_cursor_set_buffer(g_pCompositor->m_sWLRCursor, getCursorBuffer(), m_sCurrentCursorShapeData.images[0].hotspotX, m_sCurrentCursorShapeData.images[0].hotspotY,
m_fCursorScale);
if (m_vCursorBuffers.size() > 1)
wlr_buffer_drop(&m_vCursorBuffers.front()->wlrBuffer.base);
}
m_bOurBufferConnected = true;
if (m_sCurrentCursorShapeData.images.size() > 1) {
// animated
wl_event_source_timer_update(m_pAnimationTimer, m_sCurrentCursorShapeData.images[0].delay);
m_iCurrentAnimationFrame = 0;
} else {
// disarm
wl_event_source_timer_update(m_pAnimationTimer, 0);
}
}
void CCursorManager::tickAnimatedCursor() {
if (m_sCurrentCursorShapeData.images.size() < 2 || !m_bOurBufferConnected)
return;
m_iCurrentAnimationFrame++;
if ((size_t)m_iCurrentAnimationFrame >= m_sCurrentCursorShapeData.images.size())
m_iCurrentAnimationFrame = 0;
m_vCursorBuffers.emplace_back(std::make_unique<CCursorBuffer>(
m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].surface,
Vector2D{m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].size, m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].size},
Vector2D{m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotX, m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotY}));
if (g_pCompositor->m_sWLRCursor)
wlr_cursor_set_buffer(g_pCompositor->m_sWLRCursor, getCursorBuffer(), m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotX,
m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].hotspotY, m_fCursorScale);
wl_event_source_timer_update(m_pAnimationTimer, m_sCurrentCursorShapeData.images[m_iCurrentAnimationFrame].delay);
}
SCursorImageData CCursorManager::dataFor(const std::string& name) {
if (!m_pHyprcursor->valid())
return {};
const auto IMAGES = m_pHyprcursor->getShape(name.c_str(), m_sCurrentStyleInfo);
if (IMAGES.images.empty())
return {};
return IMAGES.images[0];
}
void CCursorManager::setXWaylandCursor(wlr_xwayland* xwayland) {
const auto CURSOR = dataFor("left_ptr");
if (CURSOR.surface) {
wlr_xwayland_set_cursor(xwayland, cairo_image_surface_get_data(CURSOR.surface), cairo_image_surface_get_stride(CURSOR.surface), CURSOR.size, CURSOR.size, CURSOR.hotspotX,
CURSOR.hotspotY);
} else if (const auto XCURSOR = wlr_xcursor_manager_get_xcursor(m_pWLRXCursorMgr, "left_ptr", 1); XCURSOR) {
wlr_xwayland_set_cursor(xwayland, XCURSOR->images[0]->buffer, XCURSOR->images[0]->width * 4, XCURSOR->images[0]->width, XCURSOR->images[0]->height,
XCURSOR->images[0]->hotspot_x, XCURSOR->images[0]->hotspot_y);
} else
Debug::log(ERR, "CursorManager: no valid cursor for xwayland");
}
void CCursorManager::updateTheme() {
float highestScale = 1.0;
for (auto& m : g_pCompositor->m_vMonitors) {
if (m->scale > highestScale)
highestScale = m->scale;
}
if (highestScale * m_iSize == m_sCurrentStyleInfo.size)
return;
if (m_sCurrentStyleInfo.size && m_pHyprcursor->valid())
m_pHyprcursor->cursorSurfaceStyleDone(m_sCurrentStyleInfo);
m_sCurrentStyleInfo.size = m_iSize * highestScale;
m_fCursorScale = highestScale;
if (m_pHyprcursor->valid())
m_pHyprcursor->loadThemeStyle(m_sCurrentStyleInfo);
setCursorFromName("left_ptr");
for (auto& m : g_pCompositor->m_vMonitors) {
m->forceFullFrames = 5;
g_pCompositor->scheduleFrameForMonitor(m.get());
}
}
void CCursorManager::changeTheme(const std::string& name, const int size) {
m_pHyprcursor = std::make_unique<Hyprcursor::CHyprcursorManager>(name.empty() ? "" : name.c_str());
m_szTheme = name;
m_iSize = size;
setenv("XCURSOR_SIZE", std::to_string(m_iSize).c_str(), true);
setenv("XCURSOR_THEME", name.c_str(), true);
updateTheme();
}

View file

@ -0,0 +1,71 @@
#pragma once
#include <string>
#include <hyprcursor/hyprcursor.hpp>
#include <memory>
#include "../includes.hpp"
#include "../helpers/Vector2D.hpp"
struct wlr_buffer;
struct wlr_xcursor_manager;
struct wlr_xwayland;
class CCursorManager {
public:
CCursorManager();
wlr_buffer* getCursorBuffer();
void setCursorFromName(const std::string& name);
void setCursorSurface(wlr_surface* surf, const Vector2D& hotspot);
void changeTheme(const std::string& name, const int size);
void updateTheme();
SCursorImageData dataFor(const std::string& name); // for xwayland
void setXWaylandCursor(wlr_xwayland* xwayland);
void tickAnimatedCursor();
class CCursorBuffer {
public:
CCursorBuffer(cairo_surface_t* surf, const Vector2D& size, const Vector2D& hotspot);
~CCursorBuffer();
struct SCursorWlrBuffer {
wlr_buffer base;
cairo_surface_t* surface = nullptr;
bool dropped = false;
CCursorBuffer* parent = nullptr;
} wlrBuffer;
private:
Vector2D size;
Vector2D hotspot;
friend class CCursorManager;
};
void dropBufferRef(CCursorBuffer* ref);
bool m_bOurBufferConnected = false;
private:
std::vector<std::unique_ptr<CCursorBuffer>> m_vCursorBuffers;
std::unique_ptr<Hyprcursor::CHyprcursorManager> m_pHyprcursor;
std::string m_szTheme = "";
int m_iSize = 24;
float m_fCursorScale = 1.0;
Hyprcursor::SCursorStyleInfo m_sCurrentStyleInfo;
wl_event_source* m_pAnimationTimer = nullptr;
int m_iCurrentAnimationFrame = 0;
Hyprcursor::SCursorShapeData m_sCurrentCursorShapeData;
// xcursor fallback
wlr_xcursor_manager* m_pWLRXCursorMgr = nullptr;
};
inline std::unique_ptr<CCursorManager> g_pCursorManager;

View file

@ -2,6 +2,7 @@
#include "../render/decorations/CHyprGroupBarDecoration.hpp" #include "../render/decorations/CHyprGroupBarDecoration.hpp"
#include "debug/Log.hpp" #include "debug/Log.hpp"
#include "helpers/VarList.hpp" #include "helpers/VarList.hpp"
#include "../config/ConfigValue.hpp"
#include <regex> #include <regex>
@ -95,18 +96,9 @@ void CKeybindManager::addKeybind(SKeybind kb) {
m_pActiveKeybind = nullptr; m_pActiveKeybind = nullptr;
} }
void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) { void CKeybindManager::removeKeybind(uint32_t mod, const SParsedKey& key) {
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) { for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) {
if (isNumber(key) && std::stoi(key) > 9) { if (it->modmask == mod && it->key == key.key && it->keycode == key.keycode && it->catchAll == key.catchAll) {
const uint32_t KEYNUM = std::stoi(key);
if (it->modmask == mod && it->keycode == KEYNUM) {
it = m_lKeybinds.erase(it);
if (it == m_lKeybinds.end())
break;
}
} else if (it->modmask == mod && it->key == key) {
it = m_lKeybinds.erase(it); it = m_lKeybinds.erase(it);
if (it == m_lKeybinds.end()) if (it == m_lKeybinds.end())
@ -164,12 +156,12 @@ void CKeybindManager::updateXKBTranslationState() {
m_pXKBTranslationState = nullptr; m_pXKBTranslationState = nullptr;
} }
static auto* const PFILEPATH = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("input:kb_file"); static auto PFILEPATH = CConfigValue<std::string>("input:kb_file");
static auto* const PRULES = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("input:kb_rules"); static auto PRULES = CConfigValue<std::string>("input:kb_rules");
static auto* const PMODEL = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("input:kb_model"); static auto PMODEL = CConfigValue<std::string>("input:kb_model");
static auto* const PLAYOUT = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("input:kb_layout"); static auto PLAYOUT = CConfigValue<std::string>("input:kb_layout");
static auto* const PVARIANT = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("input:kb_variant"); static auto PVARIANT = CConfigValue<std::string>("input:kb_variant");
static auto* const POPTIONS = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("input:kb_options"); static auto POPTIONS = CConfigValue<std::string>("input:kb_options");
const std::string FILEPATH = std::string{*PFILEPATH} == STRVAL_EMPTY ? "" : *PFILEPATH; const std::string FILEPATH = std::string{*PFILEPATH} == STRVAL_EMPTY ? "" : *PFILEPATH;
const std::string RULES = std::string{*PRULES} == STRVAL_EMPTY ? "" : *PRULES; const std::string RULES = std::string{*PRULES} == STRVAL_EMPTY ? "" : *PRULES;
@ -234,7 +226,7 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
const auto PNEWMAINWORKSPACE = g_pCompositor->getWorkspaceByID(monitor->activeWorkspace); const auto PNEWMAINWORKSPACE = g_pCompositor->getWorkspaceByID(monitor->activeWorkspace);
g_pCompositor->setActiveMonitor(monitor); g_pInputManager->unconstrainMouse();
PNEWMAINWORKSPACE->rememberPrevWorkspace(PWORKSPACE); PNEWMAINWORKSPACE->rememberPrevWorkspace(PWORKSPACE);
const auto PNEWWORKSPACE = monitor->specialWorkspaceID != 0 ? g_pCompositor->getWorkspaceByID(monitor->specialWorkspaceID) : PNEWMAINWORKSPACE; const auto PNEWWORKSPACE = monitor->specialWorkspaceID != 0 ? g_pCompositor->getWorkspaceByID(monitor->specialWorkspaceID) : PNEWMAINWORKSPACE;
@ -243,10 +235,15 @@ bool CKeybindManager::tryMoveFocusToMonitor(CMonitor* monitor) {
if (PNEWWINDOW) { if (PNEWWINDOW) {
g_pCompositor->focusWindow(PNEWWINDOW); g_pCompositor->focusWindow(PNEWWINDOW);
g_pCompositor->warpCursorTo(PNEWWINDOW->middle()); g_pCompositor->warpCursorTo(PNEWWINDOW->middle());
g_pInputManager->m_pForcedFocus = PNEWWINDOW;
g_pInputManager->simulateMouseMovement();
g_pInputManager->m_pForcedFocus = nullptr;
} else { } else {
g_pCompositor->focusWindow(nullptr); g_pCompositor->focusWindow(nullptr);
g_pCompositor->warpCursorTo(monitor->middle()); g_pCompositor->warpCursorTo(monitor->middle());
} }
g_pCompositor->setActiveMonitor(monitor);
return true; return true;
} }
@ -257,6 +254,9 @@ void CKeybindManager::switchToWindow(CWindow* PWINDOWTOCHANGETO) {
if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO) if (PWINDOWTOCHANGETO == PLASTWINDOW || !PWINDOWTOCHANGETO)
return; return;
// remove constraints
g_pInputManager->unconstrainMouse();
if (PLASTWINDOW && PLASTWINDOW->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && PLASTWINDOW->m_bIsFullscreen) { if (PLASTWINDOW && PLASTWINDOW->m_iWorkspaceID == PWINDOWTOCHANGETO->m_iWorkspaceID && PLASTWINDOW->m_bIsFullscreen) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PLASTWINDOW->m_iWorkspaceID); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PLASTWINDOW->m_iWorkspaceID);
const auto FSMODE = PWORKSPACE->m_efFullscreenMode; const auto FSMODE = PWORKSPACE->m_efFullscreenMode;
@ -323,6 +323,7 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
.keycode = KEYCODE, .keycode = KEYCODE,
.modmaskAtPressTime = MODS, .modmaskAtPressTime = MODS,
.sent = true, .sent = true,
.submapAtPress = m_szCurrentSelectedSubmap,
}; };
bool suppressEvent = false; bool suppressEvent = false;
@ -353,7 +354,8 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
bool foundInPressedKeys = false; bool foundInPressedKeys = false;
for (auto it = m_dPressedKeys.begin(); it != m_dPressedKeys.end();) { for (auto it = m_dPressedKeys.begin(); it != m_dPressedKeys.end();) {
if (it->keycode == KEYCODE) { if (it->keycode == KEYCODE) {
suppressEvent = handleKeybinds(MODS, *it, false); if (it->submapAtPress == m_szCurrentSelectedSubmap)
handleKeybinds(MODS, *it, false);
foundInPressedKeys = true; foundInPressedKeys = true;
suppressEvent = !it->sent; suppressEvent = !it->sent;
it = m_dPressedKeys.erase(it); it = m_dPressedKeys.erase(it);
@ -376,9 +378,9 @@ bool CKeybindManager::onKeyEvent(wlr_keyboard_key_event* e, SKeyboard* pKeyboard
bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) { bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
const auto MODS = g_pInputManager->accumulateModsFromAllKBs(); const auto MODS = g_pInputManager->accumulateModsFromAllKBs();
static auto* const PDELAY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:scroll_event_delay"); static auto PDELAY = CConfigValue<Hyprlang::INT>("binds:scroll_event_delay");
if (m_tScrollTimer.getMillis() < **PDELAY) { if (m_tScrollTimer.getMillis() < *PDELAY) {
m_tScrollTimer.reset(); m_tScrollTimer.reset();
return true; // timer hasn't passed yet! return true; // timer hasn't passed yet!
} }
@ -386,12 +388,12 @@ bool CKeybindManager::onAxisEvent(wlr_pointer_axis_event* e) {
m_tScrollTimer.reset(); m_tScrollTimer.reset();
bool found = false; bool found = false;
if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_VERTICAL) { if (e->source == WL_POINTER_AXIS_SOURCE_WHEEL && e->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) {
if (e->delta < 0) if (e->delta < 0)
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_down"}, true); found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_down"}, true);
else else
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_up"}, true); found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_up"}, true);
} else if (e->source == WLR_AXIS_SOURCE_WHEEL && e->orientation == WLR_AXIS_ORIENTATION_HORIZONTAL) { } else if (e->source == WL_POINTER_AXIS_SOURCE_WHEEL && e->orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
if (e->delta < 0) if (e->delta < 0)
found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_left"}, true); found = handleKeybinds(MODS, SPressedKeyWithMods{.keyName = "mouse_left"}, true);
else else
@ -422,7 +424,7 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
.modmaskAtPressTime = MODS, .modmaskAtPressTime = MODS,
}; };
if (e->state == WLR_BUTTON_PRESSED) { if (e->state == WL_POINTER_BUTTON_STATE_PRESSED) {
m_dPressedKeys.push_back(KEY); m_dPressedKeys.push_back(KEY);
suppressEvent = handleKeybinds(MODS, KEY, true); suppressEvent = handleKeybinds(MODS, KEY, true);
@ -456,7 +458,7 @@ bool CKeybindManager::onMouseEvent(wlr_pointer_button_event* e) {
} }
void CKeybindManager::resizeWithBorder(wlr_pointer_button_event* e) { void CKeybindManager::resizeWithBorder(wlr_pointer_button_event* e) {
if (e->state == WLR_BUTTON_PRESSED) { if (e->state == WL_POINTER_BUTTON_STATE_PRESSED) {
mouse("1resizewindow"); mouse("1resizewindow");
} else { } else {
mouse("0resizewindow"); mouse("0resizewindow");
@ -523,13 +525,16 @@ bool CKeybindManager::handleKeybinds(const uint32_t modmask, const SPressedKeyWi
} else if (k.keycode != 0) { } else if (k.keycode != 0) {
if (key.keycode != k.keycode) if (key.keycode != k.keycode)
continue; continue;
} else if (k.catchAll) {
if (found)
continue;
} else { } else {
// oMg such performance hit!!11! // oMg such performance hit!!11!
// this little maneouver is gonna cost us 4µs // this little maneouver is gonna cost us 4µs
const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE); const auto KBKEY = xkb_keysym_from_name(k.key.c_str(), XKB_KEYSYM_CASE_INSENSITIVE);
if (KBKEY == 0) { if (KBKEY == 0) {
// Keysym failed to resolve from the key name of the the currently iterated bind. // Keysym failed to resolve from the key name of the currently iterated bind.
// This happens for names such as `switch:off:Lid Switch` as well as some keys // This happens for names such as `switch:off:Lid Switch` as well as some keys
// (such as yen and ro). // (such as yen and ro).
// //
@ -791,9 +796,9 @@ uint64_t CKeybindManager::spawnRaw(std::string args) {
close(socket[1]); close(socket[1]);
read(socket[0], &grandchild, sizeof(grandchild)); read(socket[0], &grandchild, sizeof(grandchild));
close(socket[0]); close(socket[0]);
// clear child and leave child to init // clear child and leave grandchild to init
waitpid(child, NULL, 0); waitpid(child, NULL, 0);
if (child < 0) { if (grandchild < 0) {
Debug::log(LOG, "Fail to create the second fork"); Debug::log(LOG, "Fail to create the second fork");
return 0; return 0;
} }
@ -870,8 +875,8 @@ void CKeybindManager::centerWindow(std::string args) {
if (args == "1") if (args == "1")
RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f; RESERVEDOFFSET = (PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight) / 2.f;
PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goalv() / 2.f + RESERVEDOFFSET; PWINDOW->m_vRealPosition = PMONITOR->middle() - PWINDOW->m_vRealSize.goal() / 2.f + RESERVEDOFFSET;
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv(); PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goal();
} }
void CKeybindManager::toggleActivePseudo(std::string args) { void CKeybindManager::toggleActivePseudo(std::string args) {
@ -892,9 +897,9 @@ void CKeybindManager::changeworkspace(std::string args) {
// Workspace_back_and_forth being enabled means that an attempt to switch to // Workspace_back_and_forth being enabled means that an attempt to switch to
// the current workspace will instead switch to the previous. // the current workspace will instead switch to the previous.
static auto* const PBACKANDFORTH = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:workspace_back_and_forth"); static auto PBACKANDFORTH = CConfigValue<Hyprlang::INT>("binds:workspace_back_and_forth");
static auto* const PALLOWWORKSPACECYCLES = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles"); static auto PALLOWWORKSPACECYCLES = CConfigValue<Hyprlang::INT>("binds:allow_workspace_cycles");
static auto* const PWORKSPACECENTERON = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:workspace_center_on"); static auto PWORKSPACECENTERON = CConfigValue<Hyprlang::INT>("binds:workspace_center_on");
const auto PMONITOR = g_pCompositor->m_pLastMonitor; const auto PMONITOR = g_pCompositor->m_pLastMonitor;
@ -929,7 +934,7 @@ void CKeybindManager::changeworkspace(std::string args) {
const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID; const bool BISWORKSPACECURRENT = workspaceToChangeTo == PCURRENTWORKSPACE->m_iID;
if (BISWORKSPACECURRENT && (!(**PBACKANDFORTH || EXPLICITPREVIOUS) || PCURRENTWORKSPACE->m_sPrevWorkspace.iID == -1)) if (BISWORKSPACECURRENT && (!(*PBACKANDFORTH || EXPLICITPREVIOUS) || PCURRENTWORKSPACE->m_sPrevWorkspace.iID == -1))
return; return;
g_pInputManager->unconstrainMouse(); g_pInputManager->unconstrainMouse();
@ -961,14 +966,14 @@ void CKeybindManager::changeworkspace(std::string args) {
Vector2D middle = PMONITORWORKSPACEOWNER->middle(); Vector2D middle = PMONITORWORKSPACEOWNER->middle();
if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) { if (const auto PLAST = pWorkspaceToChangeTo->getLastFocusedWindow(); PLAST) {
g_pCompositor->focusWindow(PLAST); g_pCompositor->focusWindow(PLAST);
if (**PWORKSPACECENTERON == 1) if (*PWORKSPACECENTERON == 1)
middle = PLAST->middle(); middle = PLAST->middle();
} }
g_pCompositor->warpCursorTo(middle); g_pCompositor->warpCursorTo(middle);
} }
if (BISWORKSPACECURRENT) { if (BISWORKSPACECURRENT) {
if (**PALLOWWORKSPACECYCLES) if (*PALLOWWORKSPACECYCLES)
pWorkspaceToChangeTo->rememberPrevWorkspace(PCURRENTWORKSPACE); pWorkspaceToChangeTo->rememberPrevWorkspace(PCURRENTWORKSPACE);
else if (!EXPLICITPREVIOUS) else if (!EXPLICITPREVIOUS)
pWorkspaceToChangeTo->rememberPrevWorkspace(nullptr); pWorkspaceToChangeTo->rememberPrevWorkspace(nullptr);
@ -989,9 +994,6 @@ void CKeybindManager::fullscreenActive(std::string args) {
if (!PWINDOW) if (!PWINDOW)
return; return;
if (g_pCompositor->isWorkspaceSpecial(PWINDOW->m_iWorkspaceID))
return;
PWINDOW->m_bDontSendFullscreen = false; PWINDOW->m_bDontSendFullscreen = false;
if (args == "2") if (args == "2")
PWINDOW->m_bDontSendFullscreen = true; PWINDOW->m_bDontSendFullscreen = true;
@ -1029,7 +1031,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
auto pWorkspace = g_pCompositor->getWorkspaceByID(WORKSPACEID); auto pWorkspace = g_pCompositor->getWorkspaceByID(WORKSPACEID);
CMonitor* pMonitor = nullptr; CMonitor* pMonitor = nullptr;
const auto POLDWS = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); const auto POLDWS = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
static auto* const PALLOWWORKSPACECYCLES = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:allow_workspace_cycles"); static auto PALLOWWORKSPACECYCLES = CConfigValue<Hyprlang::INT>("binds:allow_workspace_cycles");
g_pHyprRenderer->damageWindow(PWINDOW); g_pHyprRenderer->damageWindow(PWINDOW);
@ -1055,7 +1057,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
g_pCompositor->focusWindow(PWINDOW); g_pCompositor->focusWindow(PWINDOW);
g_pCompositor->warpCursorTo(PWINDOW->middle()); g_pCompositor->warpCursorTo(PWINDOW->middle());
if (**PALLOWWORKSPACECYCLES) if (*PALLOWWORKSPACECYCLES)
pWorkspace->rememberPrevWorkspace(POLDWS); pWorkspace->rememberPrevWorkspace(POLDWS);
} }
@ -1107,7 +1109,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
} }
void CKeybindManager::moveFocusTo(std::string args) { void CKeybindManager::moveFocusTo(std::string args) {
static auto* const PFULLCYCLE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:movefocus_cycles_fullscreen"); static auto PFULLCYCLE = CConfigValue<Hyprlang::INT>("binds:movefocus_cycles_fullscreen");
char arg = args[0]; char arg = args[0];
if (!isDirection(args)) { if (!isDirection(args)) {
@ -1121,10 +1123,7 @@ void CKeybindManager::moveFocusTo(std::string args) {
return; return;
} }
// remove constraints const auto PWINDOWTOCHANGETO = *PFULLCYCLE && PLASTWINDOW->m_bIsFullscreen ?
g_pInputManager->unconstrainMouse();
const auto PWINDOWTOCHANGETO = **PFULLCYCLE && PLASTWINDOW->m_bIsFullscreen ?
(arg == 'd' || arg == 'b' || arg == 'r' ? g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true) : g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true)) : (arg == 'd' || arg == 'b' || arg == 'r' ? g_pCompositor->getNextWindowOnWorkspace(PLASTWINDOW, true) : g_pCompositor->getPrevWindowOnWorkspace(PLASTWINDOW, true)) :
g_pCompositor->getWindowInDirection(PLASTWINDOW, arg); g_pCompositor->getWindowInDirection(PLASTWINDOW, arg);
@ -1139,8 +1138,8 @@ void CKeybindManager::moveFocusTo(std::string args) {
if (tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg))) if (tryMoveFocusToMonitor(g_pCompositor->getMonitorInDirection(arg)))
return; return;
static auto* const PNOFALLBACK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:no_focus_fallback"); static auto PNOFALLBACK = CConfigValue<Hyprlang::INT>("general:no_focus_fallback");
if (**PNOFALLBACK) if (*PNOFALLBACK)
return; return;
Debug::log(LOG, "No monitor found in direction {}, falling back to next window on current workspace", arg); Debug::log(LOG, "No monitor found in direction {}, falling back to next window on current workspace", arg);
@ -1158,9 +1157,6 @@ void CKeybindManager::focusUrgentOrLast(std::string args) {
if (!PWINDOWURGENT && !PWINDOWPREV) if (!PWINDOWURGENT && !PWINDOWPREV)
return; return;
// remove constraints
g_pInputManager->unconstrainMouse();
switchToWindow(PWINDOWURGENT ? PWINDOWURGENT : PWINDOWPREV); switchToWindow(PWINDOWURGENT ? PWINDOWURGENT : PWINDOWPREV);
} }
@ -1171,9 +1167,6 @@ void CKeybindManager::focusCurrentOrLast(std::string args) {
if (!PWINDOWPREV) if (!PWINDOWPREV)
return; return;
// remove constraints
g_pInputManager->unconstrainMouse();
switchToWindow(PWINDOWPREV); switchToWindow(PWINDOWPREV);
} }
@ -1227,14 +1220,14 @@ void CKeybindManager::moveActiveTo(std::string args) {
switch (arg) { switch (arg) {
case 'l': vPos.x = PMONITOR->vecReservedTopLeft.x + BORDERSIZE + PMONITOR->vecPosition.x; break; case 'l': vPos.x = PMONITOR->vecReservedTopLeft.x + BORDERSIZE + PMONITOR->vecPosition.x; break;
case 'r': vPos.x = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PLASTWINDOW->m_vRealSize.goalv().x - BORDERSIZE + PMONITOR->vecPosition.x; break; case 'r': vPos.x = PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x - PLASTWINDOW->m_vRealSize.goal().x - BORDERSIZE + PMONITOR->vecPosition.x; break;
case 't': case 't':
case 'u': vPos.y = PMONITOR->vecReservedTopLeft.y + BORDERSIZE + PMONITOR->vecPosition.y; break; case 'u': vPos.y = PMONITOR->vecReservedTopLeft.y + BORDERSIZE + PMONITOR->vecPosition.y; break;
case 'b': case 'b':
case 'd': vPos.y = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PLASTWINDOW->m_vRealSize.goalv().y - BORDERSIZE + PMONITOR->vecPosition.y; break; case 'd': vPos.y = PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y - PLASTWINDOW->m_vRealSize.goal().y - BORDERSIZE + PMONITOR->vecPosition.y; break;
} }
PLASTWINDOW->m_vRealPosition = Vector2D(vPos.x != 0 ? vPos.x : PLASTWINDOW->m_vRealPosition.goalv().x, vPos.y != 0 ? vPos.y : PLASTWINDOW->m_vRealPosition.goalv().y); PLASTWINDOW->m_vRealPosition = Vector2D(vPos.x != 0 ? vPos.x : PLASTWINDOW->m_vRealPosition.goal().x, vPos.y != 0 ? vPos.y : PLASTWINDOW->m_vRealPosition.goal().y);
return; return;
} }
@ -1382,22 +1375,22 @@ void CKeybindManager::moveCursorToCorner(std::string arg) {
switch (CORNER) { switch (CORNER) {
case 0: case 0:
// bottom left // bottom left
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.vec().x, wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x,
PWINDOW->m_vRealPosition.vec().y + PWINDOW->m_vRealSize.vec().y); PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
break; break;
case 1: case 1:
// bottom right // bottom right
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.vec().x + PWINDOW->m_vRealSize.vec().x, wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
PWINDOW->m_vRealPosition.vec().y + PWINDOW->m_vRealSize.vec().y); PWINDOW->m_vRealPosition.value().y + PWINDOW->m_vRealSize.value().y);
break; break;
case 2: case 2:
// top right // top right
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.vec().x + PWINDOW->m_vRealSize.vec().x, wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x + PWINDOW->m_vRealSize.value().x,
PWINDOW->m_vRealPosition.vec().y); PWINDOW->m_vRealPosition.value().y);
break; break;
case 3: case 3:
// top left // top left
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.vec().x, PWINDOW->m_vRealPosition.vec().y); wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, PWINDOW->m_vRealPosition.value().x, PWINDOW->m_vRealPosition.value().y);
break; break;
} }
} }
@ -1462,8 +1455,8 @@ void CKeybindManager::workspaceOpt(std::string args) {
continue; continue;
if (!w->m_bRequestsFloat && w->m_bIsFloating != PWORKSPACE->m_bDefaultFloating) { if (!w->m_bRequestsFloat && w->m_bIsFloating != PWORKSPACE->m_bDefaultFloating) {
const auto SAVEDPOS = w->m_vRealPosition.vec(); const auto SAVEDPOS = w->m_vRealPosition.value();
const auto SAVEDSIZE = w->m_vRealSize.vec(); const auto SAVEDSIZE = w->m_vRealSize.value();
w->m_bIsFloating = PWORKSPACE->m_bDefaultFloating; w->m_bIsFloating = PWORKSPACE->m_bDefaultFloating;
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(w); g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(w);
@ -1472,8 +1465,8 @@ void CKeybindManager::workspaceOpt(std::string args) {
w->m_vRealPosition.setValueAndWarp(SAVEDPOS); w->m_vRealPosition.setValueAndWarp(SAVEDPOS);
w->m_vRealSize.setValueAndWarp(SAVEDSIZE); w->m_vRealSize.setValueAndWarp(SAVEDSIZE);
g_pXWaylandManager->setWindowSize(w, SAVEDSIZE); g_pXWaylandManager->setWindowSize(w, SAVEDSIZE);
w->m_vRealSize = w->m_vRealSize.vec() + Vector2D(4, 4); w->m_vRealSize = w->m_vRealSize.value() + Vector2D(4, 4);
w->m_vRealPosition = w->m_vRealPosition.vec() - Vector2D(2, 2); w->m_vRealPosition = w->m_vRealPosition.value() - Vector2D(2, 2);
} }
} }
} }
@ -1556,9 +1549,9 @@ void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) { void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) {
std::string workspaceName; std::string workspaceName;
const int WORKSPACEID = getWorkspaceIDFromString(args, workspaceName); int workspaceID = getWorkspaceIDFromString(args, workspaceName);
if (WORKSPACEID == WORKSPACE_INVALID) { if (workspaceID == WORKSPACE_INVALID) {
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!"); Debug::log(ERR, "focusWorkspaceOnCurrentMonitor invalid workspace!");
return; return;
} }
@ -1570,35 +1563,48 @@ void CKeybindManager::focusWorkspaceOnCurrentMonitor(std::string args) {
return; return;
} }
auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID); auto pWorkspace = g_pCompositor->getWorkspaceByID(workspaceID);
if (!PWORKSPACE) { if (!pWorkspace) {
PWORKSPACE = g_pCompositor->createNewWorkspace(WORKSPACEID, PCURRMONITOR->ID); pWorkspace = g_pCompositor->createNewWorkspace(workspaceID, PCURRMONITOR->ID);
// we can skip the moving, since it's already on the current monitor // we can skip the moving, since it's already on the current monitor
changeworkspace(PWORKSPACE->getConfigName()); changeworkspace(pWorkspace->getConfigName());
return; return;
} }
if (PWORKSPACE->m_iMonitorID != PCURRMONITOR->ID) { static auto PBACKANDFORTH = CConfigValue<Hyprlang::INT>("binds:workspace_back_and_forth");
const auto POLDMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
if (*PBACKANDFORTH && PCURRMONITOR->activeWorkspace == workspaceID && pWorkspace->m_sPrevWorkspace.iID != -1) {
const int PREVWORKSPACEID = pWorkspace->m_sPrevWorkspace.iID;
const auto PREVWORKSPACENAME = pWorkspace->m_sPrevWorkspace.name;
// Workspace to focus is previous workspace
pWorkspace = g_pCompositor->getWorkspaceByID(PREVWORKSPACEID);
if (!pWorkspace)
pWorkspace = g_pCompositor->createNewWorkspace(PREVWORKSPACEID, PCURRMONITOR->ID, PREVWORKSPACENAME);
workspaceID = pWorkspace->m_iID;
}
if (pWorkspace->m_iMonitorID != PCURRMONITOR->ID) {
const auto POLDMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
if (!POLDMONITOR) { // wat if (!POLDMONITOR) { // wat
Debug::log(ERR, "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!"); Debug::log(ERR, "focusWorkspaceOnCurrentMonitor old monitor doesn't exist!");
return; return;
} }
if (POLDMONITOR->activeWorkspace == WORKSPACEID) { if (POLDMONITOR->activeWorkspace == workspaceID) {
g_pCompositor->swapActiveWorkspaces(POLDMONITOR, PCURRMONITOR); g_pCompositor->swapActiveWorkspaces(POLDMONITOR, PCURRMONITOR);
return; return;
} else { } else {
g_pCompositor->moveWorkspaceToMonitor(PWORKSPACE, PCURRMONITOR, true); g_pCompositor->moveWorkspaceToMonitor(pWorkspace, PCURRMONITOR, true);
} }
} }
changeworkspace(PWORKSPACE->getConfigName()); changeworkspace(pWorkspace->getConfigName());
} }
void CKeybindManager::toggleSpecialWorkspace(std::string args) { void CKeybindManager::toggleSpecialWorkspace(std::string args) {
static auto* const PFOLLOWMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
std::string workspaceName = ""; std::string workspaceName = "";
int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName); int workspaceID = getWorkspaceIDFromString("special:" + args, workspaceName);
@ -1609,7 +1615,7 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
} }
bool requestedWorkspaceIsAlreadyOpen = false; bool requestedWorkspaceIsAlreadyOpen = false;
const auto PMONITOR = **PFOLLOWMOUSE == 1 ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->m_pLastMonitor; const auto PMONITOR = *PFOLLOWMOUSE == 1 ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->m_pLastMonitor;
int specialOpenOnMonitor = PMONITOR->specialWorkspaceID; int specialOpenOnMonitor = PMONITOR->specialWorkspaceID;
for (auto& m : g_pCompositor->m_vMonitors) { for (auto& m : g_pCompositor->m_vMonitors) {
@ -1656,14 +1662,14 @@ void CKeybindManager::resizeActive(std::string args) {
if (!g_pCompositor->m_pLastWindow || g_pCompositor->m_pLastWindow->m_bIsFullscreen) if (!g_pCompositor->m_pLastWindow || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
return; return;
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goalv()); const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealSize.goal());
if (SIZ.x < 1 || SIZ.y < 1) if (SIZ.x < 1 || SIZ.y < 1)
return; return;
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - g_pCompositor->m_pLastWindow->m_vRealSize.goalv()); g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - g_pCompositor->m_pLastWindow->m_vRealSize.goal());
if (g_pCompositor->m_pLastWindow->m_vRealSize.goalv().x > 1 && g_pCompositor->m_pLastWindow->m_vRealSize.goalv().y > 1) if (g_pCompositor->m_pLastWindow->m_vRealSize.goal().x > 1 && g_pCompositor->m_pLastWindow->m_vRealSize.goal().y > 1)
g_pCompositor->m_pLastWindow->setHidden(false); g_pCompositor->m_pLastWindow->setHidden(false);
} }
@ -1671,9 +1677,9 @@ void CKeybindManager::moveActive(std::string args) {
if (!g_pCompositor->m_pLastWindow || g_pCompositor->m_pLastWindow->m_bIsFullscreen) if (!g_pCompositor->m_pLastWindow || g_pCompositor->m_pLastWindow->m_bIsFullscreen)
return; return;
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goalv()); const auto POS = g_pCompositor->parseWindowVectorArgsRelative(args, g_pCompositor->m_pLastWindow->m_vRealPosition.goal());
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - g_pCompositor->m_pLastWindow->m_vRealPosition.goalv()); g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - g_pCompositor->m_pLastWindow->m_vRealPosition.goal());
} }
void CKeybindManager::moveWindow(std::string args) { void CKeybindManager::moveWindow(std::string args) {
@ -1691,9 +1697,9 @@ void CKeybindManager::moveWindow(std::string args) {
if (PWINDOW->m_bIsFullscreen) if (PWINDOW->m_bIsFullscreen)
return; return;
const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition.goalv()); const auto POS = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealPosition.goal());
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition.goalv(), PWINDOW); g_pLayoutManager->getCurrentLayout()->moveActiveWindow(POS - PWINDOW->m_vRealPosition.goal(), PWINDOW);
} }
void CKeybindManager::resizeWindow(std::string args) { void CKeybindManager::resizeWindow(std::string args) {
@ -1711,14 +1717,14 @@ void CKeybindManager::resizeWindow(std::string args) {
if (PWINDOW->m_bIsFullscreen) if (PWINDOW->m_bIsFullscreen)
return; return;
const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goalv()); const auto SIZ = g_pCompositor->parseWindowVectorArgsRelative(MOVECMD, PWINDOW->m_vRealSize.goal());
if (SIZ.x < 1 || SIZ.y < 1) if (SIZ.x < 1 || SIZ.y < 1)
return; return;
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goalv(), CORNER_NONE, PWINDOW); g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(SIZ - PWINDOW->m_vRealSize.goal(), CORNER_NONE, PWINDOW);
if (PWINDOW->m_vRealSize.goalv().x > 1 && PWINDOW->m_vRealSize.goalv().y > 1) if (PWINDOW->m_vRealSize.goal().x > 1 && PWINDOW->m_vRealSize.goal().y > 1)
PWINDOW->setHidden(false); PWINDOW->setHidden(false);
} }
@ -1855,20 +1861,20 @@ void CKeybindManager::pass(std::string regexp) {
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED); wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED);
else else
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_PRESSED); wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_PRESSED);
} else if (g_pKeybindManager->m_iPassPressed == 0) } else if (g_pKeybindManager->m_iPassPressed == 0)
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED); wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED);
else else
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_RELEASED); wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_RELEASED);
else { else {
// dynamic call of the dispatcher // dynamic call of the dispatcher
if (g_pKeybindManager->m_uLastCode != 0) { if (g_pKeybindManager->m_uLastCode != 0) {
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED); wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_PRESSED);
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED); wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastCode - 8, WLR_BUTTON_RELEASED);
} else { } else {
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_PRESSED); wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_PRESSED);
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WLR_BUTTON_RELEASED); wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, g_pKeybindManager->m_uTimeLastMs, g_pKeybindManager->m_uLastMouseCode, WL_POINTER_BUTTON_STATE_RELEASED);
} }
} }
@ -2144,8 +2150,8 @@ void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDi
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property! g_pLayoutManager->getCurrentLayout()->onWindowRemoved(pWindow); // This removes groupped property!
static const auto* USECURRPOS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("group:insert_after_current"); static auto USECURRPOS = CConfigValue<Hyprlang::INT>("group:insert_after_current");
pWindowInDirection = **USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail(); pWindowInDirection = *USECURRPOS ? pWindowInDirection : pWindowInDirection->getGroupTail();
pWindowInDirection->insertWindowToGroup(pWindow); pWindowInDirection->insertWindowToGroup(pWindow);
pWindowInDirection->setGroupCurrent(pWindow); pWindowInDirection->setGroupCurrent(pWindow);
@ -2159,7 +2165,7 @@ void CKeybindManager::moveWindowIntoGroup(CWindow* pWindow, CWindow* pWindowInDi
} }
void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir) { void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string& dir) {
static auto* const BFOCUSREMOVEDWINDOW = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("group:focus_removed_window"); static auto BFOCUSREMOVEDWINDOW = CConfigValue<Hyprlang::INT>("group:focus_removed_window");
const auto PWINDOWPREV = pWindow->getGroupPrevious(); const auto PWINDOWPREV = pWindow->getGroupPrevious();
eDirection direction; eDirection direction;
@ -2186,7 +2192,7 @@ void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string&
g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV; g_pKeybindManager->m_bGroupsLocked = GROUPSLOCKEDPREV;
} }
if (**BFOCUSREMOVEDWINDOW) { if (*BFOCUSREMOVEDWINDOW) {
g_pCompositor->focusWindow(pWindow); g_pCompositor->focusWindow(pWindow);
g_pCompositor->warpCursorTo(pWindow->middle()); g_pCompositor->warpCursorTo(pWindow->middle());
} else { } else {
@ -2198,9 +2204,9 @@ void CKeybindManager::moveWindowOutOfGroup(CWindow* pWindow, const std::string&
void CKeybindManager::moveIntoGroup(std::string args) { void CKeybindManager::moveIntoGroup(std::string args) {
char arg = args[0]; char arg = args[0];
static auto* const PIGNOREGROUPLOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock"); static auto PIGNOREGROUPLOCK = CConfigValue<Hyprlang::INT>("binds:ignore_group_lock");
if (!**PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked) if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked)
return; return;
if (!isDirection(args)) { if (!isDirection(args)) {
@ -2219,16 +2225,16 @@ void CKeybindManager::moveIntoGroup(std::string args) {
return; return;
// Do not move window into locked group if binds:ignore_group_lock is false // Do not move window into locked group if binds:ignore_group_lock is false
if (!**PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || (PWINDOW->m_sGroupData.pNextWindow && PWINDOW->getGroupHead()->m_sGroupData.locked))) if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || (PWINDOW->m_sGroupData.pNextWindow && PWINDOW->getGroupHead()->m_sGroupData.locked)))
return; return;
moveWindowIntoGroup(PWINDOW, PWINDOWINDIR); moveWindowIntoGroup(PWINDOW, PWINDOWINDIR);
} }
void CKeybindManager::moveOutOfGroup(std::string args) { void CKeybindManager::moveOutOfGroup(std::string args) {
static auto* const PIGNOREGROUPLOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock"); static auto PIGNOREGROUPLOCK = CConfigValue<Hyprlang::INT>("binds:ignore_group_lock");
if (!**PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked) if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked)
return; return;
CWindow* PWINDOW = nullptr; CWindow* PWINDOW = nullptr;
@ -2247,7 +2253,7 @@ void CKeybindManager::moveOutOfGroup(std::string args) {
void CKeybindManager::moveWindowOrGroup(std::string args) { void CKeybindManager::moveWindowOrGroup(std::string args) {
char arg = args[0]; char arg = args[0];
static auto* const PIGNOREGROUPLOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock"); static auto PIGNOREGROUPLOCK = CConfigValue<Hyprlang::INT>("binds:ignore_group_lock");
if (!isDirection(args)) { if (!isDirection(args)) {
Debug::log(ERR, "Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg); Debug::log(ERR, "Cannot move into group in direction {}, unsupported direction. Supported: l,r,u/t,d/b", arg);
@ -2258,7 +2264,7 @@ void CKeybindManager::moveWindowOrGroup(std::string args) {
if (!PWINDOW || PWINDOW->m_bIsFullscreen) if (!PWINDOW || PWINDOW->m_bIsFullscreen)
return; return;
if (!**PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked) { if (!*PIGNOREGROUPLOCK && g_pKeybindManager->m_bGroupsLocked) {
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
return; return;
} }
@ -2271,13 +2277,13 @@ void CKeybindManager::moveWindowOrGroup(std::string args) {
// note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating // note: PWINDOWINDIR is not null implies !PWINDOW->m_bIsFloating
if (PWINDOWINDIR && PWINDOWINDIR->m_sGroupData.pNextWindow) { // target is group if (PWINDOWINDIR && PWINDOWINDIR->m_sGroupData.pNextWindow) { // target is group
if (!**PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || ISWINDOWGROUPLOCKED || PWINDOW->m_sGroupData.deny)) { if (!*PIGNOREGROUPLOCK && (PWINDOWINDIR->getGroupHead()->m_sGroupData.locked || ISWINDOWGROUPLOCKED || PWINDOW->m_sGroupData.deny)) {
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
g_pCompositor->warpCursorTo(PWINDOW->middle()); g_pCompositor->warpCursorTo(PWINDOW->middle());
} else } else
moveWindowIntoGroup(PWINDOW, PWINDOWINDIR); moveWindowIntoGroup(PWINDOW, PWINDOWINDIR);
} else if (PWINDOWINDIR) { // target is regular window } else if (PWINDOWINDIR) { // target is regular window
if ((!**PIGNOREGROUPLOCK && ISWINDOWGROUPLOCKED) || !ISWINDOWGROUP || (ISWINDOWGROUPSINGLE && PWINDOW->m_eGroupRules & GROUP_SET_ALWAYS)) { if ((!*PIGNOREGROUPLOCK && ISWINDOWGROUPLOCKED) || !ISWINDOWGROUP || (ISWINDOWGROUPSINGLE && PWINDOW->m_eGroupRules & GROUP_SET_ALWAYS)) {
g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args); g_pLayoutManager->getCurrentLayout()->moveWindowTo(PWINDOW, args);
g_pCompositor->warpCursorTo(PWINDOW->middle()); g_pCompositor->warpCursorTo(PWINDOW->middle());
} else } else
@ -2293,14 +2299,14 @@ void CKeybindManager::moveWindowOrGroup(std::string args) {
} }
void CKeybindManager::setIgnoreGroupLock(std::string args) { void CKeybindManager::setIgnoreGroupLock(std::string args) {
static auto* const BIGNOREGROUPLOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock"); static auto PIGNOREGROUPLOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:ignore_group_lock");
if (args == "toggle") if (args == "toggle")
**BIGNOREGROUPLOCK = !*BIGNOREGROUPLOCK; **PIGNOREGROUPLOCK = !**PIGNOREGROUPLOCK;
else else
**BIGNOREGROUPLOCK = args == "on"; **PIGNOREGROUPLOCK = args == "on";
g_pEventManager->postEvent(SHyprIPCEvent{"ignoregrouplock", std::to_string(**BIGNOREGROUPLOCK)}); g_pEventManager->postEvent(SHyprIPCEvent{"ignoregrouplock", std::to_string(**PIGNOREGROUPLOCK)});
} }
void CKeybindManager::denyWindowFromGroup(std::string args) { void CKeybindManager::denyWindowFromGroup(std::string args) {

View file

@ -13,6 +13,7 @@ class CPluginSystem;
struct SKeybind { struct SKeybind {
std::string key = ""; std::string key = "";
uint32_t keycode = 0; uint32_t keycode = 0;
bool catchAll = false;
uint32_t modmask = 0; uint32_t modmask = 0;
std::string handler = ""; std::string handler = "";
std::string arg = ""; std::string arg = "";
@ -42,6 +43,13 @@ struct SPressedKeyWithMods {
uint32_t keycode = 0; uint32_t keycode = 0;
uint32_t modmaskAtPressTime = 0; uint32_t modmaskAtPressTime = 0;
bool sent = false; bool sent = false;
std::string submapAtPress = "";
};
struct SParsedKey {
std::string key = "";
uint32_t keycode = 0;
bool catchAll = false;
}; };
class CKeybindManager { class CKeybindManager {
@ -57,7 +65,7 @@ class CKeybindManager {
void onSwitchOffEvent(const std::string&); void onSwitchOffEvent(const std::string&);
void addKeybind(SKeybind); void addKeybind(SKeybind);
void removeKeybind(uint32_t, const std::string&); void removeKeybind(uint32_t, const SParsedKey&);
uint32_t stringToModMask(std::string); uint32_t stringToModMask(std::string);
uint32_t keycodeToModifier(xkb_keycode_t); uint32_t keycodeToModifier(xkb_keycode_t);
void clearKeybinds(); void clearKeybinds();

View file

@ -1,5 +1,6 @@
#include "SessionLockManager.hpp" #include "SessionLockManager.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
static void handleSurfaceMap(void* owner, void* data) { static void handleSurfaceMap(void* owner, void* data) {
const auto PSURFACE = (SSessionLockSurface*)owner; const auto PSURFACE = (SSessionLockSurface*)owner;
@ -14,8 +15,6 @@ static void handleSurfaceMap(void* owner, void* data) {
if (PMONITOR) if (PMONITOR)
g_pHyprRenderer->damageMonitor(PMONITOR); g_pHyprRenderer->damageMonitor(PMONITOR);
g_pSessionLockManager->activateLock(); // activate lock here to prevent the red screen from flashing before that
} }
static void handleSurfaceCommit(void* owner, void* data) { static void handleSurfaceCommit(void* owner, void* data) {
@ -44,9 +43,9 @@ static void handleSurfaceDestroy(void* owner, void* data) {
void CSessionLockManager::onNewSessionLock(wlr_session_lock_v1* pWlrLock) { void CSessionLockManager::onNewSessionLock(wlr_session_lock_v1* pWlrLock) {
static auto* const PALLOWRELOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:allow_session_lock_restore"); static auto PALLOWRELOCK = CConfigValue<Hyprlang::INT>("misc:allow_session_lock_restore");
if (m_sSessionLock.active && (!**PALLOWRELOCK || m_sSessionLock.pWlrLock)) { if (m_sSessionLock.active && (!*PALLOWRELOCK || m_sSessionLock.pWlrLock)) {
Debug::log(LOG, "Attempted to lock a locked session!"); Debug::log(LOG, "Attempted to lock a locked session!");
wlr_session_lock_v1_destroy(pWlrLock); wlr_session_lock_v1_destroy(pWlrLock);
return; return;
@ -96,6 +95,8 @@ void CSessionLockManager::onNewSessionLock(wlr_session_lock_v1* pWlrLock) {
m_sSessionLock.active = false; m_sSessionLock.active = false;
m_sSessionLock.mMonitorsWithoutMappedSurfaceTimers.clear();
g_pCompositor->m_sSeat.exclusiveClient = nullptr; g_pCompositor->m_sSeat.exclusiveClient = nullptr;
g_pInputManager->refocus(); g_pInputManager->refocus();
@ -125,13 +126,15 @@ void CSessionLockManager::onNewSessionLock(wlr_session_lock_v1* pWlrLock) {
pWlrLock, "wlr_session_lock_v1"); pWlrLock, "wlr_session_lock_v1");
wlr_session_lock_v1_send_locked(pWlrLock); wlr_session_lock_v1_send_locked(pWlrLock);
g_pSessionLockManager->activateLock();
} }
bool CSessionLockManager::isSessionLocked() { bool CSessionLockManager::isSessionLocked() {
return m_sSessionLock.active; return m_sSessionLock.active;
} }
SSessionLockSurface* CSessionLockManager::getSessionLockSurfaceForMonitor(const int& id) { SSessionLockSurface* CSessionLockManager::getSessionLockSurfaceForMonitor(uint64_t id) {
for (auto& sls : m_sSessionLock.vSessionLockSurfaces) { for (auto& sls : m_sSessionLock.vSessionLockSurfaces) {
if (sls->iMonitorID == id) { if (sls->iMonitorID == id) {
if (sls->mapped) if (sls->mapped)
@ -144,6 +147,20 @@ SSessionLockSurface* CSessionLockManager::getSessionLockSurfaceForMonitor(const
return nullptr; return nullptr;
} }
// We don't want the red screen to flash.
// This violates the protocol a bit, but tries to handle the missing sync between a lock surface beeing created and the red screen beeing drawn.
float CSessionLockManager::getRedScreenAlphaForMonitor(uint64_t id) {
const auto& NOMAPPEDSURFACETIMER = m_sSessionLock.mMonitorsWithoutMappedSurfaceTimers.find(id);
if (NOMAPPEDSURFACETIMER == m_sSessionLock.mMonitorsWithoutMappedSurfaceTimers.end()) {
m_sSessionLock.mMonitorsWithoutMappedSurfaceTimers.emplace(id, CTimer());
m_sSessionLock.mMonitorsWithoutMappedSurfaceTimers[id].reset();
return 0.f;
}
return std::clamp(NOMAPPEDSURFACETIMER->second.getSeconds() - /* delay for screencopy */ 0.5f, 0.f, 1.f);
}
bool CSessionLockManager::isSurfaceSessionLock(wlr_surface* pSurface) { bool CSessionLockManager::isSurfaceSessionLock(wlr_surface* pSurface) {
for (auto& sls : m_sSessionLock.vSessionLockSurfaces) { for (auto& sls : m_sSessionLock.vSessionLockSurfaces) {
if (sls->pWlrLockSurface->surface == pSurface) if (sls->pWlrLockSurface->surface == pSurface)
@ -155,6 +172,17 @@ bool CSessionLockManager::isSurfaceSessionLock(wlr_surface* pSurface) {
void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) { void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
std::erase_if(m_sSessionLock.vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); }); std::erase_if(m_sSessionLock.vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
if (g_pCompositor->m_pLastFocus)
return;
for (auto& sls : m_sSessionLock.vSessionLockSurfaces) {
if (!sls->mapped)
continue;
g_pCompositor->focusSurface(sls->pWlrLockSurface->surface);
break;
}
} }
void CSessionLockManager::activateLock() { void CSessionLockManager::activateLock() {

View file

@ -1,10 +1,13 @@
#pragma once #pragma once
#include "../defines.hpp" #include "../defines.hpp"
#include "../helpers/Timer.hpp"
#include <cstdint>
#include <unordered_map>
struct SSessionLockSurface { struct SSessionLockSurface {
wlr_session_lock_surface_v1* pWlrLockSurface = nullptr; wlr_session_lock_surface_v1* pWlrLockSurface = nullptr;
int iMonitorID = -1; uint64_t iMonitorID = -1;
bool mapped = false; bool mapped = false;
@ -18,6 +21,7 @@ struct SSessionLock {
wlr_session_lock_v1* pWlrLock = nullptr; wlr_session_lock_v1* pWlrLock = nullptr;
std::vector<std::unique_ptr<SSessionLockSurface>> vSessionLockSurfaces; std::vector<std::unique_ptr<SSessionLockSurface>> vSessionLockSurfaces;
std::unordered_map<uint64_t, CTimer> mMonitorsWithoutMappedSurfaceTimers;
DYNLISTENER(newSurface); DYNLISTENER(newSurface);
DYNLISTENER(unlock); DYNLISTENER(unlock);
@ -30,7 +34,9 @@ class CSessionLockManager {
~CSessionLockManager() = default; ~CSessionLockManager() = default;
void onNewSessionLock(wlr_session_lock_v1*); void onNewSessionLock(wlr_session_lock_v1*);
SSessionLockSurface* getSessionLockSurfaceForMonitor(const int&); SSessionLockSurface* getSessionLockSurfaceForMonitor(uint64_t);
float getRedScreenAlphaForMonitor(uint64_t);
bool isSessionLocked(); bool isSessionLocked();
bool isSurfaceSessionLock(wlr_surface*); bool isSurfaceSessionLock(wlr_surface*);

View file

@ -1,15 +1,16 @@
#include "ThreadManager.hpp" #include "ThreadManager.hpp"
#include "../debug/HyprCtl.hpp" #include "../debug/HyprCtl.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
int slowUpdate = 0; int slowUpdate = 0;
int handleTimer(void* data) { int handleTimer(void* data) {
const auto PTM = (CThreadManager*)data; const auto PTM = (CThreadManager*)data;
static auto* const PDISABLECFGRELOAD = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:disable_autoreload"); static auto PDISABLECFGRELOAD = CConfigValue<Hyprlang::INT>("misc:disable_autoreload");
if (**PDISABLECFGRELOAD != 1) if (*PDISABLECFGRELOAD != 1)
g_pConfigManager->tick(); g_pConfigManager->tick();
wl_event_source_timer_update(PTM->m_esConfigTimer, 1000); wl_event_source_timer_update(PTM->m_esConfigTimer, 1000);

View file

@ -2,6 +2,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "xdg-output-unstable-v1-protocol.h" #include "xdg-output-unstable-v1-protocol.h"
#include "../config/ConfigValue.hpp"
#define OUTPUT_MANAGER_VERSION 3 #define OUTPUT_MANAGER_VERSION 3
#define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3 #define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3
@ -55,7 +56,7 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) { void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
if (pWindow->m_bIsX11) { if (pWindow->m_bIsX11) {
setWindowSize(pWindow, pWindow->m_vRealSize.vec()); // update xwayland output pos setWindowSize(pWindow, pWindow->m_vRealSize.value()); // update xwayland output pos
if (activate) { if (activate) {
wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false); wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false);
@ -98,15 +99,18 @@ void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, CBox* pbox) {
} }
std::string CHyprXWaylandManager::getTitle(CWindow* pWindow) { std::string CHyprXWaylandManager::getTitle(CWindow* pWindow) {
try {
if (pWindow->m_bIsX11) {
if (!pWindow->m_bIsMapped) if (!pWindow->m_bIsMapped)
return ""; return "";
try {
if (pWindow->m_bIsX11) {
if (pWindow->m_uSurface.xwayland && pWindow->m_uSurface.xwayland->title) { if (pWindow->m_uSurface.xwayland && pWindow->m_uSurface.xwayland->title) {
return std::string(pWindow->m_uSurface.xwayland->title); return std::string(pWindow->m_uSurface.xwayland->title);
} }
} else if (pWindow->m_uSurface.xdg) { } else if (pWindow->m_uSurface.xdg) {
if (pWindow->m_bFadingOut || !pWindow->m_uSurface.xdg)
return "";
if (pWindow->m_uSurface.xdg->toplevel && pWindow->m_uSurface.xdg->toplevel->title) { if (pWindow->m_uSurface.xdg->toplevel && pWindow->m_uSurface.xdg->toplevel->title) {
return std::string(pWindow->m_uSurface.xdg->toplevel->title); return std::string(pWindow->m_uSurface.xdg->toplevel->title);
} }
@ -119,15 +123,18 @@ std::string CHyprXWaylandManager::getTitle(CWindow* pWindow) {
} }
std::string CHyprXWaylandManager::getAppIDClass(CWindow* pWindow) { std::string CHyprXWaylandManager::getAppIDClass(CWindow* pWindow) {
try {
if (pWindow->m_bIsX11) {
if (!pWindow->m_bIsMapped) if (!pWindow->m_bIsMapped)
return ""; return "";
try {
if (pWindow->m_bIsX11) {
if (pWindow->m_uSurface.xwayland && pWindow->m_uSurface.xwayland->_class) { if (pWindow->m_uSurface.xwayland && pWindow->m_uSurface.xwayland->_class) {
return std::string(pWindow->m_uSurface.xwayland->_class); return std::string(pWindow->m_uSurface.xwayland->_class);
} }
} else if (pWindow->m_uSurface.xdg) { } else if (pWindow->m_uSurface.xdg) {
if (pWindow->m_bFadingOut || !pWindow->m_uSurface.xdg)
return "";
if (pWindow->m_uSurface.xdg->toplevel && pWindow->m_uSurface.xdg->toplevel->app_id) { if (pWindow->m_uSurface.xdg->toplevel && pWindow->m_uSurface.xdg->toplevel->app_id) {
return std::string(pWindow->m_uSurface.xdg->toplevel->app_id); return std::string(pWindow->m_uSurface.xdg->toplevel->app_id);
} }
@ -147,7 +154,7 @@ void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool force) { void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool force) {
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
@ -155,11 +162,11 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f
// calculate pos // calculate pos
// TODO: this should be decoupled from setWindowSize IMO // TODO: this should be decoupled from setWindowSize IMO
Vector2D windowPos = pWindow->m_vRealPosition.vec(); Vector2D windowPos = pWindow->m_vRealPosition.value();
if (pWindow->m_bIsX11 && PMONITOR) { if (pWindow->m_bIsX11 && PMONITOR) {
windowPos = windowPos - PMONITOR->vecPosition; // normalize to monitor windowPos = windowPos - PMONITOR->vecPosition; // normalize to monitor
if (**PXWLFORCESCALEZERO) if (*PXWLFORCESCALEZERO)
windowPos = windowPos * PMONITOR->scale; // scale if applicable windowPos = windowPos * PMONITOR->scale; // scale if applicable
windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland windowPos = windowPos + PMONITOR->vecXWaylandPosition; // move to correct position for xwayland
} }
@ -172,7 +179,7 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f
pWindow->m_fX11SurfaceScaledBy = 1.f; pWindow->m_fX11SurfaceScaledBy = 1.f;
if (**PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) { if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11 && PMONITOR) {
size = size * PMONITOR->scale; size = size * PMONITOR->scale;
pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale; pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale;
} }
@ -198,7 +205,7 @@ wlr_surface* CHyprXWaylandManager::surfaceAt(CWindow* pWindow, const Vector2D& c
return wlr_xdg_surface_surface_at(pWindow->m_uSurface.xdg, client.x, client.y, &surface.x, &surface.y); return wlr_xdg_surface_surface_at(pWindow->m_uSurface.xdg, client.x, client.y, &surface.x, &surface.y);
} }
bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) { bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow, bool pending) {
if (pWindow->m_bIsX11) { if (pWindow->m_bIsX11) {
for (size_t i = 0; i < pWindow->m_uSurface.xwayland->window_type_len; i++) for (size_t i = 0; i < pWindow->m_uSurface.xwayland->window_type_len; i++)
if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] || if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] ||
@ -216,9 +223,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"]) pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"])
pWindow->m_bX11ShouldntFocus = true; pWindow->m_bX11ShouldntFocus = true;
if (pWindow->m_uSurface.xwayland->window_type[i] != HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"])
pWindow->m_bNoInitialFocus = true; pWindow->m_bNoInitialFocus = true;
return true; return true;
} }
@ -243,7 +248,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
if (SIZEHINTS && (pWindow->m_uSurface.xwayland->parent || ((SIZEHINTS->min_width == SIZEHINTS->max_width) && (SIZEHINTS->min_height == SIZEHINTS->max_height)))) if (SIZEHINTS && (pWindow->m_uSurface.xwayland->parent || ((SIZEHINTS->min_width == SIZEHINTS->max_width) && (SIZEHINTS->min_height == SIZEHINTS->max_height))))
return true; return true;
} else { } else {
const auto PSTATE = &pWindow->m_uSurface.xdg->toplevel->current; const auto PSTATE = pending ? &pWindow->m_uSurface.xdg->toplevel->pending : &pWindow->m_uSurface.xdg->toplevel->current;
if ((PSTATE->min_width != 0 && PSTATE->min_height != 0 && (PSTATE->min_width == PSTATE->max_width || PSTATE->min_height == PSTATE->max_height)) || if ((PSTATE->min_width != 0 && PSTATE->min_height != 0 && (PSTATE->min_width == PSTATE->max_width || PSTATE->min_height == PSTATE->max_height)) ||
pWindow->m_uSurface.xdg->toplevel->parent) pWindow->m_uSurface.xdg->toplevel->parent)
@ -260,7 +265,7 @@ void CHyprXWaylandManager::moveXWaylandWindow(CWindow* pWindow, const Vector2D&
if (!pWindow->m_bIsX11) if (!pWindow->m_bIsX11)
return; return;
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.vec().x, pWindow->m_vRealSize.vec().y); wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pos.x, pos.y, pWindow->m_vRealSize.value().x, pWindow->m_vRealSize.value().y);
} }
void CHyprXWaylandManager::checkBorders(CWindow* pWindow) { void CHyprXWaylandManager::checkBorders(CWindow* pWindow) {
@ -315,14 +320,29 @@ Vector2D CHyprXWaylandManager::getMaxSizeForWindow(CWindow* pWindow) {
return MAXSIZE; return MAXSIZE;
} }
Vector2D CHyprXWaylandManager::getMinSizeForWindow(CWindow* pWindow) {
if (!g_pCompositor->windowValidMapped(pWindow))
return Vector2D(0, 0);
if ((pWindow->m_bIsX11 && !pWindow->m_uSurface.xwayland->size_hints) || (!pWindow->m_bIsX11 && !pWindow->m_uSurface.xdg->toplevel))
return Vector2D(0, 0);
auto MINSIZE = pWindow->m_bIsX11 ? Vector2D(pWindow->m_uSurface.xwayland->size_hints->min_width, pWindow->m_uSurface.xwayland->size_hints->min_height) :
Vector2D(pWindow->m_uSurface.xdg->toplevel->current.min_width, pWindow->m_uSurface.xdg->toplevel->current.min_height);
MINSIZE = MINSIZE.clamp({1, 1});
return MINSIZE;
}
Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) { Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
CMonitor* pMonitor = nullptr; CMonitor* pMonitor = nullptr;
double bestDistance = __FLT_MAX__; double bestDistance = __FLT_MAX__;
for (auto& m : g_pCompositor->m_vMonitors) { for (auto& m : g_pCompositor->m_vMonitors) {
const auto SIZ = **PXWLFORCESCALEZERO ? m->vecTransformedSize : m->vecSize; const auto SIZ = *PXWLFORCESCALEZERO ? m->vecTransformedSize : m->vecSize;
double distance = double distance =
vecToRectDistanceSquared(coord, {m->vecXWaylandPosition.x, m->vecXWaylandPosition.y}, {m->vecXWaylandPosition.x + SIZ.x - 1, m->vecXWaylandPosition.y + SIZ.y - 1}); vecToRectDistanceSquared(coord, {m->vecXWaylandPosition.x, m->vecXWaylandPosition.y}, {m->vecXWaylandPosition.x + SIZ.x - 1, m->vecXWaylandPosition.y + SIZ.y - 1});
@ -339,7 +359,7 @@ Vector2D CHyprXWaylandManager::xwaylandToWaylandCoords(const Vector2D& coord) {
// get local coords // get local coords
Vector2D result = coord - pMonitor->vecXWaylandPosition; Vector2D result = coord - pMonitor->vecXWaylandPosition;
// if scaled, unscale // if scaled, unscale
if (**PXWLFORCESCALEZERO) if (*PXWLFORCESCALEZERO)
result = result / pMonitor->scale; result = result / pMonitor->scale;
// add pos // add pos
result = result + pMonitor->vecPosition; result = result + pMonitor->vecPosition;

View file

@ -23,10 +23,11 @@ class CHyprXWaylandManager {
void setWindowStyleTiled(CWindow*, uint32_t); void setWindowStyleTiled(CWindow*, uint32_t);
void setWindowFullscreen(CWindow*, bool); void setWindowFullscreen(CWindow*, bool);
wlr_surface* surfaceAt(CWindow*, const Vector2D&, Vector2D&); wlr_surface* surfaceAt(CWindow*, const Vector2D&, Vector2D&);
bool shouldBeFloated(CWindow*); bool shouldBeFloated(CWindow*, bool pending = false);
void moveXWaylandWindow(CWindow*, const Vector2D&); void moveXWaylandWindow(CWindow*, const Vector2D&);
void checkBorders(CWindow*); void checkBorders(CWindow*);
Vector2D getMaxSizeForWindow(CWindow*); Vector2D getMaxSizeForWindow(CWindow*);
Vector2D getMinSizeForWindow(CWindow*);
Vector2D xwaylandToWaylandCoords(const Vector2D&); Vector2D xwaylandToWaylandCoords(const Vector2D&);
}; };

View file

@ -2,9 +2,10 @@
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "wlr/types/wlr_switch.h" #include "wlr/types/wlr_switch.h"
#include <ranges> #include <ranges>
#include "../../config/ConfigValue.hpp"
CInputManager::~CInputManager() { CInputManager::~CInputManager() {
m_lConstraints.clear(); m_vConstraints.clear();
m_lKeyboards.clear(); m_lKeyboards.clear();
m_lMice.clear(); m_lMice.clear();
m_lTablets.clear(); m_lTablets.clear();
@ -16,20 +17,20 @@ CInputManager::~CInputManager() {
} }
void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) { void CInputManager::onMouseMoved(wlr_pointer_motion_event* e) {
static auto* const PSENS = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("general:sensitivity"); static auto PSENS = CConfigValue<Hyprlang::FLOAT>("general:sensitivity");
static auto* const PNOACCEL = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:force_no_accel"); static auto PNOACCEL = CConfigValue<Hyprlang::INT>("input:force_no_accel");
static auto* const PSENSTORAW = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:apply_sens_to_raw"); static auto PSENSTORAW = CConfigValue<Hyprlang::INT>("general:apply_sens_to_raw");
const auto DELTA = **PNOACCEL == 1 ? Vector2D(e->unaccel_dx, e->unaccel_dy) : Vector2D(e->delta_x, e->delta_y); const auto DELTA = *PNOACCEL == 1 ? Vector2D(e->unaccel_dx, e->unaccel_dy) : Vector2D(e->delta_x, e->delta_y);
if (**PSENSTORAW == 1) if (*PSENSTORAW == 1)
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x * **PSENS, wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x * *PSENS,
DELTA.y * **PSENS, e->unaccel_dx * **PSENS, e->unaccel_dy * **PSENS); DELTA.y * *PSENS, e->unaccel_dx * *PSENS, e->unaccel_dy * *PSENS);
else else
wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x, DELTA.y, wlr_relative_pointer_manager_v1_send_relative_motion(g_pCompositor->m_sWLRRelPointerMgr, g_pCompositor->m_sSeat.seat, (uint64_t)e->time_msec * 1000, DELTA.x, DELTA.y,
e->unaccel_dx, e->unaccel_dy); e->unaccel_dx, e->unaccel_dy);
wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, DELTA.x * **PSENS, DELTA.y * **PSENS); wlr_cursor_move(g_pCompositor->m_sWLRCursor, &e->pointer->base, DELTA.x * *PSENS, DELTA.y * *PSENS);
mouseMoveUnified(e->time_msec); mouseMoveUnified(e->time_msec);
@ -56,7 +57,7 @@ void CInputManager::simulateMouseMovement() {
} }
void CInputManager::sendMotionEventsToFocused() { void CInputManager::sendMotionEventsToFocused() {
if (!g_pCompositor->m_pLastFocus) if (!g_pCompositor->m_pLastFocus || isConstrained())
return; return;
// todo: this sucks ass // todo: this sucks ass
@ -66,24 +67,26 @@ void CInputManager::sendMotionEventsToFocused() {
timespec now; timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_vRealPosition.goalv() : (PLS ? Vector2D{PLS->geometry.x, PLS->geometry.y} : Vector2D{})); const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_vRealPosition.goal() : (PLS ? Vector2D{PLS->geometry.x, PLS->geometry.y} : Vector2D{}));
m_bEmptyFocusCursorSet = false;
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, g_pCompositor->m_pLastFocus, LOCAL.x, LOCAL.y); wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, g_pCompositor->m_pLastFocus, LOCAL.x, LOCAL.y);
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, now.tv_sec * 1000 + now.tv_nsec / 10000000, LOCAL.x, LOCAL.y); wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, now.tv_sec * 1000 + now.tv_nsec / 10000000, LOCAL.x, LOCAL.y);
} }
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
static auto* const PFOLLOWMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto* const PMOUSEREFOCUS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:mouse_refocus"); static auto PMOUSEREFOCUS = CConfigValue<Hyprlang::INT>("input:mouse_refocus");
static auto* const PMOUSEDPMS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:mouse_move_enables_dpms"); static auto PMOUSEDPMS = CConfigValue<Hyprlang::INT>("misc:mouse_move_enables_dpms");
static auto* const PFOLLOWONDND = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:always_follow_on_dnd"); static auto PFOLLOWONDND = CConfigValue<Hyprlang::INT>("misc:always_follow_on_dnd");
static auto* const PFLOATBEHAVIOR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:float_switch_override_focus"); static auto PFLOATBEHAVIOR = CConfigValue<Hyprlang::INT>("input:float_switch_override_focus");
static auto* const PMOUSEFOCUSMON = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:mouse_move_focuses_monitor"); static auto PMOUSEFOCUSMON = CConfigValue<Hyprlang::INT>("misc:mouse_move_focuses_monitor");
static auto* const PRESIZEONBORDER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:resize_on_border"); static auto PRESIZEONBORDER = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto* const PRESIZECURSORICON = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:hover_icon_on_border"); static auto PRESIZECURSORICON = CConfigValue<Hyprlang::INT>("general:hover_icon_on_border");
static auto* const PZOOMFACTOR = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("misc:cursor_zoom_factor"); static auto PZOOMFACTOR = CConfigValue<Hyprlang::FLOAT>("misc:cursor_zoom_factor");
const auto FOLLOWMOUSE = **PFOLLOWONDND && m_sDrag.drag ? 1 : **PFOLLOWMOUSE; const auto FOLLOWMOUSE = *PFOLLOWONDND && m_sDrag.drag ? 1 : *PFOLLOWMOUSE;
m_pFoundSurfaceToFocus = nullptr; m_pFoundSurfaceToFocus = nullptr;
m_pFoundLSToFocus = nullptr; m_pFoundLSToFocus = nullptr;
@ -97,7 +100,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState) if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
return; return;
if (!g_pCompositor->m_bDPMSStateON && **PMOUSEDPMS) { if (!g_pCompositor->m_bDPMSStateON && *PMOUSEDPMS) {
// enable dpms // enable dpms
g_pKeybindManager->dpms("on"); g_pKeybindManager->dpms("on");
} }
@ -121,7 +124,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (PMONITOR == nullptr) if (PMONITOR == nullptr)
return; return;
if (**PZOOMFACTOR != 1.f) if (*PZOOMFACTOR != 1.f)
g_pHyprRenderer->damageMonitor(PMONITOR); g_pHyprRenderer->damageMonitor(PMONITOR);
if (!PMONITOR->solitaryClient && g_pHyprRenderer->shouldRenderCursor() && PMONITOR->output->software_cursor_locks > 0) if (!PMONITOR->solitaryClient && g_pHyprRenderer->shouldRenderCursor() && PMONITOR->output->software_cursor_locks > 0)
@ -134,61 +137,33 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (forcedFocus) { if (forcedFocus) {
pFoundWindow = forcedFocus; pFoundWindow = forcedFocus;
surfacePos = pFoundWindow->m_vRealPosition.vec(); surfacePos = pFoundWindow->m_vRealPosition.value();
foundSurface = pFoundWindow->m_pWLSurface.wlr(); foundSurface = pFoundWindow->m_pWLSurface.wlr();
} }
// constraints // constraints
// All constraints TODO: multiple mice? if (g_pCompositor->m_sSeat.mouse && isConstrained()) {
if (g_pCompositor->m_sSeat.mouse && g_pCompositor->m_sSeat.mouse->currentConstraint && !g_pCompositor->m_sSeat.exclusiveClient && !g_pSessionLockManager->isSessionLocked()) { const auto SURF = CWLSurface::surfaceFromWlr(g_pCompositor->m_pLastFocus);
// XWayland windows sometimes issue constraints weirdly. const auto CONSTRAINT = SURF->constraint();
// TODO: We probably should search their parent. wlr_xwayland_surface->parent
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse);
const auto PCONSTRAINT = constraintFromWlr(g_pCompositor->m_sSeat.mouse->currentConstraint);
if (!CONSTRAINTWINDOW || !PCONSTRAINT) { if (SURF && CONSTRAINT) {
unconstrainMouse(); if (CONSTRAINT->isLocked()) {
const auto HINT = CONSTRAINT->logicPositionHint();
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, HINT.x, HINT.y);
} else { } else {
// Native Wayland apps know how 2 constrain themselves. const auto RG = CONSTRAINT->logicConstraintRegion();
// XWayland, we just have to accept them. Might cause issues, but thats XWayland for ya. const auto CLOSEST = RG.closestPoint(mouseCoords);
const auto CONSTRAINTPOS = PCONSTRAINT->getLogicConstraintPos(); const auto BOX = SURF->getSurfaceBoxGlobal();
const auto CONSTRAINTSIZE = PCONSTRAINT->getLogicConstraintSize(); const auto CLOSESTLOCAL = (CLOSEST - (BOX.has_value() ? BOX->pos() : Vector2D{})) * (SURF->getWindow() ? SURF->getWindow()->m_fX11SurfaceScaledBy : 1.0);
if (g_pCompositor->m_sSeat.mouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) { wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, CLOSEST.x, CLOSEST.y);
// we just snap the cursor to where it should be. wlr_seat_pointer_send_motion(g_pCompositor->m_sSeat.seat, time, CLOSESTLOCAL.x, CLOSESTLOCAL.y);
if (PCONSTRAINT->hintSet)
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, CONSTRAINTPOS.x + PCONSTRAINT->positionHint.x,
CONSTRAINTPOS.y + PCONSTRAINT->positionHint.y);
return; // don't process anything else, the cursor is locked. The surface should not receive any further events.
// these are usually FPS games. They will use the relative motion.
} else {
// we restrict the cursor to the confined region
const auto REGION = PCONSTRAINT->getLogicCoordsRegion();
if (!REGION.containsPoint(mouseCoords)) {
if (g_pCompositor->m_sSeat.mouse->constraintActive) {
const auto CLOSEST = REGION.closestPoint(mouseCoords);
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, NULL, CLOSEST.x, CLOSEST.y);
mouseCoords = getMouseCoordsInternal();
}
} else {
if ((!CONSTRAINTWINDOW->m_bIsX11 && PMONITOR && CONSTRAINTWINDOW->m_iWorkspaceID == PMONITOR->activeWorkspace) || (CONSTRAINTWINDOW->m_bIsX11)) {
g_pCompositor->m_sSeat.mouse->constraintActive = true;
}
}
} }
if (CONSTRAINTWINDOW->m_bIsX11) { return;
foundSurface = CONSTRAINTWINDOW->m_pWLSurface.wlr();
surfacePos = CONSTRAINTWINDOW->m_vRealPosition.vec();
} else {
g_pCompositor->vectorWindowToSurface(mouseCoords, CONSTRAINTWINDOW, surfaceCoords);
}
pFoundWindow = CONSTRAINTWINDOW; } else
} Debug::log(ERR, "BUG THIS: Null SURF/CONSTRAINT in mouse refocus. Ignoring constraints. {:x} {:x}", (uintptr_t)SURF, (uintptr_t)CONSTRAINT);
} }
// update stuff // update stuff
@ -220,7 +195,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal()); g_pLayoutManager->getCurrentLayout()->onMouseMove(getMouseCoordsInternal());
if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor && (**PMOUSEFOCUSMON || refocus)) if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor && (*PMOUSEFOCUSMON || refocus))
g_pCompositor->setActiveMonitor(PMONITOR); g_pCompositor->setActiveMonitor(PMONITOR);
if (g_pSessionLockManager->isSessionLocked()) { if (g_pSessionLockManager->isSessionLocked()) {
@ -273,7 +248,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
surfacePos = Vector2D(-1337, -1337); surfacePos = Vector2D(-1337, -1337);
} else { } else {
foundSurface = pFoundWindow->m_pWLSurface.wlr(); foundSurface = pFoundWindow->m_pWLSurface.wlr();
surfacePos = pFoundWindow->m_vRealPosition.vec(); surfacePos = pFoundWindow->m_vRealPosition.value();
} }
} }
@ -302,7 +277,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
} else { } else {
foundSurface = pFoundWindow->m_pWLSurface.wlr(); foundSurface = pFoundWindow->m_pWLSurface.wlr();
surfacePos = pFoundWindow->m_vRealPosition.vec(); surfacePos = pFoundWindow->m_vRealPosition.value();
} }
} }
} }
@ -320,7 +295,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (!foundSurface) { if (!foundSurface) {
if (!m_bEmptyFocusCursorSet) { if (!m_bEmptyFocusCursorSet) {
if (**PRESIZEONBORDER && **PRESIZECURSORICON && m_eBorderIconDirection != BORDERICON_NONE) { if (*PRESIZEONBORDER && *PRESIZECURSORICON && m_eBorderIconDirection != BORDERICON_NONE) {
m_eBorderIconDirection = BORDERICON_NONE; m_eBorderIconDirection = BORDERICON_NONE;
unsetCursorImage(); unsetCursorImage();
} }
@ -390,7 +365,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (pFoundWindow) { if (pFoundWindow) {
// change cursor icon if hovering over border // change cursor icon if hovering over border
if (**PRESIZEONBORDER && **PRESIZECURSORICON) { if (*PRESIZEONBORDER && *PRESIZECURSORICON) {
if (!pFoundWindow->m_bIsFullscreen && !pFoundWindow->hasPopupAt(mouseCoords)) { if (!pFoundWindow->m_bIsFullscreen && !pFoundWindow->hasPopupAt(mouseCoords)) {
setCursorIconOnBorder(pFoundWindow); setCursorIconOnBorder(pFoundWindow);
} else if (m_eBorderIconDirection != BORDERICON_NONE) { } else if (m_eBorderIconDirection != BORDERICON_NONE) {
@ -400,7 +375,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (FOLLOWMOUSE != 1 && !refocus) { if (FOLLOWMOUSE != 1 && !refocus) {
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow && if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow &&
((pFoundWindow->m_bIsFloating && **PFLOATBEHAVIOR == 2) || (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating && **PFLOATBEHAVIOR != 0))) { ((pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR == 2) || (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating && *PFLOATBEHAVIOR != 0))) {
// enter if change floating style // enter if change floating style
if (FOLLOWMOUSE != 3 && allowKeyboardRefocus) if (FOLLOWMOUSE != 3 && allowKeyboardRefocus)
g_pCompositor->focusWindow(pFoundWindow, foundSurface); g_pCompositor->focusWindow(pFoundWindow, foundSurface);
@ -438,7 +413,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
m_bLastFocusOnLS = false; m_bLastFocusOnLS = false;
} else { } else {
if (**PRESIZEONBORDER && **PRESIZECURSORICON && m_eBorderIconDirection != BORDERICON_NONE) { if (*PRESIZEONBORDER && *PRESIZECURSORICON && m_eBorderIconDirection != BORDERICON_NONE) {
m_eBorderIconDirection = BORDERICON_NONE; m_eBorderIconDirection = BORDERICON_NONE;
unsetCursorImage(); unsetCursorImage();
} }
@ -466,7 +441,7 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
m_tmrLastCursorMovement.reset(); m_tmrLastCursorMovement.reset();
if (e->state == WLR_BUTTON_PRESSED) { if (e->state == WL_POINTER_BUTTON_STATE_PRESSED) {
m_lCurrentlyHeldButtons.push_back(e->button); m_lCurrentlyHeldButtons.push_back(e->button);
} else { } else {
if (std::find_if(m_lCurrentlyHeldButtons.begin(), m_lCurrentlyHeldButtons.end(), [&](const auto& other) { return other == e->button; }) == m_lCurrentlyHeldButtons.end()) if (std::find_if(m_lCurrentlyHeldButtons.begin(), m_lCurrentlyHeldButtons.end(), [&](const auto& other) { return other == e->button; }) == m_lCurrentlyHeldButtons.end())
@ -480,7 +455,7 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
default: break; default: break;
} }
if (m_bFocusHeldByButtons && m_lCurrentlyHeldButtons.empty() && e->state == WLR_BUTTON_RELEASED) { if (m_bFocusHeldByButtons && m_lCurrentlyHeldButtons.empty() && e->state == WL_POINTER_BUTTON_STATE_RELEASED) {
if (m_bRefocusHeldByButtons) if (m_bRefocusHeldByButtons)
refocus(); refocus();
else else
@ -605,15 +580,15 @@ void CInputManager::setClickMode(eClickBehaviorMode mode) {
void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) { void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
// notify the keybind manager // notify the keybind manager
static auto* const PPASSMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("binds:pass_mouse_when_bound"); static auto PPASSMOUSE = CConfigValue<Hyprlang::INT>("binds:pass_mouse_when_bound");
const auto PASS = g_pKeybindManager->onMouseEvent(e); const auto PASS = g_pKeybindManager->onMouseEvent(e);
static auto* const PFOLLOWMOUSE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto* const PRESIZEONBORDER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:resize_on_border"); static auto PRESIZEONBORDER = CConfigValue<Hyprlang::INT>("general:resize_on_border");
static auto* const PBORDERSIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:border_size"); static auto PBORDERSIZE = CConfigValue<Hyprlang::INT>("general:border_size");
static auto* const PBORDERGRABEXTEND = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:extend_border_grab_area"); static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
const auto BORDER_GRAB_AREA = **PRESIZEONBORDER ? **PBORDERSIZE + **PBORDERGRABEXTEND : 0; const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0;
if (!PASS && !**PPASSMOUSE) if (!PASS && !*PPASSMOUSE)
return; return;
const auto mouseCoords = g_pInputManager->getMouseCoordsInternal(); const auto mouseCoords = g_pInputManager->getMouseCoordsInternal();
@ -624,9 +599,9 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
// clicking on border triggers resize // clicking on border triggers resize
// TODO detect click on LS properly // TODO detect click on LS properly
if (**PRESIZEONBORDER && !m_bLastFocusOnLS && e->state == WLR_BUTTON_PRESSED) { if (*PRESIZEONBORDER && !m_bLastFocusOnLS && e->state == WL_POINTER_BUTTON_STATE_PRESSED) {
if (w && !w->m_bIsFullscreen) { if (w && !w->m_bIsFullscreen) {
const CBox real = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y}; const CBox real = {w->m_vRealPosition.value().x, w->m_vRealPosition.value().y, w->m_vRealSize.value().x, w->m_vRealSize.value().y};
const CBox grab = {real.x - BORDER_GRAB_AREA, real.y - BORDER_GRAB_AREA, real.width + 2 * BORDER_GRAB_AREA, real.height + 2 * BORDER_GRAB_AREA}; const CBox grab = {real.x - BORDER_GRAB_AREA, real.y - BORDER_GRAB_AREA, real.width + 2 * BORDER_GRAB_AREA, real.height + 2 * BORDER_GRAB_AREA};
if ((grab.containsPoint(mouseCoords) && (!real.containsPoint(mouseCoords) || w->isInCurvedCorner(mouseCoords.x, mouseCoords.y))) && !w->hasPopupAt(mouseCoords)) { if ((grab.containsPoint(mouseCoords) && (!real.containsPoint(mouseCoords) || w->isInCurvedCorner(mouseCoords.x, mouseCoords.y))) && !w->hasPopupAt(mouseCoords)) {
@ -638,10 +613,10 @@ void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
switch (e->state) { switch (e->state) {
case WLR_BUTTON_PRESSED: case WLR_BUTTON_PRESSED:
if (**PFOLLOWMOUSE == 3) // don't refocus on full loose if (*PFOLLOWMOUSE == 3) // don't refocus on full loose
break; break;
if ((!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) /* No constraints */ if ((!g_pCompositor->m_sSeat.mouse || !isConstrained()) /* No constraints */
&& (w && g_pCompositor->m_pLastWindow != w) /* window should change */) { && (w && g_pCompositor->m_pLastWindow != w) /* window should change */) {
// a bit hacky // a bit hacky
// if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus // if we only pressed one button, allow us to refocus. m_lCurrentlyHeldButtons.size() > 0 will stick the focus
@ -693,9 +668,10 @@ void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
} }
void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) { void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
static auto* const PSCROLLFACTOR = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("input:touchpad:scroll_factor"); static auto PINPUTSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:scroll_factor");
static auto PTOUCHPADSCROLLFACTOR = CConfigValue<Hyprlang::FLOAT>("input:touchpad:scroll_factor");
auto factor = (**PSCROLLFACTOR <= 0.f || e->source != WLR_AXIS_SOURCE_FINGER ? 1.f : **PSCROLLFACTOR); auto factor = (*PTOUCHPADSCROLLFACTOR <= 0.f || e->source == WL_POINTER_AXIS_SOURCE_FINGER ? *PTOUCHPADSCROLLFACTOR : *PINPUTSCROLLFACTOR);
const auto EMAP = std::unordered_map<std::string, std::any>{{"event", e}}; const auto EMAP = std::unordered_map<std::string, std::any>{{"event", e}};
EMIT_HOOK_EVENT_CANCELLABLE("mouseAxis", EMAP); EMIT_HOOK_EVENT_CANCELLABLE("mouseAxis", EMAP);
@ -716,7 +692,7 @@ void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
} }
wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, factor * e->delta, std::round(factor * e->delta_discrete), e->source, wlr_seat_pointer_notify_axis(g_pCompositor->m_sSeat.seat, e->time_msec, e->orientation, factor * e->delta, std::round(factor * e->delta_discrete), e->source,
WLR_AXIS_RELATIVE_DIRECTION_IDENTICAL); WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL);
} }
Vector2D CInputManager::getMouseCoordsInternal() { Vector2D CInputManager::getMouseCoordsInternal() {
@ -908,11 +884,10 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
} }
xkb_state_unref(pKeyboard->xkbTranslationState);
pKeyboard->xkbTranslationState = xkb_state_new(KEYMAP);
wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP); wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP);
pKeyboard->updateXKBTranslationState();
wlr_keyboard_modifiers wlrMods = {0}; wlr_keyboard_modifiers wlrMods = {0};
if (NUMLOCKON == 1) { if (NUMLOCKON == 1) {
@ -1189,8 +1164,8 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", e}}; const auto EMAP = std::unordered_map<std::string, std::any>{{"keyboard", pKeyboard}, {"event", e}};
EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP); EMIT_HOOK_EVENT_CANCELLABLE("keyPress", EMAP);
static auto* const PDPMS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:key_press_enables_dpms"); static auto PDPMS = CConfigValue<Hyprlang::INT>("misc:key_press_enables_dpms");
if (**PDPMS && !g_pCompositor->m_bDPMSStateON) { if (*PDPMS && !g_pCompositor->m_bDPMSStateON) {
// enable dpms // enable dpms
g_pKeybindManager->dpms("on"); g_pKeybindManager->dpms("on");
} }
@ -1246,6 +1221,8 @@ void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard); const auto LAYOUT = getActiveLayoutForKeyboard(pKeyboard);
pKeyboard->updateXKBTranslationState();
g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT}); g_pEventManager->postEvent(SHyprIPCEvent{"activelayout", pKeyboard->name + "," + LAYOUT});
EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUT})); EMIT_HOOK_EVENT("activeLayout", (std::vector<void*>{pKeyboard, (void*)&LAYOUT}));
} }
@ -1277,133 +1254,27 @@ void CInputManager::updateDragIcon() {
} }
} }
void CInputManager::recheckConstraint(SMouse* pMouse) {
if (!pMouse->currentConstraint)
return;
const auto PREGION = &pMouse->currentConstraint->region;
if (pMouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED)
pMouse->confinedTo.set(PREGION);
else
pMouse->confinedTo.clear();
}
void CInputManager::constrainMouse(SMouse* pMouse, wlr_pointer_constraint_v1* constraint) {
if (pMouse->currentConstraint == constraint)
return;
const auto MOUSECOORDS = getMouseCoordsInternal();
const auto PCONSTRAINT = constraintFromWlr(constraint);
pMouse->hyprListener_commitConstraint.removeCallback();
if (pMouse->currentConstraint)
wlr_pointer_constraint_v1_send_deactivated(pMouse->currentConstraint);
if (const auto PWINDOW = g_pCompositor->getWindowFromSurface(constraint->surface); PWINDOW) {
const auto RELATIVETO = PWINDOW->m_bIsX11 ?
(PWINDOW->m_bIsMapped ? PWINDOW->m_vRealPosition.goalv() :
g_pXWaylandManager->xwaylandToWaylandCoords({PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y})) :
PWINDOW->m_vRealPosition.goalv();
PCONSTRAINT->cursorPosOnActivate = (MOUSECOORDS - RELATIVETO) * PWINDOW->m_fX11SurfaceScaledBy;
}
if (constraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) {
PCONSTRAINT->hintSet = true;
PCONSTRAINT->positionHint = {constraint->current.cursor_hint.x, constraint->current.cursor_hint.y};
}
if (constraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT && constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED)
warpMouseToConstraintMiddle(PCONSTRAINT);
pMouse->currentConstraint = constraint;
pMouse->constraintActive = true;
if (pixman_region32_not_empty(&constraint->current.region))
pixman_region32_intersect(&constraint->region, &constraint->surface->input_region, &constraint->current.region);
else
pixman_region32_copy(&constraint->region, &constraint->surface->input_region);
// warp to the constraint
recheckConstraint(pMouse);
PCONSTRAINT->active = true;
wlr_pointer_constraint_v1_send_activated(pMouse->currentConstraint);
pMouse->hyprListener_commitConstraint.initCallback(&pMouse->currentConstraint->surface->events.commit, &Events::listener_commitConstraint, pMouse, "Mouse constraint commit");
Debug::log(LOG, "Constrained mouse to {:x}", (uintptr_t)pMouse->currentConstraint);
}
void CInputManager::warpMouseToConstraintMiddle(SConstraint* pConstraint) {
if (!pConstraint)
return;
const auto PWINDOW = g_pCompositor->getWindowFromSurface(pConstraint->constraint->surface);
if (PWINDOW) {
const auto RELATIVETO = pConstraint->getLogicConstraintPos();
const auto HINTSCALE = PWINDOW->m_fX11SurfaceScaledBy;
auto HINT = pConstraint->hintSet ? pConstraint->positionHint : pConstraint->cursorPosOnActivate;
if (HINT == Vector2D{-1, -1})
HINT = pConstraint->getLogicConstraintSize() / 2.f;
if (HINT != Vector2D{-1, -1}) {
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, RELATIVETO.x + HINT.x / HINTSCALE, RELATIVETO.y + HINT.y / HINTSCALE);
wlr_seat_pointer_warp(pConstraint->constraint->seat, pConstraint->constraint->current.cursor_hint.x, pConstraint->constraint->current.cursor_hint.y);
}
}
}
void CInputManager::unconstrainMouse() { void CInputManager::unconstrainMouse() {
if (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint) if (!g_pCompositor->m_sSeat.mouse)
return; return;
const auto CONSTRAINTWINDOW = g_pCompositor->getConstraintWindow(g_pCompositor->m_sSeat.mouse); for (auto& c : m_vConstraints) {
if (!c->active())
continue;
if (CONSTRAINTWINDOW) c->deactivate();
g_pXWaylandManager->activateSurface(CONSTRAINTWINDOW->m_pWLSurface.wlr(), false); }
wlr_pointer_constraint_v1_send_deactivated(g_pCompositor->m_sSeat.mouse->currentConstraint);
const auto PCONSTRAINT = constraintFromWlr(g_pCompositor->m_sSeat.mouse->currentConstraint);
if (PCONSTRAINT)
PCONSTRAINT->active = false;
g_pCompositor->m_sSeat.mouse->constraintActive = false;
// TODO: its better to somehow detect the workspace...
g_pCompositor->m_sSeat.mouse->currentConstraint = nullptr;
g_pCompositor->m_sSeat.mouse->hyprListener_commitConstraint.removeCallback();
} }
void Events::listener_commitConstraint(void* owner, void* data) { bool CInputManager::isConstrained() {
const auto PMOUSE = (SMouse*)owner; for (auto& c : m_vConstraints) {
if (!c->active() || c->owner()->wlr() != g_pCompositor->m_pLastFocus)
continue;
if (PMOUSE->currentConstraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_CURSOR_HINT) { return true;
const auto PCONSTRAINT = g_pInputManager->constraintFromWlr(PMOUSE->currentConstraint);
if (PCONSTRAINT) { // should never be null but who knows
PCONSTRAINT->positionHint = Vector2D(PMOUSE->currentConstraint->current.cursor_hint.x, PMOUSE->currentConstraint->current.cursor_hint.y);
PCONSTRAINT->hintSet = true;
}
} }
if (PMOUSE->currentConstraint->current.committed & WLR_POINTER_CONSTRAINT_V1_STATE_REGION) { return false;
if (pixman_region32_not_empty(&PMOUSE->currentConstraint->current.region))
pixman_region32_intersect(&PMOUSE->currentConstraint->region, &PMOUSE->currentConstraint->surface->input_region, &PMOUSE->currentConstraint->current.region);
else
pixman_region32_copy(&PMOUSE->currentConstraint->region, &PMOUSE->currentConstraint->surface->input_region);
g_pInputManager->recheckConstraint(PMOUSE);
}
} }
void CInputManager::updateCapabilities() { void CInputManager::updateCapabilities() {
@ -1669,15 +1540,6 @@ std::string CInputManager::getNameForNewDevice(std::string internalName) {
return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno))); return proposedNewName + (dupeno == 0 ? "" : ("-" + std::to_string(dupeno)));
} }
SConstraint* CInputManager::constraintFromWlr(wlr_pointer_constraint_v1* constraint) {
for (auto& c : m_lConstraints) {
if (c.constraint == constraint)
return &c;
}
return nullptr;
}
void CInputManager::releaseAllMouseButtons() { void CInputManager::releaseAllMouseButtons() {
const auto buttonsCopy = m_lCurrentlyHeldButtons; const auto buttonsCopy = m_lCurrentlyHeldButtons;
@ -1685,7 +1547,7 @@ void CInputManager::releaseAllMouseButtons() {
return; return;
for (auto& mb : buttonsCopy) { for (auto& mb : buttonsCopy) {
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, 0, mb, WLR_BUTTON_RELEASED); wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, 0, mb, WL_POINTER_BUTTON_STATE_RELEASED);
} }
m_lCurrentlyHeldButtons.clear(); m_lCurrentlyHeldButtons.clear();
@ -1698,7 +1560,7 @@ void CInputManager::setCursorIconOnBorder(CWindow* w) {
return; return;
} }
static auto* const PEXTENDBORDERGRAB = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:extend_border_grab_area"); static auto PEXTENDBORDERGRAB = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
const int BORDERSIZE = w->getRealBorderSize(); const int BORDERSIZE = w->getRealBorderSize();
const int ROUNDING = w->rounding(); const int ROUNDING = w->rounding();
@ -1707,8 +1569,8 @@ void CInputManager::setCursorIconOnBorder(CWindow* w) {
const auto mouseCoords = getMouseCoordsInternal(); const auto mouseCoords = getMouseCoordsInternal();
CBox box = w->getWindowMainSurfaceBox(); CBox box = w->getWindowMainSurfaceBox();
eBorderIconDirection direction = BORDERICON_NONE; eBorderIconDirection direction = BORDERICON_NONE;
CBox boxFullGrabInput = {box.x - **PEXTENDBORDERGRAB - BORDERSIZE, box.y - **PEXTENDBORDERGRAB - BORDERSIZE, box.width + 2 * (**PEXTENDBORDERGRAB + BORDERSIZE), CBox boxFullGrabInput = {box.x - *PEXTENDBORDERGRAB - BORDERSIZE, box.y - *PEXTENDBORDERGRAB - BORDERSIZE, box.width + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE),
box.height + 2 * (**PEXTENDBORDERGRAB + BORDERSIZE)}; box.height + 2 * (*PEXTENDBORDERGRAB + BORDERSIZE)};
if (w->hasPopupAt(mouseCoords)) if (w->hasPopupAt(mouseCoords))
direction = BORDERICON_NONE; direction = BORDERICON_NONE;

View file

@ -7,6 +7,8 @@
#include "../../helpers/Timer.hpp" #include "../../helpers/Timer.hpp"
#include "InputMethodRelay.hpp" #include "InputMethodRelay.hpp"
class CConstraint;
enum eClickBehaviorMode { enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0, CLICKMODE_DEFAULT = 0,
CLICKMODE_KILL CLICKMODE_KILL
@ -80,11 +82,8 @@ class CInputManager {
void destroyMouse(wlr_input_device*); void destroyMouse(wlr_input_device*);
void destroySwitch(SSwitchDevice*); void destroySwitch(SSwitchDevice*);
void constrainMouse(SMouse*, wlr_pointer_constraint_v1*);
void warpMouseToConstraintMiddle(SConstraint*);
void recheckConstraint(SMouse*);
void unconstrainMouse(); void unconstrainMouse();
SConstraint* constraintFromWlr(wlr_pointer_constraint_v1*); bool isConstrained();
std::string getActiveLayoutForKeyboard(SKeyboard*); std::string getActiveLayoutForKeyboard(SKeyboard*);
Vector2D getMouseCoordsInternal(); Vector2D getMouseCoordsInternal();
@ -124,7 +123,6 @@ class CInputManager {
SDrag m_sDrag; SDrag m_sDrag;
std::list<SConstraint> m_lConstraints;
std::list<SKeyboard> m_lKeyboards; std::list<SKeyboard> m_lKeyboards;
std::list<SMouse> m_lMice; std::list<SMouse> m_lMice;
@ -145,6 +143,9 @@ class CInputManager {
// Exclusive layer surfaces // Exclusive layer surfaces
std::deque<SLayerSurface*> m_dExclusiveLSes; std::deque<SLayerSurface*> m_dExclusiveLSes;
// constraints
std::vector<CConstraint*> m_vConstraints;
void newTabletTool(wlr_input_device*); void newTabletTool(wlr_input_device*);
void newTabletPad(wlr_input_device*); void newTabletPad(wlr_input_device*);
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false); void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
@ -190,13 +191,15 @@ class CInputManager {
CWindow* m_pLastMouseFocus = nullptr; CWindow* m_pLastMouseFocus = nullptr;
wlr_surface* m_pLastMouseSurface = nullptr; wlr_surface* m_pLastMouseSurface = nullptr;
//
bool m_bEmptyFocusCursorSet = false;
private: private:
bool m_bCursorImageOverridden = false; bool m_bCursorImageOverridden = false;
eBorderIconDirection m_eBorderIconDirection = BORDERICON_NONE; eBorderIconDirection m_eBorderIconDirection = BORDERICON_NONE;
// for click behavior override // for click behavior override
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT; eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
bool m_bEmptyFocusCursorSet = false;
Vector2D m_vLastCursorPosFloored = Vector2D(); Vector2D m_vLastCursorPosFloored = Vector2D();
void processMouseDownNormal(wlr_pointer_button_event* e); void processMouseDownNormal(wlr_pointer_button_event* e);

View file

@ -192,8 +192,8 @@ void CInputMethodRelay::updateInputPopup(SIMEPopup* pPopup) {
const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE); const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE);
if (PWINDOW) { if (PWINDOW) {
parentPos = PWINDOW->m_vRealPosition.goalv(); parentPos = PWINDOW->m_vRealPosition.goal();
parentSize = PWINDOW->m_vRealSize.goalv(); parentSize = PWINDOW->m_vRealSize.goal();
pMonitor = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); pMonitor = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
} }
} }
@ -298,7 +298,7 @@ void CInputMethodRelay::damagePopup(SIMEPopup* pPopup) {
const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE); const auto PWINDOW = g_pCompositor->getWindowFromSurface(PFOCUSEDSURFACE);
if (PWINDOW) { if (PWINDOW) {
parentPos = PWINDOW->m_vRealPosition.goalv(); parentPos = PWINDOW->m_vRealPosition.goal();
} }
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <list>
#include "../../defines.hpp" #include "../../defines.hpp"
#include "../../helpers/WLClasses.hpp" #include "../../helpers/WLClasses.hpp"

View file

@ -1,12 +1,13 @@
#include "InputManager.hpp" #include "InputManager.hpp"
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../config/ConfigValue.hpp"
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) { void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
static auto* const PSWIPE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe"); static auto PSWIPE = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe");
static auto* const PSWIPEFINGERS = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_fingers"); static auto PSWIPEFINGERS = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_fingers");
static auto* const PSWIPENEW = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_create_new"); static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
if (e->fingers != **PSWIPEFINGERS || **PSWIPE == 0 || g_pSessionLockManager->isSessionLocked()) if (e->fingers != *PSWIPEFINGERS || *PSWIPE == 0 || g_pSessionLockManager->isSessionLocked())
return; return;
int onMonitor = 0; int onMonitor = 0;
@ -16,7 +17,7 @@ void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
} }
} }
if (onMonitor < 2 && !**PSWIPENEW) if (onMonitor < 2 && !*PSWIPENEW)
return; // disallow swiping when there's 1 workspace on a monitor return; // disallow swiping when there's 1 workspace on a monitor
beginWorkspaceSwipe(); beginWorkspaceSwipe();
@ -44,20 +45,20 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
if (!m_sActiveSwipe.pWorkspaceBegin) if (!m_sActiveSwipe.pWorkspaceBegin)
return; // no valid swipe return; // no valid swipe
static auto* const PSWIPEPERC = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_cancel_ratio"); static auto PSWIPEPERC = CConfigValue<Hyprlang::FLOAT>("gestures:workspace_swipe_cancel_ratio");
static auto* const PSWIPEDIST = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance"); static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
static auto* const PSWIPEFORC = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_min_speed_to_force"); static auto PSWIPEFORC = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_min_speed_to_force");
static auto* const PSWIPENEW = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_create_new"); static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
static auto* const PSWIPENUMBER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_numbered"); static auto PSWIPENUMBER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_numbered");
static auto* const PSWIPEUSER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_use_r"); static auto PSWIPEUSER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_use_r");
static auto* const PWORKSPACEGAP = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_workspaces"); static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" ||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert");
// commit // commit
std::string wsname = ""; std::string wsname = "";
auto workspaceIDLeft = getWorkspaceIDFromString(**PSWIPENUMBER ? "-1" : (**PSWIPEUSER ? "r-1" : "m-1"), wsname); auto workspaceIDLeft = getWorkspaceIDFromString(*PSWIPENUMBER ? "-1" : (*PSWIPEUSER ? "r-1" : "m-1"), wsname);
auto workspaceIDRight = getWorkspaceIDFromString(**PSWIPENUMBER ? "+1" : (**PSWIPEUSER ? "r+1" : "m+1"), wsname); auto workspaceIDRight = getWorkspaceIDFromString(*PSWIPENUMBER ? "+1" : (*PSWIPEUSER ? "r+1" : "m+1"), wsname);
// If we've been swiping off the right end with PSWIPENEW enabled, there is // If we've been swiping off the right end with PSWIPENEW enabled, there is
// no workspace there yet, and we need to choose an ID for a new one now. // no workspace there yet, and we need to choose an ID for a new one now.
@ -68,7 +69,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
// be counterintuitive to swipe rightwards onto a new workspace and end up // be counterintuitive to swipe rightwards onto a new workspace and end up
// left of where we started. Instead, it's one more than the greatest // left of where we started. Instead, it's one more than the greatest
// workspace ID that currently exists. // workspace ID that currently exists.
if (workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID && **PSWIPENEW) { if (workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID && *PSWIPENEW) {
int maxWorkspace = 0; int maxWorkspace = 0;
for (const auto& ws : g_pCompositor->m_vWorkspaces) { for (const auto& ws : g_pCompositor->m_vWorkspaces) {
maxWorkspace = std::max(maxWorkspace, ws->m_iID); maxWorkspace = std::max(maxWorkspace, ws->m_iID);
@ -79,13 +80,13 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER
auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec(); const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.value();
const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + **PWORKSPACEGAP; const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP;
const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + **PWORKSPACEGAP; const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP;
CWorkspace* pSwitchedTo = nullptr; CWorkspace* pSwitchedTo = nullptr;
if ((abs(m_sActiveSwipe.delta) < **PSWIPEDIST * **PSWIPEPERC && (**PSWIPEFORC == 0 || (**PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < **PSWIPEFORC))) || if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) ||
abs(m_sActiveSwipe.delta) < 2) { abs(m_sActiveSwipe.delta) < 2) {
// revert // revert
if (abs(m_sActiveSwipe.delta) < 2) { if (abs(m_sActiveSwipe.delta) < 2) {
@ -118,7 +119,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
pSwitchedTo = m_sActiveSwipe.pWorkspaceBegin; pSwitchedTo = m_sActiveSwipe.pWorkspaceBegin;
} else if (m_sActiveSwipe.delta < 0) { } else if (m_sActiveSwipe.delta < 0) {
// switch to left // switch to left
const auto RENDEROFFSET = PWORKSPACEL ? PWORKSPACEL->m_vRenderOffset.vec() : Vector2D(); const auto RENDEROFFSET = PWORKSPACEL ? PWORKSPACEL->m_vRenderOffset.value() : Vector2D();
if (PWORKSPACEL) if (PWORKSPACEL)
m_sActiveSwipe.pMonitor->changeWorkspace(workspaceIDLeft); m_sActiveSwipe.pMonitor->changeWorkspace(workspaceIDLeft);
@ -144,7 +145,7 @@ void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
pSwitchedTo = PWORKSPACEL; pSwitchedTo = PWORKSPACEL;
} else { } else {
// switch to right // switch to right
const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_vRenderOffset.vec() : Vector2D(); const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_vRenderOffset.value() : Vector2D();
if (PWORKSPACER) if (PWORKSPACER)
m_sActiveSwipe.pMonitor->changeWorkspace(workspaceIDRight); m_sActiveSwipe.pMonitor->changeWorkspace(workspaceIDRight);
@ -194,40 +195,40 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
if (!m_sActiveSwipe.pWorkspaceBegin) if (!m_sActiveSwipe.pWorkspaceBegin)
return; return;
static auto* const PSWIPEDIST = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance"); static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
static auto* const PSWIPEINVR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_invert"); static auto PSWIPEINVR = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_invert");
static auto* const PSWIPENEW = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_create_new"); static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
static auto* const PSWIPEDIRLOCK = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_direction_lock"); static auto PSWIPEDIRLOCK = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_direction_lock");
static auto* const PSWIPEDIRLOCKTHRESHOLD = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_direction_lock_threshold"); static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_direction_lock_threshold");
static auto* const PSWIPEFOREVER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_forever"); static auto PSWIPEFOREVER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_forever");
static auto* const PSWIPENUMBER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_numbered"); static auto PSWIPENUMBER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_numbered");
static auto* const PSWIPEUSER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_use_r"); static auto PSWIPEUSER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_use_r");
static auto* const PWORKSPACEGAP = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("general:gaps_workspaces"); static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + **PWORKSPACEGAP; const auto XDISTANCE = m_sActiveSwipe.pMonitor->vecSize.x + *PWORKSPACEGAP;
const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + **PWORKSPACEGAP; const auto YDISTANCE = m_sActiveSwipe.pMonitor->vecSize.y + *PWORKSPACEGAP;
const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" || const bool VERTANIMS = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle == "slidevert" ||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert"); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.getConfig()->pValues->internalStyle.starts_with("slidefadevert");
m_sActiveSwipe.delta += VERTANIMS ? (**PSWIPEINVR ? -e->dy : e->dy) : (**PSWIPEINVR ? -e->dx : e->dx); m_sActiveSwipe.delta += VERTANIMS ? (*PSWIPEINVR ? -e->dy : e->dy) : (*PSWIPEINVR ? -e->dx : e->dx);
m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1); m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1);
m_sActiveSwipe.speedPoints++; m_sActiveSwipe.speedPoints++;
std::string wsname = ""; std::string wsname = "";
auto workspaceIDLeft = getWorkspaceIDFromString(**PSWIPENUMBER ? "-1" : (**PSWIPEUSER ? "r-1" : "m-1"), wsname); auto workspaceIDLeft = getWorkspaceIDFromString(*PSWIPENUMBER ? "-1" : (*PSWIPEUSER ? "r-1" : "m-1"), wsname);
auto workspaceIDRight = getWorkspaceIDFromString(**PSWIPENUMBER ? "+1" : (**PSWIPEUSER ? "r+1" : "m+1"), wsname); auto workspaceIDRight = getWorkspaceIDFromString(*PSWIPENUMBER ? "+1" : (*PSWIPEUSER ? "r+1" : "m+1"), wsname);
if ((workspaceIDLeft == WORKSPACE_INVALID || workspaceIDRight == WORKSPACE_INVALID || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) && !**PSWIPENEW) { if ((workspaceIDLeft == WORKSPACE_INVALID || workspaceIDRight == WORKSPACE_INVALID || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID) && !*PSWIPENEW) {
m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe m_sActiveSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe
return; return;
} }
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = true; m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = true;
m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-**PSWIPEDIST, (double)**PSWIPEDIST); m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-*PSWIPEDIST, (double)*PSWIPEDIST);
if ((m_sActiveSwipe.pWorkspaceBegin->m_iID == workspaceIDLeft && **PSWIPENEW && (m_sActiveSwipe.delta < 0)) || if ((m_sActiveSwipe.pWorkspaceBegin->m_iID == workspaceIDLeft && *PSWIPENEW && (m_sActiveSwipe.delta < 0)) ||
(m_sActiveSwipe.delta > 0 && g_pCompositor->getWindowsOnWorkspace(m_sActiveSwipe.pWorkspaceBegin->m_iID) == 0 && (m_sActiveSwipe.delta > 0 && g_pCompositor->getWindowsOnWorkspace(m_sActiveSwipe.pWorkspaceBegin->m_iID) == 0 &&
workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID) || workspaceIDRight <= m_sActiveSwipe.pWorkspaceBegin->m_iID) ||
(m_sActiveSwipe.delta < 0 && m_sActiveSwipe.pWorkspaceBegin->m_iID <= workspaceIDLeft)) { (m_sActiveSwipe.delta < 0 && m_sActiveSwipe.pWorkspaceBegin->m_iID <= workspaceIDLeft)) {
@ -236,10 +237,10 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
return; return;
} }
if (**PSWIPEDIRLOCK) { if (*PSWIPEDIRLOCK) {
if (m_sActiveSwipe.initialDirection != 0 && m_sActiveSwipe.initialDirection != (m_sActiveSwipe.delta < 0 ? -1 : 1)) if (m_sActiveSwipe.initialDirection != 0 && m_sActiveSwipe.initialDirection != (m_sActiveSwipe.delta < 0 ? -1 : 1))
m_sActiveSwipe.delta = 0; m_sActiveSwipe.delta = 0;
else if (m_sActiveSwipe.initialDirection == 0 && abs(m_sActiveSwipe.delta) > **PSWIPEDIRLOCKTHRESHOLD) else if (m_sActiveSwipe.initialDirection == 0 && abs(m_sActiveSwipe.delta) > *PSWIPEDIRLOCKTHRESHOLD)
m_sActiveSwipe.initialDirection = m_sActiveSwipe.delta < 0 ? -1 : 1; m_sActiveSwipe.initialDirection = m_sActiveSwipe.delta < 0 ? -1 : 1;
} }
@ -247,13 +248,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) { if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) {
if (**PSWIPENEW || **PSWIPENUMBER) { if (*PSWIPENEW || *PSWIPENUMBER) {
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor); g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
if (VERTANIMS) if (VERTANIMS)
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / **PSWIPEDIST) * YDISTANCE)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * YDISTANCE));
else else
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / **PSWIPEDIST) * XDISTANCE, 0)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * XDISTANCE, 0));
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID); g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
return; return;
@ -275,11 +276,11 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
} }
if (VERTANIMS) { if (VERTANIMS) {
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / **PSWIPEDIST) * YDISTANCE - YDISTANCE)); PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * YDISTANCE - YDISTANCE));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / **PSWIPEDIST) * YDISTANCE)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * YDISTANCE));
} else { } else {
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / **PSWIPEDIST) * XDISTANCE - XDISTANCE, 0)); PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * XDISTANCE - XDISTANCE, 0));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / **PSWIPEDIST) * XDISTANCE, 0)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * XDISTANCE, 0));
} }
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft); g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft);
@ -287,13 +288,13 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) { if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID || !PWORKSPACE) {
if (**PSWIPENEW || **PSWIPENUMBER) { if (*PSWIPENEW || *PSWIPENUMBER) {
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor); g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
if (VERTANIMS) if (VERTANIMS)
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / **PSWIPEDIST) * YDISTANCE)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * YDISTANCE));
else else
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / **PSWIPEDIST) * XDISTANCE, 0)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * XDISTANCE, 0));
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID); g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
return; return;
@ -315,11 +316,11 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
} }
if (VERTANIMS) { if (VERTANIMS) {
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / **PSWIPEDIST) * YDISTANCE + YDISTANCE)); PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * YDISTANCE + YDISTANCE));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / **PSWIPEDIST) * YDISTANCE)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(0, ((-m_sActiveSwipe.delta) / *PSWIPEDIST) * YDISTANCE));
} else { } else {
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / **PSWIPEDIST) * XDISTANCE + XDISTANCE, 0)); PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * XDISTANCE + XDISTANCE, 0));
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / **PSWIPEDIST) * XDISTANCE, 0)); m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((-m_sActiveSwipe.delta) / *PSWIPEDIST) * XDISTANCE, 0));
} }
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight); g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
@ -329,8 +330,8 @@ void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID); g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
if (**PSWIPEFOREVER) { if (*PSWIPEFOREVER) {
if (abs(m_sActiveSwipe.delta) >= **PSWIPEDIST) { if (abs(m_sActiveSwipe.delta) >= *PSWIPEDIST) {
onSwipeEnd(nullptr); onSwipeEnd(nullptr);
beginWorkspaceSwipe(); beginWorkspaceSwipe();
} }

View file

@ -267,7 +267,7 @@ void CInputManager::focusTablet(STablet* pTab, wlr_tablet_tool* pTool, bool moti
} }
if (motion) { if (motion) {
auto local = CURSORPOS - PWINDOW->m_vRealPosition.goalv(); auto local = CURSORPOS - PWINDOW->m_vRealPosition.goal();
if (PWINDOW->m_bIsX11) if (PWINDOW->m_bIsX11)
local = local * PWINDOW->m_fX11SurfaceScaledBy; local = local * PWINDOW->m_fX11SurfaceScaledBy;

View file

@ -19,7 +19,7 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
if (m_ecbClickBehavior == CLICKMODE_KILL) { if (m_ecbClickBehavior == CLICKMODE_KILL) {
wlr_pointer_button_event e; wlr_pointer_button_event e;
e.state = WLR_BUTTON_PRESSED; e.state = WL_POINTER_BUTTON_STATE_PRESSED;
g_pInputManager->processMouseDownKill(&e); g_pInputManager->processMouseDownKill(&e);
return; return;
} }
@ -34,8 +34,8 @@ void CInputManager::onTouchDown(wlr_touch_down_event* e) {
if (m_sTouchData.touchFocusWindow) { if (m_sTouchData.touchFocusWindow) {
if (m_sTouchData.touchFocusWindow->m_bIsX11) { if (m_sTouchData.touchFocusWindow->m_bIsX11) {
local = (g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusWindow->m_vRealPosition.goalv()) * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy; local = (g_pInputManager->getMouseCoordsInternal() - m_sTouchData.touchFocusWindow->m_vRealPosition.goal()) * m_sTouchData.touchFocusWindow->m_fX11SurfaceScaledBy;
m_sTouchData.touchSurfaceOrigin = m_sTouchData.touchFocusWindow->m_vRealPosition.goalv(); m_sTouchData.touchSurfaceOrigin = m_sTouchData.touchFocusWindow->m_vRealPosition.goal();
} else { } else {
g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), m_sTouchData.touchFocusWindow, local); g_pCompositor->vectorWindowToSurface(g_pInputManager->getMouseCoordsInternal(), m_sTouchData.touchFocusWindow, local);
m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local; m_sTouchData.touchSurfaceOrigin = g_pInputManager->getMouseCoordsInternal() - local;

View file

@ -11,6 +11,7 @@ executable('Hyprland', src,
dependency('wayland-client'), dependency('wayland-client'),
wlroots.get_variable('wlroots'), wlroots.get_variable('wlroots'),
dependency('cairo'), dependency('cairo'),
dependency('hyprcursor'),
dependency('hyprlang', version: '>= 0.3.2'), dependency('hyprlang', version: '>= 0.3.2'),
dependency('libdrm'), dependency('libdrm'),
dependency('egl'), dependency('egl'),

View file

@ -484,9 +484,9 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
} }
CBox monbox = CBox{0, 0, frame->pMonitor->vecTransformedSize.x, frame->pMonitor->vecTransformedSize.y}.translate({-frame->box.x, -frame->box.y}); CBox monbox = CBox{0, 0, frame->pMonitor->vecTransformedSize.x, frame->pMonitor->vecTransformedSize.y}.translate({-frame->box.x, -frame->box.y});
g_pHyprOpenGL->setMonitorTransformEnabled(false);
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1);
g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
#ifndef GLES2 #ifndef GLES2
glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.m_iFb); glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.m_iFb);
@ -535,15 +535,17 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) {
if (!sourceTex) if (!sourceTex)
return false; return false;
CRegion fakeDamage = {0, 0, frame->box.width, frame->box.height}; CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer)) if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer))
return false; return false;
CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y}.translate({-frame->box.x, -frame->box.y}); CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y}
g_pHyprOpenGL->setMonitorTransformEnabled(false); .translate({-frame->box.x, -frame->box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1); .transform(wlr_output_transform_invert(frame->pMonitor->output->transform), frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y);
g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1);
g_pHyprOpenGL->setMonitorTransformEnabled(false);
g_pHyprRenderer->endRender(); g_pHyprRenderer->endRender();

View file

@ -212,7 +212,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
PFRAME->dmabufFormat = DRM_FORMAT_INVALID; PFRAME->dmabufFormat = DRM_FORMAT_INVALID;
} }
PFRAME->box = {0, 0, (int)(PFRAME->pWindow->m_vRealSize.vec().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.vec().y * PMONITOR->scale)}; PFRAME->box = {0, 0, (int)(PFRAME->pWindow->m_vRealSize.value().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.value().y * PMONITOR->scale)};
int ow, oh; int ow, oh;
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh); wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
PFRAME->box.transform(PMONITOR->transform, ow, oh).round(); PFRAME->box.transform(PMONITOR->transform, ow, oh).round();
@ -322,7 +322,7 @@ void CToplevelExportProtocolManager::onOutputCommit(CMonitor* pMonitor, wlr_outp
if (PMONITOR != g_pCompositor->getMonitorFromID(f->pWindow->m_iMonitorID)) if (PMONITOR != g_pCompositor->getMonitorFromID(f->pWindow->m_iMonitorID))
continue; continue;
CBox geometry = {f->pWindow->m_vRealPosition.vec().x, f->pWindow->m_vRealPosition.vec().y, f->pWindow->m_vRealSize.vec().x, f->pWindow->m_vRealSize.vec().y}; CBox geometry = {f->pWindow->m_vRealPosition.value().x, f->pWindow->m_vRealPosition.value().y, f->pWindow->m_vRealSize.value().x, f->pWindow->m_vRealSize.value().y};
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr())) if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, pMonitor->output, geometry.pWlr()))
continue; continue;
@ -404,7 +404,7 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
g_pHyprRenderer->m_bBlockSurfaceFeedback = false; g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
if (frame->overlayCursor) if (frame->overlayCursor)
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.vec()); g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.value());
const auto PFORMAT = g_pHyprOpenGL->getPixelFormatFromDRM(format); const auto PFORMAT = g_pHyprOpenGL->getPixelFormatFromDRM(format);
if (!PFORMAT) { if (!PFORMAT) {
@ -450,7 +450,7 @@ bool CToplevelExportProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame, ti
g_pHyprRenderer->m_bBlockSurfaceFeedback = false; g_pHyprRenderer->m_bBlockSurfaceFeedback = false;
if (frame->overlayCursor) if (frame->overlayCursor)
g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.vec()); g_pHyprRenderer->renderSoftwareCursors(PMONITOR, fakeDamage, g_pInputManager->getMouseCoordsInternal() - frame->pWindow->m_vRealPosition.value());
g_pHyprRenderer->endRender(); g_pHyprRenderer->endRender();
return true; return true;

View file

@ -1,5 +1,6 @@
#include "XDGOutput.hpp" #include "XDGOutput.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
#include "xdg-output-unstable-v1-protocol.h" #include "xdg-output-unstable-v1-protocol.h"
@ -112,7 +113,7 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* r
} }
void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) { void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
static auto* const PXWLFORCESCALEZERO = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling"); static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
if (!pOutput->resource->good() || !pOutput->monitor) if (!pOutput->resource->good() || !pOutput->monitor)
return; return;
@ -120,7 +121,7 @@ void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
const auto POS = pOutput->isXWayland ? pOutput->monitor->vecXWaylandPosition : pOutput->monitor->vecPosition; const auto POS = pOutput->isXWayland ? pOutput->monitor->vecXWaylandPosition : pOutput->monitor->vecPosition;
zxdg_output_v1_send_logical_position(pOutput->resource->resource(), POS.x, POS.y); zxdg_output_v1_send_logical_position(pOutput->resource->resource(), POS.x, POS.y);
if (**PXWLFORCESCALEZERO && pOutput->isXWayland) if (*PXWLFORCESCALEZERO && pOutput->isXWayland)
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecTransformedSize.x, pOutput->monitor->vecTransformedSize.y); zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecTransformedSize.x, pOutput->monitor->vecTransformedSize.y);
else else
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecSize.x, pOutput->monitor->vecSize.y); zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecSize.x, pOutput->monitor->vecSize.y);

View file

@ -4,6 +4,7 @@
#include "../helpers/MiscFunctions.hpp" #include "../helpers/MiscFunctions.hpp"
#include "Shaders.hpp" #include "Shaders.hpp"
#include <random> #include <random>
#include "../config/ConfigValue.hpp"
inline void loadGLProc(void* pProc, const char* name) { inline void loadGLProc(void* pProc, const char* name) {
void* proc = (void*)eglGetProcAddress(name); void* proc = (void*)eglGetProcAddress(name);
@ -120,10 +121,10 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool
bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
// passes requiring introspection are the ones that need to render blur. // passes requiring introspection are the ones that need to render blur.
static auto* const PBLUR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"); static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
static auto* const PXRAY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:xray"); static auto PXRAY = CConfigValue<Hyprlang::INT>("decoration:blur:xray");
static auto* const POPTIM = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations"); static auto POPTIM = CConfigValue<Hyprlang::INT>("decoration:blur:new_optimizations");
static auto* const PBLURSPECIAL = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:special"); static auto PBLURSPECIAL = CConfigValue<Hyprlang::INT>("decoration:blur:special");
if (m_RenderData.mouseZoomFactor != 1.0 || g_pHyprRenderer->m_bCrashingInProgress) if (m_RenderData.mouseZoomFactor != 1.0 || g_pHyprRenderer->m_bCrashingInProgress)
return true; return true;
@ -131,7 +132,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
if (!pMonitor->mirrors.empty()) if (!pMonitor->mirrors.empty())
return true; return true;
if (**PBLUR == 0) if (*PBLUR == 0)
return false; return false;
if (m_RenderData.pCurrentMonData->blurFBShouldRender) if (m_RenderData.pCurrentMonData->blurFBShouldRender)
@ -141,13 +142,13 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
return false; return false;
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) { for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
const auto XRAYMODE = ls->xray == -1 ? **PXRAY : ls->xray; const auto XRAYMODE = ls->xray == -1 ? *PXRAY : ls->xray;
if (ls->forceBlur && !XRAYMODE) if (ls->forceBlur && !XRAYMODE)
return true; return true;
} }
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) { for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
const auto XRAYMODE = ls->xray == -1 ? **PXRAY : ls->xray; const auto XRAYMODE = ls->xray == -1 ? *PXRAY : ls->xray;
if (ls->forceBlur && !XRAYMODE) if (ls->forceBlur && !XRAYMODE)
return true; return true;
} }
@ -168,18 +169,18 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
if (!ws->m_bIsSpecialWorkspace || ws->m_iMonitorID != pMonitor->ID) if (!ws->m_bIsSpecialWorkspace || ws->m_iMonitorID != pMonitor->ID)
continue; continue;
if (ws->m_fAlpha.fl() == 0) if (ws->m_fAlpha.value() == 0)
continue; continue;
return true; return true;
} }
} }
if (**PXRAY) if (*PXRAY)
return false; return false;
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (!w->m_bIsMapped || w->isHidden() || (!w->m_bIsFloating && **POPTIM && !g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID))) if (!w->m_bIsMapped || w->isHidden() || (!w->m_bIsFloating && *POPTIM && !g_pCompositor->isWorkspaceSpecial(w->m_iWorkspaceID)))
continue; continue;
if (!g_pHyprRenderer->shouldRenderWindow(w.get())) if (!g_pHyprRenderer->shouldRenderWindow(w.get()))
@ -200,7 +201,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) {
void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebuffer* fb, std::optional<CRegion> finalDamage) { void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebuffer* fb, std::optional<CRegion> finalDamage) {
m_RenderData.pMonitor = pMonitor; m_RenderData.pMonitor = pMonitor;
static auto* const PFORCEINTROSPECTION = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("opengl:force_introspection"); static auto PFORCEINTROSPECTION = CConfigValue<Hyprlang::INT>("opengl:force_introspection");
#ifndef GLES2 #ifndef GLES2
@ -258,13 +259,13 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebu
if (m_bReloadScreenShader) { if (m_bReloadScreenShader) {
m_bReloadScreenShader = false; m_bReloadScreenShader = false;
static auto* const PSHADER = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("decoration:screen_shader"); static auto PSHADER = CConfigValue<std::string>("decoration:screen_shader");
applyScreenShader(*PSHADER); applyScreenShader(*PSHADER);
} }
const auto PRBO = g_pHyprRenderer->getCurrentRBO(); const auto PRBO = g_pHyprRenderer->getCurrentRBO();
const bool FBPROPERSIZE = !fb || fb->m_vSize == pMonitor->vecPixelSize; const bool FBPROPERSIZE = !fb || fb->m_vSize == pMonitor->vecPixelSize;
const bool USERFORCEDINTROSPECTION = **PFORCEINTROSPECTION == 1 ? true : (**PFORCEINTROSPECTION == 2 ? g_pHyprRenderer->isNvidia() : false); // 0 - no, 1 - yes, 2 - nvidia only const bool USERFORCEDINTROSPECTION = *PFORCEINTROSPECTION == 1 ? true : (*PFORCEINTROSPECTION == 2 ? g_pHyprRenderer->isNvidia() : false); // 0 - no, 1 - yes, 2 - nvidia only
if (USERFORCEDINTROSPECTION || m_RenderData.forceIntrospection || !FBPROPERSIZE || m_sFinalScreenShader.program > 0 || if (USERFORCEDINTROSPECTION || m_RenderData.forceIntrospection || !FBPROPERSIZE || m_sFinalScreenShader.program > 0 ||
(PRBO && pMonitor->vecPixelSize != PRBO->getFB()->m_vSize) || passRequiresIntrospection(pMonitor)) { (PRBO && pMonitor->vecPixelSize != PRBO->getFB()->m_vSize) || passRequiresIntrospection(pMonitor)) {
@ -290,7 +291,7 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, const CRegion& damage_, CFramebu
} }
void CHyprOpenGLImpl::end() { void CHyprOpenGLImpl::end() {
static auto* const PZOOMRIGID = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:cursor_zoom_rigid"); static auto PZOOMRIGID = CConfigValue<Hyprlang::INT>("misc:cursor_zoom_rigid");
TRACY_GPU_ZONE("RenderEnd"); TRACY_GPU_ZONE("RenderEnd");
@ -310,7 +311,7 @@ void CHyprOpenGLImpl::end() {
(g_pInputManager->getMouseCoordsInternal() - m_RenderData.pMonitor->vecPosition) * m_RenderData.pMonitor->scale : (g_pInputManager->getMouseCoordsInternal() - m_RenderData.pMonitor->vecPosition) * m_RenderData.pMonitor->scale :
m_RenderData.pMonitor->vecTransformedSize / 2.f; m_RenderData.pMonitor->vecTransformedSize / 2.f;
monbox.translate(-ZOOMCENTER).scale(m_RenderData.mouseZoomFactor).translate(**PZOOMRIGID ? m_RenderData.pMonitor->vecTransformedSize / 2.0 : ZOOMCENTER); monbox.translate(-ZOOMCENTER).scale(m_RenderData.mouseZoomFactor).translate(*PZOOMRIGID ? m_RenderData.pMonitor->vecTransformedSize / 2.0 : ZOOMCENTER);
if (monbox.x > 0) if (monbox.x > 0)
monbox.x = 0; monbox.x = 0;
@ -353,7 +354,11 @@ void CHyprOpenGLImpl::end() {
// check for gl errors // check for gl errors
const GLenum ERR = glGetError(); const GLenum ERR = glGetError();
#ifdef GLES2
if (ERR == GL_CONTEXT_LOST_KHR) /* We don't have infra to recover from this */
#else
if (ERR == GL_CONTEXT_LOST) /* We don't have infra to recover from this */ if (ERR == GL_CONTEXT_LOST) /* We don't have infra to recover from this */
#endif
RASSERT(false, "glGetError at Opengl::end() returned GL_CONTEXT_LOST. Cannot continue until proper GPU reset handling is implemented."); RASSERT(false, "glGetError at Opengl::end() returned GL_CONTEXT_LOST. Cannot continue until proper GPU reset handling is implemented.");
} }
@ -526,7 +531,7 @@ void CHyprOpenGLImpl::initShaders() {
void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { void CHyprOpenGLImpl::applyScreenShader(const std::string& path) {
static auto* const PDT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("debug:damage_tracking"); static auto PDT = CConfigValue<Hyprlang::INT>("debug:damage_tracking");
m_sFinalScreenShader.destroy(); m_sFinalScreenShader.destroy();
@ -553,7 +558,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) {
m_sFinalScreenShader.tex = glGetUniformLocation(m_sFinalScreenShader.program, "tex"); m_sFinalScreenShader.tex = glGetUniformLocation(m_sFinalScreenShader.program, "tex");
m_sFinalScreenShader.time = glGetUniformLocation(m_sFinalScreenShader.program, "time"); m_sFinalScreenShader.time = glGetUniformLocation(m_sFinalScreenShader.program, "time");
m_sFinalScreenShader.wl_output = glGetUniformLocation(m_sFinalScreenShader.program, "wl_output"); m_sFinalScreenShader.wl_output = glGetUniformLocation(m_sFinalScreenShader.program, "wl_output");
if (m_sFinalScreenShader.time != -1 && **PDT != 0 && !g_pHyprRenderer->m_bCrashingInProgress) { if (m_sFinalScreenShader.time != -1 && *PDT != 0 && !g_pHyprRenderer->m_bCrashingInProgress) {
// The screen shader uses the "time" uniform // The screen shader uses the "time" uniform
// Since the screen shader could change every frame, damage tracking *needs* to be disabled // Since the screen shader could change every frame, damage tracking *needs* to be disabled
g_pConfigManager->addParseError("Screen shader: Screen shader uses uniform 'time', which requires debug:damage_tracking to be switched off.\n" g_pConfigManager->addParseError("Screen shader: Screen shader uses uniform 'time', which requires debug:damage_tracking to be switched off.\n"
@ -777,8 +782,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox*
CBox newBox = *pBox; CBox newBox = *pBox;
m_RenderData.renderModif.applyToBox(newBox); m_RenderData.renderModif.applyToBox(newBox);
static auto* const PDIMINACTIVE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:dim_inactive"); static auto PDIMINACTIVE = CConfigValue<Hyprlang::INT>("decoration:dim_inactive");
static auto* const PDT = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("debug:damage_tracking"); static auto PDT = CConfigValue<Hyprlang::INT>("debug:damage_tracking");
// get transform // get transform
const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform); const auto TRANSFORM = wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform);
@ -838,7 +843,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox*
#endif #endif
glUniform1i(shader->tex, 0); glUniform1i(shader->tex, 0);
if ((usingFinalShader && **PDT == 0) || CRASHING) { if ((usingFinalShader && *PDT == 0) || CRASHING) {
glUniform1f(shader->time, m_tGlobalTimer.getSeconds()); glUniform1f(shader->time, m_tGlobalTimer.getSeconds());
} else if (usingFinalShader && shader->time != -1) { } else if (usingFinalShader && shader->time != -1) {
// Don't let time be unitialised // Don't let time be unitialised
@ -879,9 +884,9 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox*
glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y); glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y);
glUniform1f(shader->radius, round); glUniform1f(shader->radius, round);
if (allowDim && m_pCurrentWindow && **PDIMINACTIVE) { if (allowDim && m_pCurrentWindow && *PDIMINACTIVE) {
glUniform1i(shader->applyTint, 1); glUniform1i(shader->applyTint, 1);
const auto DIM = m_pCurrentWindow->m_fDimPercent.fl(); const auto DIM = m_pCurrentWindow->m_fDimPercent.value();
glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM);
} else { } else {
glUniform1i(shader->applyTint, 0); glUniform1i(shader->applyTint, 0);
@ -1063,16 +1068,16 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix); wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
// get the config settings // get the config settings
static auto* const PBLURSIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:size"); static auto PBLURSIZE = CConfigValue<Hyprlang::INT>("decoration:blur:size");
static auto* const PBLURPASSES = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:passes"); static auto PBLURPASSES = CConfigValue<Hyprlang::INT>("decoration:blur:passes");
static auto* const PBLURVIBRANCY = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:vibrancy"); static auto PBLURVIBRANCY = CConfigValue<Hyprlang::FLOAT>("decoration:blur:vibrancy");
static auto* const PBLURVIBRANCYDARKNESS = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:vibrancy_darkness"); static auto PBLURVIBRANCYDARKNESS = CConfigValue<Hyprlang::FLOAT>("decoration:blur:vibrancy_darkness");
// prep damage // prep damage
CRegion damage{*originalDamage}; CRegion damage{*originalDamage};
wlr_region_transform(damage.pixman(), damage.pixman(), wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x, wlr_region_transform(damage.pixman(), damage.pixman(), wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x,
m_RenderData.pMonitor->vecTransformedSize.y); m_RenderData.pMonitor->vecTransformedSize.y);
wlr_region_expand(damage.pixman(), damage.pixman(), **PBLURPASSES > 10 ? pow(2, 15) : std::clamp(**PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, **PBLURPASSES)); wlr_region_expand(damage.pixman(), damage.pixman(), *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES));
// helper // helper
const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB; const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB;
@ -1083,8 +1088,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
// Begin with base color adjustments - global brightness and contrast // Begin with base color adjustments - global brightness and contrast
// TODO: make this a part of the first pass maybe to save on a drawcall? // TODO: make this a part of the first pass maybe to save on a drawcall?
{ {
static auto* const PBLURCONTRAST = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:contrast"); static auto PBLURCONTRAST = CConfigValue<Hyprlang::FLOAT>("decoration:blur:contrast");
static auto* const PBLURBRIGHTNESS = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:brightness"); static auto PBLURBRIGHTNESS = CConfigValue<Hyprlang::FLOAT>("decoration:blur:brightness");
PMIRRORSWAPFB->bind(); PMIRRORSWAPFB->bind();
@ -1102,8 +1107,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
wlr_matrix_transpose(glMatrix, glMatrix); wlr_matrix_transpose(glMatrix, glMatrix);
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURPREPARE.proj, 1, GL_FALSE, glMatrix); glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURPREPARE.proj, 1, GL_FALSE, glMatrix);
#endif #endif
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.contrast, **PBLURCONTRAST); glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.contrast, *PBLURCONTRAST);
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.brightness, **PBLURBRIGHTNESS); glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.brightness, *PBLURBRIGHTNESS);
glUniform1i(m_RenderData.pCurrentMonData->m_shBLURPREPARE.tex, 0); glUniform1i(m_RenderData.pCurrentMonData->m_shBLURPREPARE.tex, 0);
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURPREPARE.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURPREPARE.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
@ -1147,13 +1152,13 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
wlr_matrix_transpose(glMatrix, glMatrix); wlr_matrix_transpose(glMatrix, glMatrix);
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix); glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
#endif #endif
glUniform1f(pShader->radius, **PBLURSIZE * a); // this makes the blursize change with a glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a
if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1) { if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1) {
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f),
0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f)); 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
glUniform1i(m_RenderData.pCurrentMonData->m_shBLUR1.passes, **PBLURPASSES); glUniform1i(m_RenderData.pCurrentMonData->m_shBLUR1.passes, *PBLURPASSES);
glUniform1f(m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy, **PBLURVIBRANCY); glUniform1f(m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy, *PBLURVIBRANCY);
glUniform1f(m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy_darkness, **PBLURVIBRANCYDARKNESS); glUniform1f(m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy_darkness, *PBLURVIBRANCYDARKNESS);
} else } else
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f), glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f),
0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f)); 0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
@ -1190,20 +1195,20 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
CRegion tempDamage{damage}; CRegion tempDamage{damage};
// and draw // and draw
for (int i = 1; i <= **PBLURPASSES; ++i) { for (int i = 1; i <= *PBLURPASSES; ++i) {
wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i)); wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i));
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down
} }
for (int i = **PBLURPASSES - 1; i >= 0; --i) { for (int i = *PBLURPASSES - 1; i >= 0; --i) {
wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i)); // when upsampling we make the region twice as big wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i)); // when upsampling we make the region twice as big
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
} }
// finalize the image // finalize the image
{ {
static auto* const PBLURNOISE = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:noise"); static auto PBLURNOISE = CConfigValue<Hyprlang::FLOAT>("decoration:blur:noise");
static auto* const PBLURBRIGHTNESS = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:brightness"); static auto PBLURBRIGHTNESS = CConfigValue<Hyprlang::FLOAT>("decoration:blur:brightness");
if (currentRenderToFB == PMIRRORFB) if (currentRenderToFB == PMIRRORFB)
PMIRRORSWAPFB->bind(); PMIRRORSWAPFB->bind();
@ -1224,8 +1229,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
wlr_matrix_transpose(glMatrix, glMatrix); wlr_matrix_transpose(glMatrix, glMatrix);
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix); glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
#endif #endif
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.noise, **PBLURNOISE); glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.noise, *PBLURNOISE);
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness, **PBLURBRIGHTNESS); glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness, *PBLURBRIGHTNESS);
glUniform1i(m_RenderData.pCurrentMonData->m_shBLURFINISH.tex, 0); glUniform1i(m_RenderData.pCurrentMonData->m_shBLURFINISH.tex, 0);
@ -1264,11 +1269,11 @@ void CHyprOpenGLImpl::markBlurDirtyForMonitor(CMonitor* pMonitor) {
} }
void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) { void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
static auto* const PBLURNEWOPTIMIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations"); static auto PBLURNEWOPTIMIZE = CConfigValue<Hyprlang::INT>("decoration:blur:new_optimizations");
static auto* const PBLURXRAY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:xray"); static auto PBLURXRAY = CConfigValue<Hyprlang::INT>("decoration:blur:xray");
static auto* const PBLUR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"); static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
if (!**PBLURNEWOPTIMIZE || !m_mMonitorRenderResources[pMonitor].blurFBDirty || !**PBLUR) if (!*PBLURNEWOPTIMIZE || !m_mMonitorRenderResources[pMonitor].blurFBDirty || !*PBLUR)
return; return;
// ignore if solitary present, nothing to blur // ignore if solitary present, nothing to blur
@ -1292,7 +1297,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
const auto PSURFACE = pWindow->m_pWLSurface.wlr(); const auto PSURFACE = pWindow->m_pWLSurface.wlr();
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
const float A = pWindow->m_fAlpha.fl() * pWindow->m_fActiveInactiveAlpha.fl() * PWORKSPACE->m_fAlpha.fl(); const float A = pWindow->m_fAlpha.value() * pWindow->m_fActiveInactiveAlpha.value() * PWORKSPACE->m_fAlpha.value();
if (A >= 1.f) { if (A >= 1.f) {
if (PSURFACE->opaque) if (PSURFACE->opaque)
@ -1313,7 +1318,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
bool hasWindows = false; bool hasWindows = false;
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_iWorkspaceID == pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && (!w->m_bIsFloating || **PBLURXRAY)) { if (w->m_iWorkspaceID == pMonitor->activeWorkspace && !w->isHidden() && w->m_bIsMapped && (!w->m_bIsFloating || *PBLURXRAY)) {
// check if window is valid // check if window is valid
if (!windowShouldBeBlurred(w.get())) if (!windowShouldBeBlurred(w.get()))
@ -1330,7 +1335,7 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
if (!ls->layerSurface || ls->xray != 1) if (!ls->layerSurface || ls->xray != 1)
continue; continue;
if (ls->layerSurface->surface->opaque && ls->alpha.fl() >= 1.f) if (ls->layerSurface->surface->opaque && ls->alpha.value() >= 1.f)
continue; continue;
hasWindows = true; hasWindows = true;
@ -1386,15 +1391,15 @@ void CHyprOpenGLImpl::preWindowPass() {
} }
bool CHyprOpenGLImpl::preBlurQueued() { bool CHyprOpenGLImpl::preBlurQueued() {
static auto* const PBLURNEWOPTIMIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations"); static auto PBLURNEWOPTIMIZE = CConfigValue<Hyprlang::INT>("decoration:blur:new_optimizations");
static auto* const PBLUR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"); static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
return !(!m_RenderData.pCurrentMonData->blurFBDirty || !**PBLURNEWOPTIMIZE || !**PBLUR || !m_RenderData.pCurrentMonData->blurFBShouldRender); return !(!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE || !*PBLUR || !m_RenderData.pCurrentMonData->blurFBShouldRender);
} }
bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWindow* pWindow) { bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWindow* pWindow) {
static auto* const PBLURNEWOPTIMIZE = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations"); static auto PBLURNEWOPTIMIZE = CConfigValue<Hyprlang::INT>("decoration:blur:new_optimizations");
static auto* const PBLURXRAY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:xray"); static auto PBLURXRAY = CConfigValue<Hyprlang::INT>("decoration:blur:xray");
if (!m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID) if (!m_RenderData.pCurrentMonData->blurFB.m_cTex.m_iTexID)
return false; return false;
@ -1405,7 +1410,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWind
if (pLayer && pLayer->xray == 0) if (pLayer && pLayer->xray == 0)
return false; return false;
if ((**PBLURNEWOPTIMIZE && pWindow && !pWindow->m_bIsFloating && !g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) || **PBLURXRAY) if ((*PBLURNEWOPTIMIZE && pWindow && !pWindow->m_bIsFloating && !g_pCompositor->isWorkspaceSpecial(pWindow->m_iWorkspaceID)) || *PBLURXRAY)
return true; return true;
if ((pLayer && pLayer->xray == 1) || (pWindow && pWindow->m_sAdditionalConfigData.xray.toUnderlying() == 1)) if ((pLayer && pLayer->xray == 1) || (pWindow && pWindow->m_sAdditionalConfigData.xray.toUnderlying() == 1))
@ -1417,8 +1422,8 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWind
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, float a, wlr_surface* pSurface, int round, bool blockBlurOptimization, float blurA) { void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, float a, wlr_surface* pSurface, int round, bool blockBlurOptimization, float blurA) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
static auto* const PBLURENABLED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"); static auto PBLURENABLED = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
static auto* const PNOBLUROVERSIZED = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized"); static auto PNOBLUROVERSIZED = CConfigValue<Hyprlang::INT>("decoration:no_blur_on_oversized");
TRACY_GPU_ZONE("RenderTextureWithBlur"); TRACY_GPU_ZONE("RenderTextureWithBlur");
@ -1429,7 +1434,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
if (texDamage.empty()) if (texDamage.empty())
return; return;
if (**PBLURENABLED == 0 || (**PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) ||
(m_pCurrentWindow && (m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur || m_pCurrentWindow->m_sAdditionalConfigData.forceRGBX))) { (m_pCurrentWindow && (m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur || m_pCurrentWindow->m_sAdditionalConfigData.forceRGBX))) {
renderTexture(tex, pBox, a, round, false, true); renderTexture(tex, pBox, a, round, false, true);
return; return;
@ -1490,11 +1495,11 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
// stencil done. Render everything. // stencil done. Render everything.
CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; CBox MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
// render our great blurred FB // render our great blurred FB
static auto* const PBLURIGNOREOPACITY = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:ignore_opacity"); static auto PBLURIGNOREOPACITY = CConfigValue<Hyprlang::INT>("decoration:blur:ignore_opacity");
m_bEndFrame = true; // fix transformed m_bEndFrame = true; // fix transformed
const auto SAVEDRENDERMODIF = m_RenderData.renderModif; const auto SAVEDRENDERMODIF = m_RenderData.renderModif;
m_RenderData.renderModif = {}; // fix shit m_RenderData.renderModif = {}; // fix shit
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, **PBLURIGNOREOPACITY ? blurA : a * blurA, &texDamage, 0, false, false, false); renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? blurA : a * blurA, &texDamage, 0, false, false, false);
m_bEndFrame = false; m_bEndFrame = false;
m_RenderData.renderModif = SAVEDRENDERMODIF; m_RenderData.renderModif = SAVEDRENDERMODIF;
@ -1644,7 +1649,7 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra
// will try to copy the bg to apply blur. // will try to copy the bg to apply blur.
// this isn't entirely correct, but like, oh well. // this isn't entirely correct, but like, oh well.
// small todo: maybe make this correct? :P // small todo: maybe make this correct? :P
static auto* const PBLUR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"); static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"));
const auto BLURVAL = **PBLUR; const auto BLURVAL = **PBLUR;
**PBLUR = 0; **PBLUR = 0;
@ -1697,7 +1702,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
// will try to copy the bg to apply blur. // will try to copy the bg to apply blur.
// this isn't entirely correct, but like, oh well. // this isn't entirely correct, but like, oh well.
// small todo: maybe make this correct? :P // small todo: maybe make this correct? :P
static auto* const PBLUR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"); static auto* const PBLUR = (Hyprlang::INT* const*)(g_pConfigManager->getConfigValuePtr("decoration:blur:enabled"));
const auto BLURVAL = **PBLUR; const auto BLURVAL = **PBLUR;
**PBLUR = 0; **PBLUR = 0;
@ -1756,7 +1761,7 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!");
const auto PWINDOW = *pWindow; const auto PWINDOW = *pWindow;
static auto* const PDIMAROUND = (Hyprlang::FLOAT* const*)g_pConfigManager->getConfigValuePtr("decoration:dim_around"); static auto PDIMAROUND = CConfigValue<Hyprlang::FLOAT>("decoration:dim_around");
auto it = m_mWindowFramebuffers.begin(); auto it = m_mWindowFramebuffers.begin();
for (; it != m_mWindowFramebuffers.end(); it++) { for (; it != m_mWindowFramebuffers.end(); it++) {
@ -1773,25 +1778,25 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
CBox windowBox; CBox windowBox;
// some mafs to figure out the correct box // some mafs to figure out the correct box
// the originalClosedPos is relative to the monitor's pos // the originalClosedPos is relative to the monitor's pos
Vector2D scaleXY = Vector2D((PMONITOR->scale * PWINDOW->m_vRealSize.vec().x / (PWINDOW->m_vOriginalClosedSize.x * PMONITOR->scale)), Vector2D scaleXY = Vector2D((PMONITOR->scale * PWINDOW->m_vRealSize.value().x / (PWINDOW->m_vOriginalClosedSize.x * PMONITOR->scale)),
(PMONITOR->scale * PWINDOW->m_vRealSize.vec().y / (PWINDOW->m_vOriginalClosedSize.y * PMONITOR->scale))); (PMONITOR->scale * PWINDOW->m_vRealSize.value().y / (PWINDOW->m_vOriginalClosedSize.y * PMONITOR->scale)));
windowBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x; windowBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x;
windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y; windowBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y;
windowBox.x = ((PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x); windowBox.x = ((PWINDOW->m_vRealPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x);
windowBox.y = ((PWINDOW->m_vRealPosition.vec().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y); windowBox.y = ((PWINDOW->m_vRealPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y);
CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
if (**PDIMAROUND && (*pWindow)->m_sAdditionalConfigData.dimAround) { if (*PDIMAROUND && (*pWindow)->m_sAdditionalConfigData.dimAround) {
CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y}; CBox monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y};
g_pHyprOpenGL->renderRect(&monbox, CColor(0, 0, 0, **PDIMAROUND * PWINDOW->m_fAlpha.fl())); g_pHyprOpenGL->renderRect(&monbox, CColor(0, 0, 0, *PDIMAROUND * PWINDOW->m_fAlpha.value()));
g_pHyprRenderer->damageMonitor(PMONITOR); g_pHyprRenderer->damageMonitor(PMONITOR);
} }
m_bEndFrame = true; m_bEndFrame = true;
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), &fakeDamage, 0); renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.value(), &fakeDamage, 0);
m_bEndFrame = false; m_bEndFrame = false;
} }
@ -1812,13 +1817,22 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID);
CBox monbox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; CBox layerBox;
// some mafs to figure out the correct box
// the originalClosedPos is relative to the monitor's pos
Vector2D scaleXY = Vector2D((PMONITOR->scale * PLAYER->realSize.value().x / (PLAYER->geometry.w * PMONITOR->scale)),
(PMONITOR->scale * PLAYER->realSize.value().y / (PLAYER->geometry.h * PMONITOR->scale)));
layerBox.width = PMONITOR->vecTransformedSize.x * scaleXY.x;
layerBox.height = PMONITOR->vecTransformedSize.y * scaleXY.y;
layerBox.x = ((PLAYER->realPosition.value().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - (((PLAYER->geometry.x - PMONITOR->vecPosition.x) * PMONITOR->scale) * scaleXY.x);
layerBox.y = ((PLAYER->realPosition.value().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - (((PLAYER->geometry.y - PMONITOR->vecPosition.y) * PMONITOR->scale) * scaleXY.y);
CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
m_bEndFrame = true; m_bEndFrame = true;
renderTextureInternalWithDamage(it->second.m_cTex, &monbox, PLAYER->alpha.fl(), &fakeDamage, 0); renderTextureInternalWithDamage(it->second.m_cTex, &layerBox, PLAYER->alpha.value(), &fakeDamage, 0);
m_bEndFrame = false; m_bEndFrame = false;
} }
@ -1838,9 +1852,9 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const
box = &newBox; box = &newBox;
static auto* const PSHADOWPOWER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("decoration:shadow_render_power"); static auto PSHADOWPOWER = CConfigValue<Hyprlang::INT>("decoration:shadow_render_power");
const auto SHADOWPOWER = std::clamp((int)**PSHADOWPOWER, 1, 4); const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
const auto col = color; const auto col = color;
@ -1932,16 +1946,16 @@ void CHyprOpenGLImpl::renderMirrored() {
} }
void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY, const Vector2D& size) { void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY, const Vector2D& size) {
static auto* const PSPLASHCOLOR = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:col.splash"); static auto PSPLASHCOLOR = CConfigValue<Hyprlang::INT>("misc:col.splash");
static auto* const PSPLASHFONT = (Hyprlang::STRING const*)g_pConfigManager->getConfigValuePtr("misc:splash_font_family"); static auto PSPLASHFONT = CConfigValue<std::string>("misc:splash_font_family");
cairo_select_font_face(CAIRO, *PSPLASHFONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_select_font_face(CAIRO, (*PSPLASHFONT).c_str(), CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
const auto FONTSIZE = (int)(size.y / 76); const auto FONTSIZE = (int)(size.y / 76);
cairo_set_font_size(CAIRO, FONTSIZE); cairo_set_font_size(CAIRO, FONTSIZE);
const auto COLOR = CColor(**PSPLASHCOLOR); const auto COLOR = CColor(*PSPLASHCOLOR);
cairo_set_source_rgba(CAIRO, COLOR.r, COLOR.g, COLOR.b, COLOR.a); cairo_set_source_rgba(CAIRO, COLOR.r, COLOR.g, COLOR.b, COLOR.a);
@ -1958,15 +1972,15 @@ void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const
void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) { void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
static auto* const PRENDERTEX = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo"); static auto PRENDERTEX = CConfigValue<Hyprlang::INT>("misc:disable_hyprland_logo");
static auto* const PNOSPLASH = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering"); static auto PNOSPLASH = CConfigValue<Hyprlang::INT>("misc:disable_splash_rendering");
static auto* const PFORCEWALLPAPER = (Hyprlang::INT* const*)g_pConfigManager->getConfigValuePtr("misc:force_default_wallpaper"); static auto PFORCEWALLPAPER = CConfigValue<Hyprlang::INT>("misc:force_default_wallpaper");
const auto FORCEWALLPAPER = std::clamp(**PFORCEWALLPAPER, static_cast<int64_t>(-1L), static_cast<int64_t>(2L)); const auto FORCEWALLPAPER = std::clamp(*PFORCEWALLPAPER, static_cast<int64_t>(-1L), static_cast<int64_t>(2L));
static std::string texPath = ""; static std::string texPath = "";
if (**PRENDERTEX) if (*PRENDERTEX)
return; return;
// release the last tex if exists // release the last tex if exists
@ -1988,7 +2002,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
texPath += std::to_string(distribution(engine)); texPath += std::to_string(distribution(engine));
} else } else
texPath += std::to_string(std::clamp(**PFORCEWALLPAPER, (int64_t)0, (int64_t)2)); texPath += std::to_string(std::clamp(*PFORCEWALLPAPER, (int64_t)0, (int64_t)2));
texPath += ".png"; texPath += ".png";
@ -2039,7 +2053,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
cairo_set_source_surface(CAIRO, CAIROISURFACE, 0, 0); cairo_set_source_surface(CAIRO, CAIROISURFACE, 0, 0);
cairo_paint(CAIRO); cairo_paint(CAIRO);
if (!**PNOSPLASH) if (!*PNOSPLASH)
renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO * scale, IMAGESIZE); renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO * scale, IMAGESIZE);
cairo_surface_flush(CAIROSURFACE); cairo_surface_flush(CAIROSURFACE);
@ -2048,7 +2062,13 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
tex.m_vSize = IMAGESIZE * scale; tex.m_vSize = IMAGESIZE * scale;
// copy the data to an OpenGL texture we have // copy the data to an OpenGL texture we have
const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA; const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ?
#ifdef GLES2
GL_RGB32F_EXT :
#else
GL_RGB32F :
#endif
GL_RGBA;
const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA; const GLint glFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE; const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
@ -2154,7 +2174,7 @@ void CHyprOpenGLImpl::bindBackOnMain() {
} }
void CHyprOpenGLImpl::setMonitorTransformEnabled(bool enabled) { void CHyprOpenGLImpl::setMonitorTransformEnabled(bool enabled) {
m_bEndFrame = !enabled; m_bEndFrame = enabled;
} }
inline const SGLPixelFormat GLES2_FORMATS[] = { inline const SGLPixelFormat GLES2_FORMATS[] = {

Some files were not shown because too many files have changed in this diff Show more