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**
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.*

View File

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

View File

@@ -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)

View File

@@ -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
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="${_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
View File

@@ -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": {

View File

@@ -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: {

View File

@@ -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);

View File

@@ -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
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"
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();

View File

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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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:

View File

@@ -12,5 +12,8 @@ enum LogLevel {
};
namespace Debug {
void init(std::string IS);
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};
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) {

View File

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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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.

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
};

View File

@@ -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);

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, "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);

View File

@@ -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);
};

View File

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