mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-03 05:31:59 -07:00
Compare commits
37 Commits
v0.2.2beta
...
v0.3.0beta
Author | SHA1 | Date | |
---|---|---|---|
|
f99ad521a4 | ||
|
9486a230c7 | ||
|
6f3b004199 | ||
|
19b17b590c | ||
|
f9c8a72e46 | ||
|
e11cb8b328 | ||
|
7b568d7ad8 | ||
|
a2f718059b | ||
|
feb0499597 | ||
|
601abc7e92 | ||
|
7451890fd7 | ||
|
f5cdb5b95e | ||
|
7afcf656bd | ||
|
6daa866beb | ||
|
9447fcd603 | ||
|
9acf15efd7 | ||
|
b5a100379e | ||
|
4f76d5d8d7 | ||
|
8d850b0ce1 | ||
|
0f28d2ae55 | ||
|
d2451aea4b | ||
|
680705ff91 | ||
|
300fc2ab0f | ||
|
02210d3d96 | ||
|
879345c1e9 | ||
|
1e3bea5e70 | ||
|
f64cae2b7f | ||
|
c433b14e3d | ||
|
8d1c495878 | ||
|
4264a0b08d | ||
|
40ab062a3c | ||
|
35bcea38e3 | ||
|
1ccb944509 | ||
|
c600249aee | ||
|
6d6e967a8d | ||
|
f6b8a96621 | ||
|
8e8d5a99c2 |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -13,6 +13,6 @@ assignees: ''
|
||||
**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.*
|
||||
|
7
.github/workflows/nix-update.yaml
vendored
7
.github/workflows/nix-update.yaml
vendored
@@ -1,9 +1,6 @@
|
||||
name: "Nix: update lockfile"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 */14 * *'
|
||||
workflow_dispatch:
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
update:
|
||||
@@ -19,7 +16,7 @@ jobs:
|
||||
auto-optimise-store = true
|
||||
experimental-features = nix-command flakes
|
||||
- name: Update lockfile
|
||||
run: nix flake update
|
||||
run: nix/update-inputs.sh
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: "[gha] bump flake inputs"
|
||||
|
@@ -37,10 +37,9 @@ For Hyprland without the `land` part, see [Hypr], the Xorg window manager.
|
||||
|
||||
# Notice
|
||||
|
||||
This project is still in its early development, expect bugs.
|
||||
|
||||
Once you get it working though, it's pretty stable.<br/>
|
||||
Hyprland is still in pretty early development compared to some other Wayland compositors.
|
||||
|
||||
Although Hyprland is pretty stable, it may have some bugs.
|
||||
|
||||
### Help Wanted
|
||||
|
||||
@@ -55,6 +54,8 @@ Try it out and report bugs / suggestions!
|
||||
- wlr_ext workspaces protocol support
|
||||
- Dual Kawase blur
|
||||
- Fully dynamic workspaces
|
||||
- Closely follows wlroots-git
|
||||
- Bundled wlroots
|
||||
- Window / layer fade in / out
|
||||
- Tiling / floating / fullscreen windows
|
||||
- Special Workspace (Scratchpad)
|
||||
|
47
aur/PKGBUILD
47
aur/PKGBUILD
@@ -2,20 +2,59 @@
|
||||
|
||||
_pkgname="hyprland"
|
||||
pkgname="${_pkgname}"
|
||||
pkgver="0.1.1beta"
|
||||
pkgrel=2
|
||||
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 wlroots-git cairo pango)
|
||||
makedepends=(git cmake ninja gcc gdb)
|
||||
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=('SKIP')
|
||||
conflicts=("${_pkgname}-git" "${_pkgname}" "${_pkgname}-bin")
|
||||
options=(!makeflags !buildflags)
|
||||
|
||||
build() {
|
||||
cd "$srcdir/Hyprland-$pkgver"
|
||||
git submodule update --init
|
||||
make all
|
||||
}
|
||||
|
||||
|
55
aur/PKGBUILD-bin
Normal file
55
aur/PKGBUILD-bin
Normal 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}"
|
||||
}
|
@@ -2,15 +2,53 @@
|
||||
|
||||
_pkgname="hyprland"
|
||||
pkgname="${_pkgname}-git"
|
||||
pkgver=r568.g632d00c
|
||||
pkgrel=1
|
||||
pkgver=r615.g119e776
|
||||
pkgrel=4
|
||||
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 wlroots-git cairo pango)
|
||||
makedepends=(git cmake ninja gcc gdb)
|
||||
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}-git" "${_pkgname}" "${_pkgname}-bin")
|
||||
sha256sums=('SKIP')
|
||||
options=(!makeflags !buildflags)
|
||||
|
||||
@@ -24,6 +62,7 @@ pkgver() {
|
||||
|
||||
build() {
|
||||
cd "${srcdir}/${_pkgname}"
|
||||
git submodule update --init
|
||||
make all
|
||||
}
|
||||
|
||||
|
12
flake.lock
generated
12
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1653581809,
|
||||
"narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=",
|
||||
"lastModified": 1653931853,
|
||||
"narHash": "sha256-O3wncIouj9x7gBPntzHeK/Hkmm9M1SGlYq7JI7saTAE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "83658b28fe638a170a19b8933aa008b30640fbd1",
|
||||
"rev": "f1c167688a6f81f4a51ab542e5f476c8c595e457",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -26,11 +26,11 @@
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1653733431,
|
||||
"narHash": "sha256-0JwNH2E9XlMVa7ZCsqxazpKwpZ2rW5QQjbk0DdZxa48=",
|
||||
"lastModified": 1653658290,
|
||||
"narHash": "sha256-zZaona39DOZNL93A1KG3zAi8vDttJBirxacq24hWCn4=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "93ee4c7684050807e959bb3b6d57826a72fba8c2",
|
||||
"rev": "75d31509db8c28e8379fe9570118ef8c82284581",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
@@ -36,7 +36,7 @@
|
||||
version = mkVersion inputs.wlroots.lastModifiedDate;
|
||||
src = inputs.wlroots;
|
||||
});
|
||||
default = pkgsFor.${system}.callPackage ./default.nix {
|
||||
default = pkgsFor.${system}.callPackage ./nix/default.nix {
|
||||
version = mkVersion self.lastModifiedDate;
|
||||
inherit (self.packages.${system}) wlroots;
|
||||
};
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
formatter = genSystems (system: pkgsFor.${system}.alejandra);
|
||||
|
||||
nixosModules.default = import ./module.nix self;
|
||||
nixosModules.default = import ./nix/module.nix self;
|
||||
|
||||
# Deprecated
|
||||
overlays.default = _: prev: {
|
||||
|
@@ -23,6 +23,7 @@ usage: hyprctl [command] [(opt)args]
|
||||
clients
|
||||
activewindow
|
||||
layers
|
||||
devices
|
||||
dispatch
|
||||
keyword
|
||||
version
|
||||
@@ -44,12 +45,25 @@ void request(std::string arg) {
|
||||
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};
|
||||
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) {
|
||||
std::cout << "Couldn't connect to /tmp/hypr/.socket.sock. (3) Is Hyprland running?";
|
||||
std::cout << "Couldn't connect to " << socketPath << ". (3)";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,6 +131,7 @@ int main(int argc, char** argv) {
|
||||
else if (!strcmp(argv[1], "activewindow")) request("activewindow");
|
||||
else if (!strcmp(argv[1], "layers")) request("layers");
|
||||
else if (!strcmp(argv[1], "version")) request("version");
|
||||
else if (!strcmp(argv[1], "devices")) request("devices");
|
||||
else if (!strcmp(argv[1], "reload")) request("reload");
|
||||
else if (!strcmp(argv[1], "dispatch")) dispatchRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "keyword")) keywordRequest(argc, argv);
|
||||
|
@@ -24,7 +24,7 @@
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyprland";
|
||||
inherit version;
|
||||
src = ./.;
|
||||
src = ../.;
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
@@ -52,8 +52,12 @@ stdenv.mkDerivation {
|
||||
["-DCMAKE_BUILD_TYPE=Release"]
|
||||
++ lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
||||
|
||||
# enables building with nix-supplied wlroots instead of submodule
|
||||
prePatch = ''
|
||||
make config
|
||||
sed -Ei 's/"\.\.\/wlroots\/include\/([a-zA-Z0-9./_-]+)"/<\1>/g' src/includes.hpp
|
||||
'';
|
||||
postPatch = ''
|
||||
make protocols
|
||||
'';
|
||||
|
||||
postBuild = ''
|
19
nix/update-inputs.sh
Executable file
19
nix/update-inputs.sh
Executable 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
|
@@ -1,11 +1,16 @@
|
||||
#include "Compositor.hpp"
|
||||
|
||||
CCompositor::CCompositor() {
|
||||
unlink("/tmp/hypr/hyprland.log");
|
||||
unlink("/tmp/hypr/hyprlandd.log");
|
||||
unlink("/tmp/hypr/.hyprlandrq");
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||
|
||||
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();
|
||||
|
||||
|
@@ -63,6 +63,7 @@ public:
|
||||
|
||||
|
||||
const char* m_szWLDisplaySocket;
|
||||
std::string m_szInstanceSignature = "";
|
||||
|
||||
std::list<SMonitor> m_lMonitors;
|
||||
std::list<CWindow> m_lWindows;
|
||||
|
@@ -45,6 +45,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["decoration:active_opacity"].floatValue = 1;
|
||||
configValues["decoration:inactive_opacity"].floatValue = 1;
|
||||
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
||||
configValues["decoration:multisample_edges"].intValue = 0;
|
||||
|
||||
configValues["dwindle:pseudotile"].intValue = 0;
|
||||
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
||||
@@ -80,6 +81,7 @@ void CConfigManager::setDefaultVars() {
|
||||
configValues["input:repeat_rate"].intValue = 25;
|
||||
configValues["input:repeat_delay"].intValue = 600;
|
||||
configValues["input:natural_scroll"].intValue = 0;
|
||||
configValues["input:numlock_by_default"].intValue = 0;
|
||||
configValues["input:touchpad:disable_while_typing"].intValue = 1;
|
||||
|
||||
configValues["input:follow_mouse"].intValue = 1;
|
||||
|
@@ -72,6 +72,24 @@ std::string layersRequest() {
|
||||
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 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();
|
||||
else if (request == "reload")
|
||||
return reloadRequest();
|
||||
else if (request == "devices")
|
||||
return devicesRequest();
|
||||
else if (request.find("dispatch") == 0)
|
||||
return dispatchRequest(request);
|
||||
else if (request.find("keyword") == 0)
|
||||
@@ -246,11 +266,11 @@ void HyprCtl::startHyprCtlSocket() {
|
||||
return;
|
||||
}
|
||||
|
||||
unlink("/tmp/hypr/.socket.sock");
|
||||
|
||||
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));
|
||||
|
||||
@@ -262,7 +282,7 @@ void HyprCtl::startHyprCtlSocket() {
|
||||
|
||||
char readBuffer[1024] = {0};
|
||||
|
||||
Debug::log(LOG, "Hypr socket started.");
|
||||
Debug::log(LOG, "Hypr socket started at %s", socketPath.c_str());
|
||||
|
||||
while(1) {
|
||||
const auto ACCEPTEDCONNECTION = accept(SOCKET, (sockaddr*)&clientAddress, &clientSize);
|
||||
|
@@ -1,15 +1,22 @@
|
||||
#include "Log.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#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, ...) {
|
||||
|
||||
// log to a file
|
||||
const std::string DEBUGPATH = ISDEBUG ? "/tmp/hypr/hyprlandd.log" : "/tmp/hypr/hyprland.log";
|
||||
std::ofstream ofs;
|
||||
ofs.open(DEBUGPATH, std::ios::out | std::ios::app);
|
||||
ofs.open(logFile, std::ios::out | std::ios::app);
|
||||
|
||||
switch (level) {
|
||||
case LOG:
|
||||
|
@@ -12,5 +12,8 @@ enum LogLevel {
|
||||
};
|
||||
|
||||
namespace Debug {
|
||||
void init(std::string IS);
|
||||
void log(LogLevel level, const char* fmt, ...);
|
||||
|
||||
inline std::string logFile;
|
||||
};
|
@@ -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};
|
||||
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) {
|
||||
|
@@ -65,6 +65,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||
if (monitorRule.disabled) {
|
||||
wlr_output_enable(OUTPUT, 0);
|
||||
wlr_output_commit(OUTPUT);
|
||||
|
||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromName(std::string(OUTPUT->name)); PMONITOR) {
|
||||
listener_monitorDestroy(nullptr, PMONITOR->output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -73,16 +73,23 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
|
||||
// window rules
|
||||
const auto WINDOWRULES = g_pConfigManager->getMatchingRules(PWINDOW);
|
||||
std::string requestedWorkspace = "";
|
||||
bool workspaceSilent = false;
|
||||
|
||||
for (auto& r : WINDOWRULES) {
|
||||
if (r.szRule.find("monitor") == 0) {
|
||||
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)
|
||||
PWINDOW->m_iMonitorID = 0;
|
||||
else
|
||||
PWINDOW->m_iMonitorID = MONITOR;
|
||||
if (MONITORSTR == "unset") {
|
||||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
} else {
|
||||
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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
} else if (r.szRule.find("workspace") == 0) {
|
||||
// switch to workspace
|
||||
g_pKeybindManager->m_mDispatchers["workspace"](r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
// check if it isnt unset
|
||||
const auto WORKSPACERQ = r.szRule.substr(r.szRule.find_first_of(' ') + 1);
|
||||
|
||||
PWINDOW->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
||||
PWINDOW->m_iWorkspaceID = g_pCompositor->m_pLastMonitor->activeWorkspace;
|
||||
if (WORKSPACERQ == "unset") {
|
||||
requestedWorkspace = "";
|
||||
} else {
|
||||
requestedWorkspace = WORKSPACERQ;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Rule workspace matched by window %x, %s applied.", PWINDOW, r.szValue.c_str());
|
||||
} 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) {
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowCreatedFloating(PWINDOW);
|
||||
PWINDOW->m_bCreatedOverFullscreen = true;
|
||||
@@ -205,6 +234,15 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
// do the animation thing
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -46,16 +46,35 @@ void wlr_signal_emit_safe(struct wl_signal *signal, void *data) {
|
||||
}
|
||||
|
||||
std::string getFormat(const char *fmt, ...) {
|
||||
char buf[2048] = "";
|
||||
char buf[LOGMESSAGESIZE] = "";
|
||||
char* outputStr;
|
||||
int logLen;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
vsprintf(buf, fmt, args);
|
||||
|
||||
logLen = vsnprintf(buf, sizeof buf, fmt, 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) {
|
||||
@@ -172,7 +191,7 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
||||
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) {
|
||||
currentID = PWORKSPACE->m_iID;
|
||||
|
||||
|
@@ -57,7 +57,7 @@ void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
m_fAlpha.setValueAndWarp(255.f);
|
||||
m_fAlpha = 0.f;
|
||||
}
|
||||
} else if ("slidevert") {
|
||||
} else if (ANIMSTYLE == "slidevert") {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
|
||||
|
||||
|
@@ -452,6 +452,13 @@ void CHyprDwindleLayout::onBeginDragWindow() {
|
||||
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;
|
||||
|
||||
if (!DRAGGINGWINDOW->m_bIsFloating) {
|
||||
|
11
src/main.cpp
11
src/main.cpp
@@ -3,6 +3,7 @@
|
||||
#include "Compositor.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "init/initHelpers.hpp"
|
||||
#include <iostream>
|
||||
|
||||
// I am a bad bad boy and have used some global vars here,
|
||||
// just for this file
|
||||
@@ -19,17 +20,19 @@ int main(int argc, char** argv) {
|
||||
ignoreSudo = true;
|
||||
}
|
||||
|
||||
system("mkdir -p /tmp/hypr");
|
||||
|
||||
if (!ignoreSudo) {
|
||||
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.");
|
||||
return 1;
|
||||
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;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Welcome to Hyprland!");
|
||||
std::cout << "Welcome to Hyprland!\n";
|
||||
|
||||
// let's init the compositor.
|
||||
// it initializes basic Wayland stuff in the constructor.
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "EventManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -26,10 +27,9 @@ void CEventManager::startThread() {
|
||||
return;
|
||||
}
|
||||
|
||||
unlink("/tmp/hypr/.socket2.sock");
|
||||
|
||||
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));
|
||||
|
||||
@@ -41,7 +41,7 @@ void CEventManager::startThread() {
|
||||
sockaddr_in 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
|
||||
int flags = fcntl(SOCKET, F_GETFL, 0);
|
||||
|
@@ -285,10 +285,31 @@ void CInputManager::setKeyboardLayout() {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PLASTKEEB = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
// 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_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_context_unref(CONTEXT);
|
||||
|
||||
|
@@ -36,12 +36,11 @@ public:
|
||||
|
||||
SDrag m_sDrag;
|
||||
|
||||
std::list<SConstraint> m_lConstraints;
|
||||
std::list<SConstraint> m_lConstraints;
|
||||
std::list<SKeyboard> m_lKeyboards;
|
||||
std::list<SMouse> m_lMice;
|
||||
|
||||
private:
|
||||
|
||||
std::list<SKeyboard> m_lKeyboards;
|
||||
std::list<SMouse> m_lMice;
|
||||
private:
|
||||
|
||||
void mouseMoveUnified(uint32_t, bool refocus = false);
|
||||
};
|
||||
|
@@ -337,14 +337,19 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->onWindowRemoved(PWINDOW);
|
||||
|
||||
const auto OLDWORKSPACE = g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID);
|
||||
|
||||
// hack
|
||||
std::string 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);
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID);
|
||||
|
@@ -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, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
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.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);
|
||||
}
|
||||
|
||||
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((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, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
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->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);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
|
||||
|
||||
// then stop
|
||||
glStencilFunc(GL_EQUAL, 1, -1);
|
||||
|
@@ -110,7 +110,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);
|
||||
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);
|
||||
};
|
||||
|
||||
|
@@ -26,6 +26,8 @@ uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
|
||||
void main() {
|
||||
if (radius == 0.0) {
|
||||
gl_FragColor = v_color;
|
||||
@@ -38,15 +40,57 @@ void main() {
|
||||
// we're close left
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(topLeft, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(topLeft, pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||
|
||||
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
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(bottomRight, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||
|
||||
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 primitiveMultisample;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||
@@ -109,15 +197,57 @@ void main() {
|
||||
// we're close left
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(topLeft, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(topLeft, pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||
|
||||
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
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(bottomRight, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||
|
||||
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,6 +326,8 @@ uniform float radius;
|
||||
|
||||
uniform int discardOpaque;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
|
||||
void main() {
|
||||
|
||||
if (discardOpaque == 1 && alpha == 1.0) {
|
||||
@@ -161,21 +335,65 @@ void main() {
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
// we're close left
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(topLeft, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(topLeft, pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||
|
||||
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
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(bottomRight, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||
|
||||
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"#(
|
||||
@@ -261,6 +521,8 @@ uniform float radius;
|
||||
|
||||
uniform int discardOpaque;
|
||||
|
||||
uniform int primitiveMultisample;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||
@@ -276,15 +538,57 @@ void main() {
|
||||
// we're close left
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(topLeft, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(topLeft, pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||
|
||||
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
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top
|
||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||
|
||||
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]) {
|
||||
// bottom
|
||||
if (distance(bottomRight, pixCoord) > radius) {
|
||||
discard;
|
||||
return;
|
||||
|
||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user