mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-10 07:45:59 +01:00
Merge branch 'hyprwm:main' into main
This commit is contained in:
commit
be460ea954
41 changed files with 655 additions and 410 deletions
48
.github/workflows/ci.yaml
vendored
48
.github/workflows/ci.yaml
vendored
|
@ -13,34 +13,44 @@ jobs:
|
||||||
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
|
||||||
pacman --noconfirm --noprogressbar -Syyu
|
pacman --noconfirm --noprogressbar -Syyu
|
||||||
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers xcb-util-errors xcb-util-renderutil xcb-util-wm xorg-fonts-encodings xorg-server-common xorg-setxkbmap xorg-xkbcomp xorg-xwayland git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd
|
pacman --noconfirm --noprogressbar -Sy glslang libepoxy libfontenc libxcvt libxfont2 libxkbfile vulkan-headers vulkan-validation-layers xcb-util-errors xcb-util-renderutil xcb-util-wm xorg-fonts-encodings xorg-server-common xorg-setxkbmap xorg-xkbcomp xorg-xwayland git cmake go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd
|
||||||
|
|
||||||
- name: Set up user
|
- name: Set up user
|
||||||
run: |
|
run: |
|
||||||
useradd -m githubuser
|
useradd -m githubuser
|
||||||
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
|
||||||
|
|
||||||
- name: Build wlroots
|
- name: Build wlroots
|
||||||
run: |
|
run: |
|
||||||
su githubuser -c "cd ~ && git clone https://gitlab.freedesktop.org/wlroots/wlroots"
|
su githubuser -c "cd ~ && git clone https://gitlab.freedesktop.org/wlroots/wlroots"
|
||||||
su githubuser -c "cd ~/wlroots && meson build/ --prefix=/usr && ninja -C build/ && sudo ninja -C build/ install && cd .."
|
su githubuser -c "cd ~/wlroots && meson build/ --prefix=/usr && ninja -C build/ && sudo ninja -C build/ install && cd .."
|
||||||
|
|
||||||
- name: Fix permissions for git
|
- name: Fix permissions for git
|
||||||
run: |
|
run: |
|
||||||
git config --global --add safe.directory /__w/Hyprland/Hyprland
|
git config --global --add safe.directory /__w/Hyprland/Hyprland
|
||||||
|
|
||||||
- name: Checkout Hyprland
|
- name: Checkout Hyprland
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
- name: Build Hyprland
|
||||||
- name: Build Hyprland With default settings
|
|
||||||
run: |
|
run: |
|
||||||
git submodule sync --recursive && git submodule update --init --force --recursive
|
git submodule sync --recursive && git submodule update --init --force --recursive
|
||||||
make all
|
make all
|
||||||
|
- name: Compress and package artifacts
|
||||||
- name: Build Hyprland with LEGACY_RENDERER
|
|
||||||
run: |
|
run: |
|
||||||
make legacyrenderer
|
mkdir x86_64-pc-linux-gnu
|
||||||
|
mkdir hyprland
|
||||||
|
mkdir hyprland/example
|
||||||
|
mkdir hyprland/assets
|
||||||
|
cp ./LICENSE hyprland/
|
||||||
|
cp build/Hyprland hyprland/
|
||||||
|
cp hyprctl/hyprctl hyprland/
|
||||||
|
cp subprojects/wlroots/build/libwlroots.so.11032 hyprland/
|
||||||
|
cp build/Hyprland hyprland/
|
||||||
|
cp -r example/ hyprland/
|
||||||
|
cp -r assets/ hyprland/
|
||||||
|
tar -cvf Hyprland.tar.xz hyprland
|
||||||
|
- name: Release
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: Build archive
|
||||||
|
path: Hyprland.tar.xz
|
||||||
|
|
||||||
meson:
|
meson:
|
||||||
name: "Build Hyprland with Meson (Arch)"
|
name: "Build Hyprland with Meson (Arch)"
|
||||||
|
@ -63,13 +73,13 @@ jobs:
|
||||||
-Ddefault_library=static
|
-Ddefault_library=static
|
||||||
- name: Compile
|
- name: Compile
|
||||||
run: ninja -C obj-x86_64-pc-linux-gnu
|
run: ninja -C obj-x86_64-pc-linux-gnu
|
||||||
- name: Compress artifacts
|
# - name: Compress artifacts
|
||||||
run: |
|
# run: |
|
||||||
mkdir x86_64-pc-linux-gnu
|
# mkdir x86_64-pc-linux-gnu
|
||||||
DESTDIR=$PWD/x86_64-pc-linux-gnu meson install -C obj-x86_64-pc-linux-gnu --tags runtime
|
# DESTDIR=$PWD/x86_64-pc-linux-gnu meson install -C obj-x86_64-pc-linux-gnu --tags runtime
|
||||||
tar -cvf x86_64-pc-linux-gnu.tar.xz x86_64-pc-linux-gnu
|
# tar -cvf x86_64-pc-linux-gnu.tar.xz x86_64-pc-linux-gnu
|
||||||
- name: Upload artifacts
|
# - name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v3
|
# uses: actions/upload-artifact@v3
|
||||||
with:
|
# with:
|
||||||
name: Build artifacts (x86_64-pc-linux-gnu)
|
# name: Build artifacts (x86_64-pc-linux-gnu)
|
||||||
path: x86_64-pc-linux-gnu.tar.xz
|
# path: x86_64-pc-linux-gnu.tar.xz
|
||||||
|
|
26
.github/workflows/version-update.sh
vendored
Normal file
26
.github/workflows/version-update.sh
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
name: "Nix & Meson: update version"
|
||||||
|
|
||||||
|
on: [push, workflow_dispatch]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Update flake and meson version
|
||||||
|
run: |
|
||||||
|
REGEX="([0-9]+(\.[0-9a-zA-Z]+)+)"
|
||||||
|
|
||||||
|
CRT_REV=$(git show-ref --tags --head --abbrev | head -n 1 | head -c 7)
|
||||||
|
TAG_REV=$(git show-ref --tags --abbrev | tail -n 1 | head -c 7)
|
||||||
|
CRT_VER=$(sed -nEe "/$REGEX/{p;q;}" meson.build | awk -F\' '{print $2}')
|
||||||
|
VERSION=$(git show-ref --tags --abbrev | tail -n 1 | tail -c +20)
|
||||||
|
|
||||||
|
if [[ $TAG_REV = $CRT_REV ]] || [[ $CRT_VER != $VERSION ]]; then
|
||||||
|
sed -Ei "s/$REGEX/$VERSION/g" meson.build
|
||||||
|
sed -Ei "s/$REGEX/$VERSION/g" flake.nix
|
||||||
|
fi
|
||||||
|
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
with:
|
||||||
|
commit_message: "[gha] bump flake and meson version"
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,3 +1,3 @@
|
||||||
[submodule "wlroots"]
|
[submodule "wlroots"]
|
||||||
path = subprojects/wlroots
|
path = subprojects/wlroots
|
||||||
url = https://github.com/ThatOneCalculator/wlroots-mirror
|
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
|
|
|
@ -59,6 +59,7 @@ ENDIF(NO_XWAYLAND MATCHES true)
|
||||||
|
|
||||||
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||||
message(STATUS "Configuring Hyprland in Debug with CMake!")
|
message(STATUS "Configuring Hyprland in Debug with CMake!")
|
||||||
|
add_definitions( -DHYPRLAND_DEBUG )
|
||||||
ELSE()
|
ELSE()
|
||||||
# add_compile_options(-O3) # may crash for some
|
# add_compile_options(-O3) # may crash for some
|
||||||
message(STATUS "Configuring Hyprland in Release with CMake!")
|
message(STATUS "Configuring Hyprland in Release with CMake!")
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -136,4 +136,4 @@ config:
|
||||||
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=release
|
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=release
|
||||||
cd subprojects/wlroots && ninja -C build/
|
cd subprojects/wlroots && ninja -C build/
|
||||||
|
|
||||||
cd subprojects/wlroots && sudo ninja -C build/ install
|
cd subprojects/wlroots && ninja -C build/ install
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div align = center>
|
<div align = center>
|
||||||
|
|
||||||
![Banner]
|
<img src="https://raw.githubusercontent.com/vaxerski/Hyprland/main/assets/header.svg" width="1000" height="500" alt="banner">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@ -151,7 +151,6 @@ Try it out and report bugs / suggestions!
|
||||||
[Preview A]: https://i.imgur.com/NbrTnZH.png
|
[Preview A]: https://i.imgur.com/NbrTnZH.png
|
||||||
[Preview B]: https://i.imgur.com/ZA4Fa8R.png
|
[Preview B]: https://i.imgur.com/ZA4Fa8R.png
|
||||||
[Preview C]: https://i.imgur.com/BpXxM8H.png
|
[Preview C]: https://i.imgur.com/BpXxM8H.png
|
||||||
[Banner]: https://raw.githubusercontent.com/vaxerski/Hyprland/main/assets/hyprland.png
|
|
||||||
|
|
||||||
|
|
||||||
<!----------------------------------{ Badges }--------------------------------->
|
<!----------------------------------{ Badges }--------------------------------->
|
||||||
|
|
83
assets/header.svg
Normal file
83
assets/header.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 798 KiB |
72
aur/PKGBUILD
72
aur/PKGBUILD
|
@ -1,72 +0,0 @@
|
||||||
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>
|
|
||||||
|
|
||||||
_pkgname="hyprland"
|
|
||||||
pkgname="${_pkgname}"
|
|
||||||
pkgver="0.4.0beta"
|
|
||||||
pkgrel=2
|
|
||||||
pkgdesc="A dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
|
||||||
arch=(any)
|
|
||||||
url="https://github.com/vaxerski/Hyprland"
|
|
||||||
license=('BSD')
|
|
||||||
depends=(
|
|
||||||
libxcb
|
|
||||||
xcb-proto
|
|
||||||
xcb-util
|
|
||||||
xcb-util-keysyms
|
|
||||||
libxfixes
|
|
||||||
libx11
|
|
||||||
libxcomposite
|
|
||||||
xorg-xinput
|
|
||||||
libxrender
|
|
||||||
pixman
|
|
||||||
wayland-protocols
|
|
||||||
cairo
|
|
||||||
pango
|
|
||||||
polkit
|
|
||||||
glslang
|
|
||||||
libinput
|
|
||||||
libxcb
|
|
||||||
libxkbcommon
|
|
||||||
opengl-driver
|
|
||||||
pixman
|
|
||||||
wayland
|
|
||||||
xcb-util-errors
|
|
||||||
xcb-util-renderutil
|
|
||||||
xcb-util-wm
|
|
||||||
seatd
|
|
||||||
vulkan-icd-loader
|
|
||||||
vulkan-validation-layers
|
|
||||||
xorg-xwayland)
|
|
||||||
makedepends=(
|
|
||||||
git
|
|
||||||
cmake
|
|
||||||
ninja
|
|
||||||
gcc
|
|
||||||
gdb
|
|
||||||
meson
|
|
||||||
vulkan-headers
|
|
||||||
wayland-protocols
|
|
||||||
xorgproto)
|
|
||||||
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/hyprland/archive/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('5969e5f88426f90acdfb5958644733d8a9409389c2d345514c58a66cf74d2f91')
|
|
||||||
conflicts=("${_pkgname}")
|
|
||||||
provides=(hyprland)
|
|
||||||
options=(!makeflags !buildflags)
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "$srcdir/Hyprland-$pkgver"
|
|
||||||
git submodule update --init
|
|
||||||
make all
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "$srcdir/Hyprland-$pkgver"
|
|
||||||
mkdir -p "${pkgdir}/usr/share/wayland-sessions"
|
|
||||||
mkdir -p "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm755 build/Hyprland -t "${pkgdir}/usr/bin"
|
|
||||||
install -Dm755 hyprctl/hyprctl -t "${pkgdir}/usr/bin"
|
|
||||||
install -Dm644 assets/*.png -t "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm644 example/hyprland.desktop -t "${pkgdir}/usr/share/wayland-sessions"
|
|
||||||
install -Dm644 example/hyprland.conf -t "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm644 LICENSE -t "${pkgdir}/usr/share/licenses/${_pkgname}"
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>
|
|
||||||
|
|
||||||
_pkgname="hyprland"
|
|
||||||
pkgname="${_pkgname}-bin"
|
|
||||||
pkgver="0.4.0beta"
|
|
||||||
pkgrel=2
|
|
||||||
pkgdesc="A dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
|
||||||
arch=(any)
|
|
||||||
url="https://github.com/vaxerski/Hyprland"
|
|
||||||
license=('BSD')
|
|
||||||
depends=(
|
|
||||||
libxcb
|
|
||||||
xcb-proto
|
|
||||||
xcb-util
|
|
||||||
xcb-util-keysyms
|
|
||||||
libxfixes
|
|
||||||
libx11
|
|
||||||
libxcomposite
|
|
||||||
xorg-xinput
|
|
||||||
libxrender
|
|
||||||
pixman
|
|
||||||
wayland-protocols
|
|
||||||
cairo
|
|
||||||
pango
|
|
||||||
polkit
|
|
||||||
glslang
|
|
||||||
libinput
|
|
||||||
libxcb
|
|
||||||
libxkbcommon
|
|
||||||
opengl-driver
|
|
||||||
pixman
|
|
||||||
wayland
|
|
||||||
xcb-util-errors
|
|
||||||
xcb-util-renderutil
|
|
||||||
xcb-util-wm
|
|
||||||
seatd
|
|
||||||
vulkan-icd-loader
|
|
||||||
vulkan-validation-layers
|
|
||||||
xorg-xwayland)
|
|
||||||
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/Hyprland/releases/download/v${pkgver}/v${pkgver}.tar.gz")
|
|
||||||
sha256sums=('5969e5f88426f90acdfb5958644733d8a9409389c2d345514c58a66cf74d2f91')
|
|
||||||
conflicts=("${_pkgname}")
|
|
||||||
provides=(hyprland)
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "$srcdir/Hyprland-$pkgver"
|
|
||||||
mkdir -p "${pkgdir}/usr/share/wayland-sessions"
|
|
||||||
mkdir -p "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm755 ./Hyprland -t "${pkgdir}/usr/bin"
|
|
||||||
install -Dm755 ./hyprctl -t "${pkgdir}/usr/bin"
|
|
||||||
install -Dm755 ./libwlroots.so.11032 -t "${pkgdir}/usr/lib"
|
|
||||||
install -Dm644 assets/*.png -t "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm644 example/hyprland.desktop -t "${pkgdir}/usr/share/wayland-sessions"
|
|
||||||
install -Dm644 example/hyprland.conf -t "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm644 LICENSE -t "${pkgdir}/usr/share/licenses/${_pkgname}"
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>, Sander van Kasteel <info@sandervankasteel.nl>
|
|
||||||
|
|
||||||
_pkgname="hyprland"
|
|
||||||
pkgname="${_pkgname}-git"
|
|
||||||
pkgver=r673.gb62e530
|
|
||||||
pkgrel=2
|
|
||||||
pkgdesc="A dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
|
|
||||||
arch=(any)
|
|
||||||
url="https://github.com/vaxerski/Hyprland"
|
|
||||||
license=('BSD')
|
|
||||||
depends=(
|
|
||||||
libxcb
|
|
||||||
xcb-proto
|
|
||||||
xcb-util
|
|
||||||
xcb-util-keysyms
|
|
||||||
libxfixes
|
|
||||||
libx11
|
|
||||||
libxcomposite
|
|
||||||
xorg-xinput
|
|
||||||
libxrender
|
|
||||||
pixman
|
|
||||||
wayland-protocols
|
|
||||||
cairo
|
|
||||||
pango
|
|
||||||
polkit
|
|
||||||
glslang
|
|
||||||
libinput
|
|
||||||
libxcb
|
|
||||||
libxkbcommon
|
|
||||||
opengl-driver
|
|
||||||
pixman
|
|
||||||
wayland
|
|
||||||
xcb-util-errors
|
|
||||||
xcb-util-renderutil
|
|
||||||
xcb-util-wm
|
|
||||||
seatd
|
|
||||||
vulkan-icd-loader
|
|
||||||
vulkan-validation-layers
|
|
||||||
xorg-xwayland)
|
|
||||||
makedepends=(
|
|
||||||
git
|
|
||||||
cmake
|
|
||||||
ninja
|
|
||||||
gcc
|
|
||||||
gdb
|
|
||||||
meson
|
|
||||||
vulkan-headers
|
|
||||||
wayland-protocols
|
|
||||||
xorgproto)
|
|
||||||
source=("${_pkgname}::git+https://github.com/vaxerski/Hyprland.git")
|
|
||||||
conflicts=("${_pkgname}")
|
|
||||||
provides=(hyprland)
|
|
||||||
sha256sums=('SKIP')
|
|
||||||
options=(!makeflags !buildflags)
|
|
||||||
|
|
||||||
pkgver() {
|
|
||||||
cd "$_pkgname"
|
|
||||||
( set -o pipefail
|
|
||||||
git describe --long 2>/dev/null | sed 's/\([^-]*-g\)/r\1/;s/-/./g' ||
|
|
||||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
|
||||||
cd "${srcdir}/${_pkgname}"
|
|
||||||
git submodule update --init
|
|
||||||
make all
|
|
||||||
}
|
|
||||||
|
|
||||||
package() {
|
|
||||||
cd "${srcdir}/${_pkgname}"
|
|
||||||
mkdir -p "${pkgdir}/usr/share/wayland-sessions"
|
|
||||||
mkdir -p "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm755 build/Hyprland -t "${pkgdir}/usr/bin"
|
|
||||||
install -Dm755 hyprctl/hyprctl -t "${pkgdir}/usr/bin"
|
|
||||||
install -Dm644 assets/*.png -t "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm644 example/hyprland.desktop -t "${pkgdir}/usr/share/wayland-sessions"
|
|
||||||
install -Dm644 example/hyprland.conf -t "${pkgdir}/usr/share/hyprland"
|
|
||||||
install -Dm644 LICENSE -t "${pkgdir}/usr/share/licenses/${_pkgname}"
|
|
||||||
}
|
|
|
@ -27,6 +27,8 @@ general {
|
||||||
col.active_border=0x66ee1111
|
col.active_border=0x66ee1111
|
||||||
col.inactive_border=0x66333333
|
col.inactive_border=0x66333333
|
||||||
|
|
||||||
|
apply_sens_to_raw=0 # do not apply the sensitivity to raw input (e.g. used by games where you aim)
|
||||||
|
|
||||||
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
|
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1654593855,
|
"lastModified": 1655807518,
|
||||||
"narHash": "sha256-c+SyXvj7THre87OyIdZfRVR+HhI/g1ZDrQ3VUtTuHkU=",
|
"narHash": "sha256-5YV29Ry/DpAJc/0Hc/+ISVBAjwHpJvAkeKkcUG5lWsc=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "033bd4fa9a8fbe0c68a88e925d9a884161044b25",
|
"rev": "a72d7811be1162dd6804c4e36e5402d76fb6e921",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
43
flake.nix
43
flake.nix
|
@ -16,40 +16,37 @@
|
||||||
}: let
|
}: let
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
genSystems = lib.genAttrs [
|
genSystems = lib.genAttrs [
|
||||||
|
# Add more systems if they are supported
|
||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
];
|
];
|
||||||
pkgsFor = nixpkgs.legacyPackages;
|
pkgsFor = nixpkgs.legacyPackages;
|
||||||
# https://github.com/NixOS/rfcs/pull/107
|
mkDate = longDate: (lib.concatStringsSep "-" [
|
||||||
mkVersion = longDate:
|
(__substring 0 4 longDate)
|
||||||
lib.concatStrings [
|
(__substring 4 2 longDate)
|
||||||
"0.pre"
|
(__substring 6 2 longDate)
|
||||||
"+date="
|
]);
|
||||||
(lib.concatStringsSep "-" [
|
|
||||||
(__substring 0 4 longDate)
|
|
||||||
(__substring 4 2 longDate)
|
|
||||||
(__substring 6 2 longDate)
|
|
||||||
])
|
|
||||||
];
|
|
||||||
in {
|
in {
|
||||||
packages = genSystems (system: {
|
overlays.default = _: prev: rec {
|
||||||
wlroots = pkgsFor.${system}.wlroots.overrideAttrs (prev: {
|
wlroots-hyprland = prev.wlroots.overrideAttrs (__: {
|
||||||
version = mkVersion (toString (inputs.wlroots.lastModifiedDate or inputs.wlroots.lastModified or "19700101"));
|
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101");
|
||||||
src = inputs.wlroots;
|
src = inputs.wlroots;
|
||||||
});
|
});
|
||||||
default = pkgsFor.${system}.callPackage ./nix/default.nix {
|
hyprland = prev.callPackage ./nix/default.nix {
|
||||||
version = mkVersion (toString (self.lastModifiedDate or self.lastModified or "19700101"));
|
version = "0.5.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||||
inherit (self.packages.${system}) wlroots;
|
wlroots = wlroots-hyprland;
|
||||||
};
|
};
|
||||||
});
|
};
|
||||||
|
|
||||||
|
packages = genSystems (system:
|
||||||
|
(self.overlays.default null pkgsFor.${system})
|
||||||
|
// {
|
||||||
|
default = self.packages.${system}.hyprland;
|
||||||
|
});
|
||||||
|
|
||||||
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
||||||
|
|
||||||
nixosModules.default = import ./nix/module.nix self;
|
nixosModules.default = import ./nix/module.nix self;
|
||||||
|
|
||||||
# Deprecated
|
overlay = throw "Hyprland: .overlay output is deprecated, please use the .overlays.default output";
|
||||||
overlays.default = _: prev: {
|
|
||||||
hyprland = self.packages.${prev.system}.default;
|
|
||||||
};
|
|
||||||
overlay = self.overlays.default;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
project('Hyprland', 'cpp', 'c',
|
project('Hyprland', 'cpp', 'c',
|
||||||
version : '0.1',
|
version : '0.5.0beta',
|
||||||
default_options : ['warning_level=3', 'cpp_std=c++20', 'default_library=static'])
|
default_options : ['warning_level=3', 'cpp_std=c++20', 'default_library=static'])
|
||||||
|
|
||||||
wlroots = subproject('wlroots', default_options: ['examples=false'])
|
wlroots = subproject('wlroots', default_options: ['examples=false'])
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
stdenv,
|
stdenv,
|
||||||
fetchFromGitHub,
|
fetchFromGitHub,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
cmake,
|
meson,
|
||||||
ninja,
|
ninja,
|
||||||
libdrm,
|
libdrm,
|
||||||
libinput,
|
libinput,
|
||||||
|
@ -27,7 +27,7 @@ stdenv.mkDerivation {
|
||||||
src = ../.;
|
src = ../.;
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
cmake
|
meson
|
||||||
ninja
|
ninja
|
||||||
pkg-config
|
pkg-config
|
||||||
];
|
];
|
||||||
|
@ -48,33 +48,14 @@ stdenv.mkDerivation {
|
||||||
]
|
]
|
||||||
++ lib.optional enableXWayland xwayland;
|
++ lib.optional enableXWayland xwayland;
|
||||||
|
|
||||||
cmakeFlags =
|
mesonBuildType = "release";
|
||||||
["-DCMAKE_BUILD_TYPE=Release"]
|
|
||||||
++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
|
||||||
|
|
||||||
# enables building with nix-supplied wlroots instead of submodule
|
mesonFlags = lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
||||||
prePatch = ''
|
|
||||||
sed -Ei 's/"\.\.\/wlroots\/include\/([a-zA-Z0-9./_-]+)"/<\1>/g' src/includes.hpp
|
|
||||||
'';
|
|
||||||
postPatch = ''
|
|
||||||
make protocols
|
|
||||||
'';
|
|
||||||
|
|
||||||
postBuild = ''
|
patches = [
|
||||||
pushd ../hyprctl
|
# make meson use the provided wlroots instead of the git submodule
|
||||||
make all
|
./meson-build.patch
|
||||||
popd
|
];
|
||||||
'';
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
pushd ..
|
|
||||||
install -Dm644 ./example/hyprland.desktop -t $out/share/wayland-sessions
|
|
||||||
install -Dm755 ./build/Hyprland -t $out/bin
|
|
||||||
install -Dm755 ./hyprctl/hyprctl -t $out/bin
|
|
||||||
install -Dm644 ./assets/* -t $out/share/hyprland
|
|
||||||
install -Dm644 ./example/hyprland.conf -t $out/share/hyprland
|
|
||||||
popd
|
|
||||||
'';
|
|
||||||
|
|
||||||
passthru.providedSessions = ["hyprland"];
|
passthru.providedSessions = ["hyprland"];
|
||||||
|
|
||||||
|
|
36
nix/meson-build.patch
Normal file
36
nix/meson-build.patch
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 22ee4bf..5528613 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -2,16 +2,10 @@ project('Hyprland', 'cpp', 'c',
|
||||||
|
version : '0.1',
|
||||||
|
default_options : ['warning_level=3', 'cpp_std=c++20', 'default_library=static'])
|
||||||
|
|
||||||
|
-wlroots = subproject('wlroots', default_options: ['examples=false'])
|
||||||
|
-have_xwlr = wlroots.get_variable('features').get('xwayland')
|
||||||
|
+wlroots = dependency('wlroots', version: '>=0.16.0')
|
||||||
|
xcb_dep = dependency('xcb', required: get_option('xwayland'))
|
||||||
|
|
||||||
|
-if get_option('xwayland').enabled() and not have_xwlr
|
||||||
|
- error('Cannot enable Xwayland in Hyprland: wlroots has been built without Xwayland support')
|
||||||
|
-endif
|
||||||
|
-have_xwayland = xcb_dep.found() and have_xwlr
|
||||||
|
-
|
||||||
|
-if not have_xwayland
|
||||||
|
+if not xcb_dep.found()
|
||||||
|
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
|
||||||
|
endif
|
||||||
|
|
||||||
|
diff --git a/src/meson.build b/src/meson.build
|
||||||
|
index 5d64188..a676333 100644
|
||||||
|
--- a/src/meson.build
|
||||||
|
+++ b/src/meson.build
|
||||||
|
@@ -7,7 +7,7 @@ executable('Hyprland', src,
|
||||||
|
server_protos,
|
||||||
|
dependency('wayland-server'),
|
||||||
|
dependency('wayland-client'),
|
||||||
|
- wlroots.get_variable('wlroots'),
|
||||||
|
+ wlroots,
|
||||||
|
dependency('cairo'),
|
||||||
|
dependency('pango'),
|
||||||
|
dependency('pangocairo'),
|
|
@ -19,7 +19,7 @@ in {
|
||||||
|
|
||||||
package = mkOption {
|
package = mkOption {
|
||||||
type = types.package;
|
type = types.package;
|
||||||
default = self.packages.${pkgs.system}.default;
|
default = pkgs.hyprland or self.packages.${pkgs.system}.default;
|
||||||
defaultText = literalExpression "<Hyprland flake>.packages.<system>.default";
|
defaultText = literalExpression "<Hyprland flake>.packages.<system>.default";
|
||||||
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
|
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
|
||||||
description = ''
|
description = ''
|
||||||
|
|
|
@ -443,7 +443,11 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
|
||||||
|
|
||||||
double subx, suby;
|
double subx, suby;
|
||||||
|
|
||||||
const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.vec().x, pos.y - pWindow->m_vRealPosition.vec().y, &subx, &suby);
|
// calc for oversized windows... fucking bullshit, again.
|
||||||
|
wlr_box geom;
|
||||||
|
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom);
|
||||||
|
|
||||||
|
const auto PFOUND = wlr_xdg_surface_surface_at(PSURFACE, pos.x - pWindow->m_vRealPosition.vec().x + geom.x, pos.y - pWindow->m_vRealPosition.vec().y + geom.y, &subx, &suby);
|
||||||
|
|
||||||
if (PFOUND) {
|
if (PFOUND) {
|
||||||
sl.x = subx;
|
sl.x = subx;
|
||||||
|
@ -454,6 +458,9 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
|
||||||
sl.x = pos.x - pWindow->m_vRealPosition.vec().x;
|
sl.x = pos.x - pWindow->m_vRealPosition.vec().x;
|
||||||
sl.y = pos.y - pWindow->m_vRealPosition.vec().y;
|
sl.y = pos.y - pWindow->m_vRealPosition.vec().y;
|
||||||
|
|
||||||
|
sl.x += geom.x;
|
||||||
|
sl.y += geom.y;
|
||||||
|
|
||||||
return PSURFACE->surface;
|
return PSURFACE->surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,18 +770,24 @@ void CCompositor::cleanupFadingOut() {
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
||||||
const auto POSA = pWindow->m_vPosition;
|
|
||||||
const auto SIZEA = pWindow->m_vSize;
|
const auto WINDOWIDEALBB = pWindow->getWindowIdealBoundingBoxIgnoreReserved();
|
||||||
|
|
||||||
|
const auto POSA = Vector2D(WINDOWIDEALBB.x, WINDOWIDEALBB.y);
|
||||||
|
const auto SIZEA = Vector2D(WINDOWIDEALBB.width, WINDOWIDEALBB.height);
|
||||||
|
|
||||||
auto longestIntersect = -1;
|
auto longestIntersect = -1;
|
||||||
CWindow* longestIntersectWindow = nullptr;
|
CWindow* longestIntersectWindow = nullptr;
|
||||||
|
|
||||||
for (auto& w : m_lWindows) {
|
for (auto& w : m_lWindows) {
|
||||||
if (&w == pWindow || !windowValidMapped(&w) || w.m_bIsFloating || w.m_iWorkspaceID != pWindow->m_iWorkspaceID)
|
if (&w == pWindow || !windowValidMapped(&w) || w.m_bIsFloating || !isWorkspaceVisible(w.m_iWorkspaceID))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto POSB = w.m_vPosition;
|
const auto BWINDOWIDEALBB = w.getWindowIdealBoundingBoxIgnoreReserved();
|
||||||
const auto SIZEB = w.m_vSize;
|
|
||||||
|
const auto POSB = Vector2D(BWINDOWIDEALBB.x, BWINDOWIDEALBB.y);
|
||||||
|
const auto SIZEB = Vector2D(BWINDOWIDEALBB.width, BWINDOWIDEALBB.height);
|
||||||
|
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case 'l':
|
case 'l':
|
||||||
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
||||||
|
|
|
@ -44,3 +44,28 @@ wlr_box CWindow::getFullWindowBoundingBox() {
|
||||||
|
|
||||||
return finalBox;
|
return finalBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlr_box CWindow::getWindowIdealBoundingBoxIgnoreReserved() {
|
||||||
|
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||||
|
|
||||||
|
auto POS = m_vPosition;
|
||||||
|
auto SIZE = m_vSize;
|
||||||
|
|
||||||
|
if (DELTALESSTHAN(POS.y - PMONITOR->vecPosition.y, PMONITOR->vecReservedTopLeft.y, 1)) {
|
||||||
|
POS.y = PMONITOR->vecPosition.y;
|
||||||
|
SIZE.y += PMONITOR->vecReservedTopLeft.y;
|
||||||
|
}
|
||||||
|
if (DELTALESSTHAN(POS.x - PMONITOR->vecPosition.x, PMONITOR->vecReservedTopLeft.x, 1)) {
|
||||||
|
POS.x = PMONITOR->vecPosition.x;
|
||||||
|
SIZE.x += PMONITOR->vecReservedTopLeft.x;
|
||||||
|
}
|
||||||
|
if (DELTALESSTHAN(POS.x + SIZE.x - PMONITOR->vecPosition.x, PMONITOR->vecSize.x - PMONITOR->vecReservedBottomRight.x, 1)) {
|
||||||
|
SIZE.x += PMONITOR->vecReservedBottomRight.x;
|
||||||
|
}
|
||||||
|
if (DELTALESSTHAN(POS.y + SIZE.y - PMONITOR->vecPosition.y, PMONITOR->vecSize.y - PMONITOR->vecReservedBottomRight.y, 1)) {
|
||||||
|
SIZE.y += PMONITOR->vecReservedBottomRight.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wlr_box{(int)POS.x, (int)POS.y, (int)SIZE.x, (int)SIZE.y};
|
||||||
|
}
|
|
@ -108,5 +108,6 @@ public:
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
wlr_box getFullWindowBoundingBox();
|
wlr_box getFullWindowBoundingBox();
|
||||||
|
wlr_box getWindowIdealBoundingBoxIgnoreReserved();
|
||||||
|
|
||||||
};
|
};
|
|
@ -20,7 +20,7 @@ CConfigManager::CConfigManager() {
|
||||||
void CConfigManager::setDefaultVars() {
|
void CConfigManager::setDefaultVars() {
|
||||||
configValues["general:max_fps"].intValue = 240;
|
configValues["general:max_fps"].intValue = 240;
|
||||||
configValues["general:sensitivity"].floatValue = 0.25f;
|
configValues["general:sensitivity"].floatValue = 0.25f;
|
||||||
configValues["general:apply_sens_to_raw"].intValue = 1;
|
configValues["general:apply_sens_to_raw"].intValue = 0;
|
||||||
configValues["general:main_mod"].strValue = "SUPER"; // exposed to the user for easier configuring
|
configValues["general:main_mod"].strValue = "SUPER"; // exposed to the user for easier configuring
|
||||||
configValues["general:main_mod_internal"].intValue = g_pKeybindManager->stringToModMask("SUPER"); // actually used and automatically calculated
|
configValues["general:main_mod_internal"].intValue = g_pKeybindManager->stringToModMask("SUPER"); // actually used and automatically calculated
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ void CConfigManager::setDefaultVars() {
|
||||||
configValues["general:damage_tracking_internal"].intValue = DAMAGE_TRACKING_NONE;
|
configValues["general:damage_tracking_internal"].intValue = DAMAGE_TRACKING_NONE;
|
||||||
|
|
||||||
configValues["general:border_size"].intValue = 1;
|
configValues["general:border_size"].intValue = 1;
|
||||||
|
configValues["general:no_border_on_floating"].intValue = 0;
|
||||||
configValues["general:gaps_in"].intValue = 5;
|
configValues["general:gaps_in"].intValue = 5;
|
||||||
configValues["general:gaps_out"].intValue = 20;
|
configValues["general:gaps_out"].intValue = 20;
|
||||||
configValues["general:col.active_border"].intValue = 0xffffffff;
|
configValues["general:col.active_border"].intValue = 0xffffffff;
|
||||||
|
@ -46,6 +47,7 @@ void CConfigManager::setDefaultVars() {
|
||||||
configValues["decoration:inactive_opacity"].floatValue = 1;
|
configValues["decoration:inactive_opacity"].floatValue = 1;
|
||||||
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
||||||
configValues["decoration:multisample_edges"].intValue = 0;
|
configValues["decoration:multisample_edges"].intValue = 0;
|
||||||
|
configValues["decoration:no_blur_on_oversized"].intValue = 1;
|
||||||
|
|
||||||
configValues["dwindle:pseudotile"].intValue = 0;
|
configValues["dwindle:pseudotile"].intValue = 0;
|
||||||
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
||||||
|
@ -415,7 +417,7 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
|
||||||
configSetValueSafe("animations:" + ANIMNAME + "_style", curitem);
|
configSetValueSafe("animations:" + ANIMNAME + "_style", curitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::handleBind(const std::string& command, const std::string& value) {
|
void CConfigManager::handleBind(const std::string& command, const std::string& value, bool locked) {
|
||||||
// example:
|
// example:
|
||||||
// bind=SUPER,G,exec,dmenu_run <args>
|
// bind=SUPER,G,exec,dmenu_run <args>
|
||||||
|
|
||||||
|
@ -448,7 +450,7 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KEY != "")
|
if (KEY != "")
|
||||||
g_pKeybindManager->addKeybind(SKeybind{KEY, MOD, HANDLER, COMMAND});
|
g_pKeybindManager->addKeybind(SKeybind{KEY, MOD, HANDLER, COMMAND, locked, m_szCurrentSubmap});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
void CConfigManager::handleUnbind(const std::string& command, const std::string& value) {
|
||||||
|
@ -495,16 +497,23 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
|
||||||
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
|
||||||
|
|
||||||
const auto DISPLAY = value.substr(0, value.find_first_of(','));
|
const auto DISPLAY = value.substr(0, value.find_first_of(','));
|
||||||
const auto WORKSPACEID = stoi(value.substr(value.find_first_of(',') + 1));
|
const auto WORKSPACE = value.substr(value.find_first_of(',') + 1);
|
||||||
|
|
||||||
for (auto& mr : m_dMonitorRules) {
|
for (auto& mr : m_dMonitorRules) {
|
||||||
if (mr.name == DISPLAY) {
|
if (mr.name == DISPLAY) {
|
||||||
mr.defaultWorkspaceID = WORKSPACEID;
|
mr.defaultWorkspace = WORKSPACE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConfigManager::handleSubmap(const std::string& command, const std::string& submap) {
|
||||||
|
if (submap == "reset")
|
||||||
|
m_szCurrentSubmap = "";
|
||||||
|
else
|
||||||
|
m_szCurrentSubmap = submap;
|
||||||
|
}
|
||||||
|
|
||||||
void CConfigManager::handleSource(const std::string& command, const std::string& rawpath) {
|
void CConfigManager::handleSource(const std::string& command, const std::string& rawpath) {
|
||||||
static const char* const ENVHOME = getenv("HOME");
|
static const char* const ENVHOME = getenv("HOME");
|
||||||
|
|
||||||
|
@ -578,12 +587,14 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
||||||
}
|
}
|
||||||
else if (COMMAND == "monitor") handleMonitor(COMMAND, VALUE);
|
else if (COMMAND == "monitor") handleMonitor(COMMAND, VALUE);
|
||||||
else if (COMMAND == "bind") handleBind(COMMAND, VALUE);
|
else if (COMMAND == "bind") handleBind(COMMAND, VALUE);
|
||||||
|
else if (COMMAND == "bindl") handleBind(COMMAND, VALUE, true);
|
||||||
else if (COMMAND == "unbind") handleUnbind(COMMAND, VALUE);
|
else if (COMMAND == "unbind") handleUnbind(COMMAND, VALUE);
|
||||||
else if (COMMAND == "workspace") handleDefaultWorkspace(COMMAND, VALUE);
|
else if (COMMAND == "workspace") handleDefaultWorkspace(COMMAND, VALUE);
|
||||||
else if (COMMAND == "windowrule") handleWindowRule(COMMAND, VALUE);
|
else if (COMMAND == "windowrule") handleWindowRule(COMMAND, VALUE);
|
||||||
else if (COMMAND == "bezier") handleBezier(COMMAND, VALUE);
|
else if (COMMAND == "bezier") handleBezier(COMMAND, VALUE);
|
||||||
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
|
||||||
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
|
||||||
|
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
|
||||||
else
|
else
|
||||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||||
|
|
||||||
|
@ -900,15 +911,26 @@ std::vector<SWindowRule> CConfigManager::getMatchingRules(CWindow* pWindow) {
|
||||||
std::string title = g_pXWaylandManager->getTitle(pWindow);
|
std::string title = g_pXWaylandManager->getTitle(pWindow);
|
||||||
std::string appidclass = g_pXWaylandManager->getAppIDClass(pWindow);
|
std::string appidclass = g_pXWaylandManager->getAppIDClass(pWindow);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Searching for matching rules for %s (title: %s)", appidclass.c_str(), title.c_str());
|
||||||
|
|
||||||
for (auto& rule : m_dWindowRules) {
|
for (auto& rule : m_dWindowRules) {
|
||||||
// check if we have a matching rule
|
// check if we have a matching rule
|
||||||
try {
|
try {
|
||||||
std::regex classCheck(rule.szValue);
|
if (rule.szValue.find("title:") == 0) {
|
||||||
|
// we have a title rule.
|
||||||
|
std::regex RULECHECK(rule.szValue.substr(6));
|
||||||
|
|
||||||
if (!std::regex_search(title, classCheck) && !std::regex_search(appidclass, classCheck))
|
if (!std::regex_search(title, RULECHECK))
|
||||||
continue;
|
continue;
|
||||||
|
} else {
|
||||||
|
std::regex classCheck(rule.szValue);
|
||||||
|
|
||||||
|
if (!std::regex_search(appidclass, classCheck))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
Debug::log(ERR, "Regex error at %s", rule.szValue.c_str());
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// applies. Read the rule and behave accordingly
|
// applies. Read the rule and behave accordingly
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct SMonitorRule {
|
||||||
Vector2D offset = Vector2D(0,0);
|
Vector2D offset = Vector2D(0,0);
|
||||||
float scale = 1;
|
float scale = 1;
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
int defaultWorkspaceID = -1;
|
std::string defaultWorkspace = "";
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
};
|
};
|
||||||
|
@ -88,6 +88,8 @@ private:
|
||||||
|
|
||||||
std::string parseError = ""; // For storing a parse error to display later
|
std::string parseError = ""; // For storing a parse error to display later
|
||||||
|
|
||||||
|
std::string m_szCurrentSubmap = ""; // For storing the current keybind submap
|
||||||
|
|
||||||
bool isFirstLaunch = true; // For exec-once
|
bool isFirstLaunch = true; // For exec-once
|
||||||
|
|
||||||
std::deque<SMonitorRule> m_dMonitorRules;
|
std::deque<SMonitorRule> m_dMonitorRules;
|
||||||
|
@ -106,13 +108,14 @@ private:
|
||||||
void configSetValueSafe(const std::string&, const std::string&);
|
void configSetValueSafe(const std::string&, const std::string&);
|
||||||
void handleRawExec(const std::string&, const std::string&);
|
void handleRawExec(const std::string&, const std::string&);
|
||||||
void handleMonitor(const std::string&, const std::string&);
|
void handleMonitor(const std::string&, const std::string&);
|
||||||
void handleBind(const std::string&, const std::string&);
|
void handleBind(const std::string&, const std::string&, bool locked = false);
|
||||||
void handleUnbind(const std::string&, const std::string&);
|
void handleUnbind(const std::string&, const std::string&);
|
||||||
void handleWindowRule(const std::string&, const std::string&);
|
void handleWindowRule(const std::string&, const std::string&);
|
||||||
void handleDefaultWorkspace(const std::string&, const std::string&);
|
void handleDefaultWorkspace(const std::string&, const std::string&);
|
||||||
void handleBezier(const std::string&, const std::string&);
|
void handleBezier(const std::string&, const std::string&);
|
||||||
void handleAnimation(const std::string&, const std::string&);
|
void handleAnimation(const std::string&, const std::string&);
|
||||||
void handleSource(const std::string&, const std::string&);
|
void handleSource(const std::string&, const std::string&);
|
||||||
|
void handleSubmap(const std::string&, const std::string&);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
|
@ -34,6 +34,8 @@ general {
|
||||||
col.active_border=0x66ee1111
|
col.active_border=0x66ee1111
|
||||||
col.inactive_border=0x66333333
|
col.inactive_border=0x66333333
|
||||||
|
|
||||||
|
apply_sens_to_raw=0 # do not apply the sensitivity to raw input (e.g. used by games where you aim)
|
||||||
|
|
||||||
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
|
damage_tracking=full # leave it on full unless you hate your GPU and want to make it suffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,15 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||||
wlr_ext_workspace_group_handle_v1_output_enter(PNEWMONITOR->pWLRWorkspaceGroupHandle, PNEWMONITOR->output);
|
wlr_ext_workspace_group_handle_v1_output_enter(PNEWMONITOR->pWLRWorkspaceGroupHandle, PNEWMONITOR->output);
|
||||||
|
|
||||||
// Workspace
|
// Workspace
|
||||||
const auto WORKSPACEID = monitorRule.defaultWorkspaceID == -1 ? g_pCompositor->m_lWorkspaces.size() + 1 /* Cuz workspaces doesnt have the new one yet and we start with 1 */ : monitorRule.defaultWorkspaceID;
|
std::string newDefaultWorkspaceName = "";
|
||||||
|
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_lWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||||
|
|
||||||
|
if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) {
|
||||||
|
WORKSPACEID = g_pCompositor->m_lWorkspaces.size() + 1;
|
||||||
|
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace);
|
||||||
|
}
|
||||||
|
|
||||||
auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||||
|
|
||||||
|
@ -127,19 +135,20 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PNEWMONITOR->ID);
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PNEWMONITOR->ID);
|
||||||
PNEWWORKSPACE->startAnim(true,true,true);
|
PNEWWORKSPACE->startAnim(true,true,true);
|
||||||
} else {
|
} else {
|
||||||
g_pCompositor->m_lWorkspaces.emplace_back(newMonitor.ID);
|
PNEWWORKSPACE = &g_pCompositor->m_lWorkspaces.emplace_back(newMonitor.ID);
|
||||||
PNEWWORKSPACE = &g_pCompositor->m_lWorkspaces.back();
|
|
||||||
|
|
||||||
// We are required to set the name here immediately
|
// We are required to set the name here immediately
|
||||||
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, std::to_string(WORKSPACEID).c_str());
|
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str());
|
||||||
|
|
||||||
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
||||||
PNEWWORKSPACE->m_szName = std::to_string(WORKSPACEID);
|
PNEWWORKSPACE->m_szName = newDefaultWorkspaceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
|
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||||
PNEWMONITOR->scale = monitorRule.scale;
|
PNEWMONITOR->scale = monitorRule.scale;
|
||||||
|
|
||||||
|
PNEWMONITOR->forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering.
|
||||||
|
|
||||||
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle);
|
||||||
PNEWWORKSPACE->setActive(true);
|
PNEWWORKSPACE->setActive(true);
|
||||||
|
|
||||||
|
@ -216,7 +225,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE) {
|
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && PMONITOR->forceFullFrames == 0) {
|
||||||
pixman_region32_fini(&damage);
|
pixman_region32_fini(&damage);
|
||||||
wlr_output_rollback(PMONITOR->output);
|
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
|
wlr_output_schedule_frame(PMONITOR->output); // we update shit at the monitor's Hz so we need to schedule frames because rollback wont
|
||||||
|
@ -224,7 +233,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR) {
|
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0) {
|
||||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||||
|
|
||||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||||
|
@ -247,6 +256,9 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PMONITOR->forceFullFrames > 0)
|
||||||
|
PMONITOR->forceFullFrames -= 1;
|
||||||
|
|
||||||
// TODO: this is getting called with extents being 0,0,0,0 should it be?
|
// TODO: this is getting called with extents being 0,0,0,0 should it be?
|
||||||
// potentially can save on resources.
|
// potentially can save on resources.
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,14 @@ void addPopupGlobalCoords(void* pPopup, int* x, int* y) {
|
||||||
px += curPopup->popup->current.geometry.x;
|
px += curPopup->popup->current.geometry.x;
|
||||||
py += curPopup->popup->current.geometry.y;
|
py += curPopup->popup->current.geometry.y;
|
||||||
|
|
||||||
|
// fix oversized fucking popups
|
||||||
|
// kill me
|
||||||
|
if (curPopup->pSurfaceTree && curPopup->pSurfaceTree->pSurface && !curPopup->parentPopup) {
|
||||||
|
const auto EXTENTSSURFACE = pixman_region32_extents(&curPopup->pSurfaceTree->pSurface->input_region);
|
||||||
|
px -= EXTENTSSURFACE->x1;
|
||||||
|
py -= EXTENTSSURFACE->y1;
|
||||||
|
}
|
||||||
|
|
||||||
if (curPopup->parentPopup) {
|
if (curPopup->parentPopup) {
|
||||||
curPopup = curPopup->parentPopup;
|
curPopup = curPopup->parentPopup;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -19,6 +19,14 @@ void addViewCoords(void* pWindow, int* x, int* y) {
|
||||||
const auto PWINDOW = (CWindow*)pWindow;
|
const auto PWINDOW = (CWindow*)pWindow;
|
||||||
*x += PWINDOW->m_vRealPosition.goalv().x;
|
*x += PWINDOW->m_vRealPosition.goalv().x;
|
||||||
*y += PWINDOW->m_vRealPosition.goalv().y;
|
*y += PWINDOW->m_vRealPosition.goalv().y;
|
||||||
|
|
||||||
|
if (!PWINDOW->m_bIsX11) {
|
||||||
|
wlr_box geom;
|
||||||
|
wlr_xdg_surface_get_geometry(PWINDOW->m_uSurface.xdg, &geom);
|
||||||
|
|
||||||
|
*x -= geom.x;
|
||||||
|
*y -= geom.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_mapWindow(void* owner, void* data) {
|
void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
|
|
|
@ -158,6 +158,12 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||||
outName = WORKSPACENAME;
|
outName = WORKSPACENAME;
|
||||||
} else {
|
} else {
|
||||||
if (in[0] == 'm') {
|
if (in[0] == 'm') {
|
||||||
|
if (!g_pCompositor->m_pLastMonitor) {
|
||||||
|
Debug::log(ERR, "Relative monitor workspace on monitor null!");
|
||||||
|
result = INT_MAX;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// monitor relative
|
// monitor relative
|
||||||
result = (int)getPlusMinusKeywordResult(in.substr(1), 0);
|
result = (int)getPlusMinusKeywordResult(in.substr(1), 0);
|
||||||
|
|
||||||
|
@ -207,7 +213,14 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||||
outName = g_pCompositor->getWorkspaceByID(currentID)->m_szName;
|
outName = g_pCompositor->getWorkspaceByID(currentID)->m_szName;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = std::clamp((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1, INT_MAX);
|
if (g_pCompositor->m_pLastMonitor)
|
||||||
|
result = std::clamp((int)getPlusMinusKeywordResult(in, g_pCompositor->m_pLastMonitor->activeWorkspace), 1, INT_MAX);
|
||||||
|
else if (isNumber(in))
|
||||||
|
result = std::clamp(std::stoi(in), 1, INT_MAX);
|
||||||
|
else {
|
||||||
|
Debug::log(ERR, "Relative workspace on no mon!");
|
||||||
|
result = INT_MAX;
|
||||||
|
}
|
||||||
outName = std::to_string(result);
|
outName = std::to_string(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct SMonitor {
|
||||||
float refreshRate = 60;
|
float refreshRate = 60;
|
||||||
wlr_output_damage* damage = nullptr;
|
wlr_output_damage* damage = nullptr;
|
||||||
int framesToSkip = 0;
|
int framesToSkip = 0;
|
||||||
|
int forceFullFrames = 0;
|
||||||
bool noFrameSchedule = false;
|
bool noFrameSchedule = false;
|
||||||
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
|
||||||
|
|
|
@ -545,11 +545,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
||||||
const auto PNODE = getNodeFromWindow(PWINDOW);
|
const auto PNODE = getNodeFromWindow(PWINDOW);
|
||||||
|
|
||||||
if (!PNODE) {
|
if (!PNODE) {
|
||||||
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() + pixResize);
|
PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999));
|
||||||
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(PWINDOW->m_vRealSize.vec().x, (double)20, (double)999999), std::clamp(PWINDOW->m_vRealSize.vec().y, (double)20, (double)999999)));
|
|
||||||
|
|
||||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,6 +902,11 @@ void CHyprDwindleLayout::switchWindows(CWindow* pWindow, CWindow* pWindow2) {
|
||||||
if (!PNODE2 || !PNODE)
|
if (!PNODE2 || !PNODE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (PNODE->workspaceID != PNODE2->workspaceID) {
|
||||||
|
Debug::log(ERR, "Dwindle: Rejecting a swap between workspaces");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// we will not delete the nodes, just fix the tree
|
// we will not delete the nodes, just fix the tree
|
||||||
if (PNODE2->pParent == PNODE->pParent) {
|
if (PNODE2->pParent == PNODE->pParent) {
|
||||||
const auto PPARENT = PNODE->pParent;
|
const auto PPARENT = PNODE->pParent;
|
||||||
|
@ -993,3 +994,19 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
|
||||||
std::string CHyprDwindleLayout::getLayoutName() {
|
std::string CHyprDwindleLayout::getLayoutName() {
|
||||||
return "dwindle";
|
return "dwindle";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprDwindleLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||||
|
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
||||||
|
|
||||||
|
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!PWINDOW->m_bIsFloating) {
|
||||||
|
Debug::log(LOG, "Dwindle cannot move a tiled window in moveActiveWindow!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goalv() + delta;
|
||||||
|
|
||||||
|
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ public:
|
||||||
virtual void changeWindowFloatingMode(CWindow*);
|
virtual void changeWindowFloatingMode(CWindow*);
|
||||||
virtual void onBeginDragWindow();
|
virtual void onBeginDragWindow();
|
||||||
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
||||||
|
virtual void moveActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
||||||
virtual void onEndDragWindow();
|
virtual void onEndDragWindow();
|
||||||
virtual void onMouseMove(const Vector2D&);
|
virtual void onMouseMove(const Vector2D&);
|
||||||
virtual void onWindowCreatedFloating(CWindow*);
|
virtual void onWindowCreatedFloating(CWindow*);
|
||||||
|
|
|
@ -55,6 +55,12 @@ public:
|
||||||
Optional pWindow for a specific window
|
Optional pWindow for a specific window
|
||||||
*/
|
*/
|
||||||
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr) = 0;
|
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr) = 0;
|
||||||
|
/*
|
||||||
|
Called when a user requests a move of the current window by a vec
|
||||||
|
Vector2D holds pixel values
|
||||||
|
Optional pWindow for a specific window
|
||||||
|
*/
|
||||||
|
virtual void moveActiveWindow(const Vector2D&, CWindow* pWindow = nullptr) = 0;
|
||||||
/*
|
/*
|
||||||
Called when a window is ended being dragged
|
Called when a window is ended being dragged
|
||||||
(mouse up)
|
(mouse up)
|
||||||
|
|
|
@ -105,6 +105,12 @@ void CEventManager::startThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEventManager::postEvent(const SHyprIPCEvent event) {
|
void CEventManager::postEvent(const SHyprIPCEvent event) {
|
||||||
|
|
||||||
|
if (m_bIgnoreEvents) {
|
||||||
|
Debug::log(WARN, "Suppressed (ignoreevents true) event of type %s, content: %s",event.event.c_str(), event.data.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::thread([&](const SHyprIPCEvent ev) {
|
std::thread([&](const SHyprIPCEvent ev) {
|
||||||
eventQueueMutex.lock();
|
eventQueueMutex.lock();
|
||||||
m_dQueuedEvents.push_back(ev);
|
m_dQueuedEvents.push_back(ev);
|
||||||
|
|
|
@ -19,6 +19,8 @@ public:
|
||||||
|
|
||||||
void startThread();
|
void startThread();
|
||||||
|
|
||||||
|
bool m_bIgnoreEvents = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex eventQueueMutex;
|
std::mutex eventQueueMutex;
|
||||||
|
|
|
@ -28,8 +28,10 @@ CKeybindManager::CKeybindManager() {
|
||||||
m_mDispatchers["togglespecialworkspace"] = toggleSpecialWorkspace;
|
m_mDispatchers["togglespecialworkspace"] = toggleSpecialWorkspace;
|
||||||
m_mDispatchers["forcerendererreload"] = forceRendererReload;
|
m_mDispatchers["forcerendererreload"] = forceRendererReload;
|
||||||
m_mDispatchers["resizeactive"] = resizeActive;
|
m_mDispatchers["resizeactive"] = resizeActive;
|
||||||
|
m_mDispatchers["moveactive"] = moveActive;
|
||||||
m_mDispatchers["cyclenext"] = circleNext;
|
m_mDispatchers["cyclenext"] = circleNext;
|
||||||
m_mDispatchers["focuswindowbyclass"] = focusWindowByClass;
|
m_mDispatchers["focuswindowbyclass"] = focusWindowByClass;
|
||||||
|
m_mDispatchers["submap"] = setSubmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::addKeybind(SKeybind kb) {
|
void CKeybindManager::addKeybind(SKeybind kb) {
|
||||||
|
@ -72,13 +74,11 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
|
||||||
if (handleInternalKeybinds(key))
|
if (handleInternalKeybinds(key))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (g_pCompositor->m_sSeat.exclusiveClient){
|
if (g_pCompositor->m_sSeat.exclusiveClient)
|
||||||
Debug::log(LOG, "Not handling keybinds due to there being an exclusive inhibited client.");
|
Debug::log(LOG, "Keybind handling only locked (inhibitor)");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& k : m_lKeybinds) {
|
for (auto& k : m_lKeybinds) {
|
||||||
if (modmask != k.modmask)
|
if (modmask != k.modmask || (g_pCompositor->m_sSeat.exclusiveClient && !k.locked) || k.submap != m_szCurrentSelectedSubmap)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// oMg such performance hit!!11!
|
// oMg such performance hit!!11!
|
||||||
|
@ -280,9 +280,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||||
// start anim on new workspace
|
// start anim on new workspace
|
||||||
PWORKSPACETOCHANGETO->startAnim(true, ANIMTOLEFT);
|
PWORKSPACETOCHANGETO->startAnim(true, ANIMTOLEFT);
|
||||||
|
|
||||||
// Event ONLY if workspace is actually "changed" and we arent just focusing
|
g_pEventManager->postEvent(SHyprIPCEvent("workspace", PWORKSPACETOCHANGETO->m_szName));
|
||||||
if (!m_bSuppressWorkspaceChangeEvents)
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent("workspace", PWORKSPACETOCHANGETO->m_szName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the monitor is not the one our cursor's at, warp to it.
|
// If the monitor is not the one our cursor's at, warp to it.
|
||||||
|
@ -291,9 +289,6 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, middle.x, middle.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// focus the first window
|
|
||||||
g_pCompositor->focusWindow(g_pCompositor->getFirstWindowOnWorkspace(workspaceToChangeTo));
|
|
||||||
|
|
||||||
// set active and deactivate all other in wlr
|
// set active and deactivate all other in wlr
|
||||||
g_pCompositor->deactivateAllWLRWorkspaces(PWORKSPACETOCHANGETO->m_pWlrHandle);
|
g_pCompositor->deactivateAllWLRWorkspaces(PWORKSPACETOCHANGETO->m_pWlrHandle);
|
||||||
PWORKSPACETOCHANGETO->setActive(true);
|
PWORKSPACETOCHANGETO->setActive(true);
|
||||||
|
@ -360,8 +355,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
if (!m_bSuppressWorkspaceChangeEvents)
|
g_pEventManager->postEvent(SHyprIPCEvent("workspace", PWORKSPACE->m_szName));
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent("workspace", PWORKSPACE->m_szName));
|
|
||||||
|
|
||||||
Debug::log(LOG, "Changed to workspace %i", workspaceToChangeTo);
|
Debug::log(LOG, "Changed to workspace %i", workspaceToChangeTo);
|
||||||
}
|
}
|
||||||
|
@ -491,7 +485,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||||
const auto POLDWORKSPACEONMON = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDONMONITOR);
|
const auto POLDWORKSPACEONMON = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDONMONITOR);
|
||||||
const auto POLDWORKSPACEIDRETURN = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDRETURN);
|
const auto POLDWORKSPACEIDRETURN = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDRETURN);
|
||||||
|
|
||||||
m_bSuppressWorkspaceChangeEvents = true;
|
g_pEventManager->m_bIgnoreEvents = true;
|
||||||
|
|
||||||
moveActiveToWorkspace(args);
|
moveActiveToWorkspace(args);
|
||||||
|
|
||||||
|
@ -510,7 +504,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
|
||||||
POLDWORKSPACEONMON->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0));
|
POLDWORKSPACEONMON->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0));
|
||||||
POLDWORKSPACEONMON->m_fAlpha.setValueAndWarp(255.f);
|
POLDWORKSPACEONMON->m_fAlpha.setValueAndWarp(255.f);
|
||||||
|
|
||||||
m_bSuppressWorkspaceChangeEvents = false;
|
g_pEventManager->m_bIgnoreEvents = false;
|
||||||
|
|
||||||
g_pInputManager->refocus();
|
g_pInputManager->refocus();
|
||||||
}
|
}
|
||||||
|
@ -899,6 +893,37 @@ void CKeybindManager::resizeActive(std::string args) {
|
||||||
std::string x = args.substr(0, args.find_first_of(' '));
|
std::string x = args.substr(0, args.find_first_of(' '));
|
||||||
std::string y = args.substr(args.find_first_of(' ') + 1);
|
std::string y = args.substr(args.find_first_of(' ') + 1);
|
||||||
|
|
||||||
|
if (x == "exact") {
|
||||||
|
std::string newX = y.substr(0, y.find_first_of(' '));
|
||||||
|
std::string newY = y.substr(y.find_first_of(' ') + 1);
|
||||||
|
|
||||||
|
if (!isNumber(newX) || !isNumber(newY)) {
|
||||||
|
Debug::log(ERR, "resizeTiledWindow: exact args not numbers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int X = std::stoi(newX);
|
||||||
|
const int Y = std::stoi(newY);
|
||||||
|
|
||||||
|
if (X < 10 || Y < 10) {
|
||||||
|
Debug::log(ERR, "resizeTiledWindow: exact args cannot be < 10");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calc the delta
|
||||||
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||||
|
return; // ignore
|
||||||
|
|
||||||
|
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||||
|
|
||||||
|
const int DX = X - PWINDOW->m_vRealSize.goalv().x;
|
||||||
|
const int DY = Y - PWINDOW->m_vRealSize.goalv().y;
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(Vector2D(DX, DY));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isNumber(x) || !isNumber(y)) {
|
if (!isNumber(x) || !isNumber(y)) {
|
||||||
Debug::log(ERR, "resizeTiledWindow: args not numbers");
|
Debug::log(ERR, "resizeTiledWindow: args not numbers");
|
||||||
return;
|
return;
|
||||||
|
@ -910,6 +935,55 @@ void CKeybindManager::resizeActive(std::string args) {
|
||||||
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(Vector2D(X, Y));
|
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow(Vector2D(X, Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::moveActive(std::string args) {
|
||||||
|
if (args.find_first_of(' ') == std::string::npos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string x = args.substr(0, args.find_first_of(' '));
|
||||||
|
std::string y = args.substr(args.find_first_of(' ') + 1);
|
||||||
|
|
||||||
|
if (x == "exact") {
|
||||||
|
std::string newX = y.substr(0, y.find_first_of(' '));
|
||||||
|
std::string newY = y.substr(y.find_first_of(' ') + 1);
|
||||||
|
|
||||||
|
if (!isNumber(newX) || !isNumber(newY)) {
|
||||||
|
Debug::log(ERR, "moveActive: exact args not numbers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int X = std::stoi(newX);
|
||||||
|
const int Y = std::stoi(newY);
|
||||||
|
|
||||||
|
if (X < 10 || Y < 10) {
|
||||||
|
Debug::log(ERR, "moveActive: exact args cannot be < 10");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calc the delta
|
||||||
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||||
|
return; // ignore
|
||||||
|
|
||||||
|
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||||
|
|
||||||
|
const int DX = X - PWINDOW->m_vRealPosition.goalv().x;
|
||||||
|
const int DY = Y - PWINDOW->m_vRealPosition.goalv().y;
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(Vector2D(DX, DY));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isNumber(x) || !isNumber(y)) {
|
||||||
|
Debug::log(ERR, "moveActive: args not numbers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int X = std::stoi(x);
|
||||||
|
const int Y = std::stoi(y);
|
||||||
|
|
||||||
|
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(Vector2D(X, Y));
|
||||||
|
}
|
||||||
|
|
||||||
void CKeybindManager::circleNext(std::string) {
|
void CKeybindManager::circleNext(std::string) {
|
||||||
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
if (!g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow))
|
||||||
return;
|
return;
|
||||||
|
@ -943,3 +1017,21 @@ void CKeybindManager::focusWindowByClass(std::string clazz) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CKeybindManager::setSubmap(std::string submap) {
|
||||||
|
if (submap == "reset" || submap == "") {
|
||||||
|
m_szCurrentSelectedSubmap = "";
|
||||||
|
Debug::log(LOG, "Reset active submap to the default one.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& k : g_pKeybindManager->m_lKeybinds) {
|
||||||
|
if (k.submap == submap) {
|
||||||
|
m_szCurrentSelectedSubmap = submap;
|
||||||
|
Debug::log(LOG, "Changed keybind submap to %s", submap.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(ERR, "Cannot set submap %s, submap doesn't exist (wasn't registered!)", submap.c_str());
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ struct SKeybind {
|
||||||
uint32_t modmask = 0;
|
uint32_t modmask = 0;
|
||||||
std::string handler = "";
|
std::string handler = "";
|
||||||
std::string arg = "";
|
std::string arg = "";
|
||||||
|
bool locked = false;
|
||||||
|
std::string submap = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
class CKeybindManager {
|
class CKeybindManager {
|
||||||
|
@ -28,9 +30,9 @@ public:
|
||||||
private:
|
private:
|
||||||
std::list<SKeybind> m_lKeybinds;
|
std::list<SKeybind> m_lKeybinds;
|
||||||
|
|
||||||
bool handleInternalKeybinds(xkb_keysym_t);
|
inline static std::string m_szCurrentSelectedSubmap = "";
|
||||||
|
|
||||||
inline static bool m_bSuppressWorkspaceChangeEvents = false;
|
bool handleInternalKeybinds(xkb_keysym_t);
|
||||||
|
|
||||||
// -------------- Dispatchers -------------- //
|
// -------------- Dispatchers -------------- //
|
||||||
static void killActive(std::string);
|
static void killActive(std::string);
|
||||||
|
@ -56,8 +58,10 @@ private:
|
||||||
static void toggleSpecialWorkspace(std::string);
|
static void toggleSpecialWorkspace(std::string);
|
||||||
static void forceRendererReload(std::string);
|
static void forceRendererReload(std::string);
|
||||||
static void resizeActive(std::string);
|
static void resizeActive(std::string);
|
||||||
|
static void moveActive(std::string);
|
||||||
static void circleNext(std::string);
|
static void circleNext(std::string);
|
||||||
static void focusWindowByClass(std::string);
|
static void focusWindowByClass(std::string);
|
||||||
|
static void setSubmap(std::string);
|
||||||
|
|
||||||
friend class CCompositor;
|
friend class CCompositor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,14 +124,8 @@ void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
|
||||||
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) {
|
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) {
|
||||||
if (pWindow->m_bIsX11)
|
if (pWindow->m_bIsX11)
|
||||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
|
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
|
||||||
else {
|
else
|
||||||
// I don't know if this is fucking correct, but the fucking idea of putting shadows into a window's surface is borderline criminal.
|
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
|
||||||
|
|
||||||
const auto XDELTA = pWindow->m_uSurface.xdg->current.geometry.width && pWindow->m_uSurface.xdg->current.geometry.height ? pWindow->m_uSurface.xdg->surface->current.width - pWindow->m_uSurface.xdg->current.geometry.width : 0;
|
|
||||||
const auto YDELTA = pWindow->m_uSurface.xdg->current.geometry.width && pWindow->m_uSurface.xdg->current.geometry.height ? pWindow->m_uSurface.xdg->surface->current.height - pWindow->m_uSurface.xdg->current.geometry.height : 0;
|
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x - XDELTA, size.y - YDELTA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
|
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
|
||||||
|
|
|
@ -35,6 +35,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
Vector2D mouseCoords = getMouseCoordsInternal();
|
Vector2D mouseCoords = getMouseCoordsInternal();
|
||||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||||
|
|
||||||
|
bool didConstraintOnCursor = false;
|
||||||
|
|
||||||
// constraints
|
// constraints
|
||||||
// All constraints TODO: multiple mice?
|
// All constraints TODO: multiple mice?
|
||||||
if (g_pCompositor->m_sSeat.mouse->currentConstraint) {
|
if (g_pCompositor->m_sSeat.mouse->currentConstraint) {
|
||||||
|
@ -50,23 +52,25 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
const auto CONSTRAINTPOS = CONSTRAINTWINDOW->m_bIsX11 ? Vector2D(CONSTRAINTWINDOW->m_uSurface.xwayland->x, CONSTRAINTWINDOW->m_uSurface.xwayland->y) : CONSTRAINTWINDOW->m_vRealPosition.vec();
|
const auto CONSTRAINTPOS = CONSTRAINTWINDOW->m_bIsX11 ? Vector2D(CONSTRAINTWINDOW->m_uSurface.xwayland->x, CONSTRAINTWINDOW->m_uSurface.xwayland->y) : CONSTRAINTWINDOW->m_vRealPosition.vec();
|
||||||
const auto CONSTRAINTSIZE = CONSTRAINTWINDOW->m_bIsX11 ? Vector2D(CONSTRAINTWINDOW->m_uSurface.xwayland->width, CONSTRAINTWINDOW->m_uSurface.xwayland->height) : CONSTRAINTWINDOW->m_vRealSize.vec();
|
const auto CONSTRAINTSIZE = CONSTRAINTWINDOW->m_bIsX11 ? Vector2D(CONSTRAINTWINDOW->m_uSurface.xwayland->width, CONSTRAINTWINDOW->m_uSurface.xwayland->height) : CONSTRAINTWINDOW->m_vRealSize.vec();
|
||||||
|
|
||||||
if (!VECINRECT(mouseCoords, CONSTRAINTPOS.x, CONSTRAINTPOS.y, CONSTRAINTPOS.x + CONSTRAINTSIZE.x, CONSTRAINTPOS.y + CONSTRAINTSIZE.y)) {
|
if (!VECINRECT(mouseCoords, CONSTRAINTPOS.x, CONSTRAINTPOS.y, CONSTRAINTPOS.x + CONSTRAINTSIZE.x - 1.0, CONSTRAINTPOS.y + CONSTRAINTSIZE.y - 1.0)) {
|
||||||
if (g_pCompositor->m_sSeat.mouse->constraintActive) {
|
if (g_pCompositor->m_sSeat.mouse->constraintActive) {
|
||||||
Vector2D deltaToFit;
|
Vector2D newConstrainedCoords = mouseCoords;
|
||||||
|
|
||||||
if (mouseCoords.x < CONSTRAINTPOS.x)
|
if (mouseCoords.x < CONSTRAINTPOS.x)
|
||||||
deltaToFit.x = CONSTRAINTPOS.x - mouseCoords.x;
|
newConstrainedCoords.x = CONSTRAINTPOS.x;
|
||||||
else if (mouseCoords.x > CONSTRAINTPOS.x + CONSTRAINTSIZE.x)
|
else if (mouseCoords.x >= CONSTRAINTPOS.x + CONSTRAINTSIZE.x)
|
||||||
deltaToFit.x = CONSTRAINTPOS.x + CONSTRAINTSIZE.x - mouseCoords.x;
|
newConstrainedCoords.x = CONSTRAINTPOS.x + CONSTRAINTSIZE.x - 1.0;
|
||||||
|
|
||||||
if (mouseCoords.y < CONSTRAINTPOS.y)
|
if (mouseCoords.y < CONSTRAINTPOS.y)
|
||||||
deltaToFit.y = CONSTRAINTPOS.y - mouseCoords.y;
|
newConstrainedCoords.y = CONSTRAINTPOS.y;
|
||||||
else if (mouseCoords.y > CONSTRAINTPOS.y + CONSTRAINTSIZE.y)
|
else if (mouseCoords.y >= CONSTRAINTPOS.y + CONSTRAINTSIZE.y)
|
||||||
deltaToFit.y = CONSTRAINTPOS.y + CONSTRAINTSIZE.y - mouseCoords.y;
|
newConstrainedCoords.y = CONSTRAINTPOS.y + CONSTRAINTSIZE.y - 1.0;
|
||||||
|
|
||||||
wlr_cursor_move(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, deltaToFit.x, deltaToFit.y);
|
wlr_cursor_warp_closest(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, newConstrainedCoords.x, newConstrainedCoords.y);
|
||||||
|
|
||||||
mouseCoords = mouseCoords + deltaToFit;
|
mouseCoords = newConstrainedCoords;
|
||||||
|
|
||||||
|
didConstraintOnCursor = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((!CONSTRAINTWINDOW->m_bIsX11 && PMONITOR && CONSTRAINTWINDOW->m_iWorkspaceID == PMONITOR->activeWorkspace) || (CONSTRAINTWINDOW->m_bIsX11)) {
|
if ((!CONSTRAINTWINDOW->m_bIsX11 && PMONITOR && CONSTRAINTWINDOW->m_iWorkspaceID == PMONITOR->activeWorkspace) || (CONSTRAINTWINDOW->m_bIsX11)) {
|
||||||
|
@ -84,6 +88,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
// focus
|
// focus
|
||||||
wlr_surface* foundSurface = nullptr;
|
wlr_surface* foundSurface = nullptr;
|
||||||
|
|
||||||
|
if (didConstraintOnCursor)
|
||||||
|
return; // don't process when cursor constrained
|
||||||
|
|
||||||
if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor) {
|
if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor) {
|
||||||
g_pCompositor->m_pLastMonitor = PMONITOR;
|
g_pCompositor->m_pLastMonitor = PMONITOR;
|
||||||
|
|
||||||
|
@ -152,7 +159,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
if (!foundSurface)
|
if (!foundSurface)
|
||||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords);
|
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords);
|
||||||
|
|
||||||
|
|
||||||
if (!foundSurface) {
|
if (!foundSurface) {
|
||||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||||
|
|
||||||
|
@ -166,6 +172,14 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
|
|
||||||
Vector2D surfaceLocal = surfacePos == Vector2D(-1337, -1337) ? surfaceCoords : mouseCoords - surfacePos;
|
Vector2D surfaceLocal = surfacePos == Vector2D(-1337, -1337) ? surfaceCoords : mouseCoords - surfacePos;
|
||||||
|
|
||||||
|
if (pFoundWindow && !pFoundWindow->m_bIsX11 && surfacePos != Vector2D(-1337, -1337)) {
|
||||||
|
// calc for oversized windows... fucking bullshit.
|
||||||
|
wlr_box geom;
|
||||||
|
wlr_xdg_surface_get_geometry(pFoundWindow->m_uSurface.xdg, &geom);
|
||||||
|
|
||||||
|
surfaceLocal = mouseCoords - surfacePos + Vector2D(geom.x, geom.y);
|
||||||
|
}
|
||||||
|
|
||||||
if (pFoundWindow) {
|
if (pFoundWindow) {
|
||||||
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
|
||||||
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
if (*PFOLLOWMOUSE != 1 && !refocus) {
|
||||||
|
@ -173,17 +187,15 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
||||||
// enter if change floating style
|
// enter if change floating style
|
||||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||||
}
|
} else if (*PFOLLOWMOUSE == 2) {
|
||||||
else if (*PFOLLOWMOUSE == 2) {
|
|
||||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||||
}
|
}
|
||||||
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
wlr_seat_pointer_notify_motion(g_pCompositor->m_sSeat.seat, time, surfaceLocal.x, surfaceLocal.y);
|
||||||
return; // don't enter any new surfaces
|
return; // don't enter any new surfaces
|
||||||
} else {
|
} else {
|
||||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
g_pCompositor->focusSurface(foundSurface);
|
g_pCompositor->focusSurface(foundSurface);
|
||||||
|
|
||||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||||
|
@ -195,6 +207,11 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
|
||||||
|
|
||||||
const auto PKEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
|
const auto PKEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
|
||||||
|
|
||||||
|
if (!PKEYBOARD) { // ???
|
||||||
|
Debug::log(ERR, "No active keyboard in onMouseButton??");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (e->state) {
|
switch (e->state) {
|
||||||
case WLR_BUTTON_PRESSED:
|
case WLR_BUTTON_PRESSED:
|
||||||
if (!g_pCompositor->m_sSeat.mouse->currentConstraint)
|
if (!g_pCompositor->m_sSeat.mouse->currentConstraint)
|
||||||
|
@ -280,22 +297,34 @@ void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInputManager::setKeyboardLayout() {
|
void CInputManager::setKeyboardLayout() {
|
||||||
|
for (auto& k : m_lKeyboards)
|
||||||
|
applyConfigToKeyboard(&k);
|
||||||
|
}
|
||||||
|
|
||||||
const auto RULES = g_pConfigManager->getString("input:kb_rules");
|
void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||||
const auto MODEL = g_pConfigManager->getString("input:kb_model");
|
|
||||||
const auto LAYOUT = g_pConfigManager->getString("input:kb_layout");
|
ASSERT(pKeyboard);
|
||||||
const auto VARIANT = g_pConfigManager->getString("input:kb_variant");
|
|
||||||
const auto OPTIONS = g_pConfigManager->getString("input:kb_options");
|
const auto RULES = g_pConfigManager->getString("input:kb_rules");
|
||||||
|
const auto MODEL = g_pConfigManager->getString("input:kb_model");
|
||||||
|
const auto LAYOUT = g_pConfigManager->getString("input:kb_layout");
|
||||||
|
const auto VARIANT = g_pConfigManager->getString("input:kb_variant");
|
||||||
|
const auto OPTIONS = g_pConfigManager->getString("input:kb_options");
|
||||||
|
|
||||||
xkb_rule_names rules = {
|
xkb_rule_names rules = {
|
||||||
.rules = RULES.c_str(),
|
.rules = RULES.c_str(),
|
||||||
.model = MODEL.c_str(),
|
.model = MODEL.c_str(),
|
||||||
.layout = LAYOUT.c_str(),
|
.layout = LAYOUT.c_str(),
|
||||||
.variant = VARIANT.c_str(),
|
.variant = VARIANT.c_str(),
|
||||||
.options = OPTIONS.c_str()
|
.options = OPTIONS.c_str()};
|
||||||
};
|
|
||||||
|
|
||||||
const auto CONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
const auto CONTEXT = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
|
||||||
|
if (!CONTEXT) {
|
||||||
|
Debug::log(ERR, "applyConfigToKeyboard: CONTEXT null??");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
const auto KEYMAP = xkb_keymap_new_from_names(CONTEXT, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
if (!KEYMAP) {
|
if (!KEYMAP) {
|
||||||
|
@ -304,17 +333,7 @@ void CInputManager::setKeyboardLayout() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto PLASTKEEB = m_pActiveKeyboard->keyboard->keyboard;
|
wlr_keyboard_set_keymap(pKeyboard->keyboard->keyboard, KEYMAP);
|
||||||
|
|
||||||
if (!PLASTKEEB) {
|
|
||||||
xkb_keymap_unref(KEYMAP);
|
|
||||||
xkb_context_unref(CONTEXT);
|
|
||||||
|
|
||||||
Debug::log(ERR, "No Seat Keyboard???");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(PLASTKEEB, KEYMAP);
|
|
||||||
|
|
||||||
wlr_keyboard_modifiers wlrMods = {0};
|
wlr_keyboard_modifiers wlrMods = {0};
|
||||||
|
|
||||||
|
@ -327,13 +346,13 @@ void CInputManager::setKeyboardLayout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlrMods.locked != 0) {
|
if (wlrMods.locked != 0) {
|
||||||
wlr_keyboard_notify_modifiers(g_pInputManager->m_pActiveKeyboard->keyboard->keyboard, 0, 0, wlrMods.locked, 0);
|
wlr_keyboard_notify_modifiers(pKeyboard->keyboard->keyboard, 0, 0, wlrMods.locked, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
xkb_keymap_unref(KEYMAP);
|
xkb_keymap_unref(KEYMAP);
|
||||||
xkb_context_unref(CONTEXT);
|
xkb_context_unref(CONTEXT);
|
||||||
|
|
||||||
Debug::log(LOG, "Set the keyboard layout to %s and variant to %s", rules.layout, rules.variant);
|
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) {
|
||||||
|
|
|
@ -53,13 +53,15 @@ public:
|
||||||
|
|
||||||
SKeyboard* m_pActiveKeyboard = nullptr;
|
SKeyboard* m_pActiveKeyboard = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32_t m_uiCapabilities = 0;
|
uint32_t m_uiCapabilities = 0;
|
||||||
|
|
||||||
void mouseMoveUnified(uint32_t, bool refocus = false);
|
void mouseMoveUnified(uint32_t, bool refocus = false);
|
||||||
|
|
||||||
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
STabletTool* ensureTabletToolPresent(wlr_tablet_tool*);
|
||||||
|
|
||||||
|
void applyConfigToKeyboard(SKeyboard*);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CInputManager> g_pInputManager;
|
inline std::unique_ptr<CInputManager> g_pInputManager;
|
|
@ -240,6 +240,10 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||||
|
renderRectWithDamage(box, col, m_RenderData.pDamage, round);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixman_region32_t* damage, int round) {
|
||||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
|
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||||
|
|
||||||
|
@ -279,8 +283,8 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
|
||||||
glEnableVertexAttribArray(m_shQUAD.posAttrib);
|
glEnableVertexAttribArray(m_shQUAD.posAttrib);
|
||||||
glEnableVertexAttribArray(m_shQUAD.texAttrib);
|
glEnableVertexAttribArray(m_shQUAD.texAttrib);
|
||||||
|
|
||||||
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
if (pixman_region32_not_empty(damage)) {
|
||||||
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
PIXMAN_DAMAGE_FOREACH(damage) {
|
||||||
const auto RECT = RECTSARR[i];
|
const auto RECT = RECTSARR[i];
|
||||||
scissor(&RECT);
|
scissor(&RECT);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
@ -299,15 +303,15 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha
|
||||||
renderTexture(CTexture(tex), pBox, alpha, round);
|
renderTexture(CTexture(tex), pBox, alpha, round);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool border) {
|
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool border, bool allowPrimary) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||||
|
|
||||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, border);
|
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, border, false, allowPrimary);
|
||||||
|
|
||||||
scissor((wlr_box*)nullptr);
|
scissor((wlr_box*)nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA) {
|
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA, bool allowPrimary) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||||
|
|
||||||
|
@ -341,6 +345,23 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||||
RASSERT(false, "tex.m_iTarget unsupported!");
|
RASSERT(false, "tex.m_iTarget unsupported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stencil for when we want a border
|
||||||
|
if (border) {
|
||||||
|
glClearStencil(0);
|
||||||
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
|
glStencilFunc(GL_ALWAYS, 1, -1);
|
||||||
|
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||||
|
|
||||||
|
// hacky fix to fix broken borders.
|
||||||
|
// TODO: this is kinda slow... question mark?
|
||||||
|
renderRect(pBox, CColor(0, 0, 0, 0), round);
|
||||||
|
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(tex.m_iTarget, tex.m_iTexID);
|
glBindTexture(tex.m_iTarget, tex.m_iTexID);
|
||||||
|
|
||||||
|
@ -357,8 +378,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||||
// so we need to do some maf
|
// so we need to do some maf
|
||||||
|
|
||||||
const auto TOPLEFT = Vector2D(round, round);
|
const auto TOPLEFT = Vector2D(round, round);
|
||||||
const auto BOTTOMRIGHT = Vector2D(tex.m_vSize.x - round, tex.m_vSize.y - round);
|
const auto BOTTOMRIGHT = Vector2D(pBox->width - round, pBox->height - round);
|
||||||
const auto FULLSIZE = tex.m_vSize;
|
const auto FULLSIZE = Vector2D(pBox->width, pBox->height);
|
||||||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||||
|
|
||||||
// Rounded corners
|
// Rounded corners
|
||||||
|
@ -369,22 +390,23 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||||
glUniform1i(glGetUniformLocation(shader->program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !border && !noAA));
|
glUniform1i(glGetUniformLocation(shader->program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !border && !noAA));
|
||||||
|
|
||||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
|
||||||
|
if (allowPrimary && m_RenderData.renderingPrimarySurface && 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
|
||||||
|
m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom right
|
||||||
|
m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVBottomRight.y, // bottom left
|
||||||
|
};
|
||||||
|
|
||||||
|
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
|
||||||
|
} else {
|
||||||
|
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
}
|
||||||
|
|
||||||
glEnableVertexAttribArray(shader->posAttrib);
|
glEnableVertexAttribArray(shader->posAttrib);
|
||||||
glEnableVertexAttribArray(shader->texAttrib);
|
glEnableVertexAttribArray(shader->texAttrib);
|
||||||
|
|
||||||
// stencil for when we want a border
|
|
||||||
if (border) {
|
|
||||||
glClearStencil(0);
|
|
||||||
glClear(GL_STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
glEnable(GL_STENCIL_TEST);
|
|
||||||
|
|
||||||
glStencilFunc(GL_ALWAYS, 1, -1);
|
|
||||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
||||||
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
||||||
const auto RECT = RECTSARR[i];
|
const auto RECT = RECTSARR[i];
|
||||||
|
@ -394,6 +416,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
||||||
}
|
}
|
||||||
|
|
||||||
if (border) {
|
if (border) {
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
glStencilFunc(GL_EQUAL, 1, -1);
|
glStencilFunc(GL_EQUAL, 1, -1);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
}
|
}
|
||||||
|
@ -540,9 +564,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
||||||
|
|
||||||
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||||
|
static auto* const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
|
||||||
|
|
||||||
if (*PBLURENABLED == 0) {
|
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1))) {
|
||||||
renderTexture(tex, pBox, a, round, false, border);
|
renderTexture(tex, pBox, a, round, false, border, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,17 +624,26 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
||||||
if (pixman_region32_not_empty(&damage)) {
|
if (pixman_region32_not_empty(&damage)) {
|
||||||
// render our great blurred FB
|
// render our great blurred FB
|
||||||
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
||||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage);
|
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage, 0, false, false, false, true);
|
||||||
|
|
||||||
// render the window, but clear stencil
|
// render the window, but clear stencil
|
||||||
glClearStencil(0);
|
glClearStencil(0);
|
||||||
glClear(GL_STENCIL_BUFFER_BIT);
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
// and write to it
|
// draw window
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true, true);
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
|
// prep stencil for border
|
||||||
glStencilFunc(GL_ALWAYS, 1, -1);
|
glStencilFunc(GL_ALWAYS, 1, -1);
|
||||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
|
||||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
|
if (border) {
|
||||||
|
// hacky fix to fix broken borders.
|
||||||
|
// TODO: this is kinda slow... question mark?
|
||||||
|
renderRectWithDamage(pBox, CColor(0,0,0,0), &damage, round);
|
||||||
|
}
|
||||||
|
|
||||||
// then stop
|
// then stop
|
||||||
glStencilFunc(GL_EQUAL, 1, -1);
|
glStencilFunc(GL_EQUAL, 1, -1);
|
||||||
|
@ -649,7 +683,7 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int thick, i
|
||||||
box->width += 2 * thick;
|
box->width += 2 * thick;
|
||||||
box->height += 2 * thick;
|
box->height += 2 * thick;
|
||||||
|
|
||||||
round += thick * m_RenderData.pMonitor->scale; // cuz yeah
|
round += thick; // cuz yeah
|
||||||
|
|
||||||
// only draw on non-stencild.
|
// only draw on non-stencild.
|
||||||
glStencilFunc(GL_NOTEQUAL, 1, -1);
|
glStencilFunc(GL_NOTEQUAL, 1, -1);
|
||||||
|
|
|
@ -34,6 +34,10 @@ struct SCurrentRenderData {
|
||||||
float projection[9];
|
float projection[9];
|
||||||
|
|
||||||
pixman_region32_t* pDamage = nullptr;
|
pixman_region32_t* pDamage = nullptr;
|
||||||
|
|
||||||
|
bool renderingPrimarySurface = false;
|
||||||
|
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||||
|
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SMonitorRenderData {
|
struct SMonitorRenderData {
|
||||||
|
@ -53,8 +57,9 @@ public:
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
void renderRect(wlr_box*, const CColor&, int round = 0);
|
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(wlr_texture*, wlr_box*, float a, int round = 0);
|
||||||
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false);
|
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false, bool allowPrimary = false);
|
||||||
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);
|
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);
|
||||||
|
|
||||||
void makeWindowSnapshot(CWindow*);
|
void makeWindowSnapshot(CWindow*);
|
||||||
|
@ -110,7 +115,7 @@ private:
|
||||||
// returns the out FB, can be either Mirror or MirrorSwap
|
// returns the out FB, can be either Mirror or MirrorSwap
|
||||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
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 border = false, bool noAA = false);
|
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false, bool noAA = false, bool allowPrimary = false);
|
||||||
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
|
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,12 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||||
|
|
||||||
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding;
|
||||||
|
|
||||||
if (RDATA->surface && surface == RDATA->surface)
|
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, RDATA->decorate);
|
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, RDATA->decorate);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false);
|
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false);
|
||||||
|
|
||||||
|
@ -142,6 +146,8 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||||
|
|
||||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||||
const auto REALPOS = pWindow->m_vRealPosition.vec() + PWORKSPACE->m_vRenderOffset.vec();
|
const auto REALPOS = pWindow->m_vRealPosition.vec() + PWORKSPACE->m_vRenderOffset.vec();
|
||||||
|
static const auto PNOFLOATINGBORDERS = &g_pConfigManager->getConfigValuePtr("general:no_border_on_floating")->intValue;
|
||||||
|
|
||||||
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
SRenderData renderdata = {pMonitor->output, time, REALPOS.x, REALPOS.y};
|
||||||
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
renderdata.surface = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||||
renderdata.w = std::clamp(pWindow->m_vRealSize.vec().x, (double)5, (double)1337420); // clamp the size to min 5,
|
renderdata.w = std::clamp(pWindow->m_vRealSize.vec().x, (double)5, (double)1337420); // clamp the size to min 5,
|
||||||
|
@ -149,7 +155,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||||
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
|
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
|
||||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
|
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_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.decorate = decorate && !pWindow->m_bX11DoesntWantBorders;
|
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true);
|
||||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||||
|
|
||||||
// apply window special data
|
// apply window special data
|
||||||
|
@ -164,8 +170,30 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
||||||
for (auto& wd : pWindow->m_dWindowDecorations)
|
for (auto& wd : pWindow->m_dWindowDecorations)
|
||||||
wd->draw(pMonitor);
|
wd->draw(pMonitor);
|
||||||
|
|
||||||
|
if (!pWindow->m_bIsX11) {
|
||||||
|
|
||||||
|
// To everyone who makes apps with improperly aligned surfaces,
|
||||||
|
// For example chromium, or GTK devs who allow shadows on windows,
|
||||||
|
// a sincere FUCK YOU.
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata);
|
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) {
|
if (pWindow->m_bIsX11) {
|
||||||
if (pWindow->m_uSurface.xwayland->surface) {
|
if (pWindow->m_uSurface.xwayland->surface) {
|
||||||
wlr_surface_for_each_surface(pWindow->m_uSurface.xwayland->surface, renderSurface, &renderdata);
|
wlr_surface_for_each_surface(pWindow->m_uSurface.xwayland->surface, renderSurface, &renderdata);
|
||||||
|
|
Loading…
Reference in a new issue