Compare commits

...

37 Commits

Author SHA1 Message Date
vaxerski
f99ad521a4 Updated issue templates 2022-06-03 17:52:22 +02:00
vaxerski
9486a230c7 Log to the instance folder 2022-06-03 17:48:07 +02:00
vaxerski
6f3b004199 IPC and log changes, introduce signature 2022-06-03 17:41:57 +02:00
vaxerski
19b17b590c fix moveactivetoworkspace with same workspace 2022-06-03 11:19:17 +02:00
vaxerski
f9c8a72e46 dont enable AA by default 2022-06-02 23:03:13 +02:00
vaxerski
e11cb8b328 Added antialiasing to outer edges
simplified, stupidly fast MSAA for rounded edges
2022-06-02 22:58:54 +02:00
vaxerski
7b568d7ad8 configure keyboards one by one 2022-06-02 20:31:47 +02:00
vaxerski
a2f718059b fucking typo 2022-06-02 19:50:46 +02:00
vaxerski
feb0499597 Merge pull request #144 from fufexan/main
Fix Nix build and add updater
2022-06-02 19:47:54 +02:00
vaxerski
601abc7e92 Added locking numlock 2022-06-02 19:47:11 +02:00
Mihai Fufezan
7451890fd7 nix: replace paths dynamically 2022-06-02 19:10:56 +03:00
vaxerski
f5cdb5b95e Fix special in m+1 m-1 2022-06-02 16:54:19 +02:00
vaxerski
7afcf656bd Added hyprctl devices 2022-06-02 13:59:33 +02:00
Mihai Fufezan
6daa866beb nix/updater: only update wlroots on rev change 2022-06-02 00:09:28 +03:00
Mihai Fufezan
9447fcd603 fix Nix build and add updater
- move unnecessary toplevel files to nix/
- added patch that ignores the submodule (revert)
- add update script run by a workflow
2022-06-01 23:52:08 +03:00
vaxerski
9acf15efd7 README changes 2022-06-01 22:00:46 +02:00
vaxerski
b5a100379e reject drag on fullscreen workspace 2022-06-01 21:13:10 +02:00
vaxerski
4f76d5d8d7 destroy monitor on disabled 2022-06-01 21:10:12 +02:00
vaxerski
8d850b0ce1 Added workspace/monitor unset and workspace silent rules 2022-06-01 21:04:06 +02:00
vaxerski
0f28d2ae55 fix stupid error in anim styles 2022-06-01 20:51:21 +02:00
vaxerski
d2451aea4b use overflowing coords when surface unmaps 2022-06-01 13:38:33 +02:00
vaxerski
680705ff91 [gha] bump flake inputs 2022-06-01 00:50:00 +00:00
vaxerski
300fc2ab0f Merge pull request #140 from ThatOneCalculator/main
More AUR stuff
2022-05-31 22:49:15 +02:00
Kainoa Kanter
02210d3d96 Update PKGBUILD-bin 2022-05-31 13:46:09 -07:00
Kainoa Kanter
879345c1e9 Update PKGBUILD-git 2022-05-31 13:46:00 -07:00
Kainoa Kanter
1e3bea5e70 Update PKGBUILD 2022-05-31 13:45:51 -07:00
Kainoa Kanter
f64cae2b7f Update PKGBUILD-bin 2022-05-31 13:32:59 -07:00
Kainoa Kanter
c433b14e3d Update PKGBUILD 2022-05-31 13:32:38 -07:00
Kainoa Kanter
8d1c495878 Update PKGBUILD-git 2022-05-31 13:32:26 -07:00
Kainoa Kanter
4264a0b08d Update PKGBUILD 2022-05-31 13:26:03 -07:00
Kainoa Kanter
40ab062a3c Update PKGBUILD-bin 2022-05-31 13:25:49 -07:00
Kainoa Kanter
35bcea38e3 0.2.1beta 2022-05-31 13:19:26 -07:00
Kainoa Kanter
1ccb944509 0.2.1beta 2022-05-31 13:19:15 -07:00
Kainoa Kanter
c600249aee Merge branch 'vaxerski:main' into main 2022-05-31 13:18:36 -07:00
Kainoa Kanter
6d6e967a8d Update PKGBUILD-git 2022-05-31 13:17:02 -07:00
Kainoa Kanter
f6b8a96621 Update PKGBUILD 2022-05-31 13:15:57 -07:00
Kainoa Kanter
8e8d5a99c2 Add bin 2022-05-31 13:15:41 -07:00
32 changed files with 780 additions and 123 deletions

View File

@@ -13,6 +13,6 @@ assignees: ''
**Images/videos/anything that would help** **Images/videos/anything that would help**
Please attach a log (it's in /tmp/hypr/hyprland.log) and, if crashing, a crashdump (coredumpctl, then coredumpctl info <pid>) Please attach a log (it's in /tmp/hypr/[INSTANCE SIGNATURE]/hyprland.log, if you are unsure of the instance signature, grab the one thats the most recently modified) and, if crashing, a crashdump (coredumpctl, then coredumpctl info <pid>)
*Please do NOT attach coredumps from any packaged version of Hyprland (AUR, etc.). Compile manually, and THEN attach a coredump of that.* *Please do NOT attach coredumps from any packaged version of Hyprland (AUR, etc.). Compile manually, and THEN attach a coredump of that.*

View File

@@ -1,9 +1,6 @@
name: "Nix: update lockfile" name: "Nix: update lockfile"
on: on: [push, workflow_dispatch]
schedule:
- cron: '0 0 */14 * *'
workflow_dispatch:
jobs: jobs:
update: update:
@@ -19,7 +16,7 @@ jobs:
auto-optimise-store = true auto-optimise-store = true
experimental-features = nix-command flakes experimental-features = nix-command flakes
- name: Update lockfile - name: Update lockfile
run: nix flake update run: nix/update-inputs.sh
- uses: stefanzweifel/git-auto-commit-action@v4 - uses: stefanzweifel/git-auto-commit-action@v4
with: with:
commit_message: "[gha] bump flake inputs" commit_message: "[gha] bump flake inputs"

View File

@@ -37,10 +37,9 @@ For Hyprland without the `land` part, see [Hypr], the Xorg window manager.
# Notice # Notice
This project is still in its early development, expect bugs. Hyprland is still in pretty early development compared to some other Wayland compositors.
Once you get it working though, it's pretty stable.<br/>
Although Hyprland is pretty stable, it may have some bugs.
### Help Wanted ### Help Wanted
@@ -55,6 +54,8 @@ Try it out and report bugs / suggestions!
- wlr_ext workspaces protocol support - wlr_ext workspaces protocol support
- Dual Kawase blur - Dual Kawase blur
- Fully dynamic workspaces - Fully dynamic workspaces
- Closely follows wlroots-git
- Bundled wlroots
- Window / layer fade in / out - Window / layer fade in / out
- Tiling/floating/fullscreen windows - Tiling/floating/fullscreen windows
- Special Workspace (Scratchpad) - Special Workspace (Scratchpad)

View File

@@ -2,20 +2,59 @@
_pkgname="hyprland" _pkgname="hyprland"
pkgname="${_pkgname}" pkgname="${_pkgname}"
pkgver="0.1.1beta" pkgver="0.2.2beta"
pkgrel=2 pkgrel=3
pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks." pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
arch=(any) arch=(any)
url="https://github.com/vaxerski/Hyprland" url="https://github.com/vaxerski/Hyprland"
license=('BSD') license=('BSD')
depends=(libxcb xcb-proto xcb-util xcb-util-keysyms libxfixes libx11 libxcomposite xorg-xinput libxrender pixman wayland-protocols wlroots-git cairo pango) depends=(
makedepends=(git cmake ninja gcc gdb) 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") source=("${pkgname}-${pkgver}.tar.gz::https://github.com/vaxerski/hyprland/archive/v${pkgver}.tar.gz")
sha256sums=('SKIP') sha256sums=('SKIP')
conflicts=("${_pkgname}-git" "${_pkgname}" "${_pkgname}-bin")
options=(!makeflags !buildflags) options=(!makeflags !buildflags)
build() { build() {
cd "$srcdir/Hyprland-$pkgver" cd "$srcdir/Hyprland-$pkgver"
git submodule update --init
make all make all
} }

55
aur/PKGBUILD-bin Normal file
View File

@@ -0,0 +1,55 @@
# Maintainer: ThatOneCalculator <kainoa@t1c.dev>
_pkgname="hyprland"
pkgname="${_pkgname}-bin"
pkgver="0.2.2beta"
pkgrel=3
pkgdesc="Hyprland is 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=('SKIP')
conflicts=("${_pkgname}-git" "${_pkgname}" "${_pkgname}-bin")
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

@@ -2,15 +2,53 @@
_pkgname="hyprland" _pkgname="hyprland"
pkgname="${_pkgname}-git" pkgname="${_pkgname}-git"
pkgver=r568.g632d00c pkgver=r615.g119e776
pkgrel=1 pkgrel=4
pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks." pkgdesc="Hyprland is a dynamic tiling Wayland compositor based on wlroots that doesn't sacrifice on its looks."
arch=(any) arch=(any)
url="https://github.com/vaxerski/Hyprland" url="https://github.com/vaxerski/Hyprland"
license=('BSD') license=('BSD')
depends=(libxcb xcb-proto xcb-util xcb-util-keysyms libxfixes libx11 libxcomposite xorg-xinput libxrender pixman wayland-protocols wlroots-git cairo pango) depends=(
makedepends=(git cmake ninja gcc gdb) 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") source=("${_pkgname}::git+https://github.com/vaxerski/Hyprland.git")
conflicts=("${_pkgname}-git" "${_pkgname}" "${_pkgname}-bin")
sha256sums=('SKIP') sha256sums=('SKIP')
options=(!makeflags !buildflags) options=(!makeflags !buildflags)
@@ -24,6 +62,7 @@ pkgver() {
build() { build() {
cd "${srcdir}/${_pkgname}" cd "${srcdir}/${_pkgname}"
git submodule update --init
make all make all
} }

12
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": { "nodes": {
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1653581809, "lastModified": 1653931853,
"narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=", "narHash": "sha256-O3wncIouj9x7gBPntzHeK/Hkmm9M1SGlYq7JI7saTAE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "83658b28fe638a170a19b8933aa008b30640fbd1", "rev": "f1c167688a6f81f4a51ab542e5f476c8c595e457",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -26,11 +26,11 @@
"flake": false, "flake": false,
"locked": { "locked": {
"host": "gitlab.freedesktop.org", "host": "gitlab.freedesktop.org",
"lastModified": 1653733431, "lastModified": 1653658290,
"narHash": "sha256-0JwNH2E9XlMVa7ZCsqxazpKwpZ2rW5QQjbk0DdZxa48=", "narHash": "sha256-zZaona39DOZNL93A1KG3zAi8vDttJBirxacq24hWCn4=",
"owner": "wlroots", "owner": "wlroots",
"repo": "wlroots", "repo": "wlroots",
"rev": "93ee4c7684050807e959bb3b6d57826a72fba8c2", "rev": "75d31509db8c28e8379fe9570118ef8c82284581",
"type": "gitlab" "type": "gitlab"
}, },
"original": { "original": {

View File

@@ -36,7 +36,7 @@
version = mkVersion inputs.wlroots.lastModifiedDate; version = mkVersion inputs.wlroots.lastModifiedDate;
src = inputs.wlroots; src = inputs.wlroots;
}); });
default = pkgsFor.${system}.callPackage ./default.nix { default = pkgsFor.${system}.callPackage ./nix/default.nix {
version = mkVersion self.lastModifiedDate; version = mkVersion self.lastModifiedDate;
inherit (self.packages.${system}) wlroots; inherit (self.packages.${system}) wlroots;
}; };
@@ -44,7 +44,7 @@
formatter = genSystems (system: pkgsFor.${system}.alejandra); formatter = genSystems (system: pkgsFor.${system}.alejandra);
nixosModules.default = import ./module.nix self; nixosModules.default = import ./nix/module.nix self;
# Deprecated # Deprecated
overlays.default = _: prev: { overlays.default = _: prev: {

View File

@@ -23,6 +23,7 @@ usage: hyprctl [command] [(opt)args]
clients clients
activewindow activewindow
layers layers
devices
dispatch dispatch
keyword keyword
version version
@@ -44,12 +45,25 @@ void request(std::string arg) {
return; return;
} }
// get the instance signature
auto instanceSig = getenv("HYPRLAND_INSTANCE_SIGNATURE");
if (!instanceSig) {
std::cout << "HYPRLAND_INSTANCE_SIGNATURE was not set! (Is Hyprland running?)";
return;
}
std::string instanceSigStr = std::string(instanceSig);
sockaddr_un serverAddress = {0}; sockaddr_un serverAddress = {0};
serverAddress.sun_family = AF_UNIX; serverAddress.sun_family = AF_UNIX;
strcpy(serverAddress.sun_path, "/tmp/hypr/.socket.sock");
std::string socketPath = "/tmp/hypr/" + instanceSigStr + "/.socket.sock";
strcpy(serverAddress.sun_path, socketPath.c_str());
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) { if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
std::cout << "Couldn't connect to /tmp/hypr/.socket.sock. (3) Is Hyprland running?"; std::cout << "Couldn't connect to " << socketPath << ". (3)";
return; return;
} }
@@ -117,6 +131,7 @@ int main(int argc, char** argv) {
else if (!strcmp(argv[1], "activewindow")) request("activewindow"); else if (!strcmp(argv[1], "activewindow")) request("activewindow");
else if (!strcmp(argv[1], "layers")) request("layers"); else if (!strcmp(argv[1], "layers")) request("layers");
else if (!strcmp(argv[1], "version")) request("version"); else if (!strcmp(argv[1], "version")) request("version");
else if (!strcmp(argv[1], "devices")) request("devices");
else if (!strcmp(argv[1], "reload")) request("reload"); else if (!strcmp(argv[1], "reload")) request("reload");
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv); else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv); else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv);

View File

@@ -24,7 +24,7 @@
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "hyprland"; pname = "hyprland";
inherit version; inherit version;
src = ./.; src = ../.;
nativeBuildInputs = [ nativeBuildInputs = [
cmake cmake
@@ -52,8 +52,12 @@ stdenv.mkDerivation {
["-DCMAKE_BUILD_TYPE=Release"] ["-DCMAKE_BUILD_TYPE=Release"]
++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true"; ++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
# enables building with nix-supplied wlroots instead of submodule
prePatch = '' prePatch = ''
make config sed -Ei 's/"\.\.\/wlroots\/include\/([a-zA-Z0-9./_-]+)"/<\1>/g' src/includes.hpp
'';
postPatch = ''
make protocols
''; '';
postBuild = '' postBuild = ''

19
nix/update-inputs.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env -S nix shell nixpkgs#gawk nixpkgs#git nixpkgs#moreutils nixpkgs#jq -c bash
# get wlroots revision from submodule
SUB_REV=$(git submodule status | awk '{ print substr($1,2)}')
# and from lockfile
CRT_REV=$(jq < flake.lock '.nodes.wlroots.locked.rev' -r)
if [ $SUB_REV != $CRT_REV ]; then
# update nixpkgs to latest version
nix flake lock --update-input nixpkgs
# update wlroots to submodule revision
nix flake lock --override-input wlroots "gitlab:wlroots/wlroots/$SUB_REV?host=gitlab.freedesktop.org"
# remove "dirty" mark from lockfile
jq < flake.lock 'del(.nodes.wlroots.original.rev)' | sponge flake.lock
else
echo "wlroots is up to date!"
fi

View File

@@ -1,11 +1,16 @@
#include "Compositor.hpp" #include "Compositor.hpp"
CCompositor::CCompositor() { CCompositor::CCompositor() {
unlink("/tmp/hypr/hyprland.log"); m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
unlink("/tmp/hypr/hyprlandd.log");
unlink("/tmp/hypr/.hyprlandrq");
system("mkdir -p /tmp/hypr"); Debug::init(m_szInstanceSignature);
Debug::log(LOG, "Instance Signature: %s", m_szInstanceSignature.c_str());
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
const auto INSTANCEPATH = "/tmp/hypr/" + m_szInstanceSignature;
mkdir(INSTANCEPATH.c_str(), S_IRWXU | S_IRWXG);
m_sWLDisplay = wl_display_create(); m_sWLDisplay = wl_display_create();

View File

@@ -63,6 +63,7 @@ public:
const char* m_szWLDisplaySocket; const char* m_szWLDisplaySocket;
std::string m_szInstanceSignature = "";
std::list<SMonitor> m_lMonitors; std::list<SMonitor> m_lMonitors;
std::list<CWindow> m_lWindows; std::list<CWindow> m_lWindows;

View File

@@ -45,6 +45,7 @@ void CConfigManager::setDefaultVars() {
configValues["decoration:active_opacity"].floatValue = 1; configValues["decoration:active_opacity"].floatValue = 1;
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["dwindle:pseudotile"].intValue = 0; configValues["dwindle:pseudotile"].intValue = 0;
configValues["dwindle:col.group_border"].intValue = 0x66777700; configValues["dwindle:col.group_border"].intValue = 0x66777700;
@@ -80,6 +81,7 @@ void CConfigManager::setDefaultVars() {
configValues["input:repeat_rate"].intValue = 25; configValues["input:repeat_rate"].intValue = 25;
configValues["input:repeat_delay"].intValue = 600; configValues["input:repeat_delay"].intValue = 600;
configValues["input:natural_scroll"].intValue = 0; configValues["input:natural_scroll"].intValue = 0;
configValues["input:numlock_by_default"].intValue = 0;
configValues["input:touchpad:disable_while_typing"].intValue = 1; configValues["input:touchpad:disable_while_typing"].intValue = 1;
configValues["input:follow_mouse"].intValue = 1; configValues["input:follow_mouse"].intValue = 1;

View File

@@ -72,6 +72,24 @@ std::string layersRequest() {
return result; return result;
} }
std::string devicesRequest() {
std::string result = "";
result += "mice:\n";
for (auto& m : g_pInputManager->m_lMice) {
result += getFormat("\tMouse at %x:\n\t\t%s\n", &m, m.mouse->name);
}
result += "\n\nKeyboards:\n";
for (auto& k : g_pInputManager->m_lKeyboards) {
result += getFormat("\tKeyboard at %x:\n\t\t%s\n", &k, k.keyboard->name);
}
return result;
}
std::string versionRequest() { std::string versionRequest() {
std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + GIT_DIRTY + " (" + GIT_COMMIT_MESSAGE + ").\nflags: (if any)\n"; std::string result = "Hyprland, built from branch " + std::string(GIT_BRANCH) + " at commit " + GIT_COMMIT_HASH + GIT_DIRTY + " (" + GIT_COMMIT_MESSAGE + ").\nflags: (if any)\n";
@@ -186,6 +204,8 @@ std::string getReply(std::string request) {
return versionRequest(); return versionRequest();
else if (request == "reload") else if (request == "reload")
return reloadRequest(); return reloadRequest();
else if (request == "devices")
return devicesRequest();
else if (request.find("dispatch") == 0) else if (request.find("dispatch") == 0)
return dispatchRequest(request); return dispatchRequest(request);
else if (request.find("keyword") == 0) else if (request.find("keyword") == 0)
@@ -246,11 +266,11 @@ void HyprCtl::startHyprCtlSocket() {
return; return;
} }
unlink("/tmp/hypr/.socket.sock");
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX}; sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
strcpy(SERVERADDRESS.sun_path, "/tmp/hypr/.socket.sock"); std::string socketPath = "/tmp/hypr/" + g_pCompositor->m_szInstanceSignature + "/.socket.sock";
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)); bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
@@ -262,7 +282,7 @@ void HyprCtl::startHyprCtlSocket() {
char readBuffer[1024] = {0}; char readBuffer[1024] = {0};
Debug::log(LOG, "Hypr socket started."); Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
while(1) { while(1) {
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize); const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);

View File

@@ -1,15 +1,22 @@
#include "Log.hpp" #include "Log.hpp"
#include "../defines.hpp" #include "../defines.hpp"
#include "../Compositor.hpp"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
void Debug::init(std::string IS) {
if (ISDEBUG)
logFile = "/tmp/hypr/" + IS + "/hyprlandd.log";
else
logFile = "/tmp/hypr/" + IS + "/hyprland.log";
}
void Debug::log(LogLevel level, const char* fmt, ...) { void Debug::log(LogLevel level, const char* fmt, ...) {
// log to a file // log to a file
const std::string DEBUGPATH = ISDEBUG ? "/tmp/hypr/hyprlandd.log" : "/tmp/hypr/hyprland.log";
std::ofstream ofs; std::ofstream ofs;
ofs.open(DEBUGPATH, std::ios::out | std::ios::app); ofs.open(logFile, std::ios::out | std::ios::app);
switch (level) { switch (level) {
case LOG: case LOG:

View File

@@ -12,5 +12,8 @@ enum LogLevel {
}; };
namespace Debug { namespace Debug {
void init(std::string IS);
void log(LogLevel level, const char* fmt, ...); void log(LogLevel level, const char* fmt, ...);
inline std::string logFile;
}; };

View File

@@ -160,6 +160,12 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height}; wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
g_pHyprRenderer->damageBox(&geomFixed); g_pHyprRenderer->damageBox(&geomFixed);
geomFixed = {layersurface->geometry.x + (int)PMONITOR->vecPosition.x, layersurface->geometry.y + (int)PMONITOR->vecPosition.y, (int)layersurface->layerSurface->surface->current.width, (int)layersurface->layerSurface->surface->current.height};
g_pHyprRenderer->damageBox(&geomFixed);
geomFixed = {layersurface->geometry.x, layersurface->geometry.y, (int)layersurface->layerSurface->surface->current.width, (int)layersurface->layerSurface->surface->current.height};
layersurface->geometry = geomFixed; // because the surface can overflow... for some reason?
} }
void Events::listener_commitLayerSurface(void* owner, void* data) { void Events::listener_commitLayerSurface(void* owner, void* data) {

View File

@@ -65,6 +65,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
if (monitorRule.disabled) { if (monitorRule.disabled) {
wlr_output_enable(OUTPUT, 0); wlr_output_enable(OUTPUT, 0);
wlr_output_commit(OUTPUT); wlr_output_commit(OUTPUT);
if (const auto PMONITOR = g_pCompositor->getMonitorFromName(std::string(OUTPUT->name)); PMONITOR) {
listener_monitorDestroy(nullptr, PMONITOR->output);
}
return; return;
} }

View File

@@ -73,16 +73,23 @@ void Events::listener_mapWindow(void* owner, void* data) {
// window rules // window rules
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW); const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW);
std::string requestedWorkspace = "";
bool workspaceSilent = false;
for (auto& r : WINDOWRULES) { for (auto& r : WINDOWRULES) {
if (r.szRule.find("monitor") == 0) { if (r.szRule.find("monitor") == 0) {
try { try {
const long int MONITOR = std::stoi(r.szRule.substr(r.szRule.find(" "))); const auto MONITORSTR = r.szRule.substr(r.szRule.find(" "));
if (MONITOR >= (long int)g_pCompositor->m_lMonitors.size() || MONITOR < (long int)0) if (MONITORSTR == "unset") {
PWINDOW->m_iMonitorID = 0; PWINDOW->m_iMonitorID = PMONITOR->ID;
else } else {
PWINDOW->m_iMonitorID = MONITOR; const long int MONITOR = std::stoi(MONITORSTR);
if (MONITOR >= (long int)g_pCompositor->m_lMonitors.size() || MONITOR < (long int)0)
PWINDOW->m_iMonitorID = 0;
else
PWINDOW->m_iMonitorID = MONITOR;
}
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace; PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID)->activeWorkspace;
@@ -91,11 +98,14 @@ void Events::listener_mapWindow(void* owner, void* data) {
Debug::log(ERR, "Rule monitor failed, rule: %s -> %s | err: %s", r.szRule.c_str(), r.szValue.c_str(), e.what()); Debug::log(ERR, "Rule monitor failed, rule: %s -> %s | err: %s", r.szRule.c_str(), r.szValue.c_str(), e.what());
} }
} else if (r.szRule.find("workspace") == 0) { } else if (r.szRule.find("workspace") == 0) {
// switch to workspace // check if it isnt unset
g_pKeybindManager->m_mDispatchers["workspace"](r.szRule.substr(r.szRule.find_first_of(' ') + 1)); const auto WORKSPACERQ = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
PWINDOW->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID; if (WORKSPACERQ == "unset") {
PWINDOW->m_iWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace; requestedWorkspace = "";
} else {
requestedWorkspace = WORKSPACERQ;
}
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str()); Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
} else if (r.szRule.find("float") == 0) { } else if (r.szRule.find("float") == 0) {
@@ -132,6 +142,25 @@ void Events::listener_mapWindow(void* owner, void* data) {
} }
} }
if (requestedWorkspace != "") {
// process requested workspace
if (requestedWorkspace.find_first_of(' ') != std::string::npos) {
// check for silent
if (requestedWorkspace.find("silent") != std::string::npos) {
workspaceSilent = true;
}
requestedWorkspace = requestedWorkspace.substr(0, requestedWorkspace.find_first_of(' '));
}
if (!workspaceSilent) {
g_pKeybindManager->m_mDispatchers["workspace"](requestedWorkspace);
PWINDOW->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
PWINDOW->m_iWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace;
}
}
if (PWINDOW->m_bIsFloating) { if (PWINDOW->m_bIsFloating) {
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW); g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
PWINDOW->m_bCreatedOverFullscreen = true; PWINDOW->m_bCreatedOverFullscreen = true;
@@ -205,6 +234,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
// do the animation thing // do the animation thing
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false); g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false);
if (workspaceSilent) {
// move the window
if (g_pCompositor->m_pLastWindow == PWINDOW) {
g_pKeybindManager->m_mDispatchers["movetoworkspacesilent"](requestedWorkspace);
} else {
Debug::log(ERR, "Tried to set workspace silent rule to a nofocus window!");
}
}
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y); Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
} }

View File

@@ -46,16 +46,35 @@ void wlr_signal_emit_safe(struct wl_signal *signal, void *data) {
} }
std::string getFormat(const char *fmt, ...) { std::string getFormat(const char *fmt, ...) {
char buf[2048] = ""; char buf[LOGMESSAGESIZE] = "";
char* outputStr;
int logLen;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
logLen = vsnprintf(buf, sizeof buf, fmt, args);
vsprintf(buf, fmt, args);
va_end(args); va_end(args);
return std::string(buf); if ((long unsigned int)logLen < sizeof buf) {
outputStr = strdup(buf);
} else {
outputStr = (char*)malloc(logLen + 1);
if (!outputStr) {
printf("CRITICAL: Cannot alloc size %d for log! (Out of memory?)", logLen + 1);
return "";
}
va_start(args, fmt);
vsnprintf(outputStr, logLen + 1U, fmt, args);
va_end(args);
}
std::string output = std::string(outputStr);
free(outputStr);
return output;
} }
void scaleBox(wlr_box* box, float scale) { void scaleBox(wlr_box* box, float scale) {
@@ -172,7 +191,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
searchID = lowestID; searchID = lowestID;
} }
if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE) { if (const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(searchID); PWORKSPACE && PWORKSPACE->m_iID != SPECIAL_WORKSPACE_ID) {
if (PWORKSPACE->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) { if (PWORKSPACE->m_iMonitorID == g_pCompositor->m_pLastMonitor->ID) {
currentID = PWORKSPACE->m_iID; currentID = PWORKSPACE->m_iID;

View File

@@ -57,7 +57,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
m_fAlpha.setValueAndWarp(255.f); m_fAlpha.setValueAndWarp(255.f);
m_fAlpha = 0.f; m_fAlpha = 0.f;
} }
} else if ("slidevert") { } else if (ANIMSTYLE == "slidevert") {
// fallback is slide // fallback is slide
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);

View File

@@ -452,6 +452,13 @@ void CHyprDwindleLayout::onBeginDragWindow() {
return; return;
} }
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(DRAGGINGWINDOW->m_iWorkspaceID);
if (PWORKSPACE->m_bHasFullscreenWindow) {
Debug::log(LOG, "Rejecting drag on a fullscreen workspace.");
return;
}
DRAGGINGWINDOW->m_bDraggingTiled = false; DRAGGINGWINDOW->m_bDraggingTiled = false;
if (!DRAGGINGWINDOW->m_bIsFloating) { if (!DRAGGINGWINDOW->m_bIsFloating) {

View File

@@ -3,6 +3,7 @@
#include "Compositor.hpp" #include "Compositor.hpp"
#include "config/ConfigManager.hpp" #include "config/ConfigManager.hpp"
#include "init/initHelpers.hpp" #include "init/initHelpers.hpp"
#include <iostream>
// I am a bad bad boy and have used some global vars here, // I am a bad bad boy and have used some global vars here,
// just for this file // just for this file
@@ -19,17 +20,19 @@ int main(int argc, char** argv) {
ignoreSudo = true; ignoreSudo = true;
} }
system("mkdir -p /tmp/hypr");
if (!ignoreSudo) { if (!ignoreSudo) {
if (Init::isSudo()) { if (Init::isSudo()) {
Debug::log(CRIT, "Hyprland shall not be run as the root user. If you really want to, use the --i-am-really-stupid flag."); std::cout << "Hyprland shall not be run as the root user. If you really want to, use the --i-am-really-stupid flag.\n";
return 1; return 1;
} }
} else { } else {
Debug::log(WARN, "Running with ignored root checks, I surely hope you know what you're doing."); std::cout << "Running with ignored root checks, I surely hope you know what you're doing.\n";
sleep(1); sleep(1);
} }
Debug::log(LOG, "Welcome to Hyprland!"); std::cout << "Welcome to Hyprland!\n";
// let's init the compositor. // let's init the compositor.
// it initializes basic Wayland stuff in the constructor. // it initializes basic Wayland stuff in the constructor.

View File

@@ -1,4 +1,5 @@
#include "EventManager.hpp" #include "EventManager.hpp"
#include "../Compositor.hpp"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -26,10 +27,9 @@ void CEventManager::startThread() {
return; return;
} }
unlink("/tmp/hypr/.socket2.sock");
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX}; sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
strcpy(SERVERADDRESS.sun_path, "/tmp/hypr/.socket2.sock"); std::string socketPath = "/tmp/hypr/" + g_pCompositor->m_szInstanceSignature + "/.socket2.sock";
strcpy(SERVERADDRESS.sun_path, socketPath.c_str());
bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS)); bind(SOCKET, (sockaddr*)&SERVERADDRESS, SUN_LEN(&SERVERADDRESS));
@@ -41,7 +41,7 @@ void CEventManager::startThread() {
sockaddr_in clientAddress; sockaddr_in clientAddress;
socklen_t clientSize = sizeof(clientAddress); socklen_t clientSize = sizeof(clientAddress);
Debug::log(LOG, "Hypr socket 2 started."); Debug::log(LOG, "Hypr socket 2 started at %s", socketPath.c_str());
// set the socket nonblock // set the socket nonblock
int flags = fcntl(SOCKET, F_GETFL, 0); int flags = fcntl(SOCKET, F_GETFL, 0);

View File

@@ -285,10 +285,31 @@ void CInputManager::setKeyboardLayout() {
return; return;
} }
const auto PLASTKEEB = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
// TODO: configure devices one by one // TODO: configure devices one by one
for (auto& k : m_lKeyboards) for (auto& k : m_lKeyboards) {
wlr_keyboard_set_keymap(k.keyboard->keyboard, KEYMAP); wlr_keyboard_set_keymap(k.keyboard->keyboard, KEYMAP);
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, k.keyboard->keyboard);
wlr_keyboard_modifiers wlrMods = {0};
if (g_pConfigManager->getInt("input:numlock_by_default") == 1) {
// lock numlock
const auto IDX = xkb_map_mod_get_index(KEYMAP, XKB_MOD_NAME_NUM);
if (IDX != XKB_MOD_INVALID)
wlrMods.locked |= (uint32_t)1 << IDX;
}
if (wlrMods.locked != 0) {
wlr_seat_keyboard_notify_modifiers(g_pCompositor->m_sSeat.seat, &wlrMods);
}
}
wlr_seat_set_keyboard(g_pCompositor->m_sSeat.seat, PLASTKEEB);
xkb_keymap_unref(KEYMAP); xkb_keymap_unref(KEYMAP);
xkb_context_unref(CONTEXT); xkb_context_unref(CONTEXT);

View File

@@ -36,12 +36,11 @@ public:
SDrag m_sDrag; SDrag m_sDrag;
std::list<SConstraint> m_lConstraints; std::list<SConstraint> m_lConstraints;
std::list<SKeyboard> m_lKeyboards;
std::list<SMouse> m_lMice;
private: private:
std::list<SKeyboard> m_lKeyboards;
std::list<SMouse> m_lMice;
void mouseMoveUnified(uint32_t, bool refocus = false); void mouseMoveUnified(uint32_t, bool refocus = false);
}; };

View File

@@ -337,14 +337,19 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
if (!g_pCompositor->windowValidMapped(PWINDOW)) if (!g_pCompositor->windowValidMapped(PWINDOW))
return; return;
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID); const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
// hack // hack
std::string unusedName; std::string unusedName;
const auto WORKSPACEID = getWorkspaceIDFromString(args, unusedName); const auto WORKSPACEID = getWorkspaceIDFromString(args, unusedName);
if (WORKSPACEID == PWINDOW->m_iWorkspaceID) {
Debug::log(LOG, "Not moving to workspace because it didn't change.");
return;
}
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
g_pKeybindManager->changeworkspace(args); g_pKeybindManager->changeworkspace(args);
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID); const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);

View File

@@ -269,6 +269,7 @@ void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
glUniform2f(glGetUniformLocation(m_shQUAD.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y); glUniform2f(glGetUniformLocation(m_shQUAD.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
glUniform2f(glGetUniformLocation(m_shQUAD.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y); glUniform2f(glGetUniformLocation(m_shQUAD.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
glUniform1f(glGetUniformLocation(m_shQUAD.program, "radius"), round); glUniform1f(glGetUniformLocation(m_shQUAD.program, "radius"), round);
glUniform1i(glGetUniformLocation(m_shQUAD.program, "primitiveMultisample"), (int)(g_pConfigManager->getInt("decoration:multisample_edges") == 1 && round != 0));
glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); glVertexAttribPointer(m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
glVertexAttribPointer(m_shQUAD.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); glVertexAttribPointer(m_shQUAD.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
@@ -304,7 +305,7 @@ void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float al
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) { void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA) {
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!");
@@ -362,6 +363,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
glUniform2f(glGetUniformLocation(shader->program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y); glUniform2f(glGetUniformLocation(shader->program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
glUniform2f(glGetUniformLocation(shader->program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y); glUniform2f(glGetUniformLocation(shader->program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
glUniform1f(glGetUniformLocation(shader->program, "radius"), round); glUniform1f(glGetUniformLocation(shader->program, "radius"), round);
glUniform1i(glGetUniformLocation(shader->program, "primitiveMultisample"), (int)(g_pConfigManager->getInt("decoration:multisample_edges") == 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); glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
@@ -598,7 +600,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
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); renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
// then stop // then stop
glStencilFunc(GL_EQUAL, 1, -1); glStencilFunc(GL_EQUAL, 1, -1);

View File

@@ -110,7 +110,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); 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 renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0); void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
}; };

View File

@@ -26,6 +26,8 @@ uniform vec2 bottomRight;
uniform vec2 fullSize; uniform vec2 fullSize;
uniform float radius; uniform float radius;
uniform int primitiveMultisample;
void main() { void main() {
if (radius == 0.0) { if (radius == 0.0) {
gl_FragColor = v_color; gl_FragColor = v_color;
@@ -38,15 +40,57 @@ void main() {
// we're close left // we're close left
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(topLeft, pixCoord) > radius) {
discard; float topLeftDistance = distance(topLeft, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = v_color * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = v_color * distances;
return;
}
} }
} }
} }
@@ -54,15 +98,57 @@ void main() {
// we're close right // we're close right
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = v_color * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(bottomRight, pixCoord) > radius) {
discard; float topLeftDistance = distance(bottomRight, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = v_color * distances;
return;
}
} }
} }
} }
@@ -94,6 +180,8 @@ uniform float radius;
uniform int discardOpaque; uniform int discardOpaque;
uniform int primitiveMultisample;
void main() { void main() {
vec4 pixColor = texture2D(tex, v_texcoord); vec4 pixColor = texture2D(tex, v_texcoord);
@@ -109,15 +197,57 @@ void main() {
// we're close left // we're close left
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(topLeft, pixCoord) > radius) {
discard; float topLeftDistance = distance(topLeft, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} }
} }
@@ -125,15 +255,57 @@ void main() {
// we're close right // we're close right
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(bottomRight, pixCoord) > radius) {
discard; float topLeftDistance = distance(bottomRight, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} }
} }
@@ -154,12 +326,16 @@ uniform float radius;
uniform int discardOpaque; uniform int discardOpaque;
uniform int primitiveMultisample;
void main() { void main() {
if (discardOpaque == 1 && alpha == 1.0) { if (discardOpaque == 1 && alpha == 1.0) {
discard; discard;
return; return;
} }
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
vec2 pixCoord = fullSize * v_texcoord; vec2 pixCoord = fullSize * v_texcoord;
@@ -167,15 +343,57 @@ void main() {
// we're close left // we're close left
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(topLeft, pixCoord) > radius) {
discard; float topLeftDistance = distance(topLeft, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} }
} }
@@ -183,20 +401,62 @@ void main() {
// we're close right // we're close right
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(bottomRight, pixCoord) > radius) {
discard; float topLeftDistance = distance(bottomRight, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} }
} }
gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha; gl_FragColor = pixColor * alpha;
})#"; })#";
inline const std::string FRAGBLUR1 = R"#( inline const std::string FRAGBLUR1 = R"#(
@@ -261,6 +521,8 @@ uniform float radius;
uniform int discardOpaque; uniform int discardOpaque;
uniform int primitiveMultisample;
void main() { void main() {
vec4 pixColor = texture2D(texture0, v_texcoord); vec4 pixColor = texture2D(texture0, v_texcoord);
@@ -276,15 +538,57 @@ void main() {
// we're close left // we're close left
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(topLeft, pixCoord) > radius) {
discard; float topLeftDistance = distance(topLeft, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} }
} }
@@ -292,15 +596,57 @@ void main() {
// we're close right // we're close right
if (pixCoord[1] < topLeft[1]) { if (pixCoord[1] < topLeft[1]) {
// top // top
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
discard; float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} else if (pixCoord[1] > bottomRight[1]) { } else if (pixCoord[1] > bottomRight[1]) {
// bottom // bottom
if (distance(bottomRight, pixCoord) > radius) {
discard; float topLeftDistance = distance(bottomRight, pixCoord);
return;
if (topLeftDistance > radius - 1.0) {
if (primitiveMultisample == 0 && topLeftDistance > radius) {
discard;
return;
} else if (primitiveMultisample == 1) {
float distances = 0.0;
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
if (distances == 0.0) {
discard;
return;
}
distances = distances / 4.0;
gl_FragColor = pixColor * distances;
return;
}
} }
} }
} }