mirror of
https://github.com/hyprwm/Hyprland.git
synced 2024-08-16 16:50:23 +03:00
Merge upstream
This commit is contained in:
commit
5388b54442
38
.github/workflows/release.yaml
vendored
Normal file
38
.github/workflows/release.yaml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Release artifacts
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
source-tarball:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Hyprland
|
||||
id: checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Create tarball with submodules
|
||||
id: tar
|
||||
run: tar -czv --owner=0 --group=0 --no-same-owner --no-same-permissions -f source.tar.gz *
|
||||
|
||||
- id: whatrelease
|
||||
name: Get latest release
|
||||
uses: pozetroninc/github-action-get-latest-release@master
|
||||
with:
|
||||
owner: hyprwm
|
||||
repo: Hyprland
|
||||
excludes: prerelease, draft
|
||||
|
||||
- name: Upload to release
|
||||
id: upload
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: source.tar.gz
|
||||
asset_name: source-${{ steps.whatrelease.outputs.release }}.tar.gz
|
||||
tag: ${{ steps.whatrelease.outputs.release }}
|
||||
overwrite: true
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,6 +12,8 @@ _deps
|
||||
build/
|
||||
result
|
||||
/.vscode/
|
||||
.envrc
|
||||
.cache
|
||||
|
||||
*.o
|
||||
*-protocol.c
|
||||
|
@ -37,12 +37,12 @@ execute_process(
|
||||
|
||||
include_directories(. PRIVATE "subprojects/wlroots/include/")
|
||||
include_directories(. PRIVATE "subprojects/wlroots/build/include/")
|
||||
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-std=c++23 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo libdrm egl xkbcommon wlroots libinput xcb)
|
||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-server wayland-client wayland-cursor wayland-protocols cairo pango pangocairo libdrm egl xkbcommon libinput xcb) # we do not check for wlroots, as we provide it ourselves
|
||||
|
||||
file(GLOB_RECURSE SRCFILES "src/*.cpp")
|
||||
|
||||
@ -80,7 +80,7 @@ include(CPack)
|
||||
target_link_libraries(Hyprland PkgConfig::deps)
|
||||
|
||||
target_link_libraries(Hyprland
|
||||
wlroots
|
||||
${CMAKE_SOURCE_DIR}/subprojects/wlroots/build/libwlroots.so.11032 # wlroots is provided by us
|
||||
pixman-1
|
||||
OpenGL
|
||||
GLESv2
|
||||
|
17
Makefile
17
Makefile
@ -107,11 +107,13 @@ all:
|
||||
cd ./hyprctl && make all && cd ..
|
||||
|
||||
install:
|
||||
[ ! -d /usr/include/wlr ] || mv /usr/include/wlr /usr/include/wlrBackup
|
||||
[ ! -f /usr/lib/libwlroots.so ] || mv /usr/lib/libwlroots.so /usr/lib/libwlroots.so.backup
|
||||
[ ! -f /usr/lib/pkgconfig/wlroots.pc ] || mv /usr/lib/pkgconfig/wlroots.pc /usr/lib/pkgconfig/wlroots.pc.backup
|
||||
make clear
|
||||
make fixwlr
|
||||
cd ./subprojects/wlroots && meson build/ --buildtype=release && ninja -C build/ && cp ./build/libwlroots.so.11032 /usr/lib/ && cd ../..
|
||||
make protocols
|
||||
make release
|
||||
cd hyprctl && make all && cd ..
|
||||
|
||||
make all
|
||||
mkdir -p ${PREFIX}/share/wayland-sessions
|
||||
cp ./example/hyprland.desktop ${PREFIX}/share/wayland-sessions/
|
||||
mkdir -p ${PREFIX}/bin
|
||||
@ -122,17 +124,12 @@ install:
|
||||
cp ./assets/wall_4K.png ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_8K.png ${PREFIX}/share/hyprland
|
||||
|
||||
rm -rf /usr/include/wlr
|
||||
rm -f /usr/lib/libwlroots.so
|
||||
rm -f /usr/lib/pkgconfig/wlroots.pc
|
||||
[ ! -d /usr/include/wlrBackup ] || mv /usr/include/wlrBackup /usr/include/wlr
|
||||
[ ! -f /usr/lib/libwlroots.so.backup ] || mv -f /usr/lib/libwlroots.so.backup /usr/lib/libwlroots.so
|
||||
[ ! -f /usr/lib/pkgconfig/wlroots.pc.backup ] || mv -f /usr/lib/pkgconfig/wlroots.pc.backup /usr/lib/pkgconfig/wlroots.pc
|
||||
|
||||
uninstall:
|
||||
rm -f ${PREFIX}/share/wayland-sessions/hyprland.desktop
|
||||
rm -f ${PREFIX}/bin/Hyprland
|
||||
rm -f ${PREFIX}/bin/hyprctl
|
||||
rm -f /usr/lib/libwlroots.so.11032
|
||||
rm -rf ${PREFIX}/share/hyprland
|
||||
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o
|
||||
|
30
README.md
30
README.md
@ -122,18 +122,18 @@ Try it out and report bugs / suggestions!
|
||||
|
||||
<!----------------------------------------------------------------------------->
|
||||
|
||||
[Configure]: https://github.com/vaxerski/Hyprland/wiki/Configuring-Hyprland
|
||||
[Configure]: https://github.com/hyprwm/Hyprland/wiki/Configuring-Hyprland
|
||||
[Discord]: https://discord.gg/hQ9XvMUjjr
|
||||
[Stars]: https://starchart.cc/vaxerski/Hyprland
|
||||
[Hypr]: https://github.com/vaxerski/Hypr
|
||||
[Stars]: https://starchart.cc/hyprwm/Hyprland
|
||||
[Hypr]: https://github.com/hyprwm/Hypr
|
||||
|
||||
[Pull Requests]: https://github.com/vaxerski/Hyprland/pulls
|
||||
[Issues]: https://github.com/vaxerski/Hyprland/issues
|
||||
[Todo]: https://github.com/vaxerski/Hyprland/projects?type=beta
|
||||
[Pull Requests]: https://github.com/hyprwm/Hyprland/pulls
|
||||
[Issues]: https://github.com/hyprwm/Hyprland/issues
|
||||
[Todo]: https://github.com/hyprwm/Hyprland/projects?type=beta
|
||||
|
||||
[Contribute]: https://github.com/vaxerski/Hyprland/wiki/Contributing-&-Debugging
|
||||
[Install]: https://github.com/vaxerski/Hyprland/wiki/Installation
|
||||
[Quick Start]: https://github.com/vaxerski/Hyprland/wiki/Quick-start
|
||||
[Contribute]: https://github.com/hyprwm/Hyprland/wiki/Contributing-&-Debugging
|
||||
[Install]: https://github.com/hyprwm/Hyprland/wiki/Installation
|
||||
[Quick Start]: https://github.com/hyprwm/Hyprland/wiki/Quick-start
|
||||
[License]: LICENSE
|
||||
|
||||
|
||||
@ -156,12 +156,12 @@ Try it out and report bugs / suggestions!
|
||||
|
||||
<!----------------------------------{ Badges }--------------------------------->
|
||||
|
||||
[Badge Workflow]: https://github.com/vaxerski/Hyprland/actions/workflows/ci.yaml/badge.svg
|
||||
[Badge Workflow]: https://github.com/hyprwm/Hyprland/actions/workflows/ci.yaml/badge.svg
|
||||
|
||||
[Badge Discord]: https://img.shields.io/badge/Join%20the-Discord%20server-6666ff
|
||||
[Badge Issues]: https://img.shields.io/github/issues/vaxerski/Hyprland
|
||||
[Badge Pull Requests]: https://img.shields.io/github/issues-pr/vaxerski/Hyprland
|
||||
[Badge Language]: https://img.shields.io/github/languages/top/vaxerski/Hyprland
|
||||
[Badge License]: https://img.shields.io/github/license/vaxerski/Hyprland
|
||||
[Badge Lines]: https://img.shields.io/tokei/lines/github/vaxerski/Hyprland
|
||||
[Badge Issues]: https://img.shields.io/github/issues/hyprwm/Hyprland
|
||||
[Badge Pull Requests]: https://img.shields.io/github/issues-pr/hyprwm/Hyprland
|
||||
[Badge Language]: https://img.shields.io/github/languages/top/hyprwm/Hyprland
|
||||
[Badge License]: https://img.shields.io/github/license/hyprwm/Hyprland
|
||||
[Badge Lines]: https://img.shields.io/tokei/lines/github/hyprwm/Hyprland
|
||||
[Badge Hi Mom]: https://img.shields.io/badge/Hi-mom!-ff69b4
|
||||
|
@ -26,6 +26,7 @@ If your bug is one that doesn't crash Hyprland, but feels like invalid behavior,
|
||||
If your bug crashes Hyprland, append additionally:
|
||||
- The Hyprland log
|
||||
- Coredump / Coredump analysis (with a stacktrace)
|
||||
- Your config
|
||||
|
||||
**Important**: Please do NOT use any package for reporting bugs! Clone and compile from source.
|
||||
|
||||
|
@ -3,6 +3,11 @@
|
||||
#
|
||||
# Refer to the wiki for more information.
|
||||
|
||||
#
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
#
|
||||
|
||||
monitor=,1280x720@60,0x0,1
|
||||
workspace=DP-1,1
|
||||
|
||||
|
12
flake.lock
12
flake.lock
@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1656239181,
|
||||
"narHash": "sha256-wW1xRFBn376yGloXZ4QzBE4hjipMawpV18Lshd9QSPw=",
|
||||
"lastModified": 1657447684,
|
||||
"narHash": "sha256-FCP9AuU1q6PE3vOeM5SFf58f/UKPBAsoSGDUGamNBbo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f2537a505d45c31fe5d9c27ea9829b6f4c4e6ac5",
|
||||
"rev": "5f43d8b088d3771274bcfb69d3c7435b1121ac88",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1655824477,
|
||||
"narHash": "sha256-1kskHOLsnisR3kqIL5IHrQbQG/4xoXxeEf1ExMV6/RU=",
|
||||
"lastModified": 1656865312,
|
||||
"narHash": "sha256-xtQ0zwJZwN8sciruveM10CzKz6TWxBY8SyXa8E4jly4=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "5c4384a1330faedf975c8b8644881d50390f3613",
|
||||
"rev": "5dc1d4671dd2ca3c1f0f09587c463fdbb542f0a4",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
13
flake.nix
13
flake.nix
@ -32,7 +32,8 @@
|
||||
src = inputs.wlroots;
|
||||
});
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
version = "0.6.2beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
stdenv = prev.gcc12Stdenv;
|
||||
version = "0.7.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
@ -47,6 +48,16 @@
|
||||
default = self.packages.${system}.hyprland;
|
||||
});
|
||||
|
||||
devShells = genSystems (system: {
|
||||
default = pkgsFor.${system}.mkShell.override {stdenv = pkgsFor.${system}.gcc12Stdenv;} {
|
||||
name = "hyprland-shell";
|
||||
inputsFrom = [
|
||||
self.packages.${system}.wlroots-hyprland
|
||||
self.packages.${system}.hyprland
|
||||
];
|
||||
};
|
||||
});
|
||||
|
||||
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
||||
|
||||
nixosModules.default = import ./nix/module.nix self;
|
||||
|
@ -1,4 +1,4 @@
|
||||
all:
|
||||
g++ -std=c++20 ./main.cpp -o ./hyprctl
|
||||
g++ -std=c++23 ./main.cpp -o ./hyprctl
|
||||
clean:
|
||||
rm ./hyprctl
|
||||
rm ./hyprctl
|
||||
|
@ -14,9 +14,11 @@
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
const std::string USAGE = R"#(usage: hyprctl [command] [(opt)args]
|
||||
const std::string USAGE = R"#(usage: hyprctl [(opt)flags] [command] [(opt)args]
|
||||
|
||||
commands:
|
||||
monitors
|
||||
workspaces
|
||||
clients
|
||||
@ -27,8 +29,13 @@ const std::string USAGE = R"#(usage: hyprctl [command] [(opt)args]
|
||||
keyword
|
||||
version
|
||||
kill
|
||||
splash
|
||||
hyprpaper
|
||||
reload)#";
|
||||
reload
|
||||
|
||||
flags:
|
||||
j -> output in JSON
|
||||
)#";
|
||||
|
||||
void request(std::string arg) {
|
||||
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
@ -153,7 +160,7 @@ void dispatchRequest(int argc, char** argv) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string rq = "dispatch " + std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
std::string rq = "/dispatch " + std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
|
||||
request(rq);
|
||||
}
|
||||
@ -180,12 +187,21 @@ void hyprpaperRequest(int argc, char** argv) {
|
||||
requestHyprpaper(rq);
|
||||
}
|
||||
|
||||
void batchRequest(int argc, char** argv) {
|
||||
std::string rq = "[[BATCH]]" + std::string(argv[2]);
|
||||
void batchRequest(std::string arg) {
|
||||
std::string rq = "[[BATCH]]" + arg.substr(arg.find_first_of(" ") + 1);
|
||||
|
||||
request(rq);
|
||||
}
|
||||
|
||||
std::deque<std::string> splitArgs(int argc, char** argv) {
|
||||
std::deque<std::string> result;
|
||||
|
||||
for (auto i = 1 /* skip the executable */; i < argc; ++i)
|
||||
result.push_back(std::string(argv[i]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int bflag = 0, sflag = 0, index, c;
|
||||
|
||||
@ -194,20 +210,47 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "monitors")) request("monitors");
|
||||
else if (!strcmp(argv[1], "clients")) request("clients");
|
||||
else if (!strcmp(argv[1], "workspaces")) request("workspaces");
|
||||
else if (!strcmp(argv[1], "activewindow")) request("activewindow");
|
||||
else if (!strcmp(argv[1], "layers")) request("layers");
|
||||
else if (!strcmp(argv[1], "version")) request("version");
|
||||
else if (!strcmp(argv[1], "kill")) request("kill");
|
||||
else if (!strcmp(argv[1], "devices")) request("devices");
|
||||
else if (!strcmp(argv[1], "reload")) request("reload");
|
||||
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "hyprpaper")) hyprpaperRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "--batch")) batchRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "--help")) printf("%s", USAGE.c_str());
|
||||
std::string fullRequest = "";
|
||||
std::string fullArgs = "";
|
||||
const auto ARGS = splitArgs(argc, argv);
|
||||
|
||||
for (auto i = 0; i < ARGS.size(); ++i) {
|
||||
if (ARGS[i].contains("-")) {
|
||||
// parse
|
||||
if (ARGS[i] == "-j" && !fullArgs.contains("j")) {
|
||||
fullArgs += "j";
|
||||
} else if (ARGS[i] == "--batch") {
|
||||
fullRequest = "--batch ";
|
||||
} else {
|
||||
printf("%s\n", USAGE.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
fullRequest += ARGS[i] + " ";
|
||||
}
|
||||
|
||||
fullRequest.pop_back(); // remove trailing space
|
||||
|
||||
fullRequest = fullArgs + "/" + fullRequest;
|
||||
|
||||
if (fullRequest.contains("/--batch")) batchRequest(fullRequest);
|
||||
else if (fullRequest.contains("/monitors")) request(fullRequest);
|
||||
else if (fullRequest.contains("/clients")) request(fullRequest);
|
||||
else if (fullRequest.contains("/workspaces")) request(fullRequest);
|
||||
else if (fullRequest.contains("/activewindow")) request(fullRequest);
|
||||
else if (fullRequest.contains("/layers")) request(fullRequest);
|
||||
else if (fullRequest.contains("/version")) request(fullRequest);
|
||||
else if (fullRequest.contains("/kill")) request(fullRequest);
|
||||
else if (fullRequest.contains("/splash")) request(fullRequest);
|
||||
else if (fullRequest.contains("/devices")) request(fullRequest);
|
||||
else if (fullRequest.contains("/reload")) request(fullRequest);
|
||||
else if (fullRequest.contains("/dispatch")) dispatchRequest(argc, argv);
|
||||
else if (fullRequest.contains("/keyword")) keywordRequest(argc, argv);
|
||||
else if (fullRequest.contains("/hyprpaper")) hyprpaperRequest(argc, argv);
|
||||
else if (fullRequest.contains("/--help")) printf("%s", USAGE.c_str());
|
||||
else {
|
||||
printf("%s\n", USAGE.c_str());
|
||||
return 1;
|
||||
|
@ -1,6 +1,8 @@
|
||||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.6.2beta',
|
||||
default_options : ['warning_level=2', 'cpp_std=c++20', 'default_library=static', 'optimization=3'])
|
||||
version : '0.7.0beta',
|
||||
default_options : ['warning_level=2', 'default_library=static', 'optimization=3'])
|
||||
|
||||
add_global_arguments('-std=c++23', language: 'cpp')
|
||||
|
||||
add_project_arguments(
|
||||
[
|
||||
|
@ -61,6 +61,11 @@ stdenv.mkDerivation {
|
||||
./meson-build.patch
|
||||
];
|
||||
|
||||
# Fix hardcoded paths to /usr installation
|
||||
postPatch = ''
|
||||
sed -i "s#/usr#$out#" src/render/OpenGL.cpp
|
||||
'';
|
||||
|
||||
passthru.providedSessions = ["hyprland"];
|
||||
|
||||
meta = with lib; {
|
||||
|
@ -19,7 +19,7 @@ in {
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.hyprland or self.packages.${pkgs.system}.default;
|
||||
default = self.packages.${pkgs.system}.default;
|
||||
defaultText = literalExpression "<Hyprland flake>.packages.<system>.default";
|
||||
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
|
||||
description = ''
|
||||
|
@ -1,4 +1,16 @@
|
||||
#include "Compositor.hpp"
|
||||
#include "helpers/Splashes.hpp"
|
||||
#include <random>
|
||||
|
||||
int handleCritSignal(int signo, void* data) {
|
||||
Debug::log(LOG, "Hyprland received signal %d", signo);
|
||||
|
||||
if (signo == SIGTERM || signo == SIGINT || signo == SIGKILL) {
|
||||
g_pCompositor->cleanup();
|
||||
}
|
||||
|
||||
return 0; // everything went fine
|
||||
}
|
||||
|
||||
CCompositor::CCompositor() {
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||
@ -22,29 +34,36 @@ CCompositor::CCompositor() {
|
||||
|
||||
Debug::log(INFO, "If you are crashing, or encounter any bugs, please consult https://github.com/hyprwm/Hyprland/wiki/Crashing-and-bugs\n\n");
|
||||
|
||||
setRandomSplash();
|
||||
|
||||
Debug::log(LOG, "\nCurrent splash: %s\n\n", m_szCurrentSplash.c_str());
|
||||
|
||||
m_sWLDisplay = wl_display_create();
|
||||
|
||||
m_sWLEventLoop = wl_display_get_event_loop(m_sWLDisplay);
|
||||
|
||||
// register crit signal handler
|
||||
wl_event_loop_add_signal(m_sWLEventLoop, SIGTERM, handleCritSignal, nullptr);
|
||||
//wl_event_loop_add_signal(m_sWLEventLoop, SIGINT, handleCritSignal, nullptr);
|
||||
|
||||
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay);
|
||||
|
||||
if (!m_sWLRBackend) {
|
||||
Debug::log(CRIT, "m_sWLRBackend was NULL!");
|
||||
RIP("m_sWLRBackend NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_backend_autocreate() failed!");
|
||||
}
|
||||
|
||||
m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend);
|
||||
if (m_iDRMFD < 0) {
|
||||
Debug::log(CRIT, "Couldn't query the DRM FD!");
|
||||
RIP("DRMFD NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_backend_get_drm_fd() failed!");
|
||||
}
|
||||
|
||||
m_sWLRRenderer = wlr_gles2_renderer_create_with_drm_fd(m_iDRMFD);
|
||||
|
||||
if (!m_sWLRRenderer) {
|
||||
Debug::log(CRIT, "m_sWLRRenderer was NULL!");
|
||||
RIP("m_sWLRRenderer NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_gles2_renderer_create_with_drm_fd() failed!");
|
||||
}
|
||||
|
||||
wlr_renderer_init_wl_display(m_sWLRRenderer, m_sWLDisplay);
|
||||
@ -53,16 +72,14 @@ CCompositor::CCompositor() {
|
||||
|
||||
if (!m_sWLRAllocator) {
|
||||
Debug::log(CRIT, "m_sWLRAllocator was NULL!");
|
||||
RIP("m_sWLRAllocator NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_allocator_autocreate() failed!");
|
||||
}
|
||||
|
||||
m_sWLREGL = wlr_gles2_renderer_get_egl(m_sWLRRenderer);
|
||||
|
||||
if (!m_sWLREGL) {
|
||||
Debug::log(CRIT, "m_sWLREGL was NULL!");
|
||||
RIP("m_sWLREGL NULL!");
|
||||
return;
|
||||
throw std::runtime_error("wlr_gles2_renderer_get_egl() failed!");
|
||||
}
|
||||
|
||||
m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, m_sWLRRenderer);
|
||||
@ -124,17 +141,26 @@ CCompositor::CCompositor() {
|
||||
|
||||
m_sWLRForeignRegistry = wlr_xdg_foreign_registry_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRIdleInhibitMgr = wlr_idle_inhibit_v1_create(m_sWLDisplay);
|
||||
|
||||
wlr_xdg_foreign_v1_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||
wlr_xdg_foreign_v2_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||
|
||||
m_sWLRPointerGestures = wlr_pointer_gestures_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRSession = wlr_backend_get_session(m_sWLRBackend);
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
cleanupExit();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void handleCritSignal(int signo) {
|
||||
g_pCompositor->cleanupExit();
|
||||
exit(signo);
|
||||
void CCompositor::setRandomSplash() {
|
||||
std::random_device dev;
|
||||
std::mt19937 engine(dev());
|
||||
std::uniform_int_distribution<> distribution(0, SPLASHES.size() - 1);
|
||||
|
||||
m_szCurrentSplash = SPLASHES[distribution(engine)];
|
||||
}
|
||||
|
||||
void CCompositor::initAllSignals() {
|
||||
@ -145,6 +171,9 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRCursor->events.button, &Events::listen_mouseButton, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.axis, &Events::listen_mouseAxis, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.frame, &Events::listen_mouseFrame, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.swipe_begin, &Events::listen_swipeBegin, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.swipe_update, &Events::listen_swipeUpdate, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRCursor->events.swipe_end, &Events::listen_swipeEnd, m_sWLRCursor, "WLRCursor");
|
||||
addWLSignal(&m_sWLRBackend->events.new_input, &Events::listen_newInput, m_sWLRBackend, "Backend");
|
||||
addWLSignal(&m_sSeat.seat->events.request_set_cursor, &Events::listen_requestMouse, &m_sSeat, "Seat");
|
||||
addWLSignal(&m_sSeat.seat->events.request_set_selection, &Events::listen_requestSetSel, &m_sSeat, "Seat");
|
||||
@ -160,12 +189,12 @@ void CCompositor::initAllSignals() {
|
||||
addWLSignal(&m_sWLRXDGDecoMgr->events.new_toplevel_decoration, &Events::listen_NewXDGDeco, m_sWLRXDGDecoMgr, "XDGDecoMgr");
|
||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||
|
||||
signal(SIGINT, handleCritSignal);
|
||||
signal(SIGTERM, handleCritSignal);
|
||||
addWLSignal(&m_sWLRIdleInhibitMgr->events.new_inhibitor, &Events::listen_newIdleInhibitor, m_sWLRIdleInhibitMgr, "WLRIdleInhibitMgr");
|
||||
if (m_sWLRSession)
|
||||
addWLSignal(&m_sWLRSession->events.active, &Events::listen_sessionActive, m_sWLRSession, "Session");
|
||||
}
|
||||
|
||||
void CCompositor::cleanupExit() {
|
||||
void CCompositor::cleanup() {
|
||||
if (!m_sWLDisplay)
|
||||
return;
|
||||
|
||||
@ -180,8 +209,7 @@ void CCompositor::cleanupExit() {
|
||||
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
||||
}
|
||||
|
||||
wl_display_destroy_clients(m_sWLDisplay);
|
||||
wl_display_destroy(m_sWLDisplay);
|
||||
wl_display_terminate(m_sWLDisplay);
|
||||
|
||||
m_sWLDisplay = nullptr;
|
||||
}
|
||||
@ -245,7 +273,7 @@ void CCompositor::startCompositor() {
|
||||
if (!m_szWLDisplaySocket) {
|
||||
Debug::log(CRIT, "m_szWLDisplaySocket NULL!");
|
||||
wlr_backend_destroy(m_sWLRBackend);
|
||||
RIP("m_szWLDisplaySocket NULL!");
|
||||
throw std::runtime_error("m_szWLDisplaySocket was null! (wl_display_add_socket_auto failed)");
|
||||
}
|
||||
|
||||
setenv("WAYLAND_DISPLAY", m_szWLDisplaySocket, 1);
|
||||
@ -258,7 +286,7 @@ void CCompositor::startCompositor() {
|
||||
Debug::log(CRIT, "Backend did not start!");
|
||||
wlr_backend_destroy(m_sWLRBackend);
|
||||
wl_display_destroy(m_sWLDisplay);
|
||||
RIP("Backend did not start!");
|
||||
throw std::runtime_error("The backend could not start!");
|
||||
}
|
||||
|
||||
wlr_xcursor_manager_set_cursor_image(m_sWLRXCursorMgr, "left_ptr", m_sWLRCursor);
|
||||
@ -361,6 +389,12 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
||||
const auto PMONITOR = getMonitorFromVector(pos);
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->m_bHidden)
|
||||
@ -404,14 +438,29 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void findExtensionForVector2D(wlr_surface* surface, int x, int y, void* data) {
|
||||
const auto DATA = (SExtensionFindingData*)data;
|
||||
|
||||
wlr_box box = {DATA->origin.x + x, DATA->origin.y + y, surface->current.width, surface->current.height};
|
||||
|
||||
if (wlr_box_contains_point(&box, DATA->vec.x, DATA->vec.y))
|
||||
*DATA->found = surface;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
const auto PMONITOR = getMonitorFromVector(pos);
|
||||
|
||||
// special workspace
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !(*w)->m_bHidden && (*w)->m_iX11Type != 2)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden)
|
||||
if (!w->m_bIsFloating && w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden && w->m_iX11Type != 2)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
@ -419,13 +468,37 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
return w->get();
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden && (*w)->m_iX11Type != 2) {
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y))
|
||||
return w->get();
|
||||
|
||||
if (!(*w)->m_bIsX11) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin =(*w)->m_vRealPosition.vec();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
wlr_xdg_surface_for_each_popup_surface((*w)->m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||
|
||||
if (resultSurf)
|
||||
return w->get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for windows, we need to check their extensions too, first.
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsX11 && !w->m_bIsFloating && w->m_bIsMapped && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && w->m_iX11Type != 2) {
|
||||
wlr_surface* resultSurf = nullptr;
|
||||
Vector2D origin = w->m_vRealPosition.vec();
|
||||
SExtensionFindingData data = {origin, pos, &resultSurf};
|
||||
wlr_xdg_surface_for_each_popup_surface(w->m_uSurface.xdg, findExtensionForVector2D, &data);
|
||||
|
||||
if (resultSurf)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden)
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden && w->m_iX11Type != 2)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
@ -436,6 +509,12 @@ CWindow* CCompositor::windowFromCursor() {
|
||||
const auto PMONITOR = getMonitorFromCursor();
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && !(*w)->m_bHidden)
|
||||
return (*w).get();
|
||||
}
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped)
|
||||
@ -536,7 +615,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
|
||||
// we need to make the PLASTWINDOW not equal to m_pLastWindow so that RENDERDATA is correct for an unfocused window
|
||||
if (windowValidMapped(PLASTWINDOW)) {
|
||||
updateWindowBorderColor(PLASTWINDOW);
|
||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||
|
||||
if (PLASTWINDOW->m_bIsX11) {
|
||||
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
||||
@ -559,7 +638,7 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||
const auto POINTERLOCAL = g_pInputManager->getMouseCoordsInternal() - pWindow->m_vRealPosition.goalv();
|
||||
wlr_seat_pointer_notify_enter(m_sSeat.seat, PWINDOWSURFACE, POINTERLOCAL.x, POINTERLOCAL.y);
|
||||
|
||||
updateWindowBorderColor(pWindow);
|
||||
updateWindowAnimatedDecorationValues(pWindow);
|
||||
|
||||
// Send an event
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", g_pXWaylandManager->getAppIDClass(pWindow) + "," + pWindow->m_szTitle));
|
||||
@ -573,12 +652,16 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
if (m_sSeat.seat->keyboard_state.focused_surface == pSurface || (pWindowOwner && m_sSeat.seat->keyboard_state.focused_surface == g_pXWaylandManager->getWindowSurface(pWindowOwner)))
|
||||
return; // Don't focus when already focused on this.
|
||||
|
||||
if (!pSurface)
|
||||
return;
|
||||
|
||||
// Unfocus last surface if should
|
||||
if (m_pLastFocus && m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus))
|
||||
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(m_pLastFocus)->toplevel, false);
|
||||
if (m_pLastFocus && ((m_sSeat.seat->keyboard_state.focused_surface && wlr_surface_is_xdg_surface(m_pLastFocus)) || !pSurface))
|
||||
g_pXWaylandManager->activateSurface(m_pLastFocus, false);
|
||||
|
||||
if (!pSurface) {
|
||||
wlr_seat_keyboard_clear_focus(m_sSeat.seat);
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("activewindow", ",")); // unfocused
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto KEYBOARD = wlr_seat_get_keyboard(m_sSeat.seat);
|
||||
|
||||
@ -598,6 +681,9 @@ void CCompositor::focusSurface(wlr_surface* pSurface, CWindow* pWindowOwner) {
|
||||
Debug::log(LOG, "Set keyboard focus to surface %x, with window name: %s", pSurface, pWindowOwner->m_szTitle.c_str());
|
||||
else
|
||||
Debug::log(LOG, "Set keyboard focus to surface %x", pSurface);
|
||||
|
||||
g_pXWaylandManager->activateSurface(pSurface, false);
|
||||
m_pLastFocus = pSurface;
|
||||
}
|
||||
|
||||
bool CCompositor::windowValidMapped(CWindow* pWindow) {
|
||||
@ -689,6 +775,8 @@ void CCompositor::sanityCheckWorkspaces() {
|
||||
|
||||
if (it == m_vWorkspaces.end())
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it)->m_iID == SPECIAL_WORKSPACE_ID && WINDOWSONWORKSPACE == 0) {
|
||||
@ -700,6 +788,8 @@ void CCompositor::sanityCheckWorkspaces() {
|
||||
|
||||
if (it == m_vWorkspaces.end())
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -773,9 +863,12 @@ void CCompositor::moveWindowToTop(CWindow* pWindow) {
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::cleanupFadingOut() {
|
||||
void CCompositor::cleanupFadingOut(const int& monid) {
|
||||
for (auto& w : m_vWindowsFadingOut) {
|
||||
|
||||
if (w->m_iMonitorID != (long unsigned int)monid)
|
||||
continue;
|
||||
|
||||
bool valid = windowExists(w);
|
||||
|
||||
if (!valid || !w->m_bFadingOut || w->m_fAlpha.fl() == 0.f) {
|
||||
@ -788,11 +881,16 @@ void CCompositor::cleanupFadingOut() {
|
||||
m_vWindowsFadingOut.erase(std::remove(m_vWindowsFadingOut.begin(), m_vWindowsFadingOut.end(), w));
|
||||
|
||||
Debug::log(LOG, "Cleanup: destroyed a window");
|
||||
|
||||
glFlush(); // to free mem NOW.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& ls : m_vSurfacesFadingOut) {
|
||||
if (ls->monitorID != monid)
|
||||
continue;
|
||||
|
||||
if (ls->fadingOut && ls->readyToDelete && !ls->alpha.isBeingAnimated()) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
for (auto& lsl : m->m_aLayerSurfaceLists) {
|
||||
@ -808,6 +906,7 @@ void CCompositor::cleanupFadingOut() {
|
||||
|
||||
Debug::log(LOG, "Cleanup: destroyed a layersurface");
|
||||
|
||||
glFlush(); // to free mem NOW.
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -910,6 +1009,29 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getPrevWindowOnWorkspace(CWindow* pWindow) {
|
||||
bool gotToWindow = false;
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && !gotToWindow)
|
||||
continue;
|
||||
|
||||
if (it->get() == pWindow) {
|
||||
gotToWindow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
||||
return it->get();
|
||||
}
|
||||
|
||||
for (auto it = m_vWindows.rbegin(); it != m_vWindows.rend(); it++) {
|
||||
if (it->get() != pWindow && (*it)->m_iWorkspaceID == pWindow->m_iWorkspaceID && (*it)->m_bIsMapped && !(*it)->m_bHidden)
|
||||
return it->get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CCompositor::getNextAvailableNamedWorkspace() {
|
||||
int lowest = -1337 + 1;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
@ -1032,25 +1154,50 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::updateAllWindowsBorders() {
|
||||
void CCompositor::updateAllWindowsAnimatedDecorationValues() {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
updateWindowBorderColor(w.get());
|
||||
updateWindowAnimatedDecorationValues(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::updateWindowBorderColor(CWindow* pWindow) {
|
||||
void CCompositor::updateWindowAnimatedDecorationValues(CWindow* pWindow) {
|
||||
// optimization
|
||||
static int64_t* ACTIVECOL = &g_pConfigManager->getConfigValuePtr("general:col.active_border")->intValue;
|
||||
static int64_t* INACTIVECOL = &g_pConfigManager->getConfigValuePtr("general:col.inactive_border")->intValue;
|
||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
||||
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||
static auto *const PFULLSCREENALPHA = &g_pConfigManager->getConfigValuePtr("decoration:fullscreen_opacity")->floatValue;
|
||||
|
||||
|
||||
// border
|
||||
const auto RENDERDATA = g_pLayoutManager->getCurrentLayout()->requestRenderHints(pWindow);
|
||||
if (RENDERDATA.isBorderColor)
|
||||
pWindow->m_cRealBorderColor = RENDERDATA.borderColor;
|
||||
else
|
||||
pWindow->m_cRealBorderColor = CColor(pWindow == m_pLastWindow ? *ACTIVECOL : *INACTIVECOL);
|
||||
|
||||
|
||||
// opacity
|
||||
if (pWindow->m_bIsFullscreen) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
pWindow->m_fActiveInactiveAlpha = *PFULLSCREENALPHA;
|
||||
else {
|
||||
if (pWindow == m_pLastWindow)
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha * *PACTIVEALPHA;
|
||||
else
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA : *PINACTIVEALPHA;
|
||||
}
|
||||
} else {
|
||||
if (pWindow == m_pLastWindow)
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alpha * *PACTIVEALPHA;
|
||||
else
|
||||
pWindow->m_fActiveInactiveAlpha = pWindow->m_sSpecialRenderData.alphaInactive != -1 ? pWindow->m_sSpecialRenderData.alphaInactive * *PINACTIVEALPHA : *PINACTIVEALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& work) {
|
||||
@ -1188,4 +1335,20 @@ CWindow* CCompositor::getX11Parent(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::updateWorkspaceWindowDecos(const int& id) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID != id)
|
||||
continue;
|
||||
|
||||
w->updateWindowDecos();
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::scheduleFrameForMonitor(SMonitor* pMonitor) {
|
||||
if ((m_sWLRSession && !m_sWLRSession->active) || !m_bSessionActive)
|
||||
return;
|
||||
|
||||
wlr_output_schedule_frame(pMonitor->output);
|
||||
}
|
@ -30,7 +30,9 @@ public:
|
||||
|
||||
// ------------------ WLR BASICS ------------------ //
|
||||
wl_display* m_sWLDisplay;
|
||||
wl_event_loop* m_sWLEventLoop;
|
||||
wlr_backend* m_sWLRBackend;
|
||||
wlr_session* m_sWLRSession;
|
||||
wlr_renderer* m_sWLRRenderer;
|
||||
wlr_allocator* m_sWLRAllocator;
|
||||
wlr_compositor* m_sWLRCompositor;
|
||||
@ -61,11 +63,14 @@ public:
|
||||
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||
wlr_idle_inhibit_manager_v1* m_sWLRIdleInhibitMgr;
|
||||
wlr_pointer_gestures_v1* m_sWLRPointerGestures;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
const char* m_szWLDisplaySocket;
|
||||
std::string m_szInstanceSignature = "";
|
||||
std::string m_szCurrentSplash = "error";
|
||||
|
||||
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
|
||||
std::vector<std::unique_ptr<CWindow>> m_vWindows;
|
||||
@ -77,7 +82,7 @@ public:
|
||||
std::vector<SLayerSurface*> m_vSurfacesFadingOut;
|
||||
|
||||
void startCompositor();
|
||||
void cleanupExit();
|
||||
void cleanup();
|
||||
|
||||
wlr_surface* m_pLastFocus = nullptr;
|
||||
CWindow* m_pLastWindow = nullptr;
|
||||
@ -86,6 +91,7 @@ public:
|
||||
SSeat m_sSeat;
|
||||
|
||||
bool m_bReadyToProcess = false;
|
||||
bool m_bSessionActive = true;
|
||||
|
||||
// ------------------------------------------------- //
|
||||
|
||||
@ -99,7 +105,7 @@ public:
|
||||
bool windowExists(CWindow*);
|
||||
bool windowValidMapped(CWindow*);
|
||||
CWindow* vectorToWindow(const Vector2D&);
|
||||
CWindow* vectorToWindowIdeal(const Vector2D&);
|
||||
CWindow* vectorToWindowIdeal(const Vector2D&); // used only for finding a window to focus on, basically a "findFocusableWindow"
|
||||
CWindow* vectorToWindowTiled(const Vector2D&);
|
||||
wlr_surface* vectorToLayerSurface(const Vector2D&, std::list<SLayerSurface*>*, Vector2D*, SLayerSurface**);
|
||||
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
|
||||
@ -113,6 +119,7 @@ public:
|
||||
CWorkspace* getWorkspaceByName(const std::string&);
|
||||
CWorkspace* getWorkspaceByString(const std::string&);
|
||||
void sanityCheckWorkspaces();
|
||||
void updateWorkspaceWindowDecos(const int&);
|
||||
int getWindowsOnWorkspace(const int&);
|
||||
CWindow* getFirstWindowOnWorkspace(const int&);
|
||||
void fixXWaylandWindowsOnWorkspace(const int&);
|
||||
@ -120,16 +127,17 @@ public:
|
||||
bool doesSeatAcceptInput(wlr_surface*);
|
||||
bool isWindowActive(CWindow*);
|
||||
void moveWindowToTop(CWindow*);
|
||||
void cleanupFadingOut();
|
||||
void cleanupFadingOut(const int& monid);
|
||||
CWindow* getWindowInDirection(CWindow*, char);
|
||||
void deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude = nullptr);
|
||||
CWindow* getNextWindowOnWorkspace(CWindow*);
|
||||
CWindow* getPrevWindowOnWorkspace(CWindow*);
|
||||
int getNextAvailableNamedWorkspace();
|
||||
bool isPointOnAnyMonitor(const Vector2D&);
|
||||
CWindow* getConstraintWindow(SMouse*);
|
||||
SMonitor* getMonitorInDirection(const char&);
|
||||
void updateAllWindowsBorders();
|
||||
void updateWindowBorderColor(CWindow*);
|
||||
void updateAllWindowsAnimatedDecorationValues();
|
||||
void updateWindowAnimatedDecorationValues(CWindow*);
|
||||
void moveWindowToWorkspace(CWindow*, const std::string&);
|
||||
int getNextAvailableMonitorID();
|
||||
void moveWorkspaceToMonitor(CWorkspace*, SMonitor*);
|
||||
@ -137,9 +145,13 @@ public:
|
||||
void setWindowFullscreen(CWindow*, bool, eFullscreenMode);
|
||||
void moveUnmanagedX11ToWindows(CWindow*);
|
||||
CWindow* getX11Parent(CWindow*);
|
||||
void scheduleFrameForMonitor(SMonitor*);
|
||||
|
||||
std::string explicitConfigPath;
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
void setRandomSplash();
|
||||
};
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ CWindow::CWindow() {
|
||||
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_BORDER);
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
m_fActiveInactiveAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||
|
||||
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
||||
}
|
||||
@ -77,6 +78,18 @@ wlr_box CWindow::getWindowIdealBoundingBoxIgnoreReserved() {
|
||||
void CWindow::updateWindowDecos() {
|
||||
for (auto& wd : m_dWindowDecorations)
|
||||
wd->updateWindow(this);
|
||||
|
||||
for (auto& wd : m_vDecosToRemove) {
|
||||
for (auto it = m_dWindowDecorations.begin(); it != m_dWindowDecorations.end(); it++) {
|
||||
if (it->get() == wd) {
|
||||
it = m_dWindowDecorations.erase(it);
|
||||
if (it == m_dWindowDecorations.end())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vDecosToRemove.clear();
|
||||
}
|
||||
|
||||
pid_t CWindow::getPID() {
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
DYNLISTENER(unmapWindow);
|
||||
DYNLISTENER(destroyWindow);
|
||||
DYNLISTENER(setTitleWindow);
|
||||
DYNLISTENER(setGeometryX11U);
|
||||
DYNLISTENER(fullscreenWindow);
|
||||
DYNLISTENER(newPopupXDG);
|
||||
// DYNLISTENER(newSubsurfaceWindow);
|
||||
@ -99,11 +100,15 @@ public:
|
||||
|
||||
// Window decorations
|
||||
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
||||
|
||||
// Special render data, rules, etc
|
||||
SWindowSpecialRenderData m_sSpecialRenderData;
|
||||
SWindowAdditionalConfigData m_sAdditionalConfigData;
|
||||
|
||||
// for alpha
|
||||
CAnimatedVariable m_fActiveInactiveAlpha;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const CWindow& rhs) {
|
||||
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut;
|
||||
|
@ -12,8 +12,15 @@
|
||||
|
||||
CConfigManager::CConfigManager() {
|
||||
setDefaultVars();
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
|
||||
|
||||
std::string CONFIGPATH;
|
||||
if (g_pCompositor->explicitConfigPath == "") {
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
|
||||
} else {
|
||||
CONFIGPATH = g_pCompositor->explicitConfigPath;
|
||||
}
|
||||
|
||||
configPaths.emplace_back(CONFIGPATH);
|
||||
|
||||
Debug::disableLogs = &configValues["debug:disable_logs"].intValue;
|
||||
@ -36,6 +43,10 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["general:col.active_border"].intValue = 0xffffffff;
|
||||
configValues["general:col.inactive_border"].intValue = 0xff444444;
|
||||
configValues["general:cursor_inactive_timeout"].intValue = 0;
|
||||
|
||||
configValues["misc:disable_hyprland_logo"].intValue = 0;
|
||||
configValues["misc:disable_splash_rendering"].intValue = 0;
|
||||
configValues["misc:no_vfr"].intValue = 1;
|
||||
|
||||
configValues["debug:int"].intValue = 0;
|
||||
configValues["debug:log_damage"].intValue = 0;
|
||||
@ -66,6 +77,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["dwindle:force_split"].intValue = 0;
|
||||
configValues["dwindle:preserve_split"].intValue = 0;
|
||||
configValues["dwindle:special_scale_factor"].floatValue = 0.8f;
|
||||
configValues["dwindle:split_width_multiplier"].floatValue = 1.0f;
|
||||
|
||||
configValues["animations:enabled"].intValue = 1;
|
||||
configValues["animations:speed"].floatValue = 7.f;
|
||||
@ -102,6 +114,13 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
|
||||
configValues["input:touchpad:middle_button_emulation"].intValue = 0;
|
||||
configValues["input:touchpad:tap-to-click"].intValue = 1;
|
||||
configValues["input:touchpad:drag_lock"].intValue = 0;
|
||||
|
||||
configValues["gestures:workspace_swipe"].intValue = 0;
|
||||
configValues["gestures:workspace_swipe_distance"].intValue = 300;
|
||||
configValues["gestures:workspace_swipe_invert"].intValue = 1;
|
||||
configValues["gestures:workspace_swipe_min_speed_to_force"].intValue = 30;
|
||||
configValues["gestures:workspace_swipe_cancel_ratio"].floatValue = 0.5f;
|
||||
|
||||
configValues["input:follow_mouse"].intValue = 1;
|
||||
|
||||
@ -124,6 +143,7 @@ void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
cfgValues["clickfinger_behavior"].intValue = 0;
|
||||
cfgValues["middle_button_emulation"].intValue = 0;
|
||||
cfgValues["tap-to-click"].intValue = 1;
|
||||
cfgValues["drag_lock"].intValue = 0;
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
@ -147,17 +167,15 @@ void CConfigManager::init() {
|
||||
|
||||
void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::string& VALUE) {
|
||||
if (configValues.find(COMMAND) == configValues.end()) {
|
||||
if (COMMAND[0] == '$') {
|
||||
// register a dynamic var
|
||||
Debug::log(LOG, "Registered dynamic var \"%s\" -> %s", COMMAND.c_str(), VALUE.c_str());
|
||||
configDynamicVars[COMMAND.substr(1)] = VALUE;
|
||||
} else {
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
}
|
||||
if (COMMAND.find("device:") != 0 /* devices parsed later */) {
|
||||
if (COMMAND[0] == '$') {
|
||||
// register a dynamic var
|
||||
Debug::log(LOG, "Registered dynamic var \"%s\" -> %s", COMMAND.c_str(), VALUE.c_str());
|
||||
configDynamicVars[COMMAND.substr(1)] = VALUE;
|
||||
} else {
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
}
|
||||
|
||||
if (COMMAND.find("device:") == 0 /* devices parsed later */) {
|
||||
parseError = "";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -191,7 +209,12 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else
|
||||
} else if (VALUE.find("true") == 0 || VALUE.find("on") == 0 || VALUE.find("yes") == 0) {
|
||||
CONFIGENTRY->intValue = 1;
|
||||
} else if (VALUE.find("false") == 0 || VALUE.find("off") == 0 || VALUE.find("no") == 0) {
|
||||
CONFIGENTRY->intValue = 0;
|
||||
}
|
||||
else
|
||||
CONFIGENTRY->intValue = stol(VALUE);
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
@ -354,7 +377,7 @@ void CConfigManager::handleMonitor(const std::string& command, const std::string
|
||||
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
|
||||
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1, curitem.find_first_of('@')));
|
||||
|
||||
if (curitem.find_first_of('@') != std::string::npos)
|
||||
if (curitem.contains("@"))
|
||||
newrule.refreshRate = stof(curitem.substr(curitem.find_first_of('@') + 1));
|
||||
|
||||
nextItem();
|
||||
@ -503,8 +526,13 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||
return;
|
||||
}
|
||||
|
||||
if (KEY != "")
|
||||
g_pKeybindManager->addKeybind(SKeybind{KEY, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||
if (KEY != "") {
|
||||
if (isNumber(KEY) && std::stoi(KEY) > 9)
|
||||
g_pKeybindManager->addKeybind(SKeybind{"", std::stoi(KEY), MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||
else
|
||||
g_pKeybindManager->addKeybind(SKeybind{KEY, -1, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
||||
@ -550,6 +578,16 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||
|
||||
}
|
||||
|
||||
void CConfigManager::handleBlurLS(const std::string& command, const std::string& value) {
|
||||
if (value.find("remove,") == 0) {
|
||||
const auto TOREMOVE = value.substr(7);
|
||||
m_dBlurLSNamespaces.erase(std::remove(m_dBlurLSNamespaces.begin(), m_dBlurLSNamespaces.end(), TOREMOVE));
|
||||
return;
|
||||
}
|
||||
|
||||
m_dBlurLSNamespaces.emplace_back(value);
|
||||
}
|
||||
|
||||
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
||||
|
||||
const auto DISPLAY = value.substr(0, value.find_first_of(','));
|
||||
@ -575,6 +613,23 @@ void CConfigManager::handleSource(const std::string& command, const std::string&
|
||||
|
||||
auto value = rawpath;
|
||||
|
||||
if (value.length() < 2) {
|
||||
Debug::log(ERR, "source= path garbage");
|
||||
parseError = "source path " + value + " bogus!";
|
||||
return;
|
||||
}
|
||||
|
||||
if (value[0] == '.') {
|
||||
auto currentDir = configCurrentPath.substr(0, configCurrentPath.find_last_of('/'));
|
||||
|
||||
if (value[1] == '.') {
|
||||
auto parentDir = currentDir.substr(0, currentDir.find_last_of('/'));
|
||||
value.replace(0, 2, parentDir);
|
||||
} else {
|
||||
value.replace(0, 1, currentDir);
|
||||
}
|
||||
}
|
||||
|
||||
if (value[0] == '~') {
|
||||
value.replace(0, 1, std::string(ENVHOME));
|
||||
}
|
||||
@ -651,6 +706,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
||||
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
||||
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
|
||||
else if (COMMAND == "blurls") handleBlurLS(COMMAND, VALUE);
|
||||
else
|
||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||
|
||||
@ -663,7 +719,7 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsBorders();
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -703,7 +759,7 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
line = line.substr(1);
|
||||
}
|
||||
|
||||
if (line.find(" {") != std::string::npos) {
|
||||
if (line.contains(" {")) {
|
||||
auto cat = line.substr(0, line.find(" {"));
|
||||
transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
|
||||
if (currentCategory.length() != 0) {
|
||||
@ -717,7 +773,7 @@ void CConfigManager::parseLine(std::string& line) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (line.find("}") != std::string::npos && currentCategory != "") {
|
||||
if (line.contains("}") && currentCategory != "") {
|
||||
currentCategory = "";
|
||||
return;
|
||||
}
|
||||
@ -753,32 +809,42 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
m_mAdditionalReservedAreas.clear();
|
||||
configDynamicVars.clear();
|
||||
deviceConfigs.clear();
|
||||
m_dBlurLSNamespaces.clear();
|
||||
|
||||
// paths
|
||||
configPaths.clear();
|
||||
|
||||
std::string CONFIGPATH;
|
||||
|
||||
static const char* const ENVHOME = getenv("HOME");
|
||||
const std::string CONFIGPARENTPATH = ENVHOME + (std::string) "/.config/hypr/";
|
||||
const std::string CONFIGPATH = CONFIGPARENTPATH + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf");
|
||||
|
||||
if (g_pCompositor->explicitConfigPath == "") {
|
||||
CONFIGPATH = CONFIGPARENTPATH + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf");
|
||||
} else {
|
||||
CONFIGPATH = g_pCompositor->explicitConfigPath;
|
||||
}
|
||||
|
||||
configPaths.push_back(CONFIGPATH);
|
||||
|
||||
|
||||
std::ifstream ifs;
|
||||
ifs.open(CONFIGPATH);
|
||||
|
||||
if (!ifs.good()) {
|
||||
Debug::log(WARN, "Config reading error. (No file? Attempting to generate, backing up old one if exists)");
|
||||
try {
|
||||
std::filesystem::rename(CONFIGPATH, CONFIGPATH + ".backup");
|
||||
} catch(...) { /* Probably doesn't exist */}
|
||||
if(g_pCompositor->explicitConfigPath == "") {
|
||||
Debug::log(WARN, "Config reading error. (No file? Attempting to generate, backing up old one if exists)");
|
||||
try {
|
||||
std::filesystem::rename(CONFIGPATH, CONFIGPATH + ".backup");
|
||||
} catch(...) { /* Probably doesn't exist */}
|
||||
|
||||
try {
|
||||
if (!std::filesystem::is_directory(CONFIGPARENTPATH))
|
||||
std::filesystem::create_directories(CONFIGPARENTPATH);
|
||||
}
|
||||
catch (...) {
|
||||
parseError = "Broken config file! (Could not create directory)";
|
||||
return;
|
||||
try {
|
||||
if (!std::filesystem::is_directory(CONFIGPARENTPATH))
|
||||
std::filesystem::create_directories(CONFIGPARENTPATH);
|
||||
}
|
||||
catch (...) {
|
||||
parseError = "Broken config file! (Could not create directory)";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream ofs;
|
||||
@ -854,7 +920,7 @@ void CConfigManager::loadConfigLoadVars() {
|
||||
}
|
||||
|
||||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsBorders();
|
||||
g_pCompositor->updateAllWindowsAnimatedDecorationValues();
|
||||
|
||||
// Force the compositor to fully re-render all monitors
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
@ -1084,3 +1150,12 @@ bool CConfigManager::deviceConfigExists(const std::string& dev) {
|
||||
return it != deviceConfigs.end();
|
||||
}
|
||||
|
||||
bool CConfigManager::shouldBlurLS(const std::string& ns) {
|
||||
for (auto& bls : m_dBlurLSNamespaces) {
|
||||
if (bls == ns) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
float getDeviceFloat(const std::string&, const std::string&);
|
||||
std::string getDeviceString(const std::string&, const std::string&);
|
||||
bool deviceConfigExists(const std::string&);
|
||||
bool shouldBlurLS(const std::string&);
|
||||
|
||||
SConfigValue* getConfigValuePtr(std::string);
|
||||
|
||||
@ -102,6 +103,7 @@ private:
|
||||
|
||||
std::deque<SMonitorRule> m_dMonitorRules;
|
||||
std::deque<SWindowRule> m_dWindowRules;
|
||||
std::deque<std::string> m_dBlurLSNamespaces;
|
||||
|
||||
bool firstExecDispatched = false;
|
||||
std::deque<std::string> firstExecRequests;
|
||||
@ -127,6 +129,7 @@ private:
|
||||
void handleAnimation(const std::string&, const std::string&);
|
||||
void handleSource(const std::string&, const std::string&);
|
||||
void handleSubmap(const std::string&, const std::string&);
|
||||
void handleBlurLS(const std::string&, const std::string&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
@ -9,6 +9,12 @@ PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
|
||||
OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
|
||||
########################################################################################
|
||||
|
||||
|
||||
#
|
||||
# Please note not all available settings / options are set here.
|
||||
# For a full list, see the wiki (basic and advanced configuring)
|
||||
#
|
||||
|
||||
autogenerated=1 # remove this line to get rid of the warning on top.
|
||||
|
||||
monitor=,1920x1080@60,0x0,1
|
||||
|
@ -13,95 +13,390 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string monitorsRequest() {
|
||||
std::string monitorsRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform);
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "[";
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat(
|
||||
R"#({
|
||||
"id": %i,
|
||||
"name": "%s",
|
||||
"width": %i,
|
||||
"height": %i,
|
||||
"refreshRate": %f,
|
||||
"x": %i,
|
||||
"y": %i,
|
||||
"activeWorkspace": {
|
||||
"id": %i,
|
||||
"name": "%s"
|
||||
},
|
||||
"reserved": [%i, %i, %i, %i],
|
||||
"scale": %.2f,
|
||||
"transform": %i,
|
||||
"active": "%s"
|
||||
},)#",
|
||||
m->ID,
|
||||
m->szName.c_str(),
|
||||
(int)m->vecPixelSize.x, (int)m->vecPixelSize.y,
|
||||
m->refreshRate,
|
||||
(int)m->vecPosition.x, (int)m->vecPosition.y,
|
||||
m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(),
|
||||
(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")
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
|
||||
result += "]";
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\tactive: %s\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (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"));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string clientsRequest() {
|
||||
std::string clientsRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n",
|
||||
&w, w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID());
|
||||
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "[";
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat(
|
||||
R"#({
|
||||
"address": "0x%x",
|
||||
"at": [%i, %i],
|
||||
"size": [%i, %i],
|
||||
"workspace": {
|
||||
"id": %i,
|
||||
"name": "%s"
|
||||
},
|
||||
"floating": %i,
|
||||
"monitor": %i,
|
||||
"class": "%s",
|
||||
"title": "%s",
|
||||
"pid": %i
|
||||
},)#",
|
||||
&w,
|
||||
(int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y,
|
||||
(int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y,
|
||||
w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()),
|
||||
(int)w->m_bIsFloating,
|
||||
w->m_iMonitorID,
|
||||
g_pXWaylandManager->getAppIDClass(w.get()).c_str(),
|
||||
g_pXWaylandManager->getTitle(w.get()).c_str(),
|
||||
w->getPID()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
|
||||
result += "]";
|
||||
} else {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n",
|
||||
&w, w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string workspacesRequest() {
|
||||
std::string workspacesRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
result += getFormat("workspace ID %i (%s) on monitor %s:\n\twindows: %i\n\thasfullscreen: %i\n\n",
|
||||
w->m_iID, w->m_szName.c_str(), g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(), g_pCompositor->getWindowsOnWorkspace(w->m_iID), (int)w->m_bHasFullscreenWindow);
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "[";
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
result += getFormat(
|
||||
R"#({
|
||||
"id": %i,
|
||||
"name": "%s",
|
||||
"monitor": "%s",
|
||||
"windows": %i,
|
||||
"hasfullscreen": %i
|
||||
},)#",
|
||||
w->m_iID,
|
||||
w->m_szName.c_str(),
|
||||
g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(),
|
||||
g_pCompositor->getWindowsOnWorkspace(w->m_iID),
|
||||
(int)w->m_bHasFullscreenWindow
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
|
||||
result += "]";
|
||||
} else {
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
result += getFormat("workspace ID %i (%s) on monitor %s:\n\twindows: %i\n\thasfullscreen: %i\n\n",
|
||||
w->m_iID, w->m_szName.c_str(), g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(), g_pCompositor->getWindowsOnWorkspace(w->m_iID), (int)w->m_bHasFullscreenWindow);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string activeWindowRequest() {
|
||||
std::string activeWindowRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return "Invalid";
|
||||
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), g_pXWaylandManager->getTitle(PWINDOW).c_str(), PWINDOW->getPID());
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
return getFormat(
|
||||
R"#({
|
||||
"address": "0x%x",
|
||||
"at": [%i, %i],
|
||||
"size": [%i, %i],
|
||||
"workspace": {
|
||||
"id": %i,
|
||||
"name": "%s"
|
||||
},
|
||||
"floating": %i,
|
||||
"monitor": %i,
|
||||
"class": "%s",
|
||||
"title": "%s",
|
||||
"pid": %i
|
||||
})#",
|
||||
PWINDOW,
|
||||
(int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y,
|
||||
(int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y,
|
||||
PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()),
|
||||
(int)PWINDOW->m_bIsFloating,
|
||||
PWINDOW->m_iMonitorID,
|
||||
g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(),
|
||||
g_pXWaylandManager->getTitle(PWINDOW).c_str(),
|
||||
PWINDOW->getPID()
|
||||
);
|
||||
} else {
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), g_pXWaylandManager->getTitle(PWINDOW).c_str(), PWINDOW->getPID());
|
||||
}
|
||||
}
|
||||
|
||||
std::string layersRequest() {
|
||||
std::string layersRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
|
||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s:\n");
|
||||
int layerLevel = 0;
|
||||
for (auto& level : mon->m_aLayerSurfaceLists) {
|
||||
result += getFormat("\tLayer level %i:\n", layerLevel);
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "{\n";
|
||||
|
||||
for (auto& layer : level) {
|
||||
result += getFormat("\t\tLayer %x: xywh: %i %i %i %i\n", layer, layer->geometry.x, layer->geometry.y, layer->geometry.width, layer->geometry.height);
|
||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat(
|
||||
R"#("%s": {
|
||||
"levels": {
|
||||
)#",
|
||||
mon->szName.c_str()
|
||||
);
|
||||
|
||||
int layerLevel = 0;
|
||||
for (auto& level : mon->m_aLayerSurfaceLists) {
|
||||
result += getFormat(
|
||||
R"#(
|
||||
"%i": [
|
||||
)#",
|
||||
layerLevel
|
||||
);
|
||||
for (auto& layer : level) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"x": %i,
|
||||
"y": %i,
|
||||
"w": %i,
|
||||
"h": %i,
|
||||
"namespace": "%s"
|
||||
},)#",
|
||||
layer,
|
||||
layer->geometry.x,
|
||||
layer->geometry.y,
|
||||
layer->geometry.width,
|
||||
layer->geometry.height,
|
||||
layer->szNamespace.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
|
||||
if (level.size() > 0)
|
||||
result += "\n ";
|
||||
|
||||
result += "],";
|
||||
|
||||
layerLevel++;
|
||||
}
|
||||
|
||||
layerLevel++;
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
|
||||
result += "\n }\n},";
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
|
||||
result += "\n}\n";
|
||||
|
||||
} else {
|
||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s:\n", mon->szName.c_str());
|
||||
int layerLevel = 0;
|
||||
for (auto& level : mon->m_aLayerSurfaceLists) {
|
||||
result += getFormat("\tLayer level %i:\n", layerLevel);
|
||||
|
||||
for (auto& layer : level) {
|
||||
result += getFormat("\t\tLayer %x: xywh: %i %i %i %i, namespace: %s\n", layer, layer->geometry.x, layer->geometry.y, layer->geometry.width, layer->geometry.height, layer->szNamespace.c_str());
|
||||
}
|
||||
|
||||
layerLevel++;
|
||||
}
|
||||
result += "\n\n";
|
||||
}
|
||||
result += "\n\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string devicesRequest() {
|
||||
std::string devicesRequest(HyprCtl::eHyprCtlOutputFormat format) {
|
||||
std::string result = "";
|
||||
|
||||
result += "mice:\n";
|
||||
if (format == HyprCtl::FORMAT_JSON) {
|
||||
result += "{\n";
|
||||
result += "\"mice\": [\n";
|
||||
|
||||
for (auto& m : g_pInputManager->m_lMice) {
|
||||
result += getFormat("\tMouse at %x:\n\t\t%s\n", &m, m.mouse->name);
|
||||
}
|
||||
for (auto& m : g_pInputManager->m_lMice) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
},)#",
|
||||
&m,
|
||||
m.mouse->name
|
||||
);
|
||||
}
|
||||
|
||||
result += "\n\nKeyboards:\n";
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
result += "\n],\n";
|
||||
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
result += getFormat("\tKeyboard at %x:\n\t\t%s\n", &k, k.keyboard->name);
|
||||
}
|
||||
result += "\"keyboards\": [\n";
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
const auto KM = xkb_keymap_layout_get_name(wlr_keyboard_from_input_device(k.keyboard)->keymap, 0);
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s",
|
||||
"rules": "%s",
|
||||
"model": "%s",
|
||||
"layout": "%s",
|
||||
"variant": "%s",
|
||||
"options": "%s",
|
||||
"active_keymap": "%s"
|
||||
},)#",
|
||||
&k,
|
||||
k.keyboard->name,
|
||||
k.currentRules.rules.c_str(),
|
||||
k.currentRules.model.c_str(),
|
||||
k.currentRules.layout.c_str(),
|
||||
k.currentRules.variant.c_str(),
|
||||
k.currentRules.options.c_str(),
|
||||
KM
|
||||
);
|
||||
}
|
||||
|
||||
result += "\n\nTablets:\n";
|
||||
// remove trailing comma
|
||||
result.pop_back();
|
||||
result += "\n],\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTabletPads) {
|
||||
result += getFormat("\tTablet Pad at %x (belongs to %x -> %s)\n", &d, d.pTabletParent, d.pTabletParent ? d.pTabletParent->wlrDevice ? d.pTabletParent->wlrDevice->name : "" : "");
|
||||
}
|
||||
result += "\"tablets\": [\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTablets) {
|
||||
result += getFormat("\tTablet at %x:\n\t\t%s\n", &d, d.wlrDevice ? d.wlrDevice->name : "");
|
||||
}
|
||||
for (auto& d : g_pInputManager->m_lTabletPads) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"type": "tabletPad",
|
||||
"belongsTo": {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
}
|
||||
},)#",
|
||||
&d,
|
||||
d.pTabletParent,
|
||||
d.pTabletParent ? d.pTabletParent->wlrDevice ? d.pTabletParent->wlrDevice->name : "" : ""
|
||||
);
|
||||
}
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTabletTools) {
|
||||
result += getFormat("\tTablet Tool at %x (belongs to %x)\n", &d, d.wlrTabletTool ? d.wlrTabletTool->data : 0);
|
||||
for (auto& d : g_pInputManager->m_lTablets) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"name": "%s"
|
||||
},)#",
|
||||
&d,
|
||||
d.wlrDevice ? d.wlrDevice->name : ""
|
||||
);
|
||||
}
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTabletTools) {
|
||||
result += getFormat(
|
||||
R"#( {
|
||||
"address": "0x%x",
|
||||
"type": "tabletTool",
|
||||
"belongsTo": "0x%x"
|
||||
},)#",
|
||||
&d,
|
||||
d.wlrTabletTool ? d.wlrTabletTool->data : 0
|
||||
);
|
||||
}
|
||||
|
||||
// remove trailing comma
|
||||
if (result[result.size() - 1] == ',')
|
||||
result.pop_back();
|
||||
result += "\n]\n";
|
||||
|
||||
result += "}\n";
|
||||
|
||||
} else {
|
||||
result += "mice:\n";
|
||||
|
||||
for (auto& m : g_pInputManager->m_lMice) {
|
||||
result += getFormat("\tMouse at %x:\n\t\t%s\n", &m, m.mouse->name);
|
||||
}
|
||||
|
||||
result += "\n\nKeyboards:\n";
|
||||
|
||||
for (auto& k : g_pInputManager->m_lKeyboards) {
|
||||
const auto KM = xkb_keymap_layout_get_name(wlr_keyboard_from_input_device(k.keyboard)->keymap, 0);
|
||||
result += getFormat("\tKeyboard at %x:\n\t\t%s\n\t\t\trules: r \"%s\", m \"%s\", l \"%s\", v \"%s\", o \"%s\"\n\t\t\tactive keymap: %s\n", &k, k.keyboard->name, k.currentRules.rules.c_str(), k.currentRules.model.c_str(), k.currentRules.layout.c_str(), k.currentRules.variant.c_str(), k.currentRules.options.c_str(), KM);
|
||||
}
|
||||
|
||||
result += "\n\nTablets:\n";
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTabletPads) {
|
||||
result += getFormat("\tTablet Pad at %x (belongs to %x -> %s)\n", &d, d.pTabletParent, d.pTabletParent ? d.pTabletParent->wlrDevice ? d.pTabletParent->wlrDevice->name : "" : "");
|
||||
}
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTablets) {
|
||||
result += getFormat("\tTablet at %x:\n\t\t%s\n", &d, d.wlrDevice ? d.wlrDevice->name : "");
|
||||
}
|
||||
|
||||
for (auto& d : g_pInputManager->m_lTabletTools) {
|
||||
result += getFormat("\tTablet Tool at %x (belongs to %x)\n", &d, d.wlrTabletTool ? d.wlrTabletTool->data : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -158,7 +453,7 @@ std::string dispatchKeyword(std::string in) {
|
||||
if (COMMAND == "monitor")
|
||||
g_pConfigManager->m_bWantsMonitorReload = true; // for monitor keywords
|
||||
|
||||
if (COMMAND.find("input") != std::string::npos)
|
||||
if (COMMAND.contains("input"))
|
||||
g_pInputManager->setKeyboardLayout(); // update kb layout
|
||||
|
||||
Debug::log(LOG, "Hyprctl: keyword %s : %s", COMMAND.c_str(), VALUE.c_str());
|
||||
@ -181,6 +476,10 @@ std::string killRequest() {
|
||||
return "ok";
|
||||
}
|
||||
|
||||
std::string splashRequest() {
|
||||
return g_pCompositor->m_szCurrentSplash;
|
||||
}
|
||||
|
||||
std::string getReply(std::string);
|
||||
|
||||
std::string dispatchBatch(std::string request) {
|
||||
@ -216,24 +515,46 @@ std::string dispatchBatch(std::string request) {
|
||||
}
|
||||
|
||||
std::string getReply(std::string request) {
|
||||
auto format = HyprCtl::FORMAT_NORMAL;
|
||||
|
||||
// process flags for non-batch requests
|
||||
if (!request.contains("[[BATCH]]") && request.contains("/")) {
|
||||
long unsigned int sepIndex = 0;
|
||||
for (const auto& c : request) {
|
||||
if (c == '/') { // stop at separator
|
||||
break;
|
||||
}
|
||||
|
||||
sepIndex++;
|
||||
|
||||
if (c == 'j')
|
||||
format = HyprCtl::FORMAT_JSON;
|
||||
}
|
||||
|
||||
if (sepIndex < request.size())
|
||||
request = request.substr(sepIndex + 1); // remove flags and separator so we can compare the rest of the string
|
||||
}
|
||||
|
||||
if (request == "monitors")
|
||||
return monitorsRequest();
|
||||
return monitorsRequest(format);
|
||||
else if (request == "workspaces")
|
||||
return workspacesRequest();
|
||||
return workspacesRequest(format);
|
||||
else if (request == "clients")
|
||||
return clientsRequest();
|
||||
return clientsRequest(format);
|
||||
else if (request == "kill")
|
||||
return killRequest();
|
||||
else if (request == "activewindow")
|
||||
return activeWindowRequest();
|
||||
return activeWindowRequest(format);
|
||||
else if (request == "layers")
|
||||
return layersRequest();
|
||||
return layersRequest(format);
|
||||
else if (request == "version")
|
||||
return versionRequest();
|
||||
else if (request == "reload")
|
||||
return reloadRequest();
|
||||
else if (request == "devices")
|
||||
return devicesRequest();
|
||||
return devicesRequest(format);
|
||||
else if (request == "splash")
|
||||
return splashRequest();
|
||||
else if (request.find("dispatch") == 0)
|
||||
return dispatchRequest(request);
|
||||
else if (request.find("keyword") == 0)
|
||||
@ -264,6 +585,16 @@ void HyprCtl::tickHyprCtl() {
|
||||
}
|
||||
|
||||
std::string getRequestFromThread(std::string rq) {
|
||||
// we need to do something to wake hyprland up if VFR is enabled
|
||||
|
||||
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
|
||||
// TODO: is this safe...?
|
||||
// this might be a race condition
|
||||
// tested with 2 instances of `watch -n 0.1 hyprctl splash` and seems to not crash so I'll take that as a yes
|
||||
if (!*PNOVFR)
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_vMonitors.front().get());
|
||||
|
||||
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
}
|
||||
|
@ -14,4 +14,9 @@ namespace HyprCtl {
|
||||
inline std::string request = "";
|
||||
|
||||
inline std::ifstream requestStream;
|
||||
|
||||
enum eHyprCtlOutputFormat {
|
||||
FORMAT_NORMAL = 0,
|
||||
FORMAT_JSON
|
||||
};
|
||||
};
|
@ -16,8 +16,6 @@
|
||||
#define ISDEBUG false
|
||||
#endif
|
||||
|
||||
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
|
||||
#define LISTENER(name) void listener_##name(wl_listener*, void*); inline wl_listener listen_##name = { .notify = listener_##name };
|
||||
#define DYNLISTENFUNC(name) void listener_##name(void*, void*);
|
||||
#define DYNLISTENER(name) CHyprWLListener hyprListener_##name;
|
||||
|
@ -15,145 +15,179 @@
|
||||
// //
|
||||
// ---------------------------------------------------- //
|
||||
|
||||
void Events::listener_keyboardDestroy(void* owner, void* data) {
|
||||
SKeyboard* PKEYBOARD = (SKeyboard*)owner;
|
||||
g_pInputManager->destroyKeyboard(PKEYBOARD);
|
||||
void Events::listener_keyboardDestroy(void *owner, void *data) {
|
||||
SKeyboard *PKEYBOARD = (SKeyboard *)owner;
|
||||
g_pInputManager->destroyKeyboard(PKEYBOARD);
|
||||
|
||||
Debug::log(LOG, "Destroyed keyboard %x", PKEYBOARD);
|
||||
Debug::log(LOG, "Destroyed keyboard %x", PKEYBOARD);
|
||||
}
|
||||
|
||||
void Events::listener_keyboardKey(void* owner, void* data) {
|
||||
SKeyboard* PKEYBOARD = (SKeyboard*)owner;
|
||||
g_pInputManager->onKeyboardKey((wlr_keyboard_key_event*)data, PKEYBOARD);
|
||||
void Events::listener_keyboardKey(void *owner, void *data) {
|
||||
SKeyboard *PKEYBOARD = (SKeyboard *)owner;
|
||||
g_pInputManager->onKeyboardKey((wlr_keyboard_key_event *)data, PKEYBOARD);
|
||||
}
|
||||
|
||||
void Events::listener_keyboardMod(void* owner, void* data) {
|
||||
SKeyboard* PKEYBOARD = (SKeyboard*)owner;
|
||||
g_pInputManager->onKeyboardMod(data, PKEYBOARD);
|
||||
void Events::listener_keyboardMod(void *owner, void *data) {
|
||||
SKeyboard *PKEYBOARD = (SKeyboard *)owner;
|
||||
g_pInputManager->onKeyboardMod(data, PKEYBOARD);
|
||||
}
|
||||
|
||||
void Events::listener_mouseFrame(wl_listener* listener, void* data) {
|
||||
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat);
|
||||
void Events::listener_mouseFrame(wl_listener *listener, void *data) {
|
||||
wlr_seat_pointer_notify_frame(g_pCompositor->m_sSeat.seat);
|
||||
}
|
||||
|
||||
void Events::listener_mouseMove(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onMouseMoved((wlr_pointer_motion_event*)data);
|
||||
void Events::listener_mouseMove(wl_listener *listener, void *data) {
|
||||
g_pInputManager->onMouseMoved((wlr_pointer_motion_event *)data);
|
||||
}
|
||||
|
||||
void Events::listener_mouseMoveAbsolute(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onMouseWarp((wlr_pointer_motion_absolute_event*)data);
|
||||
void Events::listener_mouseMoveAbsolute(wl_listener *listener, void *data) {
|
||||
g_pInputManager->onMouseWarp((wlr_pointer_motion_absolute_event *)data);
|
||||
}
|
||||
|
||||
void Events::listener_mouseButton(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onMouseButton((wlr_pointer_button_event*)data);
|
||||
void Events::listener_mouseButton(wl_listener *listener, void *data) {
|
||||
g_pInputManager->onMouseButton((wlr_pointer_button_event *)data);
|
||||
}
|
||||
|
||||
void Events::listener_mouseAxis(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onMouseWheel((wlr_pointer_axis_event*)data);
|
||||
void Events::listener_mouseAxis(wl_listener *listener, void *data) {
|
||||
g_pInputManager->onMouseWheel((wlr_pointer_axis_event *)data);
|
||||
}
|
||||
|
||||
void Events::listener_requestMouse(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_seat_pointer_request_set_cursor_event*)data;
|
||||
void Events::listener_requestMouse(wl_listener *listener, void *data) {
|
||||
const auto EVENT = (wlr_seat_pointer_request_set_cursor_event *)data;
|
||||
|
||||
g_pInputManager->processMouseRequest(EVENT);
|
||||
g_pInputManager->processMouseRequest(EVENT);
|
||||
}
|
||||
|
||||
void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||
const auto DEVICE = (wlr_input_device*)data;
|
||||
|
||||
switch(DEVICE->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
Debug::log(LOG, "Attached a keyboard with name %s", DEVICE->name);
|
||||
g_pInputManager->newKeyboard(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
Debug::log(LOG, "Attached a mouse with name %s", DEVICE->name);
|
||||
g_pInputManager->newMouse(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
Debug::log(LOG, "Attached a touch device with name %s", DEVICE->name);
|
||||
Debug::log(WARN, "!!!! Hyprland does not directly support touchscreens, bugs may occur !!!!");
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
Debug::log(LOG, "Attached a tablet tool with name %s", DEVICE->name);
|
||||
g_pInputManager->newTabletTool(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
Debug::log(LOG, "Attached a tablet pad with name %s", DEVICE->name);
|
||||
g_pInputManager->newTabletPad(DEVICE);
|
||||
break;
|
||||
default:
|
||||
Debug::log(WARN, "Unrecognized input device plugged in: %s", DEVICE->name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_pInputManager->updateCapabilities(DEVICE);
|
||||
}
|
||||
|
||||
void Events::listener_newConstraint(wl_listener* listener, void* data) {
|
||||
const auto PCONSTRAINT = (wlr_pointer_constraint_v1*)data;
|
||||
|
||||
Debug::log(LOG, "New mouse constraint at %x", PCONSTRAINT);
|
||||
|
||||
g_pInputManager->m_lConstraints.emplace_back();
|
||||
const auto CONSTRAINT = &g_pInputManager->m_lConstraints.back();
|
||||
|
||||
CONSTRAINT->pMouse = g_pCompositor->m_sSeat.mouse;
|
||||
CONSTRAINT->constraint = PCONSTRAINT;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (PWINDOW->m_bIsX11) {
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y + PCONSTRAINT->constraint->current.cursor_hint.y);
|
||||
|
||||
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y);
|
||||
} else {
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.x + PWINDOW->m_vRealPosition.vec().x, PCONSTRAINT->constraint->current.cursor_hint.y + PWINDOW->m_vRealPosition.vec().y);
|
||||
|
||||
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat, PCONSTRAINT->constraint->current.cursor_hint.x, PCONSTRAINT->constraint->current.cursor_hint.y);
|
||||
}
|
||||
}
|
||||
|
||||
PCONSTRAINT->pMouse->currentConstraint = nullptr;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Unconstrained mouse from %x", PCONSTRAINT->constraint);
|
||||
|
||||
g_pInputManager->m_lConstraints.remove(*PCONSTRAINT);
|
||||
}
|
||||
|
||||
void Events::listener_setConstraintRegion(void* owner, void* data) {
|
||||
// no
|
||||
}
|
||||
|
||||
void Events::listener_newVirtPtr(wl_listener* listener, void* data) {
|
||||
const auto EV = (wlr_virtual_pointer_v1_new_pointer_event*)data;
|
||||
const auto POINTER = EV->new_pointer;
|
||||
const auto DEVICE = &POINTER->pointer.base;
|
||||
void Events::listener_newInput(wl_listener *listener, void *data) {
|
||||
const auto DEVICE = (wlr_input_device *)data;
|
||||
|
||||
switch (DEVICE->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
Debug::log(LOG, "Attached a keyboard with name %s", DEVICE->name);
|
||||
g_pInputManager->newKeyboard(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
Debug::log(LOG, "Attached a mouse with name %s", DEVICE->name);
|
||||
g_pInputManager->newMouse(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
Debug::log(LOG, "Attached a touch device with name %s", DEVICE->name);
|
||||
Debug::log(WARN, "!!!! Hyprland does not directly support touchscreens, "
|
||||
"bugs may occur !!!!");
|
||||
wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
Debug::log(LOG, "Attached a tablet tool with name %s", DEVICE->name);
|
||||
g_pInputManager->newTabletTool(DEVICE);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
Debug::log(LOG, "Attached a tablet pad with name %s", DEVICE->name);
|
||||
g_pInputManager->newTabletPad(DEVICE);
|
||||
break;
|
||||
default:
|
||||
Debug::log(WARN, "Unrecognized input device plugged in: %s", DEVICE->name);
|
||||
break;
|
||||
}
|
||||
|
||||
g_pInputManager->updateCapabilities(DEVICE);
|
||||
}
|
||||
|
||||
void Events::listener_destroyMouse(void* owner, void* data) {
|
||||
const auto PMOUSE = (SMouse*)owner;
|
||||
void Events::listener_newConstraint(wl_listener *listener, void *data) {
|
||||
const auto PCONSTRAINT = (wlr_pointer_constraint_v1 *)data;
|
||||
|
||||
g_pInputManager->destroyMouse(PMOUSE->mouse);
|
||||
Debug::log(LOG, "New mouse constraint at %x", PCONSTRAINT);
|
||||
|
||||
g_pInputManager->m_lConstraints.emplace_back();
|
||||
const auto CONSTRAINT = &g_pInputManager->m_lConstraints.back();
|
||||
|
||||
CONSTRAINT->pMouse = g_pCompositor->m_sSeat.mouse;
|
||||
CONSTRAINT->constraint = PCONSTRAINT;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (PWINDOW->m_bIsX11) {
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.x +
|
||||
PWINDOW->m_uSurface.xwayland->x,
|
||||
PWINDOW->m_uSurface.xwayland->y +
|
||||
PCONSTRAINT->constraint->current.cursor_hint.y);
|
||||
|
||||
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.x,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.y);
|
||||
} else {
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.x +
|
||||
PWINDOW->m_vRealPosition.vec().x,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.y +
|
||||
PWINDOW->m_vRealPosition.vec().y);
|
||||
|
||||
wlr_seat_pointer_warp(PCONSTRAINT->constraint->seat,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.x,
|
||||
PCONSTRAINT->constraint->current.cursor_hint.y);
|
||||
}
|
||||
}
|
||||
|
||||
PCONSTRAINT->pMouse->currentConstraint = nullptr;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Unconstrained mouse from %x", PCONSTRAINT->constraint);
|
||||
|
||||
g_pInputManager->m_lConstraints.remove(*PCONSTRAINT);
|
||||
}
|
||||
|
||||
void Events::listener_setConstraintRegion(void *owner, void *data) {
|
||||
// no
|
||||
}
|
||||
|
||||
void Events::listener_newVirtPtr(wl_listener *listener, void *data) {
|
||||
const auto EV = (wlr_virtual_pointer_v1_new_pointer_event *)data;
|
||||
const auto POINTER = EV->new_pointer;
|
||||
const auto DEVICE = &POINTER->pointer.base;
|
||||
|
||||
g_pInputManager->newMouse(DEVICE, true);
|
||||
}
|
||||
|
||||
void Events::listener_destroyMouse(void *owner, void *data) {
|
||||
const auto PMOUSE = (SMouse *)owner;
|
||||
|
||||
g_pInputManager->destroyMouse(PMOUSE->mouse);
|
||||
}
|
||||
|
||||
void Events::listener_swipeBegin(wl_listener *listener, void *data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_begin_event *)data;
|
||||
|
||||
g_pInputManager->onSwipeBegin(EVENT);
|
||||
}
|
||||
|
||||
void Events::listener_swipeUpdate(wl_listener *listener, void *data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_update_event *)data;
|
||||
|
||||
g_pInputManager->onSwipeUpdate(EVENT);
|
||||
}
|
||||
|
||||
void Events::listener_swipeEnd(wl_listener *listener, void *data) {
|
||||
const auto EVENT = (wlr_pointer_swipe_end_event *)data;
|
||||
|
||||
g_pInputManager->onSwipeEnd(EVENT);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ namespace Events {
|
||||
DYNLISTENFUNC(fullscreenWindow);
|
||||
DYNLISTENFUNC(activateX11);
|
||||
DYNLISTENFUNC(configureX11);
|
||||
DYNLISTENFUNC(unmanagedSetGeometry);
|
||||
|
||||
// Window subsurfaces
|
||||
// LISTENER(newSubsurfaceWindow);
|
||||
@ -112,4 +113,13 @@ namespace Events {
|
||||
|
||||
// Renderer destroy
|
||||
LISTENER(RendererDestroy);
|
||||
|
||||
LISTENER(newIdleInhibitor);
|
||||
|
||||
LISTENER(swipeBegin);
|
||||
LISTENER(swipeEnd);
|
||||
LISTENER(swipeUpdate);
|
||||
|
||||
// session
|
||||
LISTENER(sessionActive);
|
||||
};
|
@ -32,8 +32,9 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
}
|
||||
|
||||
const auto PMONITOR = (SMonitor*)g_pCompositor->getMonitorFromOutput(WLRLAYERSURFACE->output);
|
||||
PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].push_back(new SLayerSurface());
|
||||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].back();
|
||||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].emplace_back(new SLayerSurface());
|
||||
|
||||
layerSurface->szNamespace = WLRLAYERSURFACE->_namespace;
|
||||
|
||||
if (!WLRLAYERSURFACE->output) {
|
||||
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors.front()->output; // TODO: current mon
|
||||
@ -50,6 +51,8 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
||||
WLRLAYERSURFACE->data = layerSurface;
|
||||
layerSurface->monitorID = PMONITOR->ID;
|
||||
|
||||
layerSurface->forceBlur = g_pConfigManager->shouldBlurLS(layerSurface->szNamespace);
|
||||
|
||||
Debug::log(LOG, "LayerSurface %x (namespace %s layer %d) created on monitor %s", layerSurface->layerSurface, layerSurface->layerSurface->_namespace, layerSurface->layer, PMONITOR->szName.c_str());
|
||||
}
|
||||
|
||||
@ -96,8 +99,6 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
||||
|
||||
layersurface->layerSurface->mapped = true;
|
||||
|
||||
wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output);
|
||||
|
||||
// fix if it changed its mon
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
|
||||
|
||||
@ -115,9 +116,15 @@ void Events::listener_mapLayerSurface(void* owner, void* data) {
|
||||
|
||||
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
|
||||
|
||||
if (layersurface->layerSurface->current.keyboard_interactive)
|
||||
if (layersurface->layerSurface->current.keyboard_interactive && (!g_pCompositor->m_sSeat.mouse || !g_pCompositor->m_sSeat.mouse->currentConstraint)) { // don't focus if constrained
|
||||
wlr_surface_send_enter(layersurface->layerSurface->surface, layersurface->layerSurface->output);
|
||||
g_pCompositor->focusSurface(layersurface->layerSurface->surface);
|
||||
|
||||
const auto LOCAL = 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_motion(g_pCompositor->m_sSeat.seat, 0, LOCAL.x, LOCAL.y);
|
||||
}
|
||||
|
||||
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
@ -150,14 +157,17 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
||||
if (layersurface->layerSurface->mapped)
|
||||
layersurface->layerSurface->mapped = false;
|
||||
|
||||
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus)
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(layersurface->layerSurface->output);
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
// refocus if needed
|
||||
if (layersurface->layerSurface->surface == g_pCompositor->m_pLastFocus) {
|
||||
g_pCompositor->m_pLastFocus = nullptr;
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
@ -206,5 +216,8 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
||||
|
||||
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
|
||||
|
||||
// update geom if it changed
|
||||
layersurface->geometry = {layersurface->geometry.x, layersurface->geometry.y, layersurface->layerSurface->surface->current.width, layersurface->layerSurface->surface->current.height};
|
||||
|
||||
g_pHyprRenderer->damageSurface(layersurface->layerSurface->surface, layersurface->position.x, layersurface->position.y);
|
||||
}
|
@ -157,4 +157,10 @@ void Events::listener_InhibitDeactivate(wl_listener* listener, void* data) {
|
||||
|
||||
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "!!Renderer destroyed!!");
|
||||
}
|
||||
|
||||
void Events::listener_sessionActive(wl_listener* listener, void* data) {
|
||||
Debug::log(LOG, "Session got activated!");
|
||||
|
||||
g_pCompositor->m_bSessionActive = true;
|
||||
}
|
@ -149,10 +149,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
|
||||
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
||||
PNEWWORKSPACE->setActive(true);
|
||||
//
|
||||
|
||||
if (!pMostHzMonitor || monitorRule.refreshRate > pMostHzMonitor->refreshRate)
|
||||
pMostHzMonitor = PNEWMONITOR;
|
||||
//
|
||||
|
||||
if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet
|
||||
g_pCompositor->m_pLastMonitor = PNEWMONITOR;
|
||||
@ -166,6 +166,11 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
SMonitor* const PMONITOR = (SMonitor*)owner;
|
||||
|
||||
if ((g_pCompositor->m_sWLRSession && !g_pCompositor->m_sWLRSession->active) || !g_pCompositor->m_bSessionActive) {
|
||||
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||
return; // cannot draw on session inactive (different tty)
|
||||
}
|
||||
|
||||
static std::chrono::high_resolution_clock::time_point startRender = std::chrono::high_resolution_clock::now();
|
||||
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
@ -173,6 +178,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
static auto *const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
||||
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("general:damage_tracking_internal")->intValue;
|
||||
static auto *const PDAMAGEBLINK = &g_pConfigManager->getConfigValuePtr("debug:damage_blink")->intValue;
|
||||
static auto *const PNOVFR = &g_pConfigManager->getConfigValuePtr("misc:no_vfr")->intValue;
|
||||
|
||||
static int damageBlinkCleanup = 0; // because double-buffered
|
||||
|
||||
@ -181,28 +187,11 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
g_pDebugOverlay->frameData(PMONITOR);
|
||||
}
|
||||
|
||||
// Hack: only check when monitor with top hz refreshes, saves a bit of resources.
|
||||
// This is for stuff that should be run every frame
|
||||
if (PMONITOR->ID == pMostHzMonitor->ID) {
|
||||
g_pCompositor->sanityCheckWorkspaces();
|
||||
g_pAnimationManager->tick();
|
||||
g_pCompositor->cleanupFadingOut();
|
||||
|
||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
||||
|
||||
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
|
||||
|
||||
if (g_pConfigManager->m_bWantsMonitorReload)
|
||||
g_pConfigManager->performMonitorReload();
|
||||
|
||||
g_pHyprRenderer->ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts
|
||||
}
|
||||
|
||||
if (PMONITOR->framesToSkip > 0) {
|
||||
PMONITOR->framesToSkip -= 1;
|
||||
|
||||
if (!PMONITOR->noFrameSchedule)
|
||||
wlr_output_schedule_frame(PMONITOR->output);
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||
else {
|
||||
Debug::log(LOG, "NoFrameSchedule hit for %s.", PMONITOR->szName.c_str());
|
||||
}
|
||||
@ -210,6 +199,22 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// checks //
|
||||
if (PMONITOR->ID == pMostHzMonitor->ID || !*PNOVFR) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
|
||||
g_pCompositor->sanityCheckWorkspaces();
|
||||
g_pAnimationManager->tick();
|
||||
|
||||
HyprCtl::tickHyprCtl(); // so that we dont get that race condition multithread bullshit
|
||||
|
||||
g_pConfigManager->dispatchExecOnce(); // We exec-once when at least one monitor starts refreshing, meaning stuff has init'd
|
||||
|
||||
if (g_pConfigManager->m_bWantsMonitorReload)
|
||||
g_pConfigManager->performMonitorReload();
|
||||
|
||||
g_pHyprRenderer->ensureCursorRenderingMode(); // so that the cursor gets hidden/shown if the user requested timeouts
|
||||
}
|
||||
// //
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
@ -228,10 +233,16 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to cleanup fading out when rendering the appropriate context
|
||||
g_pCompositor->cleanupFadingOut(PMONITOR->ID);
|
||||
|
||||
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && PMONITOR->forceFullFrames == 0 && damageBlinkCleanup == 0) {
|
||||
pixman_region32_fini(&damage);
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
wlr_output_schedule_frame(PMONITOR->output); // we update shit at the monitor's Hz so we need to schedule frames because rollback wont
|
||||
|
||||
if (*PDAMAGEBLINK || *PNOVFR)
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -266,7 +277,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
// potentially can save on resources.
|
||||
|
||||
g_pHyprOpenGL->begin(PMONITOR, &damage);
|
||||
g_pHyprOpenGL->clear(CColor(100, 11, 11, 255));
|
||||
g_pHyprOpenGL->clear(CColor(17, 17, 17, 255));
|
||||
g_pHyprOpenGL->clearWithTex(); // will apply the hypr "wallpaper"
|
||||
|
||||
g_pHyprRenderer->renderAllClientsForMonitor(PMONITOR->ID, &now);
|
||||
@ -319,7 +330,8 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||
|
||||
wlr_output_commit(PMONITOR->output);
|
||||
|
||||
wlr_output_schedule_frame(PMONITOR->output);
|
||||
if (*PDAMAGEBLINK || *PNOVFR)
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||
|
||||
if (*PDEBUGOVERLAY == 1) {
|
||||
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
||||
@ -353,8 +365,7 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
|
||||
if (!BACKUPMON) {
|
||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||
g_pCompositor->cleanupExit();
|
||||
exit(1);
|
||||
g_pCompositor->cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -386,7 +397,6 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::unique_ptr<SMonitor>& el) { return el.get() == pMonitor; }));
|
||||
|
||||
// update the pMostHzMonitor
|
||||
if (pMostHzMonitor == pMonitor) {
|
||||
int mostHz = 0;
|
||||
SMonitor* pMonitorMostHz = nullptr;
|
||||
|
@ -92,6 +92,9 @@ void Events::listener_newPopupXDG(void* owner, void* data) {
|
||||
|
||||
ASSERT(PWINDOW);
|
||||
|
||||
if (!PWINDOW->m_bIsMapped)
|
||||
return;
|
||||
|
||||
Debug::log(LOG, "New layer popup created from XDG window %x -> %s", PWINDOW, PWINDOW->m_szTitle.c_str());
|
||||
|
||||
const auto WLRPOPUP = (wlr_xdg_popup*)data;
|
||||
|
@ -32,6 +32,9 @@ void addViewCoords(void* pWindow, int* x, int* y) {
|
||||
void Events::listener_mapWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
static auto *const PINACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:inactive_opacity")->floatValue;
|
||||
static auto *const PACTIVEALPHA = &g_pConfigManager->getConfigValuePtr("decoration:active_opacity")->floatValue;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
const auto PWORKSPACE = PMONITOR->specialWorkspaceOpen ? g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID) : g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
@ -145,7 +148,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
try {
|
||||
std::string alphaPart = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
|
||||
if (alphaPart.find_first_of(' ') != std::string::npos) {
|
||||
if (alphaPart.contains(' ')) {
|
||||
// we have a comma, 2 values
|
||||
PWINDOW->m_sSpecialRenderData.alpha = std::stof(alphaPart.substr(0, alphaPart.find_first_of(' ')));
|
||||
PWINDOW->m_sSpecialRenderData.alphaInactive = std::stof(alphaPart.substr(alphaPart.find_first_of(' ') + 1));
|
||||
@ -163,13 +166,17 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
if (requestedWorkspace != "") {
|
||||
// process requested workspace
|
||||
if (requestedWorkspace.find_first_of(' ') != std::string::npos) {
|
||||
if (requestedWorkspace.contains(' ')) {
|
||||
// check for silent
|
||||
if (requestedWorkspace.find("silent") != std::string::npos) {
|
||||
if (requestedWorkspace.contains("silent")) {
|
||||
workspaceSilent = true;
|
||||
}
|
||||
|
||||
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
|
||||
|
||||
if (requestedWorkspace == "special") {
|
||||
workspaceSilent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!workspaceSilent) {
|
||||
@ -192,8 +199,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto SIZEXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto SIZEYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto SIZEX = SIZEXSTR.find('%') == std::string::npos ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto SIZEY = SIZEYSTR.find('%') == std::string::npos ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
const auto SIZEX = !SIZEXSTR.contains('%') ? std::stoi(SIZEXSTR) : std::stoi(SIZEXSTR.substr(0, SIZEXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto SIZEY = !SIZEYSTR.contains('%') ? std::stoi(SIZEYSTR) : std::stoi(SIZEYSTR.substr(0, SIZEYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
|
||||
Debug::log(LOG, "Rule size, applying to window %x", PWINDOW);
|
||||
|
||||
@ -208,8 +215,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
const auto POSXSTR = VALUE.substr(0, VALUE.find(" "));
|
||||
const auto POSYSTR = VALUE.substr(VALUE.find(" ") + 1);
|
||||
|
||||
const auto POSX = POSXSTR.find('%') == std::string::npos ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto POSY = POSYSTR.find('%') == std::string::npos ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
const auto POSX = !POSXSTR.contains('%') ? std::stoi(POSXSTR) : std::stoi(POSXSTR.substr(0, POSXSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.x;
|
||||
const auto POSY = !POSYSTR.contains('%') ? std::stoi(POSYSTR) : std::stoi(POSYSTR.substr(0, POSYSTR.length() - 1)) * 0.01f * PMONITOR->vecSize.y;
|
||||
|
||||
Debug::log(LOG, "Rule move, applying to window %x", PWINDOW);
|
||||
|
||||
@ -231,8 +238,11 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10,10);
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus)
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus && PWINDOW->m_iX11Type != 2) {
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PACTIVEALPHA);
|
||||
} else
|
||||
PWINDOW->m_fActiveInactiveAlpha.setValueAndWarp(*PINACTIVEALPHA);
|
||||
|
||||
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
||||
|
||||
@ -246,6 +256,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_activateX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_activate, &Events::listener_activateX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_configureX11.initCallback(&PWINDOW->m_uSurface.xwayland->events.request_configure, &Events::listener_configureX11, PWINDOW, "XWayland Window Late");
|
||||
PWINDOW->hyprListener_setTitleWindow.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_title, &Events::listener_setTitleWindow, PWINDOW, "XWayland Window Late");
|
||||
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
PWINDOW->hyprListener_setGeometryX11U.initCallback(&PWINDOW->m_uSurface.xwayland->events.set_geometry, &Events::listener_unmanagedSetGeometry, PWINDOW, "XWayland Window Late");
|
||||
}
|
||||
|
||||
// do the animation thing
|
||||
@ -254,7 +267,10 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
if (workspaceSilent) {
|
||||
// move the window
|
||||
if (g_pCompositor->m_pLastWindow == PWINDOW) {
|
||||
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
||||
if (requestedWorkspace != "special")
|
||||
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
|
||||
else
|
||||
g_pKeybindManager->m_mDispatchers["movetoworkspace"]("special");
|
||||
} else {
|
||||
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
|
||||
}
|
||||
@ -268,9 +284,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
g_pXWaylandManager->setWindowFullscreen(PFULLWINDOW, PFULLWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
PWINDOW->m_vRealPosition.warp();
|
||||
PWINDOW->m_vRealSize.warp();
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, true, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
|
||||
|
||||
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
|
||||
@ -293,6 +315,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
PWINDOW->hyprListener_activateX11.removeCallback();
|
||||
PWINDOW->hyprListener_configureX11.removeCallback();
|
||||
PWINDOW->hyprListener_setTitleWindow.removeCallback();
|
||||
PWINDOW->hyprListener_setGeometryX11U.removeCallback();
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
@ -350,14 +373,19 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
// Destroy Foreign Toplevel
|
||||
wlr_foreign_toplevel_handle_v1_destroy(PWINDOW->m_phForeignToplevel);
|
||||
PWINDOW->m_phForeignToplevel = nullptr;
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
}
|
||||
|
||||
void Events::listener_commitWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden || (PWINDOW->m_bIsX11 && !PWINDOW->m_bMappedX11))
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageSurface(g_pXWaylandManager->getWindowSurface(PWINDOW), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y);
|
||||
|
||||
// Debug::log(LOG, "Window %x committed", PWINDOW); // SPAM!
|
||||
}
|
||||
|
||||
@ -472,6 +500,29 @@ void Events::listener_configureX11(void* owner, void* data) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
|
||||
void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
if (!PWINDOW->m_bMappedX11 || PWINDOW->m_bHidden)
|
||||
return;
|
||||
|
||||
const auto POS = PWINDOW->m_vRealPosition.goalv();
|
||||
const auto SIZ = PWINDOW->m_vRealSize.goalv();
|
||||
|
||||
if (abs(floor(POS.x) - PWINDOW->m_uSurface.xwayland->x) > 2 || abs(floor(POS.y) - PWINDOW->m_uSurface.xwayland->y) > 2 || abs(floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
PWINDOW->m_vRealPosition.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->x, PWINDOW->m_uSurface.xwayland->y));
|
||||
|
||||
if (abs(floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2)
|
||||
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
|
||||
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.vec());
|
||||
g_pCompositor->moveWindowToTop(PWINDOW);
|
||||
PWINDOW->updateWindowDecos();
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_surfaceXWayland(wl_listener* listener, void* data) {
|
||||
const auto XWSURFACE = (wlr_xwayland_surface*)data;
|
||||
|
||||
|
@ -128,10 +128,10 @@ public:
|
||||
case AVARTYPE_COLOR:
|
||||
return m_cValue != m_cGoal;
|
||||
default:
|
||||
return false;
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
return false; // unreachable
|
||||
std::unreachable();
|
||||
}
|
||||
|
||||
void warp() {
|
||||
@ -149,7 +149,7 @@ public:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
std::unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
|
||||
if (source.find_first_of("+") == 0) {
|
||||
try {
|
||||
if (source.find('.') != std::string::npos)
|
||||
if (source.contains("."))
|
||||
result = relative + std::stof(source.substr(1));
|
||||
else
|
||||
result = relative + std::stoi(source.substr(1));
|
||||
@ -147,7 +147,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
}
|
||||
} else if (source.find_first_of("-") == 0) {
|
||||
try {
|
||||
if (source.find('.') != std::string::npos)
|
||||
if (source.contains("."))
|
||||
result = relative - std::stof(source.substr(1));
|
||||
else
|
||||
result = relative - std::stoi(source.substr(1));
|
||||
@ -157,7 +157,7 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (source.find('.') != std::string::npos)
|
||||
if (source.contains("."))
|
||||
result = stof(source);
|
||||
else
|
||||
result = stoi(source);
|
||||
|
56
src/helpers/Splashes.hpp
Normal file
56
src/helpers/Splashes.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
inline const std::vector<std::string> SPLASHES = {
|
||||
"Woo, animations!",
|
||||
"It's like Hypr, but better.",
|
||||
"Release 1.0 when?",
|
||||
"It's not awesome, it's Hyprland!",
|
||||
"\"I commit too often, people can't catch up lmao\" - Vaxry",
|
||||
"This text is random.",
|
||||
"\"There are reasons to not use rust.\" - Boga",
|
||||
"Read the wiki.",
|
||||
"\"Hello everyone this is YOUR daily dose of ‘read the wiki’\" - Vaxry",
|
||||
"h",
|
||||
"\"‘why no work’, bro I haven't hacked your pc to get live feeds yet\" - Vaxry",
|
||||
"Compile, wait for 20 minutes, notice a new commit, compile again.",
|
||||
"To rice, or not to rice, that is the question.",
|
||||
"Now available on Fedora!",
|
||||
// music reference / quote section
|
||||
"J'remue le ciel, le jour, la nuit.",
|
||||
"aezakmi, aezakmi, aezakmi, aezakmi, aezakmi, aezakmi, aezakmi!",
|
||||
"Wir sind schon sehr lang zusammen...",
|
||||
"I see a red door and I want it painted black.",
|
||||
"Take on me, take me on...",
|
||||
"You spin me right round baby right round",
|
||||
"Stayin' alive, stayin' alive",
|
||||
"Say no way, say no way ya, no way!",
|
||||
"Ground control to Major Tom...",
|
||||
"Alors on danse",
|
||||
"And all that I can see, is just a yellow lemon tree.",
|
||||
"Got a one-way ticket to the blues",
|
||||
"Is this the real life, is this just fantasy",
|
||||
"What's in your head, in your head?",
|
||||
"We're all living in America, America, America.",
|
||||
"I'm still standing, better than I ever did",
|
||||
"Here comes the sun, bringing you love and shining on everyone",
|
||||
"Two trailer park girls go round the outside",
|
||||
"With the lights out, it's less dangerous",
|
||||
"Here we go back, this is the moment, tonight is the night",
|
||||
"Now you're just somebody that I used to know...",
|
||||
"Black bird, black moon, black sky",
|
||||
"Some legends are told, some turn to dust or to gold",
|
||||
"Your brain gets smart, but your head gets dumb.",
|
||||
"Save your mercy for someone who needs it more",
|
||||
"You're gonna hear my voice when I shout it out loud",
|
||||
"Ding ding pch n daa, bam-ba-ba-re-bam baram bom bom baba-bam-bam-bommm",
|
||||
"Súbeme la radio que esta es mi canción",
|
||||
"I'm beggin', beggin' you",
|
||||
//
|
||||
"Join the discord server!",
|
||||
"Thanks ThatOneCalculator!",
|
||||
"The AUR packages always work, except for the times they don't.",
|
||||
"Funny animation compositor woo"
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
#include "Vector2D.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
Vector2D::Vector2D(double xx, double yy) {
|
||||
x = xx;
|
||||
@ -20,4 +21,11 @@ double Vector2D::normalize() {
|
||||
|
||||
Vector2D Vector2D::floor() {
|
||||
return Vector2D((int)x, (int)y);
|
||||
}
|
||||
|
||||
Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) {
|
||||
return Vector2D(
|
||||
std::clamp(this->x, min.x, max.x == 0 ? INFINITY : max.x),
|
||||
std::clamp(this->y, min.y, max.y == 0 ? INFINITY : max.y)
|
||||
);
|
||||
}
|
@ -35,5 +35,7 @@ class Vector2D {
|
||||
return a.x != x || a.y != y;
|
||||
}
|
||||
|
||||
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D());
|
||||
|
||||
Vector2D floor();
|
||||
};
|
@ -25,10 +25,14 @@ struct SLayerSurface {
|
||||
|
||||
int monitorID = -1;
|
||||
|
||||
std::string szNamespace = "";
|
||||
|
||||
CAnimatedVariable alpha;
|
||||
bool fadingOut = false;
|
||||
bool readyToDelete = false;
|
||||
|
||||
bool forceBlur = false;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const SLayerSurface& rhs) {
|
||||
return layerSurface == rhs.layerSurface && monitorID == rhs.monitorID;
|
||||
@ -60,6 +64,26 @@ struct SRenderData {
|
||||
|
||||
// for custom round values
|
||||
int rounding = -1; // -1 means not set
|
||||
|
||||
// for blurring
|
||||
bool blur = false;
|
||||
|
||||
// for windows that animate poorly
|
||||
bool squishOversized = false;
|
||||
};
|
||||
|
||||
struct SExtensionFindingData {
|
||||
Vector2D origin;
|
||||
Vector2D vec;
|
||||
wlr_surface** found;
|
||||
};
|
||||
|
||||
struct SStringRuleNames {
|
||||
std::string layout = "";
|
||||
std::string model = "";
|
||||
std::string variant = "";
|
||||
std::string options = "";
|
||||
std::string rules = "";
|
||||
};
|
||||
|
||||
struct SKeyboard {
|
||||
@ -73,7 +97,7 @@ struct SKeyboard {
|
||||
|
||||
std::string name = "";
|
||||
|
||||
xkb_rule_names currentRules = {0};
|
||||
SStringRuleNames currentRules;
|
||||
int repeatRate = 0;
|
||||
int repeatDelay = 0;
|
||||
int numlockOn = -1;
|
||||
@ -94,6 +118,8 @@ struct SMouse {
|
||||
|
||||
std::string name = "";
|
||||
|
||||
bool virt = false;
|
||||
|
||||
DYNLISTENER(commitConstraint);
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
@ -221,3 +247,25 @@ struct STabletPad {
|
||||
return wlrTabletPadV2 == b.wlrTabletPadV2;
|
||||
}
|
||||
};
|
||||
|
||||
struct SIdleInhibitor {
|
||||
wlr_idle_inhibitor_v1* pWlrInhibitor = nullptr;
|
||||
CWindow* pWindow = nullptr;
|
||||
|
||||
DYNLISTENER(Destroy);
|
||||
|
||||
bool operator==(const SIdleInhibitor& b) {
|
||||
return pWlrInhibitor == b.pWlrInhibitor;
|
||||
}
|
||||
};
|
||||
|
||||
struct SSwipeGesture {
|
||||
CWorkspace* pWorkspaceBegin = nullptr;
|
||||
|
||||
double delta = 0;
|
||||
|
||||
float avgSpeed = 0;
|
||||
int speedPoints = 0;
|
||||
|
||||
SMonitor* pMonitor = nullptr;
|
||||
};
|
@ -28,6 +28,7 @@ public:
|
||||
// for animations
|
||||
CAnimatedVariable m_vRenderOffset;
|
||||
CAnimatedVariable m_fAlpha;
|
||||
bool m_bForceRendering = false;
|
||||
|
||||
// "scratchpad"
|
||||
bool m_bIsSpecialWorkspace = false;
|
||||
|
@ -14,7 +14,7 @@ void CHyprError::createQueued() {
|
||||
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
@ -27,12 +27,12 @@ void CHyprError::createQueued() {
|
||||
const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n');
|
||||
|
||||
cairo_set_source_rgba(CAIRO, m_cQueued.r / 255.f, m_cQueued.g / 255.f, m_cQueued.b / 255.f, m_cQueued.a / 255.f);
|
||||
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecSize.x, 10 * LINECOUNT);
|
||||
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecPixelSize.x, 10 * LINECOUNT);
|
||||
|
||||
// outline
|
||||
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecSize.y); // left
|
||||
cairo_rectangle(CAIRO, PMONITOR->vecSize.x - 1, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // right
|
||||
cairo_rectangle(CAIRO, 0, PMONITOR->vecSize.y - 1, PMONITOR->vecSize.x, PMONITOR->vecSize.y); // bottom
|
||||
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecPixelSize.y); // left
|
||||
cairo_rectangle(CAIRO, PMONITOR->vecPixelSize.x - 1, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // right
|
||||
cairo_rectangle(CAIRO, 0, PMONITOR->vecPixelSize.y - 1, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // bottom
|
||||
|
||||
cairo_fill(CAIRO);
|
||||
|
||||
@ -70,7 +70,7 @@ void CHyprError::createQueued() {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecSize.x, PMONITOR->vecSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
||||
|
||||
// delete cairo
|
||||
cairo_destroy(CAIRO);
|
||||
@ -104,7 +104,7 @@ void CHyprError::draw() {
|
||||
if (g_pHyprOpenGL->m_RenderData.pMonitor != PMONITOR)
|
||||
return; // wrong mon
|
||||
|
||||
wlr_box windowBox = {0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
|
||||
wlr_box windowBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
|
||||
g_pHyprOpenGL->renderTexture(m_tTexture, &windowBox, 255.f, 0);
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ extern "C" {
|
||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/xwayland.h>
|
||||
#include <wlr/util/region.h>
|
||||
@ -91,6 +92,7 @@ extern "C" {
|
||||
#include <wlr/types/wlr_xdg_foreign_registry.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||
#include <wlr/types/wlr_pointer_gestures_v1.h>
|
||||
}
|
||||
|
||||
#undef class
|
||||
@ -118,4 +120,5 @@ extern "C" {
|
||||
|
||||
#include "ext-workspace-unstable-v1-protocol.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
@ -23,19 +23,21 @@ void SDwindleNodeData::recalcSizePosRecursive() {
|
||||
|
||||
const auto REVERSESPLITRATIO = 2.f - splitRatio;
|
||||
|
||||
if (g_pConfigManager->getInt("dwindle:preserve_split") == 0)
|
||||
splitTop = size.y > size.x;
|
||||
if (g_pConfigManager->getInt("dwindle:preserve_split") == 0) {
|
||||
const auto WIDTHMULTIPLIER = g_pConfigManager->getFloat("dwindle:split_width_multiplier");
|
||||
splitTop = size.y * WIDTHMULTIPLIER > size.x;
|
||||
}
|
||||
|
||||
const auto SPLITSIDE = !splitTop;
|
||||
|
||||
if (SPLITSIDE) {
|
||||
// split sidey
|
||||
// split left/right
|
||||
children[0]->position = position;
|
||||
children[0]->size = Vector2D(size.x / 2.f * splitRatio, size.y);
|
||||
children[1]->position = Vector2D(position.x + size.x / 2.f * splitRatio, position.y);
|
||||
children[1]->size = Vector2D(size.x / 2.f * REVERSESPLITRATIO, size.y);
|
||||
} else {
|
||||
// split toppy bottomy
|
||||
// split top/bottom
|
||||
children[0]->position = position;
|
||||
children[0]->size = Vector2D(size.x, size.y / 2.f * splitRatio);
|
||||
children[1]->position = Vector2D(position.x, position.y + size.y / 2.f * splitRatio);
|
||||
@ -93,17 +95,28 @@ SDwindleNodeData* CHyprDwindleLayout::getMasterNodeOnWorkspace(const int& id) {
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID);
|
||||
|
||||
if (!PMONITOR){
|
||||
Debug::log(ERR, "Orphaned Node %x (workspace ID: %i)!!", pNode, pNode->workspaceID);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't set nodes, only windows.
|
||||
if (pNode->isNode)
|
||||
return;
|
||||
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
|
||||
if (pNode->workspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->specialWorkspaceOpen) {
|
||||
PMONITOR = m.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(g_pCompositor->getWorkspaceByID(pNode->workspaceID)->m_iMonitorID);
|
||||
}
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Orphaned Node %x (workspace ID: %i)!!", pNode, pNode->workspaceID);
|
||||
return;
|
||||
}
|
||||
|
||||
// for gaps outer
|
||||
const bool DISPLAYLEFT = STICKS(pNode->position.x, PMONITOR->vecPosition.x + PMONITOR->vecReservedTopLeft.x);
|
||||
const bool DISPLAYRIGHT = STICKS(pNode->position.x + pNode->size.x, PMONITOR->vecPosition.x + PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x);
|
||||
@ -160,9 +173,7 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
|
||||
}
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
if (PWORKSPACE->m_bIsSpecialWorkspace) {
|
||||
if (PWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
// if special, we adjust the coords a bit
|
||||
static auto *const PSCALEFACTOR = &g_pConfigManager->getConfigValuePtr("dwindle:special_scale_factor")->floatValue;
|
||||
|
||||
@ -237,16 +248,19 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
NEWPARENT->pParent = OPENINGON->pParent;
|
||||
NEWPARENT->isNode = true; // it is a node
|
||||
|
||||
const auto WIDTHMULTIPLIER = g_pConfigManager->getFloat("dwindle:split_width_multiplier");
|
||||
|
||||
// if cursor over first child, make it first, etc
|
||||
const auto SIDEBYSIDE = NEWPARENT->size.x / NEWPARENT->size.y > 1.f;
|
||||
const auto SIDEBYSIDE = NEWPARENT->size.x > NEWPARENT->size.y * WIDTHMULTIPLIER;
|
||||
NEWPARENT->splitTop = !SIDEBYSIDE;
|
||||
|
||||
const auto MOUSECOORDS = g_pInputManager->getMouseCoordsInternal();
|
||||
|
||||
const auto FORCESPLIT = g_pConfigManager->getInt("dwindle:force_split");
|
||||
|
||||
if (FORCESPLIT == 0) {
|
||||
if ((SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y, NEWPARENT->position.x + NEWPARENT->size.x / 2.f, NEWPARENT->position.y + NEWPARENT->size.y))
|
||||
|| (!SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y, NEWPARENT->position.x + NEWPARENT->size.x, NEWPARENT->position.y + NEWPARENT->size.y / 2.f))) {
|
||||
if ((SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / WIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x / 2.f, NEWPARENT->position.y + NEWPARENT->size.y))
|
||||
|| (!SIDEBYSIDE && VECINRECT(MOUSECOORDS, NEWPARENT->position.x, NEWPARENT->position.y / WIDTHMULTIPLIER, NEWPARENT->position.x + NEWPARENT->size.x, NEWPARENT->position.y + NEWPARENT->size.y / 2.f))) {
|
||||
// we are hovering over the first node, make PNODE first.
|
||||
NEWPARENT->children[1] = OPENINGON;
|
||||
NEWPARENT->children[0] = PNODE;
|
||||
@ -275,14 +289,16 @@ void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
}
|
||||
|
||||
// Update the children
|
||||
if (NEWPARENT->size.x > NEWPARENT->size.y) {
|
||||
// split sidey
|
||||
|
||||
|
||||
if (NEWPARENT->size.x * WIDTHMULTIPLIER > NEWPARENT->size.y) {
|
||||
// split left/right
|
||||
OPENINGON->position = NEWPARENT->position;
|
||||
OPENINGON->size = Vector2D(NEWPARENT->size.x / 2.f, NEWPARENT->size.y);
|
||||
PNODE->position = Vector2D(NEWPARENT->position.x + NEWPARENT->size.x / 2.f, NEWPARENT->position.y);
|
||||
PNODE->size = Vector2D(NEWPARENT->size.x / 2.f, NEWPARENT->size.y);
|
||||
} else {
|
||||
// split toppy bottomy
|
||||
// split top/bottom
|
||||
OPENINGON->position = NEWPARENT->position;
|
||||
OPENINGON->size = Vector2D(NEWPARENT->size.x, NEWPARENT->size.y / 2.f);
|
||||
PNODE->position = Vector2D(NEWPARENT->position.x, NEWPARENT->position.y + NEWPARENT->size.y / 2.f);
|
||||
@ -378,6 +394,8 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
|
||||
if (!PWORKSPACE)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
const auto TOPNODE = getMasterNodeOnWorkspace(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
@ -388,9 +406,26 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore any recalc events if we have a fullscreen window.
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow)
|
||||
// Ignore any recalc events if we have a fullscreen window, but process if fullscreen mode 2
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
if (PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||
return;
|
||||
|
||||
// massive hack from the fullscreen func
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
|
||||
SDwindleNodeData fakeNode;
|
||||
fakeNode.pWindow = PFULLWINDOW;
|
||||
fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight;
|
||||
fakeNode.workspaceID = PWORKSPACE->m_iID;
|
||||
PFULLWINDOW->m_vPosition = fakeNode.position;
|
||||
PFULLWINDOW->m_vSize = fakeNode.size;
|
||||
|
||||
applyNodeDataToWindow(&fakeNode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto TOPNODE = getMasterNodeOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
@ -513,6 +548,10 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||
pWindow->m_bIsFullscreen = on;
|
||||
PWORKSPACE->m_bHasFullscreenWindow = !PWORKSPACE->m_bHasFullscreenWindow;
|
||||
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(pWindow);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)on)));
|
||||
|
||||
if (!pWindow->m_bIsFullscreen) {
|
||||
// if it got its fullscreen disabled, set back its node if it had one
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
@ -562,6 +601,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
||||
// we need to fix XWayland windows by sending them to NARNIA
|
||||
// because otherwise they'd still be recieving mouse events
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
recalculateMonitor(PMONITOR->ID);
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::recalculateWindow(CWindow* pWindow) {
|
||||
@ -637,6 +678,8 @@ void CHyprDwindleLayout::toggleWindowGroup(CWindow* pWindow) {
|
||||
|
||||
PPARENT->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
std::deque<CWindow*> CHyprDwindleLayout::getGroupMembers(CWindow* pWindow) {
|
||||
@ -820,4 +863,4 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
|
||||
|
||||
std::string CHyprDwindleLayout::getLayoutName() {
|
||||
return "dwindle";
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||
|
||||
// TODO: detect a popup in a more consistent way.
|
||||
if (!g_pCompositor->isPointOnAnyMonitor(middlePoint) || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
if ((desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
// if it's not, fall back to the center placement
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
||||
} else {
|
||||
@ -65,10 +65,12 @@ void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
pWindow->m_vRealSize.setValue(pWindow->m_vRealSize.goalv());
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
if (pWindow->m_iX11Type != 2) {
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void IHyprLayout::onBeginDragWindow() {
|
||||
@ -210,9 +212,23 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
} else {
|
||||
pWindow->m_vSize = pWindow->m_vRealSize.vec();
|
||||
pWindow->m_vPosition = pWindow->m_vRealPosition.vec();
|
||||
|
||||
onWindowRemovedTiling(pWindow);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
|
||||
const auto POS = pWindow->m_vRealPosition.goalv();
|
||||
const auto SIZ = pWindow->m_vRealSize.goalv();
|
||||
|
||||
pWindow->m_vRealPosition.setValueAndWarp(POS + Vector2D(5, 5));
|
||||
pWindow->m_vRealSize.setValueAndWarp(SIZ - Vector2D(10, 10));
|
||||
|
||||
pWindow->m_vRealPosition = POS;
|
||||
pWindow->m_vRealSize = SIZ;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
}
|
||||
}
|
||||
|
||||
|
15
src/main.cpp
15
src/main.cpp
@ -12,12 +12,22 @@ bool ignoreSudo = false;
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
if (!getenv("XDG_RUNTIME_DIR"))
|
||||
RIP("XDG_RUNTIME_DIR not set!");
|
||||
throw std::runtime_error("XDG_RUNTIME_DIR is not set!");
|
||||
|
||||
// parse some args
|
||||
std::string configPath;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (!strcmp(argv[i], "--i-am-really-stupid"))
|
||||
ignoreSudo = true;
|
||||
else if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && argc >= i + 2) {
|
||||
configPath = std::string(argv[++i]);
|
||||
Debug::log(LOG, "Using config location %s.", configPath.c_str());
|
||||
} else {
|
||||
std::cout << "Hyprland usage: Hyprland [arg [...]].\n\nArguments:\n" <<
|
||||
"--help -h | Show this help message\n" <<
|
||||
"--config -c | Specify config file to use\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
system("mkdir -p /tmp/hypr");
|
||||
@ -37,6 +47,7 @@ int main(int argc, char** argv) {
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
g_pCompositor = std::make_unique<CCompositor>();
|
||||
g_pCompositor->explicitConfigPath = configPath;
|
||||
|
||||
Debug::log(LOG, "Hyprland init finished.");
|
||||
|
||||
@ -46,7 +57,7 @@ int main(int argc, char** argv) {
|
||||
// If we are here it means we got yote.
|
||||
Debug::log(LOG, "Hyprland reached the end.");
|
||||
|
||||
g_pCompositor->cleanupExit();
|
||||
g_pCompositor->cleanup();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -53,15 +53,18 @@ void CAnimationManager::tick() {
|
||||
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
||||
const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace;
|
||||
const auto PLAYER = (SLayerSurface*)av->m_pLayer;
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
|
||||
wlr_box WLRBOXPREV = {0,0,0,0};
|
||||
if (PWINDOW) {
|
||||
WLRBOXPREV = PWINDOW->getFullWindowBoundingBox();
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
} else if (PWORKSPACE) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
|
||||
} else if (PLAYER) {
|
||||
WLRBOXPREV = PLAYER->geometry;
|
||||
PMONITOR = g_pCompositor->getMonitorFromVector(Vector2D(PLAYER->geometry.x, PLAYER->geometry.y) + Vector2D(PLAYER->geometry.width, PLAYER->geometry.height) / 2.f);
|
||||
}
|
||||
|
||||
// beziers are with a switch unforto
|
||||
@ -188,8 +191,11 @@ void CAnimationManager::tick() {
|
||||
|
||||
|
||||
// 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)
|
||||
if (g_pCompositor->windowValidMapped(PWINDOW) && av->m_eDamagePolicy == AVARDAMAGE_ENTIRE && PWINDOW->m_iX11Type != 2)
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||
|
||||
// manually schedule a frame
|
||||
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +309,7 @@ void CAnimationManager::onWindowPostCreateClose(CWindow* pWindow, bool close) {
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle != "") {
|
||||
// the window has config'd special anim
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.find("slide") == 0) {
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.find(' ') != std::string::npos) {
|
||||
if (pWindow->m_sAdditionalConfigData.animationStyle.contains(' ')) {
|
||||
// has a direction
|
||||
animationSlide(pWindow, pWindow->m_sAdditionalConfigData.animationStyle.substr(pWindow->m_sAdditionalConfigData.animationStyle.find(' ') + 1), close);
|
||||
} else {
|
||||
|
@ -41,35 +41,48 @@ void CKeybindManager::addKeybind(SKeybind kb) {
|
||||
|
||||
void CKeybindManager::removeKeybind(uint32_t mod, const std::string& key) {
|
||||
for (auto it = m_lKeybinds.begin(); it != m_lKeybinds.end(); ++it) {
|
||||
if (it->modmask == mod && it->key == key) {
|
||||
if (isNumber(key) && std::stoi(key) > 9) {
|
||||
const auto 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);
|
||||
|
||||
if (it == m_lKeybinds.end())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CKeybindManager::stringToModMask(std::string mods) {
|
||||
uint32_t modMask = 0;
|
||||
if (mods.find("SHIFT") != std::string::npos)
|
||||
if (mods.contains("SHIFT"))
|
||||
modMask |= WLR_MODIFIER_SHIFT;
|
||||
if (mods.find("CAPS") != std::string::npos)
|
||||
if (mods.contains("CAPS"))
|
||||
modMask |= WLR_MODIFIER_CAPS;
|
||||
if (mods.find("CTRL") != std::string::npos || mods.find("CONTROL") != std::string::npos)
|
||||
if (mods.contains("CTRL") || mods.contains("CONTROL"))
|
||||
modMask |= WLR_MODIFIER_CTRL;
|
||||
if (mods.find("ALT") != std::string::npos)
|
||||
if (mods.contains("ALT"))
|
||||
modMask |= WLR_MODIFIER_ALT;
|
||||
if (mods.find("MOD2") != std::string::npos)
|
||||
if (mods.contains("MOD2"))
|
||||
modMask |= WLR_MODIFIER_MOD2;
|
||||
if (mods.find("MOD3") != std::string::npos)
|
||||
if (mods.contains("MOD3"))
|
||||
modMask |= WLR_MODIFIER_MOD3;
|
||||
if (mods.find("SUPER") != std::string::npos || mods.find("WIN") != std::string::npos || mods.find("LOGO") != std::string::npos || mods.find("MOD4") != std::string::npos)
|
||||
if (mods.contains("SUPER") || mods.contains("WIN") || mods.contains("LOGO") || mods.contains("MOD4"))
|
||||
modMask |= WLR_MODIFIER_LOGO;
|
||||
if (mods.find("MOD5") != std::string::npos)
|
||||
if (mods.contains("MOD5"))
|
||||
modMask |= WLR_MODIFIER_MOD5;
|
||||
|
||||
return modMask;
|
||||
}
|
||||
|
||||
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key) {
|
||||
bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t& key, const int& keycode) {
|
||||
bool found = false;
|
||||
|
||||
if (handleInternalKeybinds(key))
|
||||
@ -82,15 +95,24 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
|
||||
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap)
|
||||
continue;
|
||||
|
||||
// oMg such performance hit!!11!
|
||||
// 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 KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
||||
// small TODO: fix 0-9 keys and other modified ones with shift
|
||||
|
||||
if (key != KBKEY && key != KBKEYUPPER)
|
||||
continue;
|
||||
|
||||
if (k.keycode != -1) {
|
||||
if (keycode != k.keycode)
|
||||
continue;
|
||||
|
||||
} else {
|
||||
if (key == 0)
|
||||
continue; // this is a keycode check run
|
||||
|
||||
// oMg such performance hit!!11!
|
||||
// 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 KBKEYUPPER = xkb_keysym_to_upper(KBKEY);
|
||||
// small TODO: fix 0-9 keys and other modified ones with shift
|
||||
|
||||
if (key != KBKEY && key != KBKEYUPPER)
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto DISPATCHER = m_mDispatchers.find(k.handler);
|
||||
|
||||
@ -99,7 +121,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
|
||||
Debug::log(ERR, "Inavlid handler in a keybind! (handler %s does not exist)", k.handler.c_str());
|
||||
} else {
|
||||
// call the dispatcher
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %d)", modmask, KBKEYUPPER);
|
||||
Debug::log(LOG, "Keybind triggered, calling dispatcher (%d, %d)", modmask, key);
|
||||
DISPATCHER->second(k.arg);
|
||||
}
|
||||
|
||||
@ -118,11 +140,11 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||
if (PSESSION) {
|
||||
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||
wlr_session_change_vt(PSESSION, TTY);
|
||||
g_pCompositor->m_bSessionActive = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
g_pHyprOpenGL->destroyMonitorResources(m.get()); // mark resources as unusable anymore
|
||||
m->noFrameSchedule = true;
|
||||
m->framesToSkip = 2;
|
||||
m->framesToSkip = 1;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Switched to VT %i, destroyed all render data, frames to skip for each: 2", TTY);
|
||||
@ -231,9 +253,6 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
||||
moveActiveToWorkspace(std::to_string(g_pCompositor->getMonitorFromID(ACTIVEWINDOW->m_iMonitorID)->activeWorkspace));
|
||||
}
|
||||
|
||||
ACTIVEWINDOW->m_vRealPosition.setValue(ACTIVEWINDOW->m_vRealPosition.vec() + Vector2D(5, 5));
|
||||
ACTIVEWINDOW->m_vSize = ACTIVEWINDOW->m_vRealPosition.vec() - Vector2D(10, 10);
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(ACTIVEWINDOW);
|
||||
}
|
||||
}
|
||||
@ -253,7 +272,14 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
int workspaceToChangeTo = 0;
|
||||
std::string workspaceName = "";
|
||||
|
||||
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
|
||||
if (args.find("[internal]") == 0) {
|
||||
workspaceToChangeTo = std::stoi(args.substr(10));
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToChangeTo);
|
||||
if (PWORKSPACE)
|
||||
workspaceName = PWORKSPACE->m_szName;
|
||||
} else {
|
||||
workspaceToChangeTo = getWorkspaceIDFromString(args, workspaceName);
|
||||
}
|
||||
|
||||
if (workspaceToChangeTo == INT_MAX) {
|
||||
Debug::log(ERR, "Error in changeworkspace, invalid value");
|
||||
@ -277,8 +303,6 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||
const auto OLDWORKSPACEID = PMONITOR->activeWorkspace;
|
||||
|
||||
// change it
|
||||
PMONITOR->specialWorkspaceOpen = false;
|
||||
|
||||
if (workspaceToChangeTo != SPECIAL_WORKSPACE_ID)
|
||||
PMONITOR->activeWorkspace = workspaceToChangeTo;
|
||||
else
|
||||
@ -451,7 +475,7 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
|
||||
// undo the damage if we are moving to the special workspace
|
||||
if (WORKSPACEID == SPECIAL_WORKSPACE_ID) {
|
||||
changeworkspace(std::to_string(OLDWORKSPACE->m_iID));
|
||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACE->m_iID));
|
||||
OLDWORKSPACE->startAnim(true, true, true);
|
||||
toggleSpecialWorkspace("");
|
||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false, true);
|
||||
@ -503,8 +527,8 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||
|
||||
PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceToMoveTo);
|
||||
|
||||
changeworkspace(std::to_string(OLDWORKSPACEIDONMONITOR));
|
||||
changeworkspace(std::to_string(OLDWORKSPACEIDRETURN));
|
||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACEIDONMONITOR));
|
||||
changeworkspace("[internal]" + std::to_string(OLDWORKSPACEIDRETURN));
|
||||
|
||||
// revert animations
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(0,0));
|
||||
@ -663,7 +687,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
|
||||
}
|
||||
|
||||
if (monID > -1 && monID < (int)g_pCompositor->m_vMonitors.size()) {
|
||||
changeworkspace(std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
|
||||
changeworkspace("[internal]" + std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
|
||||
} else {
|
||||
Debug::log(ERR, "Error in focusMonitor: invalid arg 1");
|
||||
}
|
||||
@ -683,7 +707,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == arg) {
|
||||
changeworkspace(std::to_string(m->activeWorkspace));
|
||||
changeworkspace("[internal]" + std::to_string(m->activeWorkspace));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -788,20 +812,20 @@ void CKeybindManager::workspaceOpt(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::exitHyprland(std::string argz) {
|
||||
g_pCompositor->cleanupExit();
|
||||
exit(0);
|
||||
g_pCompositor->cleanup();
|
||||
}
|
||||
|
||||
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
if (!isNumber(args) && !isDirection(args)) {
|
||||
Debug::log(ERR, "moveCurrentWorkspaceToMonitor arg not a number or direction!");
|
||||
return;
|
||||
}
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
|
||||
const auto PMONITOR = isDirection(args) ? g_pCompositor->getMonitorInDirection(args[0]) : g_pCompositor->getMonitorFromID(std::stoi(args));
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Ignoring moveCurrentWorkspaceToMonitor: monitor doesnt exist");
|
||||
try {
|
||||
if (!isNumber(args) && !isDirection(args)) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromName(args);
|
||||
} else {
|
||||
PMONITOR = isDirection(args) ? g_pCompositor->getMonitorInDirection(args[0]) : g_pCompositor->getMonitorFromID(std::stoi(args));
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(LOG, "moveCurrentWorkspaceToMonitor: caught exception in monitor", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -815,18 +839,25 @@ void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveWorkspaceToMonitor(std::string args) {
|
||||
if (args.find_first_of(' ') == std::string::npos)
|
||||
if (!args.contains(' '))
|
||||
return;
|
||||
|
||||
std::string workspace = args.substr(0, args.find_first_of(' '));
|
||||
std::string monitor = args.substr(args.find_first_of(' ') + 1);
|
||||
|
||||
if (!isNumber(monitor) && !isDirection(monitor)) {
|
||||
Debug::log(ERR, "moveWorkspaceToMonitor monitor arg not a number or direction!");
|
||||
SMonitor* PMONITOR = nullptr;
|
||||
|
||||
try {
|
||||
if (!isNumber(monitor) && !isDirection(monitor)) {
|
||||
PMONITOR = g_pCompositor->getMonitorFromName(monitor);
|
||||
} else {
|
||||
PMONITOR = isDirection(monitor) ? g_pCompositor->getMonitorInDirection(monitor[0]) : g_pCompositor->getMonitorFromID(std::stoi(monitor));
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(LOG, "moveWorkspaceToMonitor: caught exception in monitor", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = isDirection(monitor) ? g_pCompositor->getMonitorInDirection(monitor[0]) : g_pCompositor->getMonitorFromID(std::stoi(monitor));
|
||||
|
||||
|
||||
if (!PMONITOR){
|
||||
Debug::log(ERR, "Ignoring moveWorkspaceToMonitor: monitor doesnt exist");
|
||||
@ -882,11 +913,16 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
if (!PSPECIALWORKSPACE) {
|
||||
// ??? happens sometimes...?
|
||||
PSPECIALWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(g_pCompositor->m_pLastMonitor->ID, "special", true)).get();
|
||||
}
|
||||
|
||||
g_pCompositor->m_pLastMonitor->specialWorkspaceOpen = true;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
||||
|
||||
const auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
PSPECIALWORKSPACE->startAnim(true, true);
|
||||
PSPECIALWORKSPACE->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
||||
}
|
||||
@ -910,7 +946,7 @@ void CKeybindManager::forceRendererReload(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::resizeActive(std::string args) {
|
||||
if (args.find_first_of(' ') == std::string::npos)
|
||||
if (!args.contains(' '))
|
||||
return;
|
||||
|
||||
std::string x = args.substr(0, args.find_first_of(' '));
|
||||
@ -959,7 +995,7 @@ void CKeybindManager::resizeActive(std::string args) {
|
||||
}
|
||||
|
||||
void CKeybindManager::moveActive(std::string args) {
|
||||
if (args.find_first_of(' ') == std::string::npos)
|
||||
if (!args.contains(' '))
|
||||
return;
|
||||
|
||||
std::string x = args.substr(0, args.find_first_of(' '));
|
||||
@ -1007,11 +1043,14 @@ void CKeybindManager::moveActive(std::string args) {
|
||||
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(Vector2D(X, Y));
|
||||
}
|
||||
|
||||
void CKeybindManager::circleNext(std::string) {
|
||||
void CKeybindManager::circleNext(std::string arg) {
|
||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||
return;
|
||||
|
||||
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
if (arg == "last" || arg == "l" || arg == "prev" || arg == "p")
|
||||
g_pCompositor->focusWindow(g_pCompositor->getPrevWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
else
|
||||
g_pCompositor->focusWindow(g_pCompositor->getNextWindowOnWorkspace(g_pCompositor->m_pLastWindow));
|
||||
|
||||
const auto MIDPOINT = g_pCompositor->m_pLastWindow->m_vRealPosition.goalv() + g_pCompositor->m_pLastWindow->m_vRealSize.goalv() / 2.f;
|
||||
|
||||
@ -1043,7 +1082,7 @@ void CKeybindManager::focusWindow(std::string regexp) {
|
||||
|
||||
Debug::log(LOG, "Focusing to window name: %s", w->m_szTitle.c_str());
|
||||
|
||||
changeworkspace(std::to_string(w->m_iWorkspaceID));
|
||||
changeworkspace("[internal]" + std::to_string(w->m_iWorkspaceID));
|
||||
|
||||
g_pCompositor->focusWindow(w.get());
|
||||
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include <functional>
|
||||
|
||||
struct SKeybind {
|
||||
std::string key = 0;
|
||||
std::string key = "";
|
||||
int keycode = -1;
|
||||
uint32_t modmask = 0;
|
||||
std::string handler = "";
|
||||
std::string arg = "";
|
||||
@ -19,7 +20,7 @@ class CKeybindManager {
|
||||
public:
|
||||
CKeybindManager();
|
||||
|
||||
bool handleKeybinds(const uint32_t&, const xkb_keysym_t&);
|
||||
bool handleKeybinds(const uint32_t&, const xkb_keysym_t&, const int&);
|
||||
void addKeybind(SKeybind);
|
||||
void removeKeybind(uint32_t, const std::string&);
|
||||
uint32_t stringToModMask(std::string);
|
||||
|
@ -36,7 +36,9 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
|
||||
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(pSurface)->toplevel, activate);
|
||||
else if (wlr_surface_is_xwayland_surface(pSurface)) {
|
||||
wlr_xwayland_surface_activate(wlr_xwayland_surface_from_wlr_surface(pSurface), activate);
|
||||
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
|
||||
|
||||
if (activate)
|
||||
wlr_xwayland_surface_restack(wlr_xwayland_surface_from_wlr_surface(pSurface), NULL, XCB_STACK_MODE_ABOVE);
|
||||
}
|
||||
|
||||
}
|
||||
@ -153,7 +155,7 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
|
||||
if (pWindow->m_uSurface.xwayland->role) {
|
||||
try {
|
||||
std::string winrole = std::string(pWindow->m_uSurface.xwayland->role);
|
||||
if (winrole.find("pop-up") != std::string::npos || winrole.find("task_dialog") != std::string::npos) {
|
||||
if (winrole.contains("pop-up") || winrole.contains("task_dialog")) {
|
||||
return true;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
@ -221,6 +223,4 @@ void CHyprXWaylandManager::setWindowFullscreen(CWindow* pWindow, bool fullscreen
|
||||
|
||||
if (pWindow->m_phForeignToplevel)
|
||||
wlr_foreign_toplevel_handle_v1_set_fullscreen(pWindow->m_phForeignToplevel, fullscreen);
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("fullscreen", std::to_string((int)fullscreen)));
|
||||
}
|
54
src/managers/input/IdleInhibitor.cpp
Normal file
54
src/managers/input/IdleInhibitor.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void Events::listener_newIdleInhibitor(wl_listener* listener, void* data) {
|
||||
const auto WLRIDLEINHIBITOR = (wlr_idle_inhibitor_v1*)data;
|
||||
|
||||
if (!WLRIDLEINHIBITOR)
|
||||
return;
|
||||
|
||||
g_pInputManager->newIdleInhibitor(WLRIDLEINHIBITOR);
|
||||
}
|
||||
|
||||
void CInputManager::newIdleInhibitor(wlr_idle_inhibitor_v1* pInhibitor) {
|
||||
const auto PINHIBIT = &m_lIdleInhibitors.emplace_back();
|
||||
|
||||
Debug::log(LOG, "New idle inhibitor registered");
|
||||
|
||||
PINHIBIT->pWlrInhibitor = pInhibitor;
|
||||
|
||||
PINHIBIT->hyprListener_Destroy.initCallback(&pInhibitor->events.destroy, [](void* owner, void* data){
|
||||
|
||||
const auto PINH = (SIdleInhibitor*)owner;
|
||||
|
||||
g_pInputManager->m_lIdleInhibitors.remove(*PINH);
|
||||
|
||||
Debug::log(LOG, "Destroyed an idleinhibitor");
|
||||
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
}, PINHIBIT, "IdleInhibitor");
|
||||
|
||||
PINHIBIT->pWindow = g_pCompositor->getWindowFromSurface(pInhibitor->surface);
|
||||
|
||||
if (PINHIBIT->pWindow)
|
||||
Debug::log(LOG, "IdleInhibitor got window %x (%s)", PINHIBIT->pWindow, PINHIBIT->pWindow->m_szTitle.c_str());
|
||||
|
||||
recheckIdleInhibitorStatus();
|
||||
}
|
||||
|
||||
void CInputManager::recheckIdleInhibitorStatus() {
|
||||
|
||||
for (auto& ii : m_lIdleInhibitors) {
|
||||
if (!ii.pWindow) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
} else if (g_pHyprRenderer->shouldRenderWindow(ii.pWindow)) {
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_idle_set_enabled(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat, true);
|
||||
return;
|
||||
}
|
@ -28,6 +28,8 @@ void CInputManager::onMouseWarp(wlr_pointer_motion_absolute_event* e) {
|
||||
|
||||
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
|
||||
if (!g_pCompositor->m_bReadyToProcess)
|
||||
return;
|
||||
|
||||
@ -36,10 +38,13 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_pCompositor->m_sSeat.mouse->virt)
|
||||
return; // don't refocus on virt
|
||||
|
||||
Vector2D mouseCoords = getMouseCoordsInternal();
|
||||
const auto MOUSECOORDSFLOORED = mouseCoords.floor();
|
||||
|
||||
if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored)
|
||||
if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored && !refocus)
|
||||
return;
|
||||
|
||||
m_vLastCursorPosFloored = MOUSECOORDSFLOORED;
|
||||
@ -86,6 +91,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
} else {
|
||||
if ((!CONSTRAINTWINDOW->m_bIsX11 && PMONITOR && CONSTRAINTWINDOW->m_iWorkspaceID == PMONITOR->activeWorkspace) || (CONSTRAINTWINDOW->m_bIsX11)) {
|
||||
g_pCompositor->m_sSeat.mouse->constraintActive = true;
|
||||
didConstraintOnCursor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,6 +144,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
surfacePos = Vector2D(-1337, -1337);
|
||||
} else {
|
||||
foundSurface = g_pXWaylandManager->getWindowSurface(pFoundWindow);
|
||||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||
@ -153,9 +160,21 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
// then windows
|
||||
if (!foundSurface) {
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED)
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
else
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED) {
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (pFoundWindow && pFoundWindow->m_iWorkspaceID != SPECIAL_WORKSPACE_ID) {
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
}
|
||||
} else {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (!(pFoundWindow && pFoundWindow->m_bIsFloating && pFoundWindow->m_bCreatedOverFullscreen))
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
}
|
||||
} else
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (pFoundWindow) {
|
||||
@ -183,6 +202,12 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
|
||||
wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
if (refocus) { // if we are forcing a refocus, and we don't find a surface, clear the kb focus too!
|
||||
g_pCompositor->focusSurface(nullptr);
|
||||
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -200,7 +225,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||
}
|
||||
|
||||
if (pFoundWindow) {
|
||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
||||
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating)) {
|
||||
// enter if change floating style
|
||||
@ -384,8 +408,8 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
Debug::log(ERR, "Keyboard had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->keyboard->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->keyboard->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&wlr_keyboard_from_input_device(keyboard)->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardDestroy.initCallback(&keyboard->events.destroy, &Events::listener_keyboardDestroy, PNEWKEYBOARD, "Keyboard");
|
||||
|
||||
if (m_pActiveKeyboard)
|
||||
@ -394,7 +418,7 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
|
||||
applyConfigToKeyboard(PNEWKEYBOARD);
|
||||
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, keyboard->keyboard);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(keyboard));
|
||||
|
||||
Debug::log(LOG, "New keyboard created, pointers Hypr: %x and WLR: %x", PNEWKEYBOARD, keyboard);
|
||||
}
|
||||
@ -409,6 +433,9 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
|
||||
ASSERT(pKeyboard);
|
||||
|
||||
if (!wlr_keyboard_from_input_device(pKeyboard->keyboard))
|
||||
return;
|
||||
|
||||
const auto REPEATRATE = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_rate") : g_pConfigManager->getInt("input:repeat_rate");
|
||||
const auto REPEATDELAY = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_delay") : g_pConfigManager->getInt("input:repeat_delay");
|
||||
|
||||
@ -421,7 +448,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_options") : g_pConfigManager->getString("input:kb_options");
|
||||
|
||||
try {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == std::string(pKeyboard->currentRules.rules) && MODEL == std::string(pKeyboard->currentRules.model) && LAYOUT == std::string(pKeyboard->currentRules.layout) && VARIANT == std::string(pKeyboard->currentRules.variant) && OPTIONS == std::string(pKeyboard->currentRules.options)) {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options) {
|
||||
Debug::log(LOG, "Not applying config to keyboard, it did not change.");
|
||||
return;
|
||||
}
|
||||
@ -430,7 +457,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
// we can ignore those and just apply
|
||||
}
|
||||
|
||||
wlr_keyboard_set_repeat_info(pKeyboard->keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
wlr_keyboard_set_repeat_info(wlr_keyboard_from_input_device(pKeyboard->keyboard), std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
|
||||
pKeyboard->repeatDelay = REPEATDELAY;
|
||||
pKeyboard->repeatRate = REPEATRATE;
|
||||
@ -443,7 +470,11 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
.variant = VARIANT.c_str(),
|
||||
.options = OPTIONS.c_str()};
|
||||
|
||||
pKeyboard->currentRules = rules;
|
||||
pKeyboard->currentRules.rules = RULES;
|
||||
pKeyboard->currentRules.model = MODEL;
|
||||
pKeyboard->currentRules.variant = VARIANT;
|
||||
pKeyboard->currentRules.options = OPTIONS;
|
||||
pKeyboard->currentRules.layout = LAYOUT;
|
||||
|
||||
const auto CONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
@ -460,12 +491,16 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
Debug::log(ERR, "Keyboard layout %s with variant %s (rules: %s, model: %s, options: %s) couldn't have been loaded.", rules.layout, rules.variant, rules.rules, rules.model, rules.options);
|
||||
memset(&rules, 0, sizeof(rules));
|
||||
|
||||
pKeyboard->currentRules = rules;
|
||||
pKeyboard->currentRules.rules = "";
|
||||
pKeyboard->currentRules.model = "";
|
||||
pKeyboard->currentRules.variant = "";
|
||||
pKeyboard->currentRules.options = "";
|
||||
pKeyboard->currentRules.layout = "";
|
||||
|
||||
KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
wlr_keyboard_set_keymap(pKeyboard->keyboard->keyboard, KEYMAP);
|
||||
wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(pKeyboard->keyboard), KEYMAP);
|
||||
|
||||
wlr_keyboard_modifiers wlrMods = {0};
|
||||
|
||||
@ -478,7 +513,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
}
|
||||
|
||||
if (wlrMods.locked != 0) {
|
||||
wlr_keyboard_notify_modifiers(pKeyboard->keyboard->keyboard, 0, 0, wlrMods.locked, 0);
|
||||
wlr_keyboard_notify_modifiers(wlr_keyboard_from_input_device(pKeyboard->keyboard), 0, 0, wlrMods.locked, 0);
|
||||
}
|
||||
|
||||
xkb_keymap_unref(KEYMAP);
|
||||
@ -487,11 +522,12 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
Debug::log(LOG, "Set the keyboard layout to %s and variant to %s for keyboard \"%s\"", rules.layout, rules.variant, pKeyboard->keyboard->name);
|
||||
}
|
||||
|
||||
void CInputManager::newMouse(wlr_input_device* mouse) {
|
||||
void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
|
||||
m_lMice.emplace_back();
|
||||
const auto PMOUSE = &m_lMice.back();
|
||||
|
||||
PMOUSE->mouse = mouse;
|
||||
PMOUSE->virt = virt;
|
||||
try {
|
||||
PMOUSE->name = std::string(mouse->name);
|
||||
} catch(std::exception& e) {
|
||||
@ -515,6 +551,11 @@ void CInputManager::newMouse(wlr_input_device* mouse) {
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
|
||||
}
|
||||
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "drag_lock") : g_pConfigManager->getInt("input:touchpad:drag_lock")) == 0)
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
|
||||
else
|
||||
libinput_device_config_tap_set_drag_lock_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "tap-to-click") : g_pConfigManager->getInt("input:touchpad:tap-to-click")) == 1)
|
||||
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
@ -582,29 +623,31 @@ void CInputManager::onKeyboardKey(wlr_keyboard_key_event* e, SKeyboard* pKeyboar
|
||||
const auto KEYCODE = e->keycode + 8; // Because to xkbcommon it's +8 from libinput
|
||||
|
||||
const xkb_keysym_t* keysyms;
|
||||
int syms = xkb_state_key_get_syms(pKeyboard->keyboard->keyboard->xkb_state, KEYCODE, &keysyms);
|
||||
int syms = xkb_state_key_get_syms(wlr_keyboard_from_input_device(pKeyboard->keyboard)->xkb_state, KEYCODE, &keysyms);
|
||||
|
||||
const auto MODS = wlr_keyboard_get_modifiers(pKeyboard->keyboard->keyboard);
|
||||
const auto MODS = accumulateModsFromAllKBs();
|
||||
|
||||
wlr_idle_notify_activity(g_pCompositor->m_sWLRIdle, g_pCompositor->m_sSeat.seat);
|
||||
|
||||
bool found = false;
|
||||
if (e->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
for (int i = 0; i < syms; ++i)
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i]) || found;
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, keysyms[i], 0) || found;
|
||||
|
||||
found = g_pKeybindManager->handleKeybinds(MODS, 0, KEYCODE) || found;
|
||||
} else if (e->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
// hee hee
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard->keyboard);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_key(g_pCompositor->m_sSeat.seat, e->time_msec, e->keycode, e->state);
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onKeyboardMod(void* data, SKeyboard* pKeyboard) {
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, pKeyboard->keyboard->keyboard);
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &pKeyboard->keyboard->keyboard->modifiers);
|
||||
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, wlr_keyboard_from_input_device(pKeyboard->keyboard));
|
||||
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlr_keyboard_from_input_device(pKeyboard->keyboard)->modifiers);
|
||||
}
|
||||
|
||||
void CInputManager::refocus() {
|
||||
@ -722,4 +765,15 @@ void CInputManager::updateCapabilities(wlr_input_device* pDev) {
|
||||
}
|
||||
|
||||
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, m_uiCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CInputManager::accumulateModsFromAllKBs() {
|
||||
|
||||
uint32_t finalMask = 0;
|
||||
|
||||
for (auto& kb : m_lKeyboards) {
|
||||
finalMask |= wlr_keyboard_get_modifiers(wlr_keyboard_from_input_device(kb.keyboard));
|
||||
}
|
||||
|
||||
return finalMask;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
void onKeyboardMod(void*, SKeyboard*);
|
||||
|
||||
void newKeyboard(wlr_input_device*);
|
||||
void newMouse(wlr_input_device*);
|
||||
void newMouse(wlr_input_device*, bool virt = false);
|
||||
void destroyKeyboard(SKeyboard*);
|
||||
void destroyMouse(wlr_input_device*);
|
||||
|
||||
@ -57,9 +57,20 @@ public:
|
||||
std::list<STabletTool> m_lTabletTools;
|
||||
std::list<STabletPad> m_lTabletPads;
|
||||
|
||||
// idle inhibitors
|
||||
std::list<SIdleInhibitor> m_lIdleInhibitors;
|
||||
|
||||
void newTabletTool(wlr_input_device*);
|
||||
void newTabletPad(wlr_input_device*);
|
||||
void focusTablet(STablet*, wlr_tablet_tool*, bool motion = false);
|
||||
void newIdleInhibitor(wlr_idle_inhibitor_v1*);
|
||||
void recheckIdleInhibitorStatus();
|
||||
|
||||
void onSwipeBegin(wlr_pointer_swipe_begin_event*);
|
||||
void onSwipeEnd(wlr_pointer_swipe_end_event*);
|
||||
void onSwipeUpdate(wlr_pointer_swipe_update_event*);
|
||||
|
||||
SSwipeGesture m_sActiveSwipe;
|
||||
|
||||
SKeyboard* m_pActiveKeyboard = nullptr;
|
||||
|
||||
@ -81,6 +92,9 @@ private:
|
||||
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
||||
|
||||
void applyConfigToKeyboard(SKeyboard*);
|
||||
|
||||
// for shared mods
|
||||
uint32_t accumulateModsFromAllKBs();
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
152
src/managers/input/Swipe.cpp
Normal file
152
src/managers/input/Swipe.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
void CInputManager::onSwipeBegin(wlr_pointer_swipe_begin_event* e) {
|
||||
|
||||
static auto *const PSWIPE = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe")->intValue;
|
||||
|
||||
if (e->fingers < 3 || *PSWIPE == 0)
|
||||
return;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(g_pCompositor->m_pLastMonitor->activeWorkspace);
|
||||
|
||||
Debug::log(LOG, "Starting a swipe from %s", PWORKSPACE->m_szName.c_str());
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin = PWORKSPACE;
|
||||
m_sActiveSwipe.delta = 0;
|
||||
m_sActiveSwipe.pMonitor = g_pCompositor->m_pLastMonitor;
|
||||
m_sActiveSwipe.avgSpeed = 0;
|
||||
m_sActiveSwipe.speedPoints = 0;
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeEnd(wlr_pointer_swipe_end_event* e) {
|
||||
|
||||
if (!m_sActiveSwipe.pWorkspaceBegin)
|
||||
return; // no valid swipe
|
||||
|
||||
static auto *const PSWIPEPERC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_cancel_ratio")->floatValue;
|
||||
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
|
||||
static auto *const PSWIPEFORC = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_min_speed_to_force")->intValue;
|
||||
|
||||
// commit
|
||||
std::string wsname = "";
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
const auto RENDEROFFSETMIDDLE = m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.vec();
|
||||
|
||||
if ((abs(m_sActiveSwipe.delta) < *PSWIPEDIST * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_sActiveSwipe.avgSpeed < *PSWIPEFORC))) || abs(m_sActiveSwipe.delta) < 2) {
|
||||
// revert
|
||||
if (m_sActiveSwipe.delta < 0) {
|
||||
// to left
|
||||
PWORKSPACEL->m_vRenderOffset = Vector2D({-m_sActiveSwipe.pMonitor->vecSize.x, 0});
|
||||
} else {
|
||||
// to right
|
||||
PWORKSPACER->m_vRenderOffset = Vector2D({m_sActiveSwipe.pMonitor->vecSize.x, 0});
|
||||
}
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset = Vector2D();
|
||||
} else if (m_sActiveSwipe.delta < 0) {
|
||||
// switch to left
|
||||
const auto RENDEROFFSET = PWORKSPACEL->m_vRenderOffset.vec();
|
||||
|
||||
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDLeft));
|
||||
|
||||
PWORKSPACEL->m_vRenderOffset.setValue(RENDEROFFSET);
|
||||
PWORKSPACEL->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the left");
|
||||
} else {
|
||||
// switch to right
|
||||
const auto RENDEROFFSET = PWORKSPACER->m_vRenderOffset.vec();
|
||||
|
||||
g_pKeybindManager->m_mDispatchers["workspace"]("[internal]" + std::to_string(workspaceIDRight));
|
||||
|
||||
PWORKSPACER->m_vRenderOffset.setValue(RENDEROFFSET);
|
||||
PWORKSPACER->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the right");
|
||||
}
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValue(RENDEROFFSETMIDDLE);
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
PWORKSPACER->m_bForceRendering = false;
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_bForceRendering = false;
|
||||
|
||||
m_sActiveSwipe.pWorkspaceBegin = nullptr;
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeUpdate(wlr_pointer_swipe_update_event* e) {
|
||||
if (!m_sActiveSwipe.pWorkspaceBegin)
|
||||
return;
|
||||
|
||||
static auto *const PSWIPEDIST = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_distance")->intValue;
|
||||
static auto *const PSWIPEINVR = &g_pConfigManager->getConfigValuePtr("gestures:workspace_swipe_invert")->intValue;
|
||||
|
||||
m_sActiveSwipe.delta += *PSWIPEINVR ? -e->dx : e->dx;
|
||||
|
||||
m_sActiveSwipe.avgSpeed = (m_sActiveSwipe.avgSpeed * m_sActiveSwipe.speedPoints + abs(e->dx)) / (m_sActiveSwipe.speedPoints + 1);
|
||||
m_sActiveSwipe.speedPoints++;
|
||||
|
||||
std::string wsname = "";
|
||||
auto workspaceIDLeft = getWorkspaceIDFromString("m-1", wsname);
|
||||
auto workspaceIDRight = getWorkspaceIDFromString("m+1", wsname);
|
||||
|
||||
if (workspaceIDLeft == INT_MAX || workspaceIDRight == INT_MAX || workspaceIDLeft == m_sActiveSwipe.pWorkspaceBegin->m_iID)
|
||||
return;
|
||||
|
||||
m_sActiveSwipe.delta = std::clamp(m_sActiveSwipe.delta, (double)-*PSWIPEDIST, (double)*PSWIPEDIST);
|
||||
|
||||
if (m_sActiveSwipe.delta < 0) {
|
||||
if (workspaceIDLeft > m_sActiveSwipe.pWorkspaceBegin->m_iID){
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
PWORKSPACE->m_bForceRendering = true;
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight) {
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
PWORKSPACER->m_bForceRendering = false;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x - m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDLeft);
|
||||
} else {
|
||||
if (workspaceIDRight < m_sActiveSwipe.pWorkspaceBegin->m_iID){
|
||||
m_sActiveSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
PWORKSPACE->m_bForceRendering = true;
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight) {
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
PWORKSPACEL->m_bForceRendering = false;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x + m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
m_sActiveSwipe.pWorkspaceBegin->m_vRenderOffset.setValueAndWarp(Vector2D(((- m_sActiveSwipe.delta) / *PSWIPEDIST) * m_sActiveSwipe.pMonitor->vecSize.x, 0));
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(workspaceIDRight);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_sActiveSwipe.pMonitor);
|
||||
|
||||
g_pCompositor->updateWorkspaceWindowDecos(m_sActiveSwipe.pWorkspaceBegin->m_iID);
|
||||
}
|
@ -10,7 +10,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
Debug::log(ERR, "Tablet had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWTABLET->wlrTablet = pDevice->tablet;
|
||||
PNEWTABLET->wlrTablet = wlr_tablet_from_input_device(pDevice);
|
||||
PNEWTABLET->wlrDevice = pDevice;
|
||||
PNEWTABLET->wlrTabletV2 = wlr_tablet_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||
PNEWTABLET->wlrTablet->data = PNEWTABLET;
|
||||
@ -27,7 +27,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
Debug::log(LOG, "Removed a tablet");
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Axis.initCallback(&pDevice->tablet->events.axis, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Axis.initCallback(&wlr_tablet_from_input_device(pDevice)->events.axis, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_tool_axis_event*)data;
|
||||
const auto PTAB = (STablet*)owner;
|
||||
@ -80,7 +80,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Tip.initCallback(&pDevice->tablet->events.tip, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Tip.initCallback(&wlr_tablet_from_input_device(pDevice)->events.tip, [](void* owner, void* data) {
|
||||
const auto EVENT = (wlr_tablet_tool_tip_event*)data;
|
||||
const auto PTAB = (STablet*)owner;
|
||||
|
||||
@ -98,7 +98,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Button.initCallback(&pDevice->tablet->events.button, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Button.initCallback(&wlr_tablet_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
|
||||
const auto EVENT = (wlr_tablet_tool_button_event*)data;
|
||||
|
||||
const auto PTOOL = g_pInputManager->ensureTabletToolPresent(EVENT->tool);
|
||||
@ -107,7 +107,7 @@ void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWTABLET, "Tablet");
|
||||
|
||||
PNEWTABLET->hyprListener_Proximity.initCallback(&pDevice->tablet->events.proximity, [](void* owner, void* data) {
|
||||
PNEWTABLET->hyprListener_Proximity.initCallback(&wlr_tablet_from_input_device(pDevice)->events.proximity, [](void* owner, void* data) {
|
||||
const auto EVENT = (wlr_tablet_tool_proximity_event*)data;
|
||||
const auto PTAB = (STablet*)owner;
|
||||
|
||||
@ -165,7 +165,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
PNEWPAD->wlrTabletPadV2 = wlr_tablet_pad_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||
|
||||
PNEWPAD->hyprListener_Button.initCallback(&pDevice->tablet_pad->events.button, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Button.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.button, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_pad_button_event*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
@ -175,7 +175,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWPAD, "Tablet Pad");
|
||||
|
||||
PNEWPAD->hyprListener_Strip.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Strip.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_pad_strip_event*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
@ -184,7 +184,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWPAD, "Tablet Pad");
|
||||
|
||||
PNEWPAD->hyprListener_Ring.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Ring.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
|
||||
|
||||
const auto EVENT = (wlr_tablet_pad_ring_event*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
@ -193,7 +193,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
|
||||
}, PNEWPAD, "Tablet Pad");
|
||||
|
||||
PNEWPAD->hyprListener_Attach.initCallback(&pDevice->tablet_pad->events.strip, [](void* owner, void* data) {
|
||||
PNEWPAD->hyprListener_Attach.initCallback(&wlr_tablet_pad_from_input_device(pDevice)->events.strip, [](void* owner, void* data) {
|
||||
|
||||
const auto TABLET = (wlr_tablet_tool*)data;
|
||||
const auto PPAD = (STabletPad*)owner;
|
||||
|
@ -2,15 +2,14 @@
|
||||
#include "OpenGL.hpp"
|
||||
|
||||
bool CFramebuffer::alloc(int w, int h) {
|
||||
bool firstAlloc = false;
|
||||
if (m_iFb == (uint32_t)-1)
|
||||
{
|
||||
bool firstAlloc = false;
|
||||
|
||||
if (m_iFb == (uint32_t)-1) {
|
||||
firstAlloc = true;
|
||||
glGenFramebuffers(1, &m_iFb);
|
||||
}
|
||||
|
||||
if (m_cTex.m_iTexID == 0)
|
||||
{
|
||||
if (m_cTex.m_iTexID == 0) {
|
||||
firstAlloc = true;
|
||||
glGenTextures(1, &m_cTex.m_iTexID);
|
||||
glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID);
|
||||
@ -20,13 +19,11 @@ bool CFramebuffer::alloc(int w, int h) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
if (firstAlloc || m_Size != Vector2D(w, h))
|
||||
{
|
||||
if (firstAlloc || m_Size != Vector2D(w, h)) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
|
||||
glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_cTex.m_iTexID, 0);
|
||||
|
||||
|
||||
@ -37,7 +34,6 @@ bool CFramebuffer::alloc(int w, int h) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iFb);
|
||||
glBindTexture(GL_TEXTURE_2D, m_pStencilTex->m_iTexID);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_pStencilTex->m_iTexID, 0);
|
||||
}
|
||||
@ -78,3 +74,7 @@ void CFramebuffer::release() {
|
||||
m_cTex.m_iTexID = 0;
|
||||
m_iFb = -1;
|
||||
}
|
||||
|
||||
CFramebuffer::~CFramebuffer() {
|
||||
release();
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
class CFramebuffer {
|
||||
public:
|
||||
|
||||
~CFramebuffer();
|
||||
|
||||
bool alloc(int w, int h);
|
||||
void bind();
|
||||
void release();
|
||||
|
@ -311,21 +311,21 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round) {
|
||||
void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round, bool allowCustomUV) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTexture(CTexture(tex), pBox, alpha, round);
|
||||
renderTexture(CTexture(tex), pBox, alpha, round, false, allowCustomUV);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowPrimary) {
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowCustomUV) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowPrimary);
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowCustomUV);
|
||||
|
||||
scissor((wlr_box*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowPrimary) {
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowCustomUV) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
||||
@ -388,7 +388,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
if (allowPrimary && m_RenderData.renderingPrimarySurface && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||
if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) {
|
||||
const float verts[] = {
|
||||
m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right
|
||||
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVTopLeft.y, // top left
|
||||
@ -702,8 +702,6 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
clear(CColor(0,0,0,0)); // JIC
|
||||
|
||||
timespec now;
|
||||
@ -717,7 +715,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
|
||||
g_pConfigManager->setInt("decoration:blur", 0);
|
||||
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders);
|
||||
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
|
||||
|
||||
g_pConfigManager->setInt("decoration:blur", BLURVAL);
|
||||
|
||||
@ -742,9 +740,10 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
#else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb);
|
||||
#endif
|
||||
|
||||
end();
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
}
|
||||
|
||||
@ -762,8 +761,6 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
|
||||
begin(PMONITOR, &fakeDamage, true);
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer];
|
||||
|
||||
glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y);
|
||||
@ -792,6 +789,8 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
|
||||
|
||||
end();
|
||||
|
||||
pixman_region32_fini(&fakeDamage);
|
||||
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
}
|
||||
|
||||
@ -915,9 +914,28 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) {
|
||||
cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
||||
|
||||
const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
|
||||
cairo_set_font_size(CAIRO, FONTSIZE);
|
||||
|
||||
cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f);
|
||||
|
||||
cairo_text_extents_t textExtents;
|
||||
cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
|
||||
|
||||
cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1);
|
||||
cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
|
||||
|
||||
cairo_surface_flush(CAIROSURFACE);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
|
||||
|
||||
static auto *const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue;
|
||||
|
||||
// release the last tex if exists
|
||||
const auto PTEX = &m_mMonitorBGTextures[pMonitor];
|
||||
PTEX->destroyTexture();
|
||||
@ -926,6 +944,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
|
||||
Debug::log(LOG, "Allocated texture for BGTex");
|
||||
|
||||
// TODO: use relative paths to the installation
|
||||
// or configure the paths at build time
|
||||
|
||||
// check if wallpapers exist
|
||||
if (!std::filesystem::exists("/usr/share/hyprland/wall_8K.png"))
|
||||
return; // the texture will be empty, oh well. We'll clear with a solid color anyways.
|
||||
@ -949,6 +970,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROSURFACE);
|
||||
|
||||
if (!*PNOSPLASH)
|
||||
renderSplash(CAIRO, CAIROSURFACE);
|
||||
|
||||
// copy the data to an OpenGL texture we have
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
||||
glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID);
|
||||
@ -969,9 +993,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||
void CHyprOpenGLImpl::clearWithTex() {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!");
|
||||
|
||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
|
||||
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||
if (!*PRENDERTEX) {
|
||||
wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
|
||||
renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::destroyMonitorResources(SMonitor* pMonitor) {
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
#include "Shaders.hpp"
|
||||
#include "Shader.hpp"
|
||||
#include "Texture.hpp"
|
||||
@ -45,7 +47,6 @@ struct SCurrentRenderData {
|
||||
|
||||
pixman_region32_t* pDamage = nullptr;
|
||||
|
||||
bool renderingPrimarySurface = false;
|
||||
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
};
|
||||
@ -60,8 +61,8 @@ public:
|
||||
|
||||
void renderRect(wlr_box*, const CColor&, int round = 0);
|
||||
void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0);
|
||||
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
|
||||
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowPrimary = false);
|
||||
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false);
|
||||
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowCustomUV = false);
|
||||
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0);
|
||||
void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0);
|
||||
void renderBorder(wlr_box*, const CColor&, int round);
|
||||
@ -121,7 +122,9 @@ private:
|
||||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowPrimary = false);
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false);
|
||||
|
||||
void renderSplash(cairo_t *const, cairo_surface_t *const);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
@ -12,22 +12,30 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY);
|
||||
|
||||
wlr_box windowBox;
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
if (RDATA->surface && surface == RDATA->surface)
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h};
|
||||
} else { // here we clamp to 2, these might be some tiny specks
|
||||
else // here we clamp to 2, these might be some tiny specks
|
||||
windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)};
|
||||
|
||||
// squish all oversized
|
||||
if (RDATA->squishOversized) {
|
||||
if (x + windowBox.width > RDATA->w)
|
||||
windowBox.width = RDATA->w - x;
|
||||
if (y + windowBox.height > RDATA->h)
|
||||
windowBox.height = RDATA->h - y;
|
||||
}
|
||||
|
||||
scaleBox(&windowBox, RDATA->output->scale);
|
||||
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
|
||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = false;
|
||||
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = true;
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
if (RDATA->blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
|
||||
if (RDATA->decorate) {
|
||||
auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col();
|
||||
@ -35,8 +43,18 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, col, rounding);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false);
|
||||
else {
|
||||
if (RDATA->surface && wlr_surface_is_xdg_surface(RDATA->surface)) {
|
||||
wlr_box geo;
|
||||
wlr_xdg_surface_get_geometry(wlr_xdg_surface_from_wlr_surface(RDATA->surface), &geo);
|
||||
|
||||
windowBox.x -= geo.x;
|
||||
windowBox.y -= geo.y;
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false);
|
||||
}
|
||||
|
||||
|
||||
wlr_surface_send_frame_done(surface, RDATA->when);
|
||||
|
||||
@ -54,8 +72,8 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) {
|
||||
return true;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
// if not, check if it maybe is active on a different monitor. vvv might be animation in progress
|
||||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated())))
|
||||
return true;
|
||||
|
||||
if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
@ -93,7 +111,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
continue;
|
||||
|
||||
// found it!
|
||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL);
|
||||
|
||||
pWorkspaceWindow = w.get();
|
||||
}
|
||||
@ -103,7 +121,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
renderWindow(w.get(), pMonitor, time, true);
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and then special windows
|
||||
@ -118,7 +136,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), pMonitor, time, true);
|
||||
renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and the overlay layers
|
||||
@ -140,7 +158,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) {
|
||||
void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) {
|
||||
if (pWindow->m_bHidden)
|
||||
return;
|
||||
|
||||
@ -160,9 +178,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes
|
||||
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
|
||||
renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity");
|
||||
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||
renderdata.blur = true; // if it shouldn't, it will be ignored later
|
||||
renderdata.squishOversized = pWindow->m_vRealPosition.isBeingAnimated();
|
||||
|
||||
// apply window special data
|
||||
if (pWindow->m_sSpecialRenderData.alphaInactive == -1)
|
||||
@ -173,37 +193,40 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
|
||||
|
||||
// render window decorations first, if not fullscreen full
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) {
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
|
||||
// To everyone who makes apps with improperly aligned surfaces,
|
||||
// For example chromium, or GTK devs who allow shadows on windows,
|
||||
// a sincere FUCK YOU.
|
||||
if (!pWindow->m_bIsX11) {
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
|
||||
wlr_box geom;
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height);
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) {
|
||||
// No special UV mods needed
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
} else {
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
}
|
||||
|
||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
renderdata.dontRound = false; // restore dontround
|
||||
renderdata.pMonitor = pMonitor;
|
||||
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
|
||||
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {
|
||||
if (!pWindow->m_bIsX11) {
|
||||
renderdata.dontRound = false; // restore dontround
|
||||
renderdata.pMonitor = pMonitor;
|
||||
wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata);
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = nullptr;
|
||||
@ -217,6 +240,11 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, times
|
||||
|
||||
SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
|
||||
renderdata.fadeAlpha = pLayer->alpha.fl();
|
||||
renderdata.blur = pLayer->forceBlur;
|
||||
renderdata.surface = pLayer->layerSurface->surface;
|
||||
renderdata.decorate = false;
|
||||
renderdata.w = pLayer->layerSurface->surface->current.width;
|
||||
renderdata.h = pLayer->layerSurface->surface->current.height;
|
||||
wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
|
||||
}
|
||||
|
||||
@ -243,7 +271,25 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Non-floating
|
||||
// Non-floating main
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w->m_bIsFloating)
|
||||
continue; // floating are in the second pass
|
||||
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
continue; // special are in the third pass
|
||||
|
||||
if (!shouldRenderWindow(w.get(), PMONITOR))
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_MAIN);
|
||||
}
|
||||
|
||||
// Non-floating popup
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
@ -258,7 +304,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_POPUP);
|
||||
}
|
||||
|
||||
// floating on top
|
||||
@ -276,7 +322,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// and then special
|
||||
@ -291,7 +337,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL);
|
||||
}
|
||||
|
||||
// Render surfaces above windows for monitor
|
||||
@ -428,7 +474,7 @@ void CHyprRenderer::arrangeLayerArray(SMonitor* pMonitor, const std::list<SLayer
|
||||
wlr_box full_area = {pMonitor->vecPosition.x, pMonitor->vecPosition.y, pMonitor->vecSize.x, pMonitor->vecSize.y};
|
||||
|
||||
for (auto& ls : layerSurfaces) {
|
||||
if (ls->fadingOut || ls->readyToDelete)
|
||||
if (ls->fadingOut || ls->readyToDelete || !ls->layerSurface)
|
||||
continue;
|
||||
|
||||
const auto PLAYER = ls->layerSurface;
|
||||
@ -551,6 +597,11 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
||||
pixman_region32_init(&damageBox);
|
||||
wlr_surface_get_effective_damage(pSurface, &damageBox);
|
||||
|
||||
// schedule frame events
|
||||
if (!wl_list_empty(&pSurface->current.frame_callback_list)) {
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)));
|
||||
}
|
||||
|
||||
if (!pixman_region32_not_empty(&damageBox)) {
|
||||
pixman_region32_fini(&damageBox);
|
||||
return;
|
||||
@ -799,4 +850,4 @@ void CHyprRenderer::ensureCursorRenderingMode() {
|
||||
|
||||
bool CHyprRenderer::shouldRenderCursor() {
|
||||
return m_bHasARenderedCursor;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,12 @@ enum DAMAGETRACKINGMODES {
|
||||
DAMAGE_TRACKING_FULL
|
||||
};
|
||||
|
||||
enum eRenderPassMode {
|
||||
RENDER_PASS_ALL = 0,
|
||||
RENDER_PASS_MAIN,
|
||||
RENDER_PASS_POPUP
|
||||
};
|
||||
|
||||
class CHyprRenderer {
|
||||
public:
|
||||
|
||||
@ -41,7 +47,7 @@ public:
|
||||
private:
|
||||
void arrangeLayerArray(SMonitor*, const std::list<SLayerSurface*>&, bool, wlr_box*);
|
||||
void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*);
|
||||
void renderWindow(CWindow*, SMonitor*, timespec*, bool);
|
||||
void renderWindow(CWindow*, SMonitor*, timespec*, bool, eRenderPassMode);
|
||||
void renderLayer(SLayerSurface*, SMonitor*, timespec*);
|
||||
void renderDragIcon(SMonitor*, timespec*);
|
||||
|
||||
|
@ -40,12 +40,8 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
if (g_pLayoutManager->getCurrentLayout()->getLayoutName() != "dwindle") {
|
||||
// ????
|
||||
for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
|
||||
if (it->get() == this) {
|
||||
pWindow->m_dWindowDecorations.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_pWindow->m_vDecosToRemove.push_back(this);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the group info
|
||||
@ -58,12 +54,8 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
|
||||
if (m_dwGroupMembers.size() == 0) {
|
||||
// remove
|
||||
for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) {
|
||||
if (it->get() == this) {
|
||||
pWindow->m_dWindowDecorations.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_pWindow->m_vDecosToRemove.push_back(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5c4384a1330faedf975c8b8644881d50390f3613
|
||||
Subproject commit b89ed9015c3fbe8d339e9d65cf70fdca6e5645bc
|
Loading…
Reference in New Issue
Block a user