Compare commits

..

83 Commits

Author SHA1 Message Date
Kainoa Kanter
64f6818a13 :finnadie:
https://www.youtube.com/watch?v=_asNhzXq72w
2022-06-22 15:22:22 -07:00
ThatOneCalculator
2631489a18 Syntax error in CI 2022-06-22 15:17:21 -07:00
ThatOneCalculator
5614f28dfd T1C: CMake Release Pipeline (CI) 2022-06-23 00:11:57 +02:00
ThatOneCalculator
a98c07cd00 Merge branch 'main' of https://github.com/hyprwm/Hyprland 2022-06-22 13:24:31 -07:00
Mihai Fufezan
11a5e6bcbf nix: revert to original wlroots repo 2022-06-22 23:23:46 +03:00
ThatOneCalculator
6eefd294af Upload release archive 2022-06-22 13:18:09 -07:00
ThatOneCalculator
606f4b0794 Fix release action 2022-06-22 13:09:37 -07:00
Kainoa Kanter
ff6e3a4d24 T1C: Releases pipeline 2022-06-22 22:04:55 +02:00
Kainoa Kanter
c21b062fe5 Delete aur directory 2022-06-22 11:25:41 -07:00
vaxerski
19d94b87ab Added keybind submaps 2022-06-22 20:23:20 +02:00
Vaxry
bd41776a5a Merge pull request #227 from fufexan/meson
Nix: use meson for builds
2022-06-22 16:20:02 +01:00
vaxerski
c2ff3d9e76 more shadow for readme banner 2022-06-22 16:01:51 +02:00
vaxerski
dbd060247e README better banner 2022-06-22 16:00:52 +02:00
vaxerski
0ec903808b don't use sudo in make config 2022-06-22 15:52:36 +02:00
vaxerski
770bada5d5 Fixed oversized apps' incorrect layout 2022-06-22 15:45:56 +02:00
vaxerski
499d2e41bf default apply_sens_to_raw to 0 2022-06-22 13:01:59 +02:00
vaxerski
d614fa895e Merge pull request #245 from taylor85345/main
Fixed crash on movetoworkspacesilent
2022-06-22 00:14:36 +01:00
taylor85345
b9f542a60f Fixed crash on movetoworkspacesilent 2022-06-21 16:13:05 -07:00
vaxerski
4c2459861b fix borders sometimes disappearing on certain windows 2022-06-21 23:09:20 +02:00
vaxerski
0f1ad16aec added general:no_border_on_floating 2022-06-21 22:54:41 +02:00
vaxerski
5541098f20 Added bindl 2022-06-21 22:47:27 +02:00
vaxerski
48e33023af fix crash on number workspace with null mon 2022-06-21 22:42:54 +02:00
vaxerski
0b6c04355a Merge pull request #239 from SebOuellette/main
Optimize cursor constraints for games
2022-06-21 21:34:31 +01:00
vaxerski
33abb6a5bf dang it autoformat 2022-06-21 22:30:07 +02:00
vaxerski
1810725a0c cleaner code 2022-06-21 22:29:11 +02:00
vaxerski
84d6e640ff support all workspace types in workspace keyword 2022-06-21 22:25:54 +02:00
SebOuellette
20ad9d3e7d Passes all constraint tests!
So a summary of what's been done in this fork/PR. Instead of moving the cursor, we're warp_closest ing. warp_absolute didn't work, so warp closest has kindof an auto constrain feature so it works beautifully. I'm also contraining to the right side of the window - 1, because the cursors are treating that pixel as the next pixel over, so it was actually thinking it was on the next monitor (assuming fullscreen) when the cursor got to the right or bottom of the window. TL;DR rounding issue.

This fix didn't work when you had a fullscreen video playing on a monitor beside, so I also fixed that by ignoring all focus changes or whatever when a constraint actually occured, we obviously just don't want to focus another monitor when constrained, so why not just *disable it when a constraint happened*

The PR is now ready, I love Hyprland, and I can't wait to contribute more :)
2022-06-21 16:25:40 -04:00
vaxerski
4a3f9ccba2 move ignore to eventmanager and fix double focus in changeworkspace 2022-06-21 22:17:30 +02:00
vaxerski
ff49f22440 fix rapid blinking on launch 2022-06-21 22:13:13 +02:00
vaxerski
a2fa1bc80d fix CMake debug mode 2022-06-21 22:09:46 +02:00
Mihai Fufezan
593f24a2ec workflows: add meson version updater and update versions 2022-06-21 22:28:20 +03:00
Mihai Fufezan
8bd7234d72 nix: change build system to meson
flake.nix: change wlroots url to mirror, update version
flake.lock: update wlroots & nixpkgs
nix/update-inputs.sh: update wlroots url
2022-06-21 22:11:46 +03:00
vaxerski
f58bb0187b Merge pull request #241 from viperML/main
Nix: refactor packages and overlays
2022-06-21 11:29:35 +01:00
SebOuellette
3dc2277fd0 Actually, mostly working.
One failure case: When there is a fullscreen window directly to the right of a game, for example, in a multimonitor setup, then the cursor will bug out in between the monitors. sometimes it will get constrained to the border, but just outside the window (which is what this PR fixes, so it's unusual) and sometimes the cursor will just ignore the constraint entirely. However this is only in the one case.
2022-06-21 02:23:57 -04:00
SebOuellette
ee7900f819 Mouse no longer removes focus from constraining window
The window properly constrains the mouse now

I do still notice a bug with moving the mouse in games, if you don't move the mouse fast enough, some games will not register the mouse movement. This doesn't happen in KDE so I know it's related somehow
2022-06-20 23:15:16 -04:00
Sebastian Ouellette
f7e9a27c0a Merge branch 'vaxerski:main' into main 2022-06-20 22:05:02 -04:00
vaxerski
f5f531562b Merge pull request #205 from sp1ritCS/meson
Added meson buildfiles
2022-06-20 13:56:58 +01:00
Fernando Ayats
4efd913de8 nix: use the overlay in the module 2022-06-20 13:04:40 +02:00
Fernando Ayats
bd95301188 nix: no pseudo-overlay 2022-06-20 12:16:07 +02:00
Fernando Ayats
d6b324306b nix: add a proper overlay and cleanup flake 2022-06-20 11:50:06 +02:00
Sebastian Ouellette
dc84935059 Set the constraint position to the window center (properly)
Missed one expression, it was set to the bottom middle. I missed it because i don't have an extra monitor extending from the bottom of that screen.
2022-06-19 16:54:59 -04:00
Sebastian Ouellette
95e083dbd3 Converted tabs to spaces. Now ready for PR 2022-06-19 16:51:03 -04:00
SebOuellette
39d03fc196 Removed the log file which was causing conflicts 2022-06-19 16:24:30 -04:00
SebOuellette
5058a74453 Cleaned up some old debug 2022-06-19 16:23:49 -04:00
Sebastian Ouellette
ae1bcc909d Invisible cursors are constrained to center
This is a first version of my test to properly constrain cursors. This is mostly working in the buggy applications I had before, but I feel that the cursor needs to actually move around, instead of being locked to the center of the window. 

This may cause problems when locking to the edge, but yeah.
2022-06-19 16:07:41 -04:00
Florian "sp1rit"​
7c3626f15e meson: ensure non-debug builds will use proper configuration
meson will set add -DHYPRLAND_DEBUG to CXXFLAGS during compilation of
debug builds. this avoids NDEBUG issues with wlroots and ensures asserts
will also work on release builds.
2022-06-18 13:09:38 +02:00
vaxerski
f7bdc2e870 Merge pull request #234 from alba4k/main
revised makefile, newline after execution
2022-06-17 21:23:48 +01:00
alba4k
faa1b5a44f Update main.cpp 2022-06-17 22:02:57 +02:00
Yoni FIRROLONI
f428604b6f undo formatting 2022-06-17 19:51:34 +01:00
Yoni FIRROLONI
2feca08a67 move, set active, recalc, anim on monitor connected 2022-06-17 19:51:34 +01:00
vaxerski
837d4af8f6 Merge pull request #231 from CcydtN/main
Fix zombie process problem
2022-06-17 17:53:47 +01:00
alba4k
9c6c5481bb revised makefile, newline after execution 2022-06-17 12:18:25 +02:00
Florian "sp1rit"​
75918c14d7 meson: added wayland dependencies to main executable 2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
d179501c4f meson: added default_library=static as default option 2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
8e203b0da3 added assets/wallpapers to install 2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
09cd8c45a6 dropped emoticons from meson workflow 2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
43065657c9 actions: added meson workflow 2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
89454ada6c added runtime tag to the wayland-session launchable and sample config
this allows for a small-install footprint by running
    meson install -C _build --tags runtime
2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
c169f94895 moved wlroots/xwayland definitions to the main meson file
prevents build-failure when xwayland is disabled to to
    add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
beeing called after the required wayland protocols have been built.
2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
b3ef1fcc54 replaced source list with globber script
See:
  - https://mesonbuild.com/FAQ.html#why-cant-i-specify-target-files-with-a-wildcard
  - https://github.com/vaxerski/Hyprland/pull/205#issuecomment-1154158918
2022-06-16 23:30:30 +02:00
Florian "sp1rit"​
fd0112425f Added meson buildfiles
this makes for a far better experience in combination with wlroots,
since that whole makefile mess is not required.
Additionaly, handling of wayland protocol sources is also slightly
better, but could be improved with mesons inbuilt wayland module.

To build Hyprland using meson:
    meson _build -Ddefault_library=static
    ninja -C _build
    ninja -C _build install
2022-06-16 23:30:28 +02:00
CcydtN
b69375a918 Fixing format issue 2022-06-17 03:25:08 +08:00
vaxerski
354e265128 Merge pull request #230 from bazuin-32/main
Resolves #204. Enables numlock on startup when configured to do so
2022-06-16 18:33:37 +01:00
CcydtN
5fa61e5a54 Fix generating zombie process 2022-06-17 01:14:10 +08:00
bazuin-32
1926bb4659 Resolves #204. Enables numlock on startup when configured to do so. 2022-06-16 10:49:16 -06:00
vaxerski
36ea12b315 Merge pull request #223 from PowerBall253/main
Create config directory if it doesn't exist
2022-06-15 07:41:05 +01:00
Bruno Ancona
0c5d2f04b4 Create config directory if it doesn't exist 2022-06-15 01:29:51 -05:00
vaxerski
fa6530c7e8 Merge pull request #213 from ThatOneCalculator/mirror
Change wlroots submodule url to github mirror
2022-06-13 22:16:28 +01:00
ThatOneCalculator
e97b83167f Change wlroots submodule url to github mirror 2022-06-13 14:10:49 -07:00
vaxerski
9aec355727 update contrib link in readme 2022-06-13 21:30:01 +01:00
vaxerski
a4e21a25f4 Merge pull request #200 from siemato/main
Added Touchpad Config options
2022-06-13 17:30:17 +01:00
Marco Siedentopf
f13217f698 Codestyle 2022-06-12 15:06:58 +00:00
Marco Siedentopf
85d2c1d5a6 Merge branch 'vaxerski:main' into main 2022-06-12 15:04:02 +00:00
vaxerski
2208be5175 Merge pull request #197 from spectreseven1138/main
Add loose follow_mouse option
2022-06-12 14:31:07 +02:00
spectreseven1138
46d11f7646 Access config value statically 2022-06-12 16:31:56 +09:00
Marco Siedentopf
16d1b44ef9 Implemented Config options for Touchpads
Implemented Options to 1. toggle between clickfinger behavior and software buttons, 2. button emulation and 3. tap-to-click
2022-06-12 05:40:06 +00:00
Marco Siedentopf
e69f2ab4c3 Added Config options for Touchpads
Added Options to 1. toggle between clickfinger behavior and software buttons, 2. middle button emulation and 3. tap-to-click
2022-06-12 05:40:01 +00:00
spectreseven1138
95a626f72e Add loose (2) option to follow_mouse config 2022-06-12 09:14:22 +09:00
vaxerski
70eb5053fb Note Hypr and Hyprland's differences in readme 2022-06-11 21:10:41 +01:00
vaxerski
48ab282a69 Merge pull request #195 from PowerBall253/main
Add natural_scrolling option for touchpads only
2022-06-11 18:26:24 +02:00
Bruno Ancona
018b0684dd Add natural_scrolling option for touchpads only 2022-06-11 10:24:00 -05:00
vaxerski
94528bcdbc Merge pull request #194 from frigaut/main
fullscreen fix
2022-06-11 17:06:19 +02:00
Francois Rigaut
4fa69497ca fullscreen fix 2022-06-11 16:37:40 +02:00
48 changed files with 791 additions and 446 deletions

View File

@@ -13,31 +13,73 @@ jobs:
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
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
- name: Set up user
run: |
useradd -m githubuser
echo -e "root ALL=(ALL:ALL) ALL\ngithubuser ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers
- name: Build wlroots
run: |
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 .."
- name: Fix permissions for git
run: |
git config --global --add safe.directory /__w/Hyprland/Hyprland
- name: Checkout Hyprland
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build Hyprland With default settings
- name: Build Hyprland
run: |
git submodule sync --recursive && git submodule update --init --force --recursive
make all
- name: Build Hyprland with LEGACY_RENDERER
- name: Compress and package artifacts
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:
name: "Build Hyprland with Meson (Arch)"
runs-on: ubuntu-latest
container:
image: archlinux
steps:
- name: Download dependencies
run: |
sed -i 's/SigLevel = Required DatabaseOptional/SigLevel = Optional TrustAll/' /etc/pacman.conf
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 go clang lld libc++ pkgconf meson ninja wayland wayland-protocols libinput libxkbcommon pixman glm libdrm libglvnd cairo pango systemd scdoc base-devel seatd
- name: Checkout Hyprland
uses: actions/checkout@v3
with:
submodules: true
- name: Configure
run: |
meson obj-x86_64-pc-linux-gnu \
-Ddefault_library=static
- name: Compile
run: ninja -C obj-x86_64-pc-linux-gnu
# - name: Compress artifacts
# run: |
# mkdir x86_64-pc-linux-gnu
# 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
# - name: Upload artifacts
# uses: actions/upload-artifact@v3
# with:
# name: Build artifacts (x86_64-pc-linux-gnu)
# path: x86_64-pc-linux-gnu.tar.xz

26
.github/workflows/version-update.sh vendored Normal file
View 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"

4
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "wlroots"]
path = wlroots
url = https://gitlab.freedesktop.org/wlroots/wlroots
path = subprojects/wlroots
url = https://gitlab.freedesktop.org/wlroots/wlroots.git

View File

@@ -35,7 +35,7 @@ execute_process(
#
#
include_directories(.)
include_directories(. PRIVATE "subprojects/wlroots/include/")
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
find_package(Threads REQUIRED)
@@ -59,6 +59,7 @@ ENDIF(NO_XWAYLAND MATCHES true)
IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
message(STATUS "Configuring Hyprland in Debug with CMake!")
add_definitions( -DHYPRLAND_DEBUG )
ELSE()
# add_compile_options(-O3) # may crash for some
message(STATUS "Configuring Hyprland in Release with CMake!")

View File

@@ -129,11 +129,11 @@ protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-scree
config:
make protocols
sed -i -E 's/(soversion = 11)([^032]|$$)/soversion = 11032/g' ./wlroots/meson.build
sed -i -E 's/(soversion = 11)([^032]|$$)/soversion = 11032/g' subprojects/wlroots/meson.build
rm -rf ./wlroots/build
rm -rf ./subprojects/wlroots/build
cd wlroots && meson ./build --prefix=/usr --buildtype=release
cd wlroots && ninja -C build/
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=release
cd subprojects/wlroots && ninja -C build/
cd wlroots && sudo ninja -C build/ install
cd subprojects/wlroots && ninja -C build/ install

View File

@@ -1,6 +1,6 @@
<div align = center>
![Banner]
<img src="https://raw.githubusercontent.com/vaxerski/Hyprland/main/assets/header.svg" width="1000" height="500" alt="banner">
<br>
@@ -19,6 +19,7 @@ Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sa
For Hyprland without the `land` part, see [Hypr], the Xorg window manager.
Please note, especially for folks moving from Hypr, that Hyprland and Hypr share a very different feature set and are not 1:1 experiences.
<br>
<br>
@@ -129,7 +130,7 @@ Try it out and report bugs / suggestions!
[Issues]: https://github.com/vaxerski/Hyprland/issues
[Todo]: https://github.com/vaxerski/Hyprland/projects?type=beta
[Contribute]: docs/Contribute.md
[Contribute]: https://github.com/vaxerski/Hyprland/wiki/Contributing-&-Debugging
[Install]: https://github.com/vaxerski/Hyprland/wiki/Installation
[Quick Start]: https://github.com/vaxerski/Hyprland/wiki/Quick-start
[License]: LICENSE
@@ -150,7 +151,6 @@ Try it out and report bugs / suggestions!
[Preview A]: https://i.imgur.com/NbrTnZH.png
[Preview B]: https://i.imgur.com/ZA4Fa8R.png
[Preview C]: https://i.imgur.com/BpXxM8H.png
[Banner]: https://raw.githubusercontent.com/vaxerski/Hyprland/main/assets/hyprland.png
<!----------------------------------{ Badges }--------------------------------->

83
assets/header.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 798 KiB

5
assets/meson.build Normal file
View File

@@ -0,0 +1,5 @@
wallpapers = ['wall_2K.png', 'wall_4K.png', 'wall_8K.png']
foreach wallpaper : wallpapers
install_data(wallpapers, install_dir: join_paths(get_option('datadir'), 'hyprland'), install_tag: 'runtime')
endforeach

View File

@@ -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}"
}

View File

@@ -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}"
}

View File

@@ -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}"
}

View File

@@ -27,6 +27,8 @@ general {
col.active_border=0x66ee1111
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
}

2
example/meson.build Normal file
View File

@@ -0,0 +1,2 @@
install_data('hyprland.conf', install_dir: join_paths(get_option('datadir'), 'hyprland'), install_tag: 'runtime')
install_data('hyprland.desktop', install_dir: join_paths(get_option('datadir'), 'wayland-sessions'), install_tag: 'runtime')

6
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1654593855,
"narHash": "sha256-c+SyXvj7THre87OyIdZfRVR+HhI/g1ZDrQ3VUtTuHkU=",
"lastModified": 1655807518,
"narHash": "sha256-5YV29Ry/DpAJc/0Hc/+ISVBAjwHpJvAkeKkcUG5lWsc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "033bd4fa9a8fbe0c68a88e925d9a884161044b25",
"rev": "a72d7811be1162dd6804c4e36e5402d76fb6e921",
"type": "github"
},
"original": {

View File

@@ -16,40 +16,37 @@
}: let
inherit (nixpkgs) lib;
genSystems = lib.genAttrs [
# Add more systems if they are supported
"x86_64-linux"
];
pkgsFor = nixpkgs.legacyPackages;
# https://github.com/NixOS/rfcs/pull/107
mkVersion = longDate:
lib.concatStrings [
"0.pre"
"+date="
(lib.concatStringsSep "-" [
(__substring 0 4 longDate)
(__substring 4 2 longDate)
(__substring 6 2 longDate)
])
];
mkDate = longDate: (lib.concatStringsSep "-" [
(__substring 0 4 longDate)
(__substring 4 2 longDate)
(__substring 6 2 longDate)
]);
in {
packages = genSystems (system: {
wlroots = pkgsFor.${system}.wlroots.overrideAttrs (prev: {
version = mkVersion (toString (inputs.wlroots.lastModifiedDate or inputs.wlroots.lastModified or "19700101"));
overlays.default = _: prev: rec {
wlroots-hyprland = prev.wlroots.overrideAttrs (__: {
version = mkDate (inputs.wlroots.lastModifiedDate or "19700101");
src = inputs.wlroots;
});
default = pkgsFor.${system}.callPackage ./nix/default.nix {
version = mkVersion (toString (self.lastModifiedDate or self.lastModified or "19700101"));
inherit (self.packages.${system}) wlroots;
hyprland = prev.callPackage ./nix/default.nix {
version = "0.5.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
wlroots = wlroots-hyprland;
};
});
};
packages = genSystems (system:
(self.overlays.default null pkgsFor.${system})
// {
default = self.packages.${system}.hyprland;
});
formatter = genSystems (system: pkgsFor.${system}.alejandra);
nixosModules.default = import ./nix/module.nix self;
# Deprecated
overlays.default = _: prev: {
hyprland = self.packages.${prev.system}.default;
};
overlay = self.overlays.default;
overlay = throw "Hyprland: .overlay output is deprecated, please use the .overlays.default output";
};
}

View File

@@ -1,4 +1,4 @@
clean:
rm -rf ./hyprctl ./hyprctl
all:
g++ -std=c++20 ./main.cpp -o ./hyprctl
g++ -std=c++20 ./main.cpp -o ./hyprctl
clean:
rm ./hyprctl

View File

@@ -15,8 +15,7 @@
#include <fstream>
#include <string>
const std::string USAGE = R"#(
usage: hyprctl [command] [(opt)args]
const std::string USAGE = R"#(usage: hyprctl [command] [(opt)args]
monitors
workspaces
@@ -27,8 +26,7 @@ usage: hyprctl [command] [(opt)args]
dispatch
keyword
version
reload
)#";
reload)#";
void request(std::string arg) {
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -121,7 +119,7 @@ int main(int argc, char** argv) {
int bflag = 0, sflag = 0, index, c;
if (argc < 2) {
printf("%s", USAGE.c_str());
printf("%s\n", USAGE.c_str());
return 1;
}
@@ -136,10 +134,12 @@ int main(int argc, char** argv) {
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv);
else if (!strcmp(argv[1], "--batch")) batchRequest(argc, argv);
else if (!strcmp(argv[1], "--help")) printf("%s", USAGE.c_str());
else {
printf("%s", USAGE.c_str());
printf("%s\n", USAGE.c_str());
return 1;
}
printf("\n");
return 0;
}
}

3
hyprctl/meson.build Normal file
View File

@@ -0,0 +1,3 @@
executable('hyprctl', 'main.cpp',
install: true
)

26
meson.build Normal file
View File

@@ -0,0 +1,26 @@
project('Hyprland', 'cpp', 'c',
version : '0.5.0beta',
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')
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
add_project_arguments('-DNO_XWAYLAND', language: 'cpp')
endif
if get_option('buildtype') == 'debug'
add_project_arguments('-DHYPRLAND_DEBUG', language: 'cpp')
endif
subdir('protocols')
subdir('src')
subdir('hyprctl')
subdir('assets')
subdir('example')

1
meson_options.txt Normal file
View File

@@ -0,0 +1 @@
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')

View File

@@ -3,7 +3,7 @@
stdenv,
fetchFromGitHub,
pkg-config,
cmake,
meson,
ninja,
libdrm,
libinput,
@@ -27,7 +27,7 @@ stdenv.mkDerivation {
src = ../.;
nativeBuildInputs = [
cmake
meson
ninja
pkg-config
];
@@ -48,33 +48,14 @@ stdenv.mkDerivation {
]
++ lib.optional enableXWayland xwayland;
cmakeFlags =
["-DCMAKE_BUILD_TYPE=Release"]
++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
mesonBuildType = "release";
# enables building with nix-supplied wlroots instead of submodule
prePatch = ''
sed -Ei 's/"\.\.\/wlroots\/include\/([a-zA-Z0-9./_-]+)"/<\1>/g' src/includes.hpp
'';
postPatch = ''
make protocols
'';
mesonFlags = lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
postBuild = ''
pushd ../hyprctl
make all
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
'';
patches = [
# make meson use the provided wlroots instead of the git submodule
./meson-build.patch
];
passthru.providedSessions = ["hyprland"];

36
nix/meson-build.patch Normal file
View 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'),

View File

@@ -19,7 +19,7 @@ in {
package = mkOption {
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";
example = literalExpression "<Hyprland flake>.packages.<system>.default.override { }";
description = ''

51
protocols/meson.build Normal file
View File

@@ -0,0 +1,51 @@
wayland_protos = dependency('wayland-protocols',
version: '>=1.25',
fallback: 'wayland-protocols',
default_options: ['tests=false'],
)
wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
wayland_scanner_dep = dependency('wayland-scanner', native: true)
wayland_scanner = find_program(
wayland_scanner_dep.get_variable('wayland_scanner'),
native: true,
)
protocols = [
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
['wlr-layer-shell-unstable-v1.xml'],
['ext-workspace-unstable-v1.xml'],
['pointer-constraints-unstable-v1.xml'],
['tablet-unstable-v2.xml'],
['idle.xml']
]
wl_protos_src = []
wl_protos_headers = []
foreach p : protocols
xml = join_paths(p)
wl_protos_src += custom_target(
xml.underscorify() + '_server_c',
input: xml,
output: '@BASENAME@-protocol.c',
command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
)
wl_protos_headers += custom_target(
xml.underscorify() + '_server_h',
input: xml,
output: '@BASENAME@-protocol.h',
command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'],
)
endforeach
wayland_server = dependency('wayland-server', version: '>=1.20.0')
lib_server_protos = static_library(
'server_protos',
wl_protos_src + wl_protos_headers,
dependencies: wayland_server.partial_dependency(compile_args: true),
)
server_protos = declare_dependency(
link_with: lib_server_protos,
sources: wl_protos_headers,
)

View File

@@ -443,7 +443,11 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
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) {
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.y = pos.y - pWindow->m_vRealPosition.vec().y;
sl.x += geom.x;
sl.y += geom.y;
return PSURFACE->surface;
}

View File

@@ -20,7 +20,7 @@ CConfigManager::CConfigManager() {
void CConfigManager::setDefaultVars() {
configValues["general:max_fps"].intValue = 240;
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_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:border_size"].intValue = 1;
configValues["general:no_border_on_floating"].intValue = 0;
configValues["general:gaps_in"].intValue = 5;
configValues["general:gaps_out"].intValue = 20;
configValues["general:col.active_border"].intValue = 0xffffffff;
@@ -46,6 +47,7 @@ void CConfigManager::setDefaultVars() {
configValues["decoration:inactive_opacity"].floatValue = 1;
configValues["decoration:fullscreen_opacity"].floatValue = 1;
configValues["decoration:multisample_edges"].intValue = 0;
configValues["decoration:no_blur_on_oversized"].intValue = 1;
configValues["dwindle:pseudotile"].intValue = 0;
configValues["dwindle:col.group_border"].intValue = 0x66777700;
@@ -84,7 +86,11 @@ void CConfigManager::setDefaultVars() {
configValues["input:natural_scroll"].intValue = 0;
configValues["input:numlock_by_default"].intValue = 0;
configValues["input:force_no_accel"].intValue = 0;
configValues["input:touchpad:natural_scroll"].intValue = 0;
configValues["input:touchpad:disable_while_typing"].intValue = 1;
configValues["input:touchpad:clickfinger_behavior"].intValue = 0;
configValues["input:touchpad:middle_button_emulation"].intValue = 0;
configValues["input:touchpad:tap-to-click"].intValue = 1;
configValues["input:follow_mouse"].intValue = 1;
@@ -166,11 +172,47 @@ void CConfigManager::handleRawExec(const std::string& command, const std::string
Debug::log(LOG, "Config executing %s", toExec.c_str());
if (fork() == 0) {
execl("/bin/sh", "/bin/sh", "-c", toExec.c_str(), nullptr);
int socket[2];
if (pipe(socket) != 0) {
Debug::log(LOG, "Unable to create pipe for fork");
}
pid_t child, grandchild;
child = fork();
if (child < 0) {
close(socket[0]);
close(socket[1]);
Debug::log(LOG, "Fail to create the first fork");
return;
}
if (child == 0) {
// run in child
grandchild = fork();
if (grandchild == 0) {
// run in grandchild
close(socket[0]);
close(socket[1]);
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
// exit grandchild
_exit(0);
}
close(socket[0]);
write(socket[1], &grandchild, sizeof(grandchild));
close(socket[1]);
// exit child
_exit(0);
}
// run in parent
close(socket[1]);
read(socket[0], &grandchild, sizeof(grandchild));
close(socket[0]);
// clear child and leave child to init
waitpid(child, NULL, 0);
if (child < 0) {
Debug::log(LOG, "Fail to create the second fork");
return;
}
Debug::log(LOG, "Process created with pid %d", grandchild);
}
void CConfigManager::handleMonitor(const std::string& command, const std::string& args) {
@@ -375,7 +417,7 @@ void CConfigManager::handleAnimation(const std::string& command, const std::stri
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:
// bind=SUPER,G,exec,dmenu_run <args>
@@ -408,7 +450,7 @@ void CConfigManager::handleBind(const std::string& command, const std::string& v
}
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) {
@@ -455,16 +497,23 @@ void CConfigManager::handleWindowRule(const std::string& command, const std::str
void CConfigManager::handleDefaultWorkspace(const std::string& command, const std::string& value) {
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) {
if (mr.name == DISPLAY) {
mr.defaultWorkspaceID = WORKSPACEID;
mr.defaultWorkspace = WORKSPACE;
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) {
static const char* const ENVHOME = getenv("HOME");
@@ -538,12 +587,14 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
}
else if (COMMAND == "monitor") handleMonitor(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 == "workspace") handleDefaultWorkspace(COMMAND, VALUE);
else if (COMMAND == "windowrule") handleWindowRule(COMMAND, VALUE);
else if (COMMAND == "bezier") handleBezier(COMMAND, VALUE);
else if (COMMAND == "animation") handleAnimation(COMMAND, VALUE);
else if (COMMAND == "source") handleSource(COMMAND, VALUE);
else if (COMMAND == "submap") handleSubmap(COMMAND, VALUE);
else
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
@@ -650,7 +701,8 @@ void CConfigManager::loadConfigLoadVars() {
configPaths.clear();
static const char* const ENVHOME = getenv("HOME");
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
const std::string CONFIGPARENTPATH = ENVHOME + (std::string) "/.config/hypr/";
const std::string CONFIGPATH = CONFIGPARENTPATH + (ISDEBUG ? "hyprlandd.conf" : "hyprland.conf");
configPaths.push_back(CONFIGPATH);
@@ -663,6 +715,15 @@ void CConfigManager::loadConfigLoadVars() {
std::filesystem::rename(CONFIGPATH, CONFIGPATH + ".backup");
} catch(...) { /* Probably doesn't exist */}
try {
if (!std::filesystem::is_directory(CONFIGPARENTPATH))
std::filesystem::create_directories(CONFIGPARENTPATH);
}
catch (...) {
parseError = "Broken config file! (Could not create directory)";
return;
}
std::ofstream ofs;
ofs.open(CONFIGPATH, std::ios::trunc);

View File

@@ -28,7 +28,7 @@ struct SMonitorRule {
Vector2D offset = Vector2D(0,0);
float scale = 1;
float refreshRate = 60;
int defaultWorkspaceID = -1;
std::string defaultWorkspace = "";
bool disabled = false;
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 m_szCurrentSubmap = ""; // For storing the current keybind submap
bool isFirstLaunch = true; // For exec-once
std::deque<SMonitorRule> m_dMonitorRules;
@@ -106,13 +108,14 @@ private:
void configSetValueSafe(const std::string&, const std::string&);
void handleRawExec(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 handleWindowRule(const std::string&, const std::string&);
void handleDefaultWorkspace(const std::string&, const std::string&);
void handleBezier(const std::string&, const std::string&);
void handleAnimation(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;

View File

@@ -34,6 +34,8 @@ general {
col.active_border=0x66ee1111
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
}

View File

@@ -114,6 +114,9 @@ std::string versionRequest() {
#ifndef NDEBUG
result += "debug\n";
#endif
#ifdef HYPRLAND_DEBUG
result += "debug\n";
#endif
#ifdef NO_XWAYLAND
result += "no xwayland\n";
#endif

View File

@@ -7,10 +7,14 @@
#include "wlrunstable/wlr_ext_workspace_v1.hpp"
#ifndef NDEBUG
#ifdef HYPRLAND_DEBUG
#define ISDEBUG true
#else
#define ISDEBUG false
#endif
#else
#define ISDEBUG false
#endif
#define RIP(format, ... ) { fprintf(stderr, format "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); }

View File

@@ -114,29 +114,41 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
wlr_ext_workspace_group_handle_v1_output_enter(PNEWMONITOR->pWLRWorkspaceGroupHandle, PNEWMONITOR->output);
// 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);
Debug::log(LOG, "New monitor: WORKSPACEID %d, exists: %d", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr));
if (PNEWWORKSPACE) {
// workspace exists, move it to the newly connected monitor
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, PNEWMONITOR);
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PNEWMONITOR->ID);
PNEWWORKSPACE->startAnim(true,true,true);
} else {
g_pCompositor->m_lWorkspaces.emplace_back(newMonitor.ID);
PNEWWORKSPACE = &g_pCompositor->m_lWorkspaces.back();
PNEWWORKSPACE = &g_pCompositor->m_lWorkspaces.emplace_back(newMonitor.ID);
// 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_szName = std::to_string(WORKSPACEID);
PNEWWORKSPACE->m_szName = newDefaultWorkspaceName;
}
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
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);
PNEWWORKSPACE->setActive(true);
@@ -213,7 +225,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
return;
}
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE) {
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && PMONITOR->forceFullFrames == 0) {
pixman_region32_fini(&damage);
wlr_output_rollback(PMONITOR->output);
wlr_output_schedule_frame(PMONITOR->output); // we update shit at the monitor's Hz so we need to schedule frames because rollback wont
@@ -221,7 +233,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
}
// 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_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
@@ -244,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?
// potentially can save on resources.
@@ -319,7 +334,7 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
// Cleanup everything. Move windows back, snap cursor, shit.
const auto BACKUPMON = &g_pCompositor->m_lMonitors.front();
if (!BACKUPMON) {
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
g_pCompositor->cleanupExit();

View File

@@ -19,6 +19,14 @@ void addViewCoords(void* pWindow, int* x, int* y) {
const auto PWINDOW = (CWindow*)pWindow;
*x += PWINDOW->m_vRealPosition.goalv().x;
*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) {

View File

@@ -158,6 +158,12 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
outName = WORKSPACENAME;
} else {
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
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;
} 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);
}
}

View File

@@ -28,6 +28,7 @@ struct SMonitor {
float refreshRate = 60;
wlr_output_damage* damage = nullptr;
int framesToSkip = 0;
int forceFullFrames = 0;
bool noFrameSchedule = false;
wl_output_transform transform = WL_OUTPUT_TRANSFORM_NORMAL;

View File

@@ -2,7 +2,7 @@
#include "../events/Events.hpp"
#include "../defines.hpp"
#include "../../wlr-layer-shell-unstable-v1-protocol.h"
#include "wlr-layer-shell-unstable-v1-protocol.h"
#include "../Window.hpp"
#include "SubsurfaceTree.hpp"
#include "AnimatedVariable.hpp"
@@ -205,4 +205,4 @@ struct STabletPad {
bool operator==(const STabletPad& b) {
return wlrTabletPadV2 == b.wlrTabletPadV2;
}
};
};

View File

@@ -34,59 +34,60 @@
#define static
extern "C" {
#include "../wlroots/include/wlr/backend.h"
#include "../wlroots/include/wlr/backend/libinput.h"
#include "../wlroots/include/wlr/render/allocator.h"
#include "../wlroots/include/wlr/render/wlr_renderer.h"
#include "../wlroots/include/wlr/types/wlr_compositor.h"
#include "../wlroots/include/wlr/types/wlr_cursor.h"
#include "../wlroots/include/wlr/types/wlr_data_control_v1.h"
#include "../wlroots/include/wlr/types/wlr_data_device.h"
#include "../wlroots/include/wlr/types/wlr_export_dmabuf_v1.h"
#include "../wlroots/include/wlr/types/wlr_linux_dmabuf_v1.h"
#include "../wlroots/include/wlr/types/wlr_gamma_control_v1.h"
#include "../wlroots/include/wlr/types/wlr_idle.h"
#include "../wlroots/include/wlr/types/wlr_input_device.h"
#include "../wlroots/include/wlr/types/wlr_keyboard.h"
#include "../wlroots/include/wlr/types/wlr_layer_shell_v1.h"
#include "../wlroots/include/wlr/types/wlr_matrix.h"
#include "../wlroots/include/wlr/types/wlr_output.h"
#include "../wlroots/include/wlr/types/wlr_output_layout.h"
#include "../wlroots/include/wlr/types/wlr_output_management_v1.h"
#include "../wlroots/include/wlr/types/wlr_pointer.h"
#include "../wlroots/include/wlr/types/wlr_presentation_time.h"
#include "../wlroots/include/wlr/types/wlr_primary_selection.h"
#include "../wlroots/include/wlr/types/wlr_primary_selection_v1.h"
#include "../wlroots/include/wlr/types/wlr_screencopy_v1.h"
#include "../wlroots/include/wlr/types/wlr_seat.h"
#include "../wlroots/include/wlr/types/wlr_server_decoration.h"
#include "../wlroots/include/wlr/types/wlr_viewporter.h"
#include "../wlroots/include/wlr/types/wlr_virtual_keyboard_v1.h"
#include "../wlroots/include/wlr/types/wlr_xcursor_manager.h"
#include "../wlroots/include/wlr/types/wlr_xdg_activation_v1.h"
#include "../wlroots/include/wlr/types/wlr_xdg_decoration_v1.h"
#include "../wlroots/include/wlr/types/wlr_xdg_output_v1.h"
#include "../wlroots/include/wlr/types/wlr_xdg_shell.h"
#include "../wlroots/include/wlr/types/wlr_subcompositor.h"
#include "../wlroots/include/wlr/types/wlr_scene.h"
#include "../wlroots/include/wlr/types/wlr_output_damage.h"
#include "../wlroots/include/wlr/types/wlr_input_inhibitor.h"
#include "../wlroots/include/wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h"
#include "../wlroots/include/wlr/types/wlr_virtual_pointer_v1.h"
#include "../wlroots/include/wlr/types/wlr_foreign_toplevel_management_v1.h"
#include "../wlroots/include/wlr/util/log.h"
#include "../wlroots/include/wlr/xwayland.h"
#include "../wlroots/include/wlr/util/region.h"
#include "../wlroots/include/wlr/types/wlr_tablet_pad.h"
#include "../wlroots/include/wlr/types/wlr_tablet_tool.h"
#include "../wlroots/include/wlr/types/wlr_tablet_v2.h"
#include <wlr/backend.h>
#include <wlr/backend/libinput.h>
#include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_control_v1.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_presentation_time.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_viewporter.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_activation_v1.h>
#include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_output_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
#include <wlr/util/log.h>
#include <wlr/xwayland.h>
#include <wlr/util/region.h>
#include <wlr/types/wlr_tablet_pad.h>
#include <wlr/types/wlr_tablet_tool.h>
#include <wlr/types/wlr_tablet_v2.h>
#include <xkbcommon/xkbcommon.h>
#include <X11/Xproto.h>
#include "../wlroots/include/wlr/render/egl.h"
#include "../wlroots/include/wlr/render/gles2.h"
#include "../wlroots/include/wlr/render/wlr_texture.h"
#include "../wlroots/include/wlr/types/wlr_pointer_constraints_v1.h"
#include "../wlroots/include/wlr/types/wlr_relative_pointer_v1.h"
#include <wlr/render/egl.h>
#include <wlr/render/gles2.h>
#include <wlr/render/wlr_texture.h>
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/interfaces/wlr_keyboard.h>
}
#undef class
@@ -112,4 +113,4 @@ extern "C" {
#include "helpers/Vector2D.hpp"
#include "../ext-workspace-unstable-v1-protocol.h"
#include "ext-workspace-unstable-v1-protocol.h"

View File

@@ -105,9 +105,15 @@ void CEventManager::startThread() {
}
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) {
eventQueueMutex.lock();
m_dQueuedEvents.push_back(ev);
eventQueueMutex.unlock();
}, event).detach();
}
}

View File

@@ -19,6 +19,8 @@ public:
void startThread();
bool m_bIgnoreEvents = false;
private:
std::mutex eventQueueMutex;

View File

@@ -30,6 +30,7 @@ CKeybindManager::CKeybindManager() {
m_mDispatchers["resizeactive"] = resizeActive;
m_mDispatchers["cyclenext"] = circleNext;
m_mDispatchers["focuswindowbyclass"] = focusWindowByClass;
m_mDispatchers["submap"] = setSubmap;
}
void CKeybindManager::addKeybind(SKeybind kb) {
@@ -72,13 +73,11 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
if (handleInternalKeybinds(key))
return true;
if (g_pCompositor->m_sSeat.exclusiveClient){
Debug::log(LOG, "Not handling keybinds due to there being an exclusive inhibited client.");
return false;
}
if (g_pCompositor->m_sSeat.exclusiveClient)
Debug::log(LOG, "Keybind handling only locked (inhibitor)");
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;
// oMg such performance hit!!11!
@@ -141,11 +140,48 @@ void CKeybindManager::spawn(std::string args) {
args = "WAYLAND_DISPLAY=" + std::string(g_pCompositor->m_szWLDisplaySocket) + " " + args;
Debug::log(LOG, "Executing %s", args.c_str());
if (fork() == 0) {
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
int socket[2];
if (pipe(socket) != 0) {
Debug::log(LOG, "Unable to create pipe for fork");
}
pid_t child, grandchild;
child = fork();
if (child < 0) {
close(socket[0]);
close(socket[1]);
Debug::log(LOG, "Fail to create the first fork");
return;
}
if (child == 0) {
// run in child
grandchild = fork();
if (grandchild == 0) {
// run in grandchild
close(socket[0]);
close(socket[1]);
execl("/bin/sh", "/bin/sh", "-c", args.c_str(), nullptr);
// exit grandchild
_exit(0);
}
close(socket[0]);
write(socket[1], &grandchild, sizeof(grandchild));
close(socket[1]);
// exit child
_exit(0);
}
// run in parent
close(socket[1]);
read(socket[0], &grandchild, sizeof(grandchild));
close(socket[0]);
// clear child and leave child to init
waitpid(child, NULL, 0);
if (child < 0) {
Debug::log(LOG, "Fail to create the second fork");
return;
}
Debug::log(LOG, "Process Created with pid %d", grandchild);
}
void CKeybindManager::killActive(std::string args) {
@@ -243,9 +279,7 @@ void CKeybindManager::changeworkspace(std::string args) {
// start anim on new workspace
PWORKSPACETOCHANGETO->startAnim(true, ANIMTOLEFT);
// Event ONLY if workspace is actually "changed" and we arent just focusing
if (!m_bSuppressWorkspaceChangeEvents)
g_pEventManager->postEvent(SHyprIPCEvent("workspace", PWORKSPACETOCHANGETO->m_szName));
g_pEventManager->postEvent(SHyprIPCEvent("workspace", PWORKSPACETOCHANGETO->m_szName));
}
// If the monitor is not the one our cursor's at, warp to it.
@@ -254,9 +288,6 @@ void CKeybindManager::changeworkspace(std::string args) {
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
g_pCompositor->deactivateAllWLRWorkspaces(PWORKSPACETOCHANGETO->m_pWlrHandle);
PWORKSPACETOCHANGETO->setActive(true);
@@ -323,8 +354,7 @@ void CKeybindManager::changeworkspace(std::string args) {
g_pInputManager->refocus();
// 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);
}
@@ -337,8 +367,7 @@ void CKeybindManager::fullscreenActive(std::string args) {
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, args == "1" ? eFullscreenMode::FULLSCREEN_MAXIMIZED : eFullscreenMode::FULLSCREEN_FULL);
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen && args == "0");
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen && (args == "0" || args == ""));
// make all windows on the same workspace under the fullscreen window
for (auto& w : g_pCompositor->m_lWindows) {
if (w.m_iWorkspaceID == PWINDOW->m_iWorkspaceID)
@@ -455,7 +484,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
const auto POLDWORKSPACEONMON = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDONMONITOR);
const auto POLDWORKSPACEIDRETURN = g_pCompositor->getWorkspaceByID(OLDWORKSPACEIDRETURN);
m_bSuppressWorkspaceChangeEvents = true;
g_pEventManager->m_bIgnoreEvents = true;
moveActiveToWorkspace(args);
@@ -474,7 +503,7 @@ void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {
POLDWORKSPACEONMON->m_vRenderOffset.setValueAndWarp(Vector2D(0, 0));
POLDWORKSPACEONMON->m_fAlpha.setValueAndWarp(255.f);
m_bSuppressWorkspaceChangeEvents = false;
g_pEventManager->m_bIgnoreEvents = false;
g_pInputManager->refocus();
}
@@ -907,3 +936,21 @@ void CKeybindManager::focusWindowByClass(std::string clazz) {
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());
}

View File

@@ -11,6 +11,8 @@ struct SKeybind {
uint32_t modmask = 0;
std::string handler = "";
std::string arg = "";
bool locked = false;
std::string submap = "";
};
class CKeybindManager {
@@ -28,9 +30,9 @@ public:
private:
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 -------------- //
static void killActive(std::string);
@@ -58,6 +60,7 @@ private:
static void resizeActive(std::string);
static void circleNext(std::string);
static void focusWindowByClass(std::string);
static void setSubmap(std::string);
friend class CCompositor;
};

View File

@@ -124,14 +124,8 @@ void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) {
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);
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.
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);
}
else
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
}
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {

View File

@@ -35,6 +35,8 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
Vector2D mouseCoords = getMouseCoordsInternal();
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
bool didConstraintOnCursor = false;
// constraints
// All constraints TODO: multiple mice?
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 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) {
Vector2D deltaToFit;
Vector2D newConstrainedCoords = mouseCoords;
if (mouseCoords.x < CONSTRAINTPOS.x)
deltaToFit.x = CONSTRAINTPOS.x - mouseCoords.x;
else if (mouseCoords.x > CONSTRAINTPOS.x + CONSTRAINTSIZE.x)
deltaToFit.x = CONSTRAINTPOS.x + CONSTRAINTSIZE.x - mouseCoords.x;
newConstrainedCoords.x = CONSTRAINTPOS.x;
else if (mouseCoords.x >= CONSTRAINTPOS.x + CONSTRAINTSIZE.x)
newConstrainedCoords.x = CONSTRAINTPOS.x + CONSTRAINTSIZE.x - 1.0;
if (mouseCoords.y < CONSTRAINTPOS.y)
deltaToFit.y = CONSTRAINTPOS.y - mouseCoords.y;
else if (mouseCoords.y > CONSTRAINTPOS.y + CONSTRAINTSIZE.y)
deltaToFit.y = CONSTRAINTPOS.y + CONSTRAINTSIZE.y - mouseCoords.y;
newConstrainedCoords.y = CONSTRAINTPOS.y;
else if (mouseCoords.y >= CONSTRAINTPOS.y + CONSTRAINTSIZE.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 {
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
wlr_surface* foundSurface = nullptr;
if (didConstraintOnCursor)
return; // don't process when cursor constrained
if (PMONITOR && PMONITOR != g_pCompositor->m_pLastMonitor) {
g_pCompositor->m_pLastMonitor = PMONITOR;
@@ -116,7 +123,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
if (((w->m_bIsFloating && w->m_bIsMapped && w->m_bCreatedOverFullscreen) || (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden) {
pFoundWindow = &(*w);
if (!pFoundWindow->m_bIsX11) {
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
} else {
@@ -152,7 +159,6 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (!foundSurface)
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords);
if (!foundSurface) {
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
@@ -166,20 +172,30 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
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 (g_pConfigManager->getInt("input:follow_mouse") == 0 && !refocus) {
static auto *const PFOLLOWMOUSE = &g_pConfigManager->getConfigValuePtr("input:follow_mouse")->intValue;
if (*PFOLLOWMOUSE != 1 && !refocus) {
if (pFoundWindow != g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow) && (g_pCompositor->m_pLastWindow->m_bIsFloating != pFoundWindow->m_bIsFloating)) {
// enter if change floating style
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
} else if (*PFOLLOWMOUSE == 2) {
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);
return; // don't enter any new surfaces
return; // don't enter any new surfaces
} else {
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
}
}
else
} else
g_pCompositor->focusSurface(foundSurface);
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
@@ -305,7 +321,7 @@ void CInputManager::setKeyboardLayout() {
}
if (wlrMods.locked != 0) {
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlrMods);
wlr_keyboard_notify_modifiers(g_pInputManager->m_pActiveKeyboard->keyboard->keyboard, 0, 0, wlrMods.locked, 0);
}
xkb_keymap_unref(KEYMAP);
@@ -323,11 +339,30 @@ void CInputManager::newMouse(wlr_input_device* mouse) {
if (wlr_input_device_is_libinput(mouse)) {
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(mouse);
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
if (g_pConfigManager->getInt("input:touchpad:clickfinger_behavior") == 0) // toggle software buttons or clickfinger
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
else
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
if (libinput_device_config_middle_emulation_is_available(LIBINPUTDEV)) { // middleclick on r+l mouse button pressed
if (g_pConfigManager->getInt("input:touchpad:middle_button_emulation") == 1)
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
else
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
}
if (libinput_device_config_scroll_has_natural_scroll(LIBINPUTDEV))
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, g_pConfigManager->getInt("input:natural_scroll"));
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
if (g_pConfigManager->getInt("input:touchpad:tap-to-click") == 1)
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
if (libinput_device_config_scroll_has_natural_scroll(LIBINPUTDEV)) {
double w = 0, h = 0;
if (libinput_device_has_capability(LIBINPUTDEV, LIBINPUT_DEVICE_CAP_POINTER) && libinput_device_get_size(LIBINPUTDEV, &w, &h) == 0) // pointer with size is a touchpad
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, g_pConfigManager->getInt("input:touchpad:natural_scroll"));
else
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, g_pConfigManager->getInt("input:natural_scroll"));
}
if (libinput_device_config_dwt_is_available(LIBINPUTDEV)) {
const auto DWT = static_cast<enum libinput_config_dwt_state>(g_pConfigManager->getInt("input:touchpad:disable_while_typing") != 0);
@@ -518,4 +553,4 @@ void CInputManager::updateCapabilities(wlr_input_device* pDev) {
}
wlr_seat_set_capabilities(g_pCompositor->m_sSeat.seat, m_uiCapabilities);
}
}

25
src/meson.build Normal file
View File

@@ -0,0 +1,25 @@
globber = run_command('find', '-name', '*.cpp', check: true)
src = globber.stdout().strip().split('\n')
executable('Hyprland', src,
cpp_args: ['-DWLR_USE_UNSTABLE'],
dependencies: [
server_protos,
dependency('wayland-server'),
dependency('wayland-client'),
wlroots.get_variable('wlroots'),
dependency('cairo'),
dependency('pango'),
dependency('pangocairo'),
dependency('libdrm'),
dependency('egl'),
dependency('xkbcommon'),
dependency('libinput'),
xcb_dep,
dependency('pixman-1'),
dependency('GL'),
dependency('threads')
],
install : true
)

View File

@@ -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) {
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(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.texAttrib);
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
if (pixman_region32_not_empty(damage)) {
PIXMAN_DAMAGE_FOREACH(damage) {
const auto RECT = RECTSARR[i];
scissor(&RECT);
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);
}
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()!");
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);
}
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((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!");
}
// 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);
glBindTexture(tex.m_iTarget, tex.m_iTexID);
@@ -369,22 +390,23 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
glUniform1i(glGetUniformLocation(shader->program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !border && !noAA));
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->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)) {
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
const auto RECT = RECTSARR[i];
@@ -394,6 +416,8 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
}
if (border) {
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, -1);
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()!");
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) {
renderTexture(tex, pBox, a, round, false, border);
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1))) {
renderTexture(tex, pBox, a, round, false, border, true);
return;
}
@@ -599,17 +624,26 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
if (pixman_region32_not_empty(&damage)) {
// render our great blurred FB
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
glClearStencil(0);
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);
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
glStencilFunc(GL_EQUAL, 1, -1);

View File

@@ -34,6 +34,10 @@ struct SCurrentRenderData {
float projection[9];
pixman_region32_t* pDamage = nullptr;
bool renderingPrimarySurface = false;
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
};
struct SMonitorRenderData {
@@ -53,8 +57,9 @@ public:
void end();
void renderRect(wlr_box*, const CColor&, int round = 0);
void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0);
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool 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 makeWindowSnapshot(CWindow*);
@@ -110,7 +115,7 @@ private:
// returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool 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);
};

View File

@@ -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;
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);
}
else
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 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};
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,
@@ -149,7 +155,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity");
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders;
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true);
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
// apply window special data
@@ -164,8 +170,30 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
for (auto& wd : pWindow->m_dWindowDecorations)
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);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1);
g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1);
if (pWindow->m_bIsX11) {
if (pWindow->m_uSurface.xwayland->surface) {
wlr_surface_for_each_surface(pWindow->m_uSurface.xwayland->surface, renderSurface, &renderdata);

View File

@@ -2,7 +2,7 @@
#include "../includes.hpp"
#include "../helpers/MiscFunctions.hpp"
#include "../../ext-workspace-unstable-v1-protocol.h"
#include "ext-workspace-unstable-v1-protocol.h"
#include <assert.h>
#include <string.h>