mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-10 08:25:58 +01:00
Merge branch 'hyprwm:main' into main
This commit is contained in:
commit
185c4d6ea1
59 changed files with 1836 additions and 1018 deletions
6
.github/pull_request_template.md
vendored
6
.github/pull_request_template.md
vendored
|
@ -1,9 +1,9 @@
|
|||
Describe your PR, what does it fix/add?
|
||||
#### Describe your PR, what does it fix/add?
|
||||
|
||||
|
||||
Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.)
|
||||
#### Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.)
|
||||
|
||||
|
||||
Is it ready for merging, or does it need work?
|
||||
#### Is it ready for merging, or does it need work?
|
||||
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ execute_process(
|
|||
#
|
||||
|
||||
include_directories(. PRIVATE "subprojects/wlroots/include/")
|
||||
include_directories(. PRIVATE "subprojects/wlroots/build/include/")
|
||||
add_compile_options(-std=c++20 -DWLR_USE_UNSTABLE )
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-narrowing)
|
||||
find_package(Threads REQUIRED)
|
||||
|
@ -61,7 +62,7 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
|||
message(STATUS "Configuring Hyprland in Debug with CMake!")
|
||||
add_definitions( -DHYPRLAND_DEBUG )
|
||||
ELSE()
|
||||
# add_compile_options(-O3) # may crash for some
|
||||
add_compile_options( -O3 )
|
||||
message(STATUS "Configuring Hyprland in Release with CMake!")
|
||||
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
|
||||
|
|
22
Makefile
22
Makefile
|
@ -99,7 +99,7 @@ clear:
|
|||
rm -rf build
|
||||
rm -f *.o *-protocol.h *-protocol.c
|
||||
rm -f ./hyprctl/hyprctl
|
||||
rm -rf ./wlroots/build
|
||||
rm -rf ./subprojects/wlroots/build
|
||||
|
||||
all:
|
||||
make config
|
||||
|
@ -107,6 +107,10 @@ all:
|
|||
cd ./hyprctl && make all && cd ..
|
||||
|
||||
install:
|
||||
[ ! -d /usr/include/wlr ] || mv /usr/include/wlr /usr/include/wlrBackup
|
||||
[ ! -f /usr/lib/libwlroots.so ] || mv /usr/lib/libwlroots.so /usr/lib/libwlroots.so.backup
|
||||
[ ! -f /usr/lib/pkgconfig/wlroots.pc ] || mv /usr/lib/pkgconfig/wlroots.pc /usr/lib/pkgconfig/wlroots.pc.backup
|
||||
|
||||
make all
|
||||
mkdir -p ${PREFIX}/share/wayland-sessions
|
||||
cp ./example/hyprland.desktop ${PREFIX}/share/wayland-sessions/
|
||||
|
@ -118,6 +122,13 @@ install:
|
|||
cp ./assets/wall_4K.png ${PREFIX}/share/hyprland
|
||||
cp ./assets/wall_8K.png ${PREFIX}/share/hyprland
|
||||
|
||||
rm -rf /usr/include/wlr
|
||||
rm -f /usr/lib/libwlroots.so
|
||||
rm -f /usr/lib/pkgconfig/wlroots.pc
|
||||
[ ! -d /usr/include/wlrBackup ] || mv /usr/include/wlrBackup /usr/include/wlr
|
||||
[ ! -f /usr/lib/libwlroots.so.backup ] || mv -f /usr/lib/libwlroots.so.backup /usr/lib/libwlroots.so
|
||||
[ ! -f /usr/lib/pkgconfig/wlroots.pc.backup ] || mv -f /usr/lib/pkgconfig/wlroots.pc.backup /usr/lib/pkgconfig/wlroots.pc
|
||||
|
||||
uninstall:
|
||||
rm -f ${PREFIX}/share/wayland-sessions/hyprland.desktop
|
||||
rm -f ${PREFIX}/bin/Hyprland
|
||||
|
@ -126,13 +137,16 @@ uninstall:
|
|||
|
||||
protocols: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o wlr-screencopy-unstable-v1-protocol.o idle-protocol.o ext-workspace-unstable-v1-protocol.o pointer-constraints-unstable-v1-protocol.o tablet-unstable-v2-protocol.o
|
||||
|
||||
config:
|
||||
make protocols
|
||||
|
||||
fixwlr:
|
||||
sed -i -E 's/(soversion = 11)([^032]|$$)/soversion = 11032/g' subprojects/wlroots/meson.build
|
||||
|
||||
rm -rf ./subprojects/wlroots/build
|
||||
|
||||
config:
|
||||
make protocols
|
||||
|
||||
make fixwlr
|
||||
|
||||
cd subprojects/wlroots && meson ./build --prefix=/usr --buildtype=release
|
||||
cd subprojects/wlroots && ninja -C build/
|
||||
|
||||
|
|
12
flake.lock
12
flake.lock
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1655807518,
|
||||
"narHash": "sha256-5YV29Ry/DpAJc/0Hc/+ISVBAjwHpJvAkeKkcUG5lWsc=",
|
||||
"lastModified": 1656239181,
|
||||
"narHash": "sha256-wW1xRFBn376yGloXZ4QzBE4hjipMawpV18Lshd9QSPw=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a72d7811be1162dd6804c4e36e5402d76fb6e921",
|
||||
"rev": "f2537a505d45c31fe5d9c27ea9829b6f4c4e6ac5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -26,11 +26,11 @@
|
|||
"flake": false,
|
||||
"locked": {
|
||||
"host": "gitlab.freedesktop.org",
|
||||
"lastModified": 1654618691,
|
||||
"narHash": "sha256-8y3u8CoigjoZOVbA2wCWBHlDNEakv0AVxU46/cOC00s=",
|
||||
"lastModified": 1655824477,
|
||||
"narHash": "sha256-1kskHOLsnisR3kqIL5IHrQbQG/4xoXxeEf1ExMV6/RU=",
|
||||
"owner": "wlroots",
|
||||
"repo": "wlroots",
|
||||
"rev": "b89ed9015c3fbe8d339e9d65cf70fdca6e5645bc",
|
||||
"rev": "5c4384a1330faedf975c8b8644881d50390f3613",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
@ -32,9 +32,13 @@
|
|||
src = inputs.wlroots;
|
||||
});
|
||||
hyprland = prev.callPackage ./nix/default.nix {
|
||||
version = "0.6.0beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
version = "0.6.2beta" + "+date=" + (mkDate (self.lastModifiedDate or "19700101"));
|
||||
wlroots = wlroots-hyprland;
|
||||
};
|
||||
hyprland-debug = hyprland.override {debug = true;};
|
||||
waybar-hyprland = prev.waybar.overrideAttrs (oldAttrs: {
|
||||
mesonFlags = oldAttrs.mesonFlags ++ ["-Dexperimental=true"];
|
||||
});
|
||||
};
|
||||
|
||||
packages = genSystems (system:
|
||||
|
|
|
@ -26,6 +26,8 @@ const std::string USAGE = R"#(usage: hyprctl [command] [(opt)args]
|
|||
dispatch
|
||||
keyword
|
||||
version
|
||||
kill
|
||||
hyprpaper
|
||||
reload)#";
|
||||
|
||||
void request(std::string arg) {
|
||||
|
@ -74,7 +76,65 @@ void request(std::string arg) {
|
|||
|
||||
char buffer[8192] = {0};
|
||||
|
||||
sizeWritten = read(SERVERSOCKET,buffer, 8192);
|
||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||
|
||||
if (sizeWritten < 0) {
|
||||
std::cout << "Couldn't read (5)";
|
||||
return;
|
||||
}
|
||||
|
||||
close(SERVERSOCKET);
|
||||
|
||||
std::cout << std::string(buffer);
|
||||
}
|
||||
|
||||
void requestHyprpaper(std::string arg) {
|
||||
const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (SERVERSOCKET < 0) {
|
||||
std::cout << "Couldn't open a socket (1)";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto SERVER = gethostbyname("localhost");
|
||||
|
||||
if (!SERVER) {
|
||||
std::cout << "Couldn't get host (2)";
|
||||
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;
|
||||
|
||||
std::string socketPath = "/tmp/hypr/" + instanceSigStr + "/.hyprpaper.sock";
|
||||
|
||||
strcpy(serverAddress.sun_path, socketPath.c_str());
|
||||
|
||||
if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) {
|
||||
std::cout << "Couldn't connect to " << socketPath << ". (3)";
|
||||
return;
|
||||
}
|
||||
|
||||
auto sizeWritten = write(SERVERSOCKET, arg.c_str(), arg.length());
|
||||
|
||||
if (sizeWritten < 0) {
|
||||
std::cout << "Couldn't write (4)";
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[8192] = {0};
|
||||
|
||||
sizeWritten = read(SERVERSOCKET, buffer, 8192);
|
||||
|
||||
if (sizeWritten < 0) {
|
||||
std::cout << "Couldn't read (5)";
|
||||
|
@ -109,6 +169,17 @@ void keywordRequest(int argc, char** argv) {
|
|||
request(rq);
|
||||
}
|
||||
|
||||
void hyprpaperRequest(int argc, char** argv) {
|
||||
if (argc < 4) {
|
||||
std::cout << "hyprpaper requires 2 params";
|
||||
return;
|
||||
}
|
||||
|
||||
std::string rq = std::string(argv[2]) + " " + std::string(argv[3]);
|
||||
|
||||
requestHyprpaper(rq);
|
||||
}
|
||||
|
||||
void batchRequest(int argc, char** argv) {
|
||||
std::string rq = "[[BATCH]]" + std::string(argv[2]);
|
||||
|
||||
|
@ -129,10 +200,12 @@ 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], "kill")) request("kill");
|
||||
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);
|
||||
else if (!strcmp(argv[1], "hyprpaper")) hyprpaperRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "--batch")) batchRequest(argc, argv);
|
||||
else if (!strcmp(argv[1], "--help")) printf("%s", USAGE.c_str());
|
||||
else {
|
||||
|
|
13
meson.build
13
meson.build
|
@ -1,6 +1,15 @@
|
|||
project('Hyprland', 'cpp', 'c',
|
||||
version : '0.6.0beta',
|
||||
default_options : ['warning_level=3', 'cpp_std=c++20', 'default_library=static'])
|
||||
version : '0.6.2beta',
|
||||
default_options : ['warning_level=2', 'cpp_std=c++20', 'default_library=static', 'optimization=3'])
|
||||
|
||||
add_project_arguments(
|
||||
[
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-unused-value',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-narrowing',
|
||||
],
|
||||
language: 'cpp')
|
||||
|
||||
wlroots = subproject('wlroots', default_options: ['examples=false'])
|
||||
have_xwlr = wlroots.get_variable('features').get('xwayland')
|
||||
|
|
|
@ -20,9 +20,10 @@
|
|||
xwayland,
|
||||
enableXWayland ? true,
|
||||
version ? "git",
|
||||
debug ? false,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyprland";
|
||||
pname = "hyprland" + lib.optionalString debug "-debug";
|
||||
inherit version;
|
||||
src = ../.;
|
||||
|
||||
|
@ -48,7 +49,10 @@ stdenv.mkDerivation {
|
|||
]
|
||||
++ lib.optional enableXWayland xwayland;
|
||||
|
||||
mesonBuildType = "release";
|
||||
mesonBuildType =
|
||||
if debug
|
||||
then "debug"
|
||||
else "release";
|
||||
|
||||
mesonFlags = lib.optional (!enableXWayland) "-DNO_XWAYLAND=true";
|
||||
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
CCompositor::CCompositor() {
|
||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||
|
||||
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
|
||||
|
||||
const auto INSTANCEPATH = "/tmp/hypr/" + m_szInstanceSignature;
|
||||
mkdir(INSTANCEPATH.c_str(), S_IRWXU | S_IRWXG);
|
||||
|
||||
Debug::init(m_szInstanceSignature);
|
||||
|
||||
Debug::log(LOG, "Instance Signature: %s", m_szInstanceSignature.c_str());
|
||||
|
@ -17,11 +22,6 @@ CCompositor::CCompositor() {
|
|||
|
||||
Debug::log(INFO, "If you are crashing, or encounter any bugs, please consult https://github.com/hyprwm/Hyprland/wiki/Crashing-and-bugs\n\n");
|
||||
|
||||
setenv("HYPRLAND_INSTANCE_SIGNATURE", m_szInstanceSignature.c_str(), true);
|
||||
|
||||
const auto INSTANCEPATH = "/tmp/hypr/" + m_szInstanceSignature;
|
||||
mkdir(INSTANCEPATH.c_str(), S_IRWXU | S_IRWXG);
|
||||
|
||||
m_sWLDisplay = wl_display_create();
|
||||
|
||||
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay);
|
||||
|
@ -121,6 +121,11 @@ CCompositor::CCompositor() {
|
|||
m_sWLRToplevelMgr = wlr_foreign_toplevel_manager_v1_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRTabletManager = wlr_tablet_v2_create(m_sWLDisplay);
|
||||
|
||||
m_sWLRForeignRegistry = wlr_xdg_foreign_registry_create(m_sWLDisplay);
|
||||
|
||||
wlr_xdg_foreign_v1_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||
wlr_xdg_foreign_v2_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||
}
|
||||
|
||||
CCompositor::~CCompositor() {
|
||||
|
@ -167,8 +172,8 @@ void CCompositor::cleanupExit() {
|
|||
m_pLastFocus = nullptr;
|
||||
m_pLastWindow = nullptr;
|
||||
|
||||
m_lWorkspaces.clear();
|
||||
m_lWindows.clear();
|
||||
m_vWorkspaces.clear();
|
||||
m_vWindows.clear();
|
||||
|
||||
if (g_pXWaylandManager->m_sWLRXWayland) {
|
||||
wlr_xwayland_destroy(g_pXWaylandManager->m_sWLRXWayland);
|
||||
|
@ -264,9 +269,9 @@ void CCompositor::startCompositor() {
|
|||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromID(const int& id) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (m.ID == (uint64_t)id) {
|
||||
return &m;
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->ID == (uint64_t)id) {
|
||||
return m.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,9 +279,9 @@ SMonitor* CCompositor::getMonitorFromID(const int& id) {
|
|||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromName(const std::string& name) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (m.szName == name) {
|
||||
return &m;
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->szName == name) {
|
||||
return m.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,18 +301,18 @@ SMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
|||
float bestDistance = 0.f;
|
||||
SMonitor* pBestMon = nullptr;
|
||||
|
||||
for (auto& m : m_lMonitors) {
|
||||
float dist = vecToRectDistanceSquared(point, m.vecPosition, m.vecPosition + m.vecSize);
|
||||
for (auto& m : m_vMonitors) {
|
||||
float dist = vecToRectDistanceSquared(point, m->vecPosition, m->vecPosition + m->vecSize);
|
||||
|
||||
if (dist < bestDistance || !pBestMon) {
|
||||
bestDistance = dist;
|
||||
pBestMon = &m;
|
||||
pBestMon = m.get();
|
||||
}
|
||||
}
|
||||
|
||||
if (!pBestMon) { // ?????
|
||||
Debug::log(WARN, "getMonitorFromVector no close mon???");
|
||||
return &m_lMonitors.front();
|
||||
return m_vMonitors.front().get();
|
||||
}
|
||||
|
||||
return pBestMon;
|
||||
|
@ -317,13 +322,35 @@ SMonitor* CCompositor::getMonitorFromVector(const Vector2D& point) {
|
|||
}
|
||||
|
||||
void CCompositor::removeWindowFromVectorSafe(CWindow* pWindow) {
|
||||
if (windowExists(pWindow) && !pWindow->m_bFadingOut)
|
||||
m_lWindows.remove(*pWindow);
|
||||
if (windowExists(pWindow) && !pWindow->m_bFadingOut){
|
||||
if (pWindow->m_bIsX11 && pWindow->m_iX11Type == 2) {
|
||||
m_dUnmanagedX11Windows.erase(std::remove_if(m_dUnmanagedX11Windows.begin(), m_dUnmanagedX11Windows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == pWindow; }));
|
||||
}
|
||||
|
||||
// if X11, also check its children
|
||||
// and delete any needed
|
||||
if (pWindow->m_bIsX11) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsX11)
|
||||
continue;
|
||||
|
||||
if (w->m_pX11Parent == pWindow)
|
||||
m_vWindows.erase(std::remove_if(m_vWindows.begin(), m_vWindows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == w.get(); }));
|
||||
}
|
||||
|
||||
for (auto& w : m_dUnmanagedX11Windows) {
|
||||
if (w->m_pX11Parent == pWindow)
|
||||
m_dUnmanagedX11Windows.erase(std::remove_if(m_dUnmanagedX11Windows.begin(), m_dUnmanagedX11Windows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == w.get(); }));
|
||||
}
|
||||
}
|
||||
|
||||
m_vWindows.erase(std::remove_if(m_vWindows.begin(), m_vWindows.end(), [&](std::unique_ptr<CWindow>& el) { return el.get() == pWindow; }));
|
||||
}
|
||||
}
|
||||
|
||||
bool CCompositor::windowExists(CWindow* pWindow) {
|
||||
for (auto& w : m_lWindows) {
|
||||
if (&w == pWindow)
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() == pWindow)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -334,24 +361,24 @@ CWindow* CCompositor::vectorToWindow(const Vector2D& pos) {
|
|||
const auto PMONITOR = getMonitorFromVector(pos);
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vRealPosition.vec().x, w.m_vRealPosition.vec().y, w.m_vRealSize.vec().x, w.m_vRealSize.vec().y};
|
||||
if (w.m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_bIsMapped && !w.m_bIsFloating && !w.m_bHidden)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden)
|
||||
return &(*w);
|
||||
// first loop over floating cuz they're above, m_vWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vRealPosition.vec().x, w.m_vRealPosition.vec().y, w.m_vRealSize.vec().x, w.m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && w.m_bIsMapped && !w.m_bIsFloating && PMONITOR->activeWorkspace == w.m_iWorkspaceID && !w.m_bHidden)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, pos.x, pos.y) && w->m_bIsMapped && !w->m_bIsFloating && PMONITOR->activeWorkspace == w->m_iWorkspaceID && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -361,17 +388,17 @@ CWindow* CCompositor::vectorToWindowTiled(const Vector2D& pos) {
|
|||
const auto PMONITOR = getMonitorFromVector(pos);
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
|
||||
if (w.m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && !w.m_bIsFloating && !w.m_bHidden)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bIsFloating && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
|
||||
if (w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace && !w.m_bIsFloating && !w.m_bHidden)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bIsFloating && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -382,24 +409,24 @@ CWindow* CCompositor::vectorToWindowIdeal(const Vector2D& pos) {
|
|||
|
||||
// special workspace
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
|
||||
if (w.m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w.m_bHidden)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden)
|
||||
return &(*w);
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((*w)->m_bIsFloating && (*w)->m_bIsMapped && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
|
||||
if (!w.m_bIsFloating && w.m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w.m_iWorkspaceID == PMONITOR->activeWorkspace && !w.m_bHidden)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (!w->m_bIsFloating && w->m_bIsMapped && wlr_box_contains_point(&box, pos.x, pos.y) && w->m_iWorkspaceID == PMONITOR->activeWorkspace && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -409,34 +436,34 @@ CWindow* CCompositor::windowFromCursor() {
|
|||
const auto PMONITOR = getMonitorFromCursor();
|
||||
|
||||
if (PMONITOR->specialWorkspaceOpen) {
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
|
||||
if (w.m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w.m_bIsMapped)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped)
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
|
||||
// first loop over floating cuz they're above, m_lWindows should be sorted bottom->top, for tiled it doesn't matter.
|
||||
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID))
|
||||
return &(*w);
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID))
|
||||
return w->get();
|
||||
}
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
wlr_box box = {w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w.m_bIsMapped && w.m_iWorkspaceID == PMONITOR->activeWorkspace)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
wlr_box box = {w->m_vPosition.x, w->m_vPosition.y, w->m_vSize.x, w->m_vSize.y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_iWorkspaceID == PMONITOR->activeWorkspace)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::windowFloatingFromCursor() {
|
||||
for (auto w = m_lWindows.rbegin(); w != m_lWindows.rend(); w++) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && w->m_bIsMapped && w->m_bIsFloating && isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden)
|
||||
return &(*w);
|
||||
for (auto w = m_vWindows.rbegin(); w != m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if (wlr_box_contains_point(&box, m_sWLRCursor->x, m_sWLRCursor->y) && (*w)->m_bIsMapped && (*w)->m_bIsFloating && isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden)
|
||||
return w->get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -475,9 +502,9 @@ wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, CWindow* pW
|
|||
}
|
||||
|
||||
SMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (m.output == out) {
|
||||
return &m;
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->output == out) {
|
||||
return m.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,59 +613,58 @@ bool CCompositor::windowValidMapped(CWindow* pWindow) {
|
|||
if (pWindow->m_bHidden)
|
||||
return false;
|
||||
|
||||
if (!g_pXWaylandManager->getWindowSurface(pWindow))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getWindowForPopup(wlr_xdg_popup* popup) {
|
||||
for (auto& p : m_lXDGPopups) {
|
||||
if (p.popup == popup)
|
||||
return p.parentWindow;
|
||||
for (auto& p : m_vXDGPopups) {
|
||||
if (p->popup == popup)
|
||||
return p->parentWindow;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::list<SLayerSurface*>* layerSurfaces, Vector2D* sCoords) {
|
||||
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::list<SLayerSurface*>* layerSurfaces, Vector2D* sCoords, SLayerSurface** ppLayerSurfaceFound) {
|
||||
for (auto it = layerSurfaces->rbegin(); it != layerSurfaces->rend(); it++) {
|
||||
if ((*it)->fadingOut || !(*it)->layerSurface || ((*it)->layerSurface && !(*it)->layerSurface->mapped))
|
||||
continue;
|
||||
|
||||
const auto SURFACEAT = wlr_layer_surface_v1_surface_at((*it)->layerSurface, pos.x - (*it)->geometry.x, pos.y - (*it)->geometry.y, &sCoords->x, &sCoords->y);
|
||||
|
||||
if (SURFACEAT)
|
||||
if (SURFACEAT) {
|
||||
*ppLayerSurfaceFound = *it;
|
||||
return SURFACEAT;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getWindowFromSurface(wlr_surface* pSurface) {
|
||||
for (auto& w : m_lWindows) {
|
||||
if (g_pXWaylandManager->getWindowSurface(&w) == pSurface)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
if (g_pXWaylandManager->getWindowSurface(w.get()) == pSurface)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) {
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == ID && w.m_bIsFullscreen)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == ID && w->m_bIsFullscreen)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CCompositor::isWorkspaceVisible(const int& w) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (m.activeWorkspace == w)
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m->activeWorkspace == w)
|
||||
return true;
|
||||
|
||||
if (m.specialWorkspaceOpen && w == SPECIAL_WORKSPACE_ID)
|
||||
if (m->specialWorkspaceOpen && w == SPECIAL_WORKSPACE_ID)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -646,34 +672,42 @@ bool CCompositor::isWorkspaceVisible(const int& w) {
|
|||
}
|
||||
|
||||
CWorkspace* CCompositor::getWorkspaceByID(const int& id) {
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_iID == id)
|
||||
return &w;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_iID == id)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCompositor::sanityCheckWorkspaces() {
|
||||
for (auto it = m_lWorkspaces.begin(); it != m_lWorkspaces.end(); ++it) {
|
||||
if ((getWindowsOnWorkspace(it->m_iID) == 0 && !isWorkspaceVisible(it->m_iID))) {
|
||||
it = m_lWorkspaces.erase(it);
|
||||
for (auto it = m_vWorkspaces.begin(); it != m_vWorkspaces.end(); ++it) {
|
||||
const auto WINDOWSONWORKSPACE = getWindowsOnWorkspace((*it)->m_iID);
|
||||
|
||||
if ((WINDOWSONWORKSPACE == 0 && !isWorkspaceVisible((*it)->m_iID))) {
|
||||
it = m_vWorkspaces.erase(it);
|
||||
|
||||
if (it == m_vWorkspaces.end())
|
||||
break;
|
||||
}
|
||||
|
||||
if (it->m_iID == SPECIAL_WORKSPACE_ID && getWindowsOnWorkspace(it->m_iID) == 0) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
m.specialWorkspaceOpen = false;
|
||||
if ((*it)->m_iID == SPECIAL_WORKSPACE_ID && WINDOWSONWORKSPACE == 0) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
m->specialWorkspaceOpen = false;
|
||||
}
|
||||
|
||||
it = m_lWorkspaces.erase(it);
|
||||
it = m_vWorkspaces.erase(it);
|
||||
|
||||
if (it == m_vWorkspaces.end())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CCompositor::getWindowsOnWorkspace(const int& id) {
|
||||
int no = 0;
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == id && w.m_bIsMapped)
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == id && w->m_bIsMapped)
|
||||
no++;
|
||||
}
|
||||
|
||||
|
@ -681,9 +715,9 @@ int CCompositor::getWindowsOnWorkspace(const int& id) {
|
|||
}
|
||||
|
||||
CWindow* CCompositor::getFirstWindowOnWorkspace(const int& id) {
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == id)
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == id)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -697,16 +731,16 @@ void CCompositor::fixXWaylandWindowsOnWorkspace(const int& id) {
|
|||
if (!PWORKSPACE)
|
||||
return;
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == id) {
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == id) {
|
||||
|
||||
// moveXWaylandWindow only moves XWayland windows
|
||||
// so there is no need to check here
|
||||
// if the window is XWayland or not.
|
||||
if (ISVISIBLE && (!PWORKSPACE->m_bHasFullscreenWindow || w.m_bIsFullscreen))
|
||||
g_pXWaylandManager->moveXWaylandWindow(&w, w.m_vRealPosition.vec());
|
||||
if (ISVISIBLE && (!PWORKSPACE->m_bHasFullscreenWindow || w->m_bIsFullscreen))
|
||||
g_pXWaylandManager->moveXWaylandWindow(w.get(), w->m_vRealPosition.vec());
|
||||
else
|
||||
g_pXWaylandManager->moveXWaylandWindow(&w, Vector2D(42069,42069));
|
||||
g_pXWaylandManager->moveXWaylandWindow(w.get(), Vector2D(42069,42069));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -731,37 +765,37 @@ void CCompositor::moveWindowToTop(CWindow* pWindow) {
|
|||
if (!windowValidMapped(pWindow))
|
||||
return;
|
||||
|
||||
for (auto it = m_lWindows.begin(); it != m_lWindows.end(); ++it) {
|
||||
if (&(*it) == pWindow) {
|
||||
m_lWindows.splice(m_lWindows.end(), m_lWindows, it);
|
||||
for (auto it = m_vWindows.begin(); it != m_vWindows.end(); ++it) {
|
||||
if (it->get() == pWindow) {
|
||||
std::rotate(it, it + 1, m_vWindows.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::cleanupFadingOut() {
|
||||
for (auto& w : m_lWindowsFadingOut) {
|
||||
for (auto& w : m_vWindowsFadingOut) {
|
||||
|
||||
bool valid = windowExists(w);
|
||||
|
||||
|
||||
if (!valid || !w->m_bFadingOut || w->m_fAlpha.fl() == 0.f) {
|
||||
if (valid && !w->m_bReadyToDelete)
|
||||
continue;
|
||||
|
||||
g_pHyprOpenGL->m_mWindowFramebuffers[w].release();
|
||||
g_pHyprOpenGL->m_mWindowFramebuffers.erase(w);
|
||||
m_lWindows.remove(*w);
|
||||
m_lWindowsFadingOut.remove(w);
|
||||
removeWindowFromVectorSafe(w);
|
||||
m_vWindowsFadingOut.erase(std::remove(m_vWindowsFadingOut.begin(), m_vWindowsFadingOut.end(), w));
|
||||
|
||||
Debug::log(LOG, "Cleanup: destroyed a window");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& ls : m_lSurfacesFadingOut) {
|
||||
for (auto& ls : m_vSurfacesFadingOut) {
|
||||
if (ls->fadingOut && ls->readyToDelete && !ls->alpha.isBeingAnimated()) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
for (auto& lsl : m.m_aLayerSurfaceLists) {
|
||||
for (auto& m : m_vMonitors) {
|
||||
for (auto& lsl : m->m_aLayerSurfaceLists) {
|
||||
lsl.remove(ls);
|
||||
}
|
||||
}
|
||||
|
@ -770,7 +804,7 @@ void CCompositor::cleanupFadingOut() {
|
|||
g_pHyprOpenGL->m_mLayerFramebuffers.erase(ls);
|
||||
|
||||
delete ls;
|
||||
m_lSurfacesFadingOut.remove(ls);
|
||||
m_vSurfacesFadingOut.erase(std::remove(m_vSurfacesFadingOut.begin(), m_vSurfacesFadingOut.end(), ls));
|
||||
|
||||
Debug::log(LOG, "Cleanup: destroyed a layersurface");
|
||||
|
||||
|
@ -789,11 +823,11 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||
auto longestIntersect = -1;
|
||||
CWindow* longestIntersectWindow = nullptr;
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (&w == pWindow || !windowValidMapped(&w) || w.m_bIsFloating || !isWorkspaceVisible(w.m_iWorkspaceID))
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() == pWindow || !w->m_bIsMapped || w->m_bHidden || w->m_bIsFloating || !isWorkspaceVisible(w->m_iWorkspaceID))
|
||||
continue;
|
||||
|
||||
const auto BWINDOWIDEALBB = w.getWindowIdealBoundingBoxIgnoreReserved();
|
||||
const auto BWINDOWIDEALBB = w->getWindowIdealBoundingBoxIgnoreReserved();
|
||||
|
||||
const auto POSB = Vector2D(BWINDOWIDEALBB.x, BWINDOWIDEALBB.y);
|
||||
const auto SIZEB = Vector2D(BWINDOWIDEALBB.width, BWINDOWIDEALBB.height);
|
||||
|
@ -804,7 +838,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = &w;
|
||||
longestIntersectWindow = w.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -813,7 +847,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = &w;
|
||||
longestIntersectWindow = w.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -823,7 +857,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = &w;
|
||||
longestIntersectWindow = w.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -833,7 +867,7 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectWindow = &w;
|
||||
longestIntersectWindow = w.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -847,30 +881,30 @@ CWindow* CCompositor::getWindowInDirection(CWindow* pWindow, char dir) {
|
|||
}
|
||||
|
||||
void CCompositor::deactivateAllWLRWorkspaces(wlr_ext_workspace_handle_v1* exclude) {
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_pWlrHandle && w.m_pWlrHandle != exclude)
|
||||
w.setActive(false);
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_pWlrHandle && w->m_pWlrHandle != exclude)
|
||||
w->setActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
||||
bool gotToWindow = false;
|
||||
for (auto& w : m_lWindows) {
|
||||
if (&w != pWindow && !gotToWindow)
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() != pWindow && !gotToWindow)
|
||||
continue;
|
||||
|
||||
if (&w == pWindow) {
|
||||
if (w.get() == pWindow) {
|
||||
gotToWindow = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (w.m_iWorkspaceID == pWindow->m_iWorkspaceID && windowValidMapped(&w))
|
||||
return &w;
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (&w != pWindow && w.m_iWorkspaceID == pWindow->m_iWorkspaceID && windowValidMapped(&w))
|
||||
return &w;
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w.get() != pWindow && w->m_iWorkspaceID == pWindow->m_iWorkspaceID && w->m_bIsMapped && !w->m_bHidden)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -878,18 +912,18 @@ CWindow* CCompositor::getNextWindowOnWorkspace(CWindow* pWindow) {
|
|||
|
||||
int CCompositor::getNextAvailableNamedWorkspace() {
|
||||
int lowest = -1337 + 1;
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_iID < -1 && w.m_iID < lowest)
|
||||
lowest = w.m_iID;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_iID < -1 && w->m_iID < lowest)
|
||||
lowest = w->m_iID;
|
||||
}
|
||||
|
||||
return lowest - 1;
|
||||
}
|
||||
|
||||
CWorkspace* CCompositor::getWorkspaceByName(const std::string& name) {
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_szName == name)
|
||||
return &w;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_szName == name)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -911,8 +945,8 @@ CWorkspace* CCompositor::getWorkspaceByString(const std::string& str) {
|
|||
}
|
||||
|
||||
bool CCompositor::isPointOnAnyMonitor(const Vector2D& point) {
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (VECINRECT(point, m.vecPosition.x, m.vecPosition.y, m.vecSize.x + m.vecPosition.x, m.vecSize.y + m.vecPosition.y))
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (VECINRECT(point, m->vecPosition.x, m->vecPosition.y, m->vecSize.x + m->vecPosition.x, m->vecSize.y + m->vecPosition.y))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -925,12 +959,12 @@ CWindow* CCompositor::getConstraintWindow(SMouse* pMouse) {
|
|||
|
||||
const auto PSURFACE = pMouse->currentConstraint->surface;
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (PSURFACE == g_pXWaylandManager->getWindowSurface(&w)) {
|
||||
if (!w.m_bIsX11 && !windowValidMapped(&w))
|
||||
for (auto& w : m_vWindows) {
|
||||
if (PSURFACE == g_pXWaylandManager->getWindowSurface(w.get())) {
|
||||
if (!w->m_bIsX11 && w->m_bIsMapped && !w->m_bHidden)
|
||||
continue;
|
||||
|
||||
return &w;
|
||||
return w.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -944,19 +978,19 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||
auto longestIntersect = -1;
|
||||
SMonitor* longestIntersectMonitor = nullptr;
|
||||
|
||||
for (auto& m : m_lMonitors) {
|
||||
if (&m == m_pLastMonitor)
|
||||
for (auto& m : m_vMonitors) {
|
||||
if (m.get() == m_pLastMonitor)
|
||||
continue;
|
||||
|
||||
const auto POSB = m.vecPosition;
|
||||
const auto SIZEB = m.vecSize;
|
||||
const auto POSB = m->vecPosition;
|
||||
const auto SIZEB = m->vecSize;
|
||||
switch (dir) {
|
||||
case 'l':
|
||||
if (STICKS(POSA.x, POSB.x + SIZEB.x)) {
|
||||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = &m;
|
||||
longestIntersectMonitor = m.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -965,7 +999,7 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.y + SIZEA.y, POSB.y + SIZEB.y) - std::max(POSA.y, POSB.y));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = &m;
|
||||
longestIntersectMonitor = m.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -975,7 +1009,7 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = &m;
|
||||
longestIntersectMonitor = m.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -985,7 +1019,7 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||
const auto INTERSECTLEN = std::max((double)0, std::min(POSA.x + SIZEA.x, POSB.x + SIZEB.x) - std::max(POSA.x, POSB.x));
|
||||
if (INTERSECTLEN > longestIntersect) {
|
||||
longestIntersect = INTERSECTLEN;
|
||||
longestIntersectMonitor = &m;
|
||||
longestIntersectMonitor = m.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -999,11 +1033,11 @@ SMonitor* CCompositor::getMonitorInDirection(const char& dir) {
|
|||
}
|
||||
|
||||
void CCompositor::updateAllWindowsBorders() {
|
||||
for (auto& w : m_lWindows) {
|
||||
if (!w.m_bIsMapped)
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
updateWindowBorderColor(&w);
|
||||
updateWindowBorderColor(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1028,9 +1062,9 @@ void CCompositor::moveWindowToWorkspace(CWindow* pWindow, const std::string& wor
|
|||
|
||||
int CCompositor::getNextAvailableMonitorID() {
|
||||
int64_t topID = -1;
|
||||
for (auto& m : m_lMonitors) {
|
||||
if ((int64_t)m.ID > topID)
|
||||
topID = m.ID;
|
||||
for (auto& m : m_vMonitors) {
|
||||
if ((int64_t)m->ID > topID)
|
||||
topID = m->ID;
|
||||
}
|
||||
|
||||
return topID + 1;
|
||||
|
@ -1051,9 +1085,9 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, SMonitor* pMoni
|
|||
|
||||
// fix old mon
|
||||
int nextWorkspaceOnMonitorID = -1;
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_iMonitorID == POLDMON->ID && w.m_iID != pWorkspace->m_iID) {
|
||||
nextWorkspaceOnMonitorID = w.m_iID;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == POLDMON->ID && w->m_iID != pWorkspace->m_iID) {
|
||||
nextWorkspaceOnMonitorID = w->m_iID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1077,9 +1111,9 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, SMonitor* pMoni
|
|||
pWorkspace->m_iMonitorID = pMonitor->ID;
|
||||
pWorkspace->moveToMonitor(pMonitor->ID);
|
||||
|
||||
for (auto& w : m_lWindows) {
|
||||
if (w.m_iWorkspaceID == pWorkspace->m_iID)
|
||||
w.m_iMonitorID = pMonitor->ID;
|
||||
for (auto& w : m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pWorkspace->m_iID)
|
||||
w->m_iMonitorID = pMonitor->ID;
|
||||
}
|
||||
|
||||
if (SWITCHINGISACTIVE) { // if it was active, preserve its' status. If it wasn't, don't.
|
||||
|
@ -1106,12 +1140,12 @@ bool CCompositor::workspaceIDOutOfBounds(const int& id) {
|
|||
int lowestID = 99999;
|
||||
int highestID = -99999;
|
||||
|
||||
for (auto& w : m_lWorkspaces) {
|
||||
if (w.m_iID < lowestID)
|
||||
lowestID = w.m_iID;
|
||||
for (auto& w : m_vWorkspaces) {
|
||||
if (w->m_iID < lowestID)
|
||||
lowestID = w->m_iID;
|
||||
|
||||
if (w.m_iID > highestID)
|
||||
highestID = w.m_iID;
|
||||
if (w->m_iID > highestID)
|
||||
highestID = w->m_iID;
|
||||
}
|
||||
|
||||
return std::clamp(id, lowestID, highestID) != id;
|
||||
|
@ -1125,8 +1159,33 @@ void CCompositor::setWindowFullscreen(CWindow* pWindow, bool on, eFullscreenMode
|
|||
|
||||
g_pXWaylandManager->setWindowFullscreen(pWindow, pWindow->m_bIsFullscreen && mode == FULLSCREEN_FULL);
|
||||
// make all windows on the same workspace under the fullscreen window
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (w.m_iWorkspaceID == pWindow->m_iWorkspaceID)
|
||||
w.m_bCreatedOverFullscreen = false;
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID == pWindow->m_iWorkspaceID)
|
||||
w->m_bCreatedOverFullscreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::moveUnmanagedX11ToWindows(CWindow* pWindow) {
|
||||
for (auto it = m_dUnmanagedX11Windows.begin(); it != m_dUnmanagedX11Windows.end(); it++) {
|
||||
if (it->get() == pWindow) {
|
||||
m_vWindows.emplace_back(std::move(*it));
|
||||
m_dUnmanagedX11Windows.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CWindow* CCompositor::getX11Parent(CWindow* pWindow) {
|
||||
if (!pWindow->m_bIsX11)
|
||||
return nullptr;
|
||||
|
||||
for (auto& w : m_vWindows) {
|
||||
if (!w->m_bIsX11)
|
||||
continue;
|
||||
|
||||
if (w->m_uSurface.xwayland == pWindow->m_uSurface.xwayland->parent)
|
||||
return w.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
|
@ -60,19 +60,21 @@ public:
|
|||
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
||||
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||
// ------------------------------------------------- //
|
||||
|
||||
|
||||
const char* m_szWLDisplaySocket;
|
||||
std::string m_szInstanceSignature = "";
|
||||
|
||||
std::list<SMonitor> m_lMonitors;
|
||||
std::list<CWindow> m_lWindows;
|
||||
std::list<SXDGPopup> m_lXDGPopups;
|
||||
std::list<CWorkspace> m_lWorkspaces;
|
||||
std::list<SSubsurface> m_lSubsurfaces;
|
||||
std::list<CWindow*> m_lWindowsFadingOut;
|
||||
std::list<SLayerSurface*> m_lSurfacesFadingOut;
|
||||
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
|
||||
std::vector<std::unique_ptr<CWindow>> m_vWindows;
|
||||
std::deque<std::unique_ptr<CWindow>> m_dUnmanagedX11Windows;
|
||||
std::vector<std::unique_ptr<SXDGPopup>> m_vXDGPopups;
|
||||
std::vector<std::unique_ptr<CWorkspace>> m_vWorkspaces;
|
||||
std::vector<std::unique_ptr<SSubsurface>> m_vSubsurfaces;
|
||||
std::vector<CWindow*> m_vWindowsFadingOut;
|
||||
std::vector<SLayerSurface*> m_vSurfacesFadingOut;
|
||||
|
||||
void startCompositor();
|
||||
void cleanupExit();
|
||||
|
@ -99,7 +101,7 @@ public:
|
|||
CWindow* vectorToWindow(const Vector2D&);
|
||||
CWindow* vectorToWindowIdeal(const Vector2D&);
|
||||
CWindow* vectorToWindowTiled(const Vector2D&);
|
||||
wlr_surface* vectorToLayerSurface(const Vector2D&, std::list<SLayerSurface*>*, Vector2D*);
|
||||
wlr_surface* vectorToLayerSurface(const Vector2D&, std::list<SLayerSurface*>*, Vector2D*, SLayerSurface**);
|
||||
wlr_surface* vectorWindowToSurface(const Vector2D&, CWindow*, Vector2D& sl);
|
||||
CWindow* windowFromCursor();
|
||||
CWindow* windowFloatingFromCursor();
|
||||
|
@ -133,6 +135,8 @@ public:
|
|||
void moveWorkspaceToMonitor(CWorkspace*, SMonitor*);
|
||||
bool workspaceIDOutOfBounds(const int&);
|
||||
void setWindowFullscreen(CWindow*, bool, eFullscreenMode);
|
||||
void moveUnmanagedX11ToWindows(CWindow*);
|
||||
CWindow* getX11Parent(CWindow*);
|
||||
|
||||
private:
|
||||
void initAllSignals();
|
||||
|
|
|
@ -72,4 +72,21 @@ wlr_box CWindow::getWindowIdealBoundingBoxIgnoreReserved() {
|
|||
}
|
||||
|
||||
return wlr_box{(int)POS.x, (int)POS.y, (int)SIZE.x, (int)SIZE.y};
|
||||
}
|
||||
}
|
||||
|
||||
void CWindow::updateWindowDecos() {
|
||||
for (auto& wd : m_dWindowDecorations)
|
||||
wd->updateWindow(this);
|
||||
}
|
||||
|
||||
pid_t CWindow::getPID() {
|
||||
pid_t PID = -1;
|
||||
if (!m_bIsX11) {
|
||||
const auto CLIENT = wl_resource_get_client(m_uSurface.xdg->resource);
|
||||
wl_client_get_credentials(CLIENT, &PID, nullptr, nullptr);
|
||||
} else {
|
||||
PID = m_uSurface.xwayland->pid;
|
||||
}
|
||||
|
||||
return PID;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
// XWayland stuff
|
||||
bool m_bIsX11 = false;
|
||||
bool m_bMappedX11 = false;
|
||||
CWindow* m_pX11Parent = nullptr;
|
||||
uint64_t m_iX11Type = 0;
|
||||
bool m_bIsModal = false;
|
||||
bool m_bX11DoesntWantBorders = false;
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
|
||||
// For nofocus
|
||||
bool m_bNoFocus = false;
|
||||
bool m_bNoInitialFocus = false;
|
||||
|
||||
SSurfaceTreeNode* m_pSurfaceTree = nullptr;
|
||||
|
||||
|
@ -110,5 +112,7 @@ public:
|
|||
// methods
|
||||
wlr_box getFullWindowBoundingBox();
|
||||
wlr_box getWindowIdealBoundingBoxIgnoreReserved();
|
||||
void updateWindowDecos();
|
||||
pid_t getPID();
|
||||
|
||||
};
|
||||
|
|
|
@ -15,6 +15,8 @@ CConfigManager::CConfigManager() {
|
|||
static const char* const ENVHOME = getenv("HOME");
|
||||
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
|
||||
configPaths.emplace_back(CONFIGPATH);
|
||||
|
||||
Debug::disableLogs = &configValues["debug:disable_logs"].intValue;
|
||||
}
|
||||
|
||||
void CConfigManager::setDefaultVars() {
|
||||
|
@ -38,6 +40,8 @@ void CConfigManager::setDefaultVars() {
|
|||
configValues["debug:int"].intValue = 0;
|
||||
configValues["debug:log_damage"].intValue = 0;
|
||||
configValues["debug:overlay"].intValue = 0;
|
||||
configValues["debug:damage_blink"].intValue = 0;
|
||||
configValues["debug:disable_logs"].intValue = 0;
|
||||
|
||||
configValues["decoration:rounding"].intValue = 1;
|
||||
configValues["decoration:blur"].intValue = 1;
|
||||
|
@ -47,12 +51,13 @@ 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["decoration:multisample_edges"].intValue = 1;
|
||||
configValues["decoration:no_blur_on_oversized"].intValue = 1;
|
||||
configValues["decoration:drop_shadow"].intValue = 1;
|
||||
configValues["decoration:shadow_range"].intValue = 4;
|
||||
configValues["decoration:shadow_render_power"].intValue = 3;
|
||||
configValues["decoration:shadow_ignore_window"].intValue = 1;
|
||||
configValues["decoration:shadow_offset"].strValue = "0 0";
|
||||
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
||||
|
||||
configValues["dwindle:pseudotile"].intValue = 0;
|
||||
|
@ -103,6 +108,24 @@ void CConfigManager::setDefaultVars() {
|
|||
configValues["autogenerated"].intValue = 0;
|
||||
}
|
||||
|
||||
void CConfigManager::setDeviceDefaultVars(const std::string& dev) {
|
||||
auto& cfgValues = deviceConfigs[dev];
|
||||
|
||||
cfgValues["kb_layout"].strValue = "us";
|
||||
cfgValues["kb_variant"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_options"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_rules"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["kb_model"].strValue = STRVAL_EMPTY;
|
||||
cfgValues["repeat_rate"].intValue = 25;
|
||||
cfgValues["repeat_delay"].intValue = 600;
|
||||
cfgValues["natural_scroll"].intValue = 0;
|
||||
cfgValues["numlock_by_default"].intValue = 0;
|
||||
cfgValues["disable_while_typing"].intValue = 1;
|
||||
cfgValues["clickfinger_behavior"].intValue = 0;
|
||||
cfgValues["middle_button_emulation"].intValue = 0;
|
||||
cfgValues["tap-to-click"].intValue = 1;
|
||||
}
|
||||
|
||||
void CConfigManager::init() {
|
||||
|
||||
loadConfigLoadVars();
|
||||
|
@ -132,33 +155,58 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
|||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
}
|
||||
|
||||
return;
|
||||
if (COMMAND.find("device:") == 0 /* devices parsed later */) {
|
||||
parseError = "";
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SConfigValue* CONFIGENTRY = nullptr;
|
||||
|
||||
auto& CONFIGENTRY = configValues.at(COMMAND);
|
||||
if (CONFIGENTRY.intValue != -1) {
|
||||
if (COMMAND.find("device:") == 0) {
|
||||
const auto DEVICE = COMMAND.substr(7).substr(0, COMMAND.find_last_of(':') - 7);
|
||||
const auto CONFIGVAR = COMMAND.substr(COMMAND.find_last_of(':') + 1);
|
||||
|
||||
if (!deviceConfigExists(DEVICE))
|
||||
setDeviceDefaultVars(DEVICE);
|
||||
|
||||
auto it = deviceConfigs.find(DEVICE);
|
||||
|
||||
if (it->second.find(CONFIGVAR) == it->second.end()) {
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">: No such field.";
|
||||
return;
|
||||
}
|
||||
|
||||
CONFIGENTRY = &it->second.at(CONFIGVAR);
|
||||
} else {
|
||||
CONFIGENTRY = &configValues.at(COMMAND);
|
||||
}
|
||||
|
||||
CONFIGENTRY->set = true;
|
||||
|
||||
if (CONFIGENTRY->intValue != -1) {
|
||||
try {
|
||||
if (VALUE.find("0x") == 0) {
|
||||
// Values with 0x are hex
|
||||
const auto VALUEWITHOUTHEX = VALUE.substr(2);
|
||||
CONFIGENTRY.intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
CONFIGENTRY->intValue = stol(VALUEWITHOUTHEX, nullptr, 16);
|
||||
} else
|
||||
CONFIGENTRY.intValue = stol(VALUE);
|
||||
CONFIGENTRY->intValue = stol(VALUE);
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} else if (CONFIGENTRY.floatValue != -1) {
|
||||
} else if (CONFIGENTRY->floatValue != -1) {
|
||||
try {
|
||||
CONFIGENTRY.floatValue = stof(VALUE);
|
||||
CONFIGENTRY->floatValue = stof(VALUE);
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
}
|
||||
} else if (CONFIGENTRY.strValue != "") {
|
||||
} else if (CONFIGENTRY->strValue != "") {
|
||||
try {
|
||||
CONFIGENTRY.strValue = VALUE;
|
||||
CONFIGENTRY->strValue = VALUE;
|
||||
} catch (...) {
|
||||
Debug::log(WARN, "Error reading value of %s", COMMAND.c_str());
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">.";
|
||||
|
@ -611,8 +659,8 @@ std::string CConfigManager::parseKeyword(const std::string& COMMAND, const std::
|
|||
parseError = "";
|
||||
|
||||
// invalidate layouts jic
|
||||
for (auto& m : g_pCompositor->m_lMonitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m.ID);
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsBorders();
|
||||
|
@ -704,6 +752,7 @@ void CConfigManager::loadConfigLoadVars() {
|
|||
g_pAnimationManager->removeAllBeziers();
|
||||
m_mAdditionalReservedAreas.clear();
|
||||
configDynamicVars.clear();
|
||||
deviceConfigs.clear();
|
||||
|
||||
// paths
|
||||
configPaths.clear();
|
||||
|
@ -772,8 +821,8 @@ void CConfigManager::loadConfigLoadVars() {
|
|||
ifs.close();
|
||||
}
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m.ID);
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
// Update the keyboard layout to the cfg'd one if this is not the first launch
|
||||
if (!isFirstLaunch)
|
||||
|
@ -806,6 +855,10 @@ void CConfigManager::loadConfigLoadVars() {
|
|||
|
||||
// Update window border colors
|
||||
g_pCompositor->updateAllWindowsBorders();
|
||||
|
||||
// Force the compositor to fully re-render all monitors
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
m->forceFullFrames = 2;
|
||||
}
|
||||
|
||||
void CConfigManager::tick() {
|
||||
|
@ -843,7 +896,7 @@ void CConfigManager::tick() {
|
|||
}
|
||||
|
||||
std::mutex configmtx;
|
||||
SConfigValue CConfigManager::getConfigValueSafe(std::string val) {
|
||||
SConfigValue CConfigManager::getConfigValueSafe(const std::string& val) {
|
||||
std::lock_guard<std::mutex> lg(configmtx);
|
||||
|
||||
SConfigValue copy = configValues[val];
|
||||
|
@ -851,15 +904,38 @@ SConfigValue CConfigManager::getConfigValueSafe(std::string val) {
|
|||
return copy;
|
||||
}
|
||||
|
||||
int CConfigManager::getInt(std::string v) {
|
||||
SConfigValue CConfigManager::getConfigValueSafeDevice(const std::string& dev, const std::string& val) {
|
||||
std::lock_guard<std::mutex> lg(configmtx);
|
||||
|
||||
const auto it = deviceConfigs.find(dev);
|
||||
|
||||
if (it == deviceConfigs.end()) {
|
||||
return SConfigValue();
|
||||
}
|
||||
|
||||
SConfigValue copy = it->second[val];
|
||||
|
||||
// fallback if not set explicitly
|
||||
if (!copy.set) {
|
||||
for (auto& cv : configValues) {
|
||||
if (cv.first.find(val) == cv.first.length() - val.length()) {
|
||||
copy = cv.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
int CConfigManager::getInt(const std::string& v) {
|
||||
return getConfigValueSafe(v).intValue;
|
||||
}
|
||||
|
||||
float CConfigManager::getFloat(std::string v) {
|
||||
float CConfigManager::getFloat(const std::string& v) {
|
||||
return getConfigValueSafe(v).floatValue;
|
||||
}
|
||||
|
||||
std::string CConfigManager::getString(std::string v) {
|
||||
std::string CConfigManager::getString(const std::string& v) {
|
||||
const auto VAL = getConfigValueSafe(v).strValue;
|
||||
|
||||
if (VAL == STRVAL_EMPTY)
|
||||
|
@ -868,6 +944,23 @@ std::string CConfigManager::getString(std::string v) {
|
|||
return VAL;
|
||||
}
|
||||
|
||||
int CConfigManager::getDeviceInt(const std::string& dev, const std::string& v) {
|
||||
return getConfigValueSafeDevice(dev, v).intValue;
|
||||
}
|
||||
|
||||
float CConfigManager::getDeviceFloat(const std::string& dev, const std::string& v) {
|
||||
return getConfigValueSafeDevice(dev, v).floatValue;
|
||||
}
|
||||
|
||||
std::string CConfigManager::getDeviceString(const std::string& dev, const std::string& v) {
|
||||
const auto VAL = getConfigValueSafeDevice(dev, v).strValue;
|
||||
|
||||
if (VAL == STRVAL_EMPTY)
|
||||
return "";
|
||||
|
||||
return VAL;
|
||||
}
|
||||
|
||||
void CConfigManager::setInt(std::string v, int val) {
|
||||
configValues[v].intValue = val;
|
||||
}
|
||||
|
@ -964,14 +1057,30 @@ void CConfigManager::dispatchExecOnce() {
|
|||
}
|
||||
|
||||
void CConfigManager::performMonitorReload() {
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
auto rule = getMonitorRuleFor(m.szName);
|
||||
g_pHyprRenderer->applyMonitorRule(&m, &rule);
|
||||
|
||||
bool overAgain = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
auto rule = getMonitorRuleFor(m->szName);
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (overAgain)
|
||||
performMonitorReload();
|
||||
|
||||
m_bWantsMonitorReload = false;
|
||||
}
|
||||
|
||||
SConfigValue* CConfigManager::getConfigValuePtr(std::string val) {
|
||||
return &configValues[val];
|
||||
}
|
||||
|
||||
bool CConfigManager::deviceConfigExists(const std::string& dev) {
|
||||
const auto it = deviceConfigs.find(dev);
|
||||
|
||||
return it != deviceConfigs.end();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ struct SConfigValue {
|
|||
int64_t intValue = -1;
|
||||
float floatValue = -1;
|
||||
std::string strValue = "";
|
||||
|
||||
bool set = false; // used for device configs
|
||||
};
|
||||
|
||||
struct SMonitorRule {
|
||||
|
@ -52,13 +54,18 @@ public:
|
|||
void tick();
|
||||
void init();
|
||||
|
||||
int getInt(std::string);
|
||||
float getFloat(std::string);
|
||||
std::string getString(std::string);
|
||||
int getInt(const std::string&);
|
||||
float getFloat(const std::string&);
|
||||
std::string getString(const std::string&);
|
||||
void setFloat(std::string, float);
|
||||
void setInt(std::string, int);
|
||||
void setString(std::string, std::string);
|
||||
|
||||
int getDeviceInt(const std::string&, const std::string&);
|
||||
float getDeviceFloat(const std::string&, const std::string&);
|
||||
std::string getDeviceString(const std::string&, const std::string&);
|
||||
bool deviceConfigExists(const std::string&);
|
||||
|
||||
SConfigValue* getConfigValuePtr(std::string);
|
||||
|
||||
SMonitorRule getMonitorRuleFor(std::string);
|
||||
|
@ -81,6 +88,7 @@ private:
|
|||
std::unordered_map<std::string, time_t> configModifyTimes; // stores modify times
|
||||
std::unordered_map<std::string, std::string> configDynamicVars; // stores dynamic vars declared by the user
|
||||
std::unordered_map<std::string, SConfigValue> configValues;
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, SConfigValue>> deviceConfigs; // stores device configs
|
||||
|
||||
std::string configCurrentPath;
|
||||
|
||||
|
@ -100,12 +108,15 @@ private:
|
|||
|
||||
// internal methods
|
||||
void setDefaultVars();
|
||||
void setDeviceDefaultVars(const std::string&);
|
||||
|
||||
void applyUserDefinedVars(std::string&, const size_t);
|
||||
void loadConfigLoadVars();
|
||||
SConfigValue getConfigValueSafe(std::string);
|
||||
SConfigValue getConfigValueSafe(const std::string&);
|
||||
SConfigValue getConfigValueSafeDevice(const std::string&, const std::string&);
|
||||
void parseLine(std::string&);
|
||||
void configSetValueSafe(const std::string&, const std::string&);
|
||||
void handleDeviceConfig(const std::string&, const std::string&);
|
||||
void handleRawExec(const std::string&, const std::string&);
|
||||
void handleMonitor(const std::string&, const std::string&);
|
||||
void handleBind(const std::string&, const std::string&, bool locked = false);
|
||||
|
|
|
@ -71,6 +71,7 @@ dwindle {
|
|||
|
||||
# example binds
|
||||
bind=SUPER,Q,exec,kitty
|
||||
bind=SUPER,RETURN,exec,alacritty
|
||||
bind=SUPER,C,killactive,
|
||||
bind=SUPER,M,exit,
|
||||
bind=SUPER,E,exec,dolphin
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
|
||||
std::string monitorsRequest() {
|
||||
std::string result = "";
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\n",
|
||||
m.szName.c_str(), m.ID, (int)m.vecSize.x, (int)m.vecSize.y, m.refreshRate, (int)m.vecPosition.x, (int)m.vecPosition.y, m.activeWorkspace, g_pCompositor->getWorkspaceByID(m.activeWorkspace)->m_szName.c_str(), (int)m.vecReservedTopLeft.x, (int)m.vecReservedTopLeft.y, (int)m.vecReservedBottomRight.x, (int)m.vecReservedBottomRight.y);
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s (ID %i):\n\t%ix%i@%f at %ix%i\n\tactive workspace: %i (%s)\n\treserved: %i %i %i %i\n\tscale: %.2f\n\ttransform: %i\n\n",
|
||||
m->szName.c_str(), m->ID, (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -25,19 +25,21 @@ std::string monitorsRequest() {
|
|||
|
||||
std::string clientsRequest() {
|
||||
std::string result = "";
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (w.m_bIsMapped)
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\n",
|
||||
&w, w.m_szTitle.c_str(), (int)w.m_vRealPosition.vec().x, (int)w.m_vRealPosition.vec().y, (int)w.m_vRealSize.vec().x, (int)w.m_vRealSize.vec().y, w.m_iWorkspaceID, (w.m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w.m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w.m_iWorkspaceID)).c_str()), (int)w.m_bIsFloating, w.m_iMonitorID, g_pXWaylandManager->getAppIDClass(&w).c_str());
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bIsMapped) {
|
||||
result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n",
|
||||
&w, w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID());
|
||||
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string workspacesRequest() {
|
||||
std::string result = "";
|
||||
for (auto& w : g_pCompositor->m_lWorkspaces) {
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
result += getFormat("workspace ID %i (%s) on monitor %s:\n\twindows: %i\n\thasfullscreen: %i\n\n",
|
||||
w.m_iID, w.m_szName.c_str(), g_pCompositor->getMonitorFromID(w.m_iMonitorID)->szName.c_str(), g_pCompositor->getWindowsOnWorkspace(w.m_iID), (int)w.m_bHasFullscreenWindow);
|
||||
w->m_iID, w->m_szName.c_str(), g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(), g_pCompositor->getWindowsOnWorkspace(w->m_iID), (int)w->m_bHasFullscreenWindow);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -48,17 +50,17 @@ std::string activeWindowRequest() {
|
|||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return "Invalid";
|
||||
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||
return getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n",
|
||||
PWINDOW, PWINDOW->m_szTitle.c_str(), (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), (int)PWINDOW->m_bIsFloating, (int)PWINDOW->m_iMonitorID, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), g_pXWaylandManager->getTitle(PWINDOW).c_str(), PWINDOW->getPID());
|
||||
}
|
||||
|
||||
std::string layersRequest() {
|
||||
std::string result = "";
|
||||
|
||||
for (auto& mon : g_pCompositor->m_lMonitors) {
|
||||
for (auto& mon : g_pCompositor->m_vMonitors) {
|
||||
result += getFormat("Monitor %s:\n");
|
||||
int layerLevel = 0;
|
||||
for (auto& level : mon.m_aLayerSurfaceLists) {
|
||||
for (auto& level : mon->m_aLayerSurfaceLists) {
|
||||
result += getFormat("\tLayer level %i:\n", layerLevel);
|
||||
|
||||
for (auto& layer : level) {
|
||||
|
@ -173,6 +175,12 @@ std::string reloadRequest() {
|
|||
return "ok";
|
||||
}
|
||||
|
||||
std::string killRequest() {
|
||||
g_pInputManager->setClickMode(CLICKMODE_KILL);
|
||||
|
||||
return "ok";
|
||||
}
|
||||
|
||||
std::string getReply(std::string);
|
||||
|
||||
std::string dispatchBatch(std::string request) {
|
||||
|
@ -214,6 +222,8 @@ std::string getReply(std::string request) {
|
|||
return workspacesRequest();
|
||||
else if (request == "clients")
|
||||
return clientsRequest();
|
||||
else if (request == "kill")
|
||||
return killRequest();
|
||||
else if (request == "activewindow")
|
||||
return activeWindowRequest();
|
||||
else if (request == "layers")
|
||||
|
|
|
@ -120,7 +120,7 @@ int CHyprMonitorDebugOverlay::draw(int offset) {
|
|||
yOffset += 11;
|
||||
|
||||
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||
m_wbLastDrawnBox = {(int)g_pCompositor->m_lMonitors.front().vecPosition.x, (int)g_pCompositor->m_lMonitors.front().vecPosition.y + offset - 1, (int)maxX + 2, yOffset - offset + 2};
|
||||
m_wbLastDrawnBox = {(int)g_pCompositor->m_vMonitors.front()->vecPosition.x, (int)g_pCompositor->m_vMonitors.front()->vecPosition.y + offset - 1, (int)maxX + 2, yOffset - offset + 2};
|
||||
g_pHyprRenderer->damageBox(&m_wbLastDrawnBox);
|
||||
|
||||
return yOffset - offset;
|
||||
|
@ -140,7 +140,7 @@ void CHyprDebugOverlay::frameData(SMonitor* pMonitor) {
|
|||
|
||||
void CHyprDebugOverlay::draw() {
|
||||
|
||||
const auto PMONITOR = &g_pCompositor->m_lMonitors.front();
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
|
||||
if (!m_pCairoSurface || !m_pCairo) {
|
||||
m_pCairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||
|
@ -155,8 +155,8 @@ void CHyprDebugOverlay::draw() {
|
|||
|
||||
// draw the things
|
||||
int offsetY = 0;
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
offsetY += m_mMonitorOverlays[&m].draw(offsetY);
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
offsetY += m_mMonitorOverlays[m.get()].draw(offsetY);
|
||||
offsetY += 5; // for padding between mons
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ void Debug::init(std::string IS) {
|
|||
|
||||
void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
|
||||
if (disableLogs && *disableLogs)
|
||||
return;
|
||||
|
||||
// log to a file
|
||||
std::ofstream ofs;
|
||||
ofs.open(logFile, std::ios::out | std::ios::app);
|
||||
|
|
|
@ -17,4 +17,5 @@ namespace Debug {
|
|||
void log(LogLevel level, const char* fmt, ...);
|
||||
|
||||
inline std::string logFile;
|
||||
inline int64_t* disableLogs = nullptr;
|
||||
};
|
|
@ -55,17 +55,7 @@ void Events::listener_mouseAxis(wl_listener* listener, void* data) {
|
|||
void Events::listener_requestMouse(wl_listener* listener, void* data) {
|
||||
const auto EVENT = (wlr_seat_pointer_request_set_cursor_event*)data;
|
||||
|
||||
if (!g_pHyprRenderer->shouldRenderCursor())
|
||||
return;
|
||||
|
||||
if (!EVENT->surface) {
|
||||
g_pHyprRenderer->m_bWindowRequestedCursorHide = true;
|
||||
} else {
|
||||
g_pHyprRenderer->m_bWindowRequestedCursorHide = false;
|
||||
}
|
||||
|
||||
if (EVENT->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, EVENT->surface, EVENT->hotspot_x, EVENT->hotspot_y);
|
||||
g_pInputManager->processMouseRequest(EVENT);
|
||||
}
|
||||
|
||||
void Events::listener_newInput(wl_listener* listener, void* data) {
|
||||
|
|
|
@ -36,7 +36,7 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
|
|||
SLayerSurface* layerSurface = PMONITOR->m_aLayerSurfaceLists[WLRLAYERSURFACE->pending.layer].back();
|
||||
|
||||
if (!WLRLAYERSURFACE->output) {
|
||||
WLRLAYERSURFACE->output = g_pCompositor->m_lMonitors.front().output; // TODO: current mon
|
||||
WLRLAYERSURFACE->output = g_pCompositor->m_vMonitors.front()->output; // TODO: current mon
|
||||
}
|
||||
|
||||
layerSurface->hyprListener_commitLayerSurface.initCallback(&WLRLAYERSURFACE->surface->events.commit, &Events::listener_commitLayerSurface, layerSurface, "layerSurface");
|
||||
|
@ -145,7 +145,7 @@ void Events::listener_unmapLayerSurface(void* owner, void* data) {
|
|||
|
||||
layersurface->fadingOut = true;
|
||||
|
||||
g_pCompositor->m_lSurfacesFadingOut.push_back(layersurface);
|
||||
g_pCompositor->m_vSurfacesFadingOut.push_back(layersurface);
|
||||
|
||||
if (layersurface->layerSurface->mapped)
|
||||
layersurface->layerSurface->mapped = false;
|
||||
|
@ -179,7 +179,7 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
|||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
wlr_box geomFixed = {layersurface->geometry.x + PMONITOR->vecPosition.x, layersurface->geometry.y + PMONITOR->vecPosition.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
wlr_box geomFixed = {layersurface->geometry.x, layersurface->geometry.y, layersurface->geometry.width, layersurface->geometry.height};
|
||||
g_pHyprRenderer->damageBox(&geomFixed);
|
||||
|
||||
// fix if it changed its mon
|
||||
|
@ -206,6 +206,5 @@ void Events::listener_commitLayerSurface(void* owner, void* data) {
|
|||
|
||||
layersurface->position = Vector2D(layersurface->geometry.x, layersurface->geometry.y);
|
||||
|
||||
// TODO: optimize this. This does NOT need to be here but it prevents some issues with full DT.
|
||||
g_pHyprRenderer->damageMonitor(PMONITOR);
|
||||
g_pHyprRenderer->damageSurface(layersurface->layerSurface->surface, layersurface->position.x, layersurface->position.y);
|
||||
}
|
|
@ -21,24 +21,24 @@ void Events::listener_change(wl_listener* listener, void* data) {
|
|||
// layout got changed, let's update monitors.
|
||||
const auto CONFIG = wlr_output_configuration_v1_create();
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
const auto CONFIGHEAD = wlr_output_configuration_head_v1_create(CONFIG, m.output);
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
const auto CONFIGHEAD = wlr_output_configuration_head_v1_create(CONFIG, m->output);
|
||||
|
||||
// TODO: clients off of disabled
|
||||
wlr_box BOX;
|
||||
wlr_output_layout_get_box(g_pCompositor->m_sWLROutputLayout, m.output, &BOX);
|
||||
wlr_output_layout_get_box(g_pCompositor->m_sWLROutputLayout, m->output, &BOX);
|
||||
|
||||
//m.vecSize.x = BOX.width;
|
||||
// m.vecSize.y = BOX.height;
|
||||
m.vecPosition.x = BOX.x;
|
||||
m.vecPosition.y = BOX.y;
|
||||
//m->vecSize.x = BOX.width;
|
||||
// m->vecSize.y = BOX.height;
|
||||
m->vecPosition.x = BOX.x;
|
||||
m->vecPosition.y = BOX.y;
|
||||
|
||||
CONFIGHEAD->state.enabled = m.output->enabled;
|
||||
CONFIGHEAD->state.mode = m.output->current_mode;
|
||||
CONFIGHEAD->state.x = m.vecPosition.x;
|
||||
CONFIGHEAD->state.y = m.vecPosition.y;
|
||||
CONFIGHEAD->state.enabled = m->output->enabled;
|
||||
CONFIGHEAD->state.mode = m->output->current_mode;
|
||||
CONFIGHEAD->state.x = m->vecPosition.x;
|
||||
CONFIGHEAD->state.y = m->vecPosition.y;
|
||||
|
||||
wlr_output_set_custom_mode(m.output, m.vecPixelSize.x, m.vecPixelSize.y, (int)(round(m.refreshRate * 1000)));
|
||||
wlr_output_set_custom_mode(m->output, m->vecPixelSize.x, m->vecPixelSize.y, (int)(round(m->refreshRate * 1000)));
|
||||
}
|
||||
|
||||
wlr_output_manager_v1_set_configuration(g_pCompositor->m_sWLROutputMgr, CONFIG);
|
||||
|
@ -90,8 +90,7 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
|||
newMonitor.vecSize = monitorRule.resolution;
|
||||
newMonitor.refreshRate = monitorRule.refreshRate;
|
||||
|
||||
g_pCompositor->m_lMonitors.push_back(newMonitor);
|
||||
const auto PNEWMONITOR = &g_pCompositor->m_lMonitors.back();
|
||||
const auto PNEWMONITOR = g_pCompositor->m_vMonitors.emplace_back(std::make_unique<SMonitor>(newMonitor)).get();
|
||||
|
||||
PNEWMONITOR->hyprListener_monitorFrame.initCallback(&OUTPUT->events.frame, &Events::listener_monitorFrame, PNEWMONITOR);
|
||||
PNEWMONITOR->hyprListener_monitorDestroy.initCallback(&OUTPUT->events.destroy, &Events::listener_monitorDestroy, PNEWMONITOR);
|
||||
|
@ -115,10 +114,10 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
|||
|
||||
// Workspace
|
||||
std::string newDefaultWorkspaceName = "";
|
||||
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_lWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||
auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName);
|
||||
|
||||
if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) {
|
||||
WORKSPACEID = g_pCompositor->m_lWorkspaces.size() + 1;
|
||||
WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1;
|
||||
newDefaultWorkspaceName = std::to_string(WORKSPACEID);
|
||||
|
||||
Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace);
|
||||
|
@ -135,13 +134,12 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
|||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PNEWMONITOR->ID);
|
||||
PNEWWORKSPACE->startAnim(true,true,true);
|
||||
} else {
|
||||
PNEWWORKSPACE = &g_pCompositor->m_lWorkspaces.emplace_back(newMonitor.ID);
|
||||
PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(newMonitor.ID, newDefaultWorkspaceName)).get();
|
||||
|
||||
// We are required to set the name here immediately
|
||||
wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str());
|
||||
|
||||
PNEWWORKSPACE->m_iID = WORKSPACEID;
|
||||
PNEWWORKSPACE->m_szName = newDefaultWorkspaceName;
|
||||
}
|
||||
|
||||
PNEWMONITOR->activeWorkspace = PNEWWORKSPACE->m_iID;
|
||||
|
@ -174,6 +172,9 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
|
||||
static auto *const PDEBUGOVERLAY = &g_pConfigManager->getConfigValuePtr("debug:overlay")->intValue;
|
||||
static auto *const PDAMAGETRACKINGMODE = &g_pConfigManager->getConfigValuePtr("general:damage_tracking_internal")->intValue;
|
||||
static auto *const PDAMAGEBLINK = &g_pConfigManager->getConfigValuePtr("debug:damage_blink")->intValue;
|
||||
|
||||
static int damageBlinkCleanup = 0; // because double-buffered
|
||||
|
||||
if (*PDEBUGOVERLAY == 1) {
|
||||
startRender = std::chrono::high_resolution_clock::now();
|
||||
|
@ -227,7 +228,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && PMONITOR->forceFullFrames == 0) {
|
||||
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && PMONITOR->forceFullFrames == 0 && damageBlinkCleanup == 0) {
|
||||
pixman_region32_fini(&damage);
|
||||
wlr_output_rollback(PMONITOR->output);
|
||||
wlr_output_schedule_frame(PMONITOR->output); // we update shit at the monitor's Hz so we need to schedule frames because rollback wont
|
||||
|
@ -235,7 +236,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
}
|
||||
|
||||
// if we have no tracking or full tracking, invalidate the entire monitor
|
||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0) {
|
||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || PMONITOR->forceFullFrames > 0 || damageBlinkCleanup > 0) {
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
pixman_region32_copy(&g_pHyprOpenGL->m_rOriginalDamageRegion, &damage);
|
||||
|
@ -281,6 +282,16 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
if (*PDAMAGEBLINK && damageBlinkCleanup == 0) {
|
||||
wlr_box monrect = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
g_pHyprOpenGL->renderRect(&monrect, CColor(255,0,255,100), 0);
|
||||
damageBlinkCleanup = 1;
|
||||
} else if (*PDAMAGEBLINK) {
|
||||
damageBlinkCleanup++;
|
||||
if (damageBlinkCleanup > 3)
|
||||
damageBlinkCleanup = 0;
|
||||
}
|
||||
|
||||
wlr_renderer_begin(g_pCompositor->m_sWLRRenderer, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
||||
wlr_output_render_software_cursors(PMONITOR->output, NULL);
|
||||
|
@ -299,6 +310,9 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
|||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR)
|
||||
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
|
||||
|
||||
if (*PDAMAGEBLINK)
|
||||
pixman_region32_union(&frameDamage, &frameDamage, &damage);
|
||||
|
||||
wlr_output_set_damage(PMONITOR->output, &frameDamage);
|
||||
pixman_region32_fini(&frameDamage);
|
||||
pixman_region32_fini(&damage);
|
||||
|
@ -324,9 +338,9 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
|||
|
||||
SMonitor* pMonitor = nullptr;
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (m.szName == OUTPUT->name) {
|
||||
pMonitor = &m;
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == OUTPUT->name) {
|
||||
pMonitor = m.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +349,7 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
|||
return;
|
||||
|
||||
// Cleanup everything. Move windows back, snap cursor, shit.
|
||||
const auto BACKUPMON = &g_pCompositor->m_lMonitors.front();
|
||||
const auto BACKUPMON = g_pCompositor->m_vMonitors.front().get();
|
||||
|
||||
if (!BACKUPMON) {
|
||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||
|
@ -351,9 +365,9 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
|||
|
||||
// move workspaces
|
||||
std::deque<CWorkspace*> wspToMove;
|
||||
for (auto& w : g_pCompositor->m_lWorkspaces) {
|
||||
if (w.m_iMonitorID == pMonitor->ID) {
|
||||
wspToMove.push_back(&w);
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iMonitorID == pMonitor->ID) {
|
||||
wspToMove.push_back(w.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,27 +378,23 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
|||
|
||||
pMonitor->activeWorkspace = -1;
|
||||
|
||||
for (auto it = g_pCompositor->m_lWorkspaces.begin(); it != g_pCompositor->m_lWorkspaces.end(); ++it) {
|
||||
if (it->m_iMonitorID == pMonitor->ID) {
|
||||
it = g_pCompositor->m_lWorkspaces.erase(it);
|
||||
}
|
||||
}
|
||||
g_pCompositor->m_vWorkspaces.erase(std::remove_if(g_pCompositor->m_vWorkspaces.begin(), g_pCompositor->m_vWorkspaces.end(), [&](std::unique_ptr<CWorkspace>& el) { return el->m_iMonitorID == pMonitor->ID; }));
|
||||
|
||||
Debug::log(LOG, "Removed monitor %s!", pMonitor->szName.c_str());
|
||||
|
||||
g_pEventManager->postEvent(SHyprIPCEvent("monitorremoved", pMonitor->szName));
|
||||
|
||||
g_pCompositor->m_lMonitors.remove(*pMonitor);
|
||||
g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::unique_ptr<SMonitor>& el) { return el.get() == pMonitor; }));
|
||||
|
||||
// update the pMostHzMonitor
|
||||
if (pMostHzMonitor == pMonitor) {
|
||||
int mostHz = 0;
|
||||
SMonitor* pMonitorMostHz = nullptr;
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (m.refreshRate > mostHz) {
|
||||
pMonitorMostHz = &m;
|
||||
mostHz = m.refreshRate;
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->refreshRate > mostHz) {
|
||||
pMonitorMostHz = m.get();
|
||||
mostHz = m->refreshRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,8 +76,7 @@ void Events::listener_newPopup(void* owner, void* data) {
|
|||
|
||||
const auto WLRPOPUP = (wlr_xdg_popup*)data;
|
||||
|
||||
g_pCompositor->m_lXDGPopups.push_back(SXDGPopup());
|
||||
const auto PNEWPOPUP = &g_pCompositor->m_lXDGPopups.back();
|
||||
const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(layersurface->monitorID);
|
||||
|
||||
|
@ -97,8 +96,7 @@ void Events::listener_newPopupXDG(void* owner, void* data) {
|
|||
|
||||
const auto WLRPOPUP = (wlr_xdg_popup*)data;
|
||||
|
||||
g_pCompositor->m_lXDGPopups.push_back(SXDGPopup());
|
||||
const auto PNEWPOPUP = &g_pCompositor->m_lXDGPopups.back();
|
||||
const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
|
||||
|
@ -122,8 +120,7 @@ void Events::listener_newPopupFromPopupXDG(void* owner, void* data) {
|
|||
|
||||
const auto WLRPOPUP = (wlr_xdg_popup*)data;
|
||||
|
||||
g_pCompositor->m_lXDGPopups.push_back(SXDGPopup());
|
||||
const auto PNEWPOPUP = &g_pCompositor->m_lXDGPopups.back();
|
||||
const auto PNEWPOPUP = g_pCompositor->m_vXDGPopups.emplace_back(std::make_unique<SXDGPopup>()).get();
|
||||
|
||||
PNEWPOPUP->popup = WLRPOPUP;
|
||||
PNEWPOPUP->parentPopup = PPOPUP;
|
||||
|
@ -170,5 +167,5 @@ void Events::listener_destroyPopupXDG(void* owner, void* data) {
|
|||
PPOPUP->pSurfaceTree = nullptr;
|
||||
}
|
||||
|
||||
g_pCompositor->m_lXDGPopups.remove(*PPOPUP);
|
||||
g_pCompositor->m_vXDGPopups.erase(std::remove_if(g_pCompositor->m_vXDGPopups.begin(), g_pCompositor->m_vXDGPopups.end(), [&](std::unique_ptr<SXDGPopup>& el) { return el.get() == PPOPUP; }));
|
||||
}
|
|
@ -43,6 +43,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
PWINDOW->m_szTitle = g_pXWaylandManager->getTitle(PWINDOW);
|
||||
PWINDOW->m_fAlpha = 255.f;
|
||||
|
||||
if (PWINDOW->m_iX11Type == 2)
|
||||
g_pCompositor->moveUnmanagedX11ToWindows(PWINDOW);
|
||||
|
||||
// Set all windows tiled regardless of anything
|
||||
g_pXWaylandManager->setWindowStyleTiled(PWINDOW, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
|
||||
|
||||
|
@ -57,7 +60,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(PWINDOW);
|
||||
|
||||
if (!PWINDOWSURFACE) {
|
||||
g_pCompositor->m_lWindows.remove(*PWINDOW);
|
||||
g_pCompositor->removeWindowFromVectorSafe(PWINDOW);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -97,7 +100,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
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)
|
||||
if (MONITOR >= (long int)g_pCompositor->m_vMonitors.size() || MONITOR < (long int)0)
|
||||
PWINDOW->m_iMonitorID = 0;
|
||||
else
|
||||
PWINDOW->m_iMonitorID = MONITOR;
|
||||
|
@ -228,11 +231,9 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
PWINDOW->m_vPseudoSize = PWINDOW->m_vRealSize.goalv() - Vector2D(10,10);
|
||||
}
|
||||
|
||||
if (!PWINDOW->m_bNoFocus)
|
||||
if (!PWINDOW->m_bNoFocus && !PWINDOW->m_bNoInitialFocus)
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
|
||||
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
|
||||
|
||||
Debug::log(LOG, "Window got assigned a surfaceTreeNode %x", PWINDOW->m_pSurfaceTree);
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
|
@ -260,16 +261,25 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||
}
|
||||
|
||||
if (requestsFullscreen) {
|
||||
// fix fullscreen on requested (basically do a switcheroo)
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow) {
|
||||
const auto PFULLWINDOW = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PFULLWINDOW, FULLSCREEN_FULL, false);
|
||||
g_pXWaylandManager->setWindowFullscreen(PFULLWINDOW, PFULLWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
g_pCompositor->setWindowFullscreen(PWINDOW, true, FULLSCREEN_FULL);
|
||||
}
|
||||
|
||||
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
Debug::log(LOG, "Window %x unmapped", PWINDOW);
|
||||
Debug::log(LOG, "Window %x unmapped (class %s)", PWINDOW, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||
|
||||
if (!PWINDOW->m_bIsX11) {
|
||||
Debug::log(LOG, "Unregistered late callbacks XDG: %x %x %x %x", &PWINDOW->hyprListener_commitWindow.m_sListener.link, &PWINDOW->hyprListener_setTitleWindow.m_sListener.link, &PWINDOW->hyprListener_fullscreenWindow.m_sListener.link, &PWINDOW->hyprListener_newPopupXDG.m_sListener.link);
|
||||
|
@ -285,6 +295,11 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||
PWINDOW->hyprListener_setTitleWindow.removeCallback();
|
||||
}
|
||||
|
||||
if (PWINDOW->m_bIsFullscreen) {
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, false);
|
||||
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
// Allow the renderer to catch the last frame.
|
||||
g_pHyprOpenGL->makeWindowSnapshot(PWINDOW);
|
||||
|
||||
|
@ -318,12 +333,14 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
|||
|
||||
PWINDOW->m_bFadingOut = true;
|
||||
|
||||
g_pCompositor->m_lWindowsFadingOut.push_back(PWINDOW);
|
||||
g_pCompositor->m_vWindowsFadingOut.emplace_back(PWINDOW);
|
||||
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID));
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
|
||||
|
||||
// do the animation thing
|
||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec();
|
||||
PWINDOW->m_vOriginalClosedPos = PWINDOW->m_vRealPosition.vec() - PMONITOR->vecPosition;
|
||||
PWINDOW->m_vOriginalClosedSize = PWINDOW->m_vRealSize.vec();
|
||||
|
||||
if (!PWINDOW->m_bX11DoesntWantBorders) // don't animate out if they weren't animated in.
|
||||
|
@ -347,7 +364,10 @@ void Events::listener_commitWindow(void* owner, void* data) {
|
|||
void Events::listener_destroyWindow(void* owner, void* data) {
|
||||
CWindow* PWINDOW = (CWindow*)owner;
|
||||
|
||||
Debug::log(LOG, "Window %x destroyed, queueing.", PWINDOW);
|
||||
Debug::log(LOG, "Window %x destroyed, queueing. (class %s)", PWINDOW, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
|
||||
|
||||
if (PWINDOW->m_bIsX11)
|
||||
Debug::log(LOG, "XWayland class raw: %s", PWINDOW->m_uSurface.xwayland->_class);
|
||||
|
||||
if (PWINDOW == g_pCompositor->m_pLastWindow) {
|
||||
g_pCompositor->m_pLastWindow = nullptr;
|
||||
|
@ -393,9 +413,9 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
|||
const auto REQUESTED = &PWINDOW->m_uSurface.xdg->toplevel->requested;
|
||||
|
||||
if (REQUESTED->fullscreen != PWINDOW->m_bIsFullscreen)
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, true);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, REQUESTED->fullscreen);
|
||||
} else {
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, true);
|
||||
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, !PWINDOW->m_bIsFullscreen);
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Window %x fullscreen to %i", PWINDOW, PWINDOW->m_bIsFullscreen);
|
||||
|
@ -455,15 +475,18 @@ void Events::listener_configureX11(void* owner, void* data) {
|
|||
void Events::listener_surfaceXWayland(wl_listener* listener, void* data) {
|
||||
const auto XWSURFACE = (wlr_xwayland_surface*)data;
|
||||
|
||||
Debug::log(LOG, "New XWayland Surface created.");
|
||||
Debug::log(LOG, "New XWayland Surface created (class %s).", XWSURFACE->_class);
|
||||
if (XWSURFACE->parent)
|
||||
Debug::log(LOG, "Window parent data: %s at %x", XWSURFACE->parent->_class, XWSURFACE->parent);
|
||||
|
||||
g_pCompositor->m_lWindows.emplace_back();
|
||||
const auto PNEWWINDOW = &g_pCompositor->m_lWindows.back();
|
||||
const auto PNEWWINDOW = XWSURFACE->override_redirect ? g_pCompositor->m_dUnmanagedX11Windows.emplace_back(std::make_unique<CWindow>()).get() : g_pCompositor->m_vWindows.emplace_back(std::make_unique<CWindow>()).get();
|
||||
|
||||
PNEWWINDOW->m_uSurface.xwayland = XWSURFACE;
|
||||
PNEWWINDOW->m_iX11Type = XWSURFACE->override_redirect ? 2 : 1;
|
||||
PNEWWINDOW->m_bIsX11 = true;
|
||||
|
||||
PNEWWINDOW->m_pX11Parent = g_pCompositor->getX11Parent(PNEWWINDOW);
|
||||
|
||||
PNEWWINDOW->hyprListener_mapWindow.initCallback(&XWSURFACE->events.map, &Events::listener_mapWindow, PNEWWINDOW, "XWayland Window");
|
||||
PNEWWINDOW->hyprListener_unmapWindow.initCallback(&XWSURFACE->events.unmap, &Events::listener_unmapWindow, PNEWWINDOW, "XWayland Window");
|
||||
PNEWWINDOW->hyprListener_destroyWindow.initCallback(&XWSURFACE->events.destroy, &Events::listener_destroyWindow, PNEWWINDOW, "XWayland Window");
|
||||
|
@ -473,13 +496,12 @@ void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
|||
// A window got opened
|
||||
const auto XDGSURFACE = (wlr_xdg_surface*)data;
|
||||
|
||||
Debug::log(LOG, "New XDG Surface created. (%ix%i at %i %i)", XDGSURFACE->current.geometry.width, XDGSURFACE->current.geometry.height, XDGSURFACE->current.geometry.x, XDGSURFACE->current.geometry.y);
|
||||
Debug::log(LOG, "New XDG Surface created. (class: %s)", XDGSURFACE->toplevel->app_id);
|
||||
|
||||
if (XDGSURFACE->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
||||
return; // TODO: handle?
|
||||
|
||||
g_pCompositor->m_lWindows.emplace_back();
|
||||
const auto PNEWWINDOW = &g_pCompositor->m_lWindows.back();
|
||||
const auto PNEWWINDOW = g_pCompositor->m_vWindows.emplace_back(std::make_unique<CWindow>()).get();
|
||||
PNEWWINDOW->m_uSurface.xdg = XDGSURFACE;
|
||||
|
||||
PNEWWINDOW->hyprListener_mapWindow.initCallback(&XDGSURFACE->events.map, &Events::listener_mapWindow, PNEWWINDOW, "XDG Window");
|
||||
|
|
|
@ -33,56 +33,47 @@ public:
|
|||
|
||||
// gets the current vector value (real time)
|
||||
const Vector2D& vec() const {
|
||||
RASSERT(m_eVarType == AVARTYPE_VECTOR, "Tried to access vec() of AVARTYPE %i!", m_eVarType);
|
||||
return m_vValue;
|
||||
}
|
||||
|
||||
// gets the current float value (real time)
|
||||
const float& fl() const {
|
||||
RASSERT(m_eVarType == AVARTYPE_FLOAT, "Tried to access fl() of AVARTYPE %i!", m_eVarType);
|
||||
return m_fValue;
|
||||
}
|
||||
|
||||
// gets the current color value (real time)
|
||||
const CColor& col() const {
|
||||
RASSERT(m_eVarType == AVARTYPE_COLOR, "Tried to access col() of AVARTYPE %i!", m_eVarType);
|
||||
return m_cValue;
|
||||
}
|
||||
|
||||
// gets the goal vector value
|
||||
const Vector2D& goalv() const {
|
||||
RASSERT(m_eVarType == AVARTYPE_VECTOR, "Tried to access goalv() of AVARTYPE %i!", m_eVarType);
|
||||
return m_vGoal;
|
||||
}
|
||||
|
||||
// gets the goal float value
|
||||
const float& goalf() const {
|
||||
RASSERT(m_eVarType == AVARTYPE_FLOAT, "Tried to access goalf() of AVARTYPE %i!", m_eVarType);
|
||||
return m_fGoal;
|
||||
}
|
||||
|
||||
// gets the goal color value
|
||||
const CColor& goalc() const {
|
||||
RASSERT(m_eVarType == AVARTYPE_COLOR, "Tried to access goalc() of AVARTYPE %i!", m_eVarType);
|
||||
return m_cGoal;
|
||||
}
|
||||
|
||||
void operator=(const Vector2D& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_VECTOR, "Tried to access =v of AVARTYPE %i!", m_eVarType);
|
||||
m_vGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
}
|
||||
|
||||
void operator=(const float& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_FLOAT, "Tried to access =f of AVARTYPE %i!", m_eVarType);
|
||||
m_fGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_fBegun = m_fValue;
|
||||
}
|
||||
|
||||
void operator=(const CColor& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_COLOR, "Tried to access =c of AVARTYPE %i!", m_eVarType);
|
||||
m_cGoal = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_cBegun = m_cValue;
|
||||
|
@ -90,7 +81,6 @@ public:
|
|||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const Vector2D& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_VECTOR, "Tried to access setValue(v) of AVARTYPE %i!", m_eVarType);
|
||||
m_vValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
@ -98,7 +88,6 @@ public:
|
|||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const float& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_FLOAT, "Tried to access setValue(f) of AVARTYPE %i!", m_eVarType);
|
||||
m_fValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
@ -106,7 +95,6 @@ public:
|
|||
|
||||
// Sets the actual stored value, without affecting the goal, but resets the timer
|
||||
void setValue(const CColor& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_COLOR, "Tried to access setValue(c) of AVARTYPE %i!", m_eVarType);
|
||||
m_cValue = v;
|
||||
animationBegin = std::chrono::system_clock::now();
|
||||
m_vBegun = m_vValue;
|
||||
|
@ -114,21 +102,18 @@ public:
|
|||
|
||||
// Sets the actual value and goal
|
||||
void setValueAndWarp(const Vector2D& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_VECTOR, "Tried to access setValueAndWarp(v) of AVARTYPE %i!", m_eVarType);
|
||||
m_vGoal = v;
|
||||
warp();
|
||||
}
|
||||
|
||||
// Sets the actual value and goal
|
||||
void setValueAndWarp(const float& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_FLOAT, "Tried to access setValueAndWarp(f) of AVARTYPE %i!", m_eVarType);
|
||||
m_fGoal = v;
|
||||
warp();
|
||||
}
|
||||
|
||||
// Sets the actual value and goal
|
||||
void setValueAndWarp(const CColor& v) {
|
||||
RASSERT(m_eVarType == AVARTYPE_COLOR, "Tried to access setValueAndWarp(c) of AVARTYPE %i!", m_eVarType);
|
||||
m_cGoal = v;
|
||||
warp();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,41 @@
|
|||
#include "../Compositor.hpp"
|
||||
#include <sys/utsname.h>
|
||||
|
||||
static const float transforms[][9] = {{
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
0.0f, 1.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
-1.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
0.0f, -1.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
-1.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
0.0f, 1.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},{
|
||||
0.0f, -1.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
},
|
||||
};
|
||||
|
||||
void addWLSignal(wl_signal* pSignal, wl_listener* pListener, void* pOwner, std::string ownerString) {
|
||||
ASSERT(pSignal);
|
||||
ASSERT(pListener);
|
||||
|
@ -79,8 +114,8 @@ std::string getFormat(const char *fmt, ...) {
|
|||
}
|
||||
|
||||
void scaleBox(wlr_box* box, float scale) {
|
||||
box->width = std::round((box->x + box->width) * scale) - std::round(box->x * scale);
|
||||
box->height = std::round((box->y + box->height) * scale) - std::round(box->y * scale);
|
||||
box->width = std::round(box->width * scale);
|
||||
box->height = std::round(box->height * scale);
|
||||
box->x = std::round(box->x * scale);
|
||||
box->y = std::round(box->y * scale);
|
||||
}
|
||||
|
@ -135,8 +170,8 @@ float getPlusMinusKeywordResult(std::string source, float relative) {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool isNumber(const std::string& str) {
|
||||
return std::ranges::all_of(str.begin(), str.end(), [](char c) { return isdigit(c) != 0 || c == '-'; });
|
||||
bool isNumber(const std::string& str, bool allowfloat) {
|
||||
return std::ranges::all_of(str.begin(), str.end(), [&](char c) { return isdigit(c) != 0 || c == '-' || (allowfloat && c == '.'); });
|
||||
}
|
||||
|
||||
bool isDirection(const std::string& arg) {
|
||||
|
@ -184,12 +219,12 @@ int getWorkspaceIDFromString(const std::string& in, std::string& outName) {
|
|||
int lowestID = 99999;
|
||||
int highestID = -99999;
|
||||
|
||||
for (auto& w : g_pCompositor->m_lWorkspaces) {
|
||||
if (w.m_iID < lowestID)
|
||||
lowestID = w.m_iID;
|
||||
for (auto& w : g_pCompositor->m_vWorkspaces) {
|
||||
if (w->m_iID < lowestID)
|
||||
lowestID = w->m_iID;
|
||||
|
||||
if (w.m_iID > highestID)
|
||||
highestID = w.m_iID;
|
||||
if (w->m_iID > highestID)
|
||||
highestID = w->m_iID;
|
||||
}
|
||||
|
||||
if (remains < 0)
|
||||
|
@ -264,4 +299,25 @@ void logSystemInfo() {
|
|||
Debug::log(LOG, "os-release:");
|
||||
|
||||
Debug::log(NONE, "%s", execAndGet("cat /etc/os-release").c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr) {
|
||||
memset(mat, 0, sizeof(*mat) * 9);
|
||||
|
||||
const float* t = transforms[tr];
|
||||
float x = 2.0f / w;
|
||||
float y = 2.0f / h;
|
||||
|
||||
// Rotation + reflection
|
||||
mat[0] = x * t[0];
|
||||
mat[1] = x * t[1];
|
||||
mat[3] = y * -t[3];
|
||||
mat[4] = y * -t[4];
|
||||
|
||||
// Translation
|
||||
mat[2] = -copysign(1.0f, mat[0] + mat[1]);
|
||||
mat[5] = -copysign(1.0f, mat[3] + mat[4]);
|
||||
|
||||
// Identity
|
||||
mat[8] = 1.0f;
|
||||
}
|
||||
|
|
|
@ -7,11 +7,13 @@ void wlr_signal_emit_safe(struct wl_signal *signal, void *data);
|
|||
std::string getFormat(const char *fmt, ...); // Basically Debug::log to a string
|
||||
void scaleBox(wlr_box*, float);
|
||||
std::string removeBeginEndSpacesTabs(std::string);
|
||||
bool isNumber(const std::string&);
|
||||
bool isNumber(const std::string&, bool allowfloat = false);
|
||||
bool isDirection(const std::string&);
|
||||
int getWorkspaceIDFromString(const std::string&, std::string&);
|
||||
float vecToRectDistanceSquared(const Vector2D& vec, const Vector2D& p1, const Vector2D& p2);
|
||||
void logSystemInfo();
|
||||
std::string execAndGet(const char*);
|
||||
|
||||
float getPlusMinusKeywordResult(std::string in, float relative);
|
||||
float getPlusMinusKeywordResult(std::string in, float relative);
|
||||
|
||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
|
|
@ -188,16 +188,27 @@ void Events::listener_commitSubsurface(void* owner, void* data) {
|
|||
|
||||
// no damaging if it's not visible
|
||||
if (!g_pHyprRenderer->shouldRenderWindow(pNode->pWindowOwner)) {
|
||||
if (g_pConfigManager->getInt("debug:log_damage"))
|
||||
static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Refusing to commit damage from %x because it's invisible.", pNode->pWindowOwner);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int lx = 0, ly = 0;
|
||||
|
||||
addSurfaceGlobalOffset(pNode, &lx, &ly);
|
||||
|
||||
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
|
||||
// What this does is that basically, if the pNode is a child of some other node, on commit,
|
||||
// it will also damage (check & damage if needed) all its siblings.
|
||||
if (pNode->pParent) for (auto& cs : pNode->pParent->childSubsurfaces) {
|
||||
const auto NODECOORDS = pNode->pSubsurface ? Vector2D(pNode->pSubsurface->pSubsurface->current.x, pNode->pSubsurface->pSubsurface->current.y) : Vector2D();
|
||||
|
||||
if (&cs != pNode->pSubsurface && cs.pSubsurface) {
|
||||
g_pHyprRenderer->damageSurface(cs.pSubsurface->surface, lx - NODECOORDS.x + cs.pSubsurface->current.x, ly - NODECOORDS.y + cs.pSubsurface->current.y);
|
||||
}
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageSurface(pNode->pSurface, lx, ly);
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,12 @@ struct SKeyboard {
|
|||
|
||||
bool active = false;
|
||||
|
||||
xkb_rule_names currentRules;
|
||||
std::string name = "";
|
||||
|
||||
xkb_rule_names currentRules = {0};
|
||||
int repeatRate = 0;
|
||||
int repeatDelay = 0;
|
||||
int numlockOn = -1;
|
||||
|
||||
// For the list lookup
|
||||
bool operator==(const SKeyboard& rhs) {
|
||||
|
@ -87,6 +92,8 @@ struct SMouse {
|
|||
|
||||
pixman_region32_t confinedTo;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
DYNLISTENER(commitConstraint);
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
|
@ -168,6 +175,8 @@ struct STablet {
|
|||
wlr_tablet_v2_tablet* wlrTabletV2 = nullptr;
|
||||
wlr_input_device* wlrDevice = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
bool operator==(const STablet& b) {
|
||||
return wlrDevice == b.wlrDevice;
|
||||
}
|
||||
|
@ -186,6 +195,8 @@ struct STabletTool {
|
|||
|
||||
bool active = true;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
DYNLISTENER(TabletToolDestroy);
|
||||
DYNLISTENER(TabletToolSetCursor);
|
||||
|
||||
|
@ -198,6 +209,8 @@ struct STabletPad {
|
|||
wlr_tablet_v2_tablet_pad* wlrTabletPadV2 = nullptr;
|
||||
STablet* pTabletParent = nullptr;
|
||||
|
||||
std::string name = "";
|
||||
|
||||
DYNLISTENER(Attach);
|
||||
DYNLISTENER(Button);
|
||||
DYNLISTENER(Strip);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "Workspace.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
CWorkspace::CWorkspace(int monitorID, bool special) {
|
||||
CWorkspace::CWorkspace(int monitorID, std::string name, bool special) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
|
||||
|
||||
if (!PMONITOR) {
|
||||
|
@ -10,7 +10,7 @@ CWorkspace::CWorkspace(int monitorID, bool special) {
|
|||
}
|
||||
|
||||
m_iMonitorID = monitorID;
|
||||
|
||||
m_szName = name;
|
||||
m_bIsSpecialWorkspace = special;
|
||||
|
||||
if (!special) {
|
||||
|
@ -30,6 +30,8 @@ CWorkspace::CWorkspace(int monitorID, bool special) {
|
|||
m_fAlpha.m_pWorkspace = this;
|
||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:workspaces_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces")->intValue, &g_pConfigManager->getConfigValuePtr("animations:workspaces_curve")->strValue, nullptr, AVARDAMAGE_ENTIRE);
|
||||
m_fAlpha.setValueAndWarp(255.f);
|
||||
|
||||
g_pEventManager->postEvent({"createworkspace", m_szName}, true);
|
||||
}
|
||||
|
||||
CWorkspace::~CWorkspace() {
|
||||
|
@ -42,6 +44,8 @@ CWorkspace::~CWorkspace() {
|
|||
wlr_ext_workspace_handle_v1_destroy(m_pWlrHandle);
|
||||
m_pWlrHandle = nullptr;
|
||||
}
|
||||
|
||||
g_pEventManager->postEvent({"destroyworkspace", m_szName}, true);
|
||||
}
|
||||
|
||||
void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
|
|
|
@ -10,7 +10,7 @@ enum eFullscreenMode : uint8_t {
|
|||
|
||||
class CWorkspace {
|
||||
public:
|
||||
CWorkspace(int monitorID, bool special = false);
|
||||
CWorkspace(int monitorID, std::string name, bool special = false);
|
||||
~CWorkspace();
|
||||
|
||||
// Workspaces ID-based have IDs > 0
|
||||
|
|
|
@ -12,7 +12,7 @@ void CHyprError::createQueued() {
|
|||
m_tTexture.destroyTexture();
|
||||
}
|
||||
|
||||
const auto PMONITOR = &g_pCompositor->m_lMonitors.front();
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
|
||||
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||
|
||||
|
@ -95,11 +95,11 @@ void CHyprError::draw() {
|
|||
m_tTexture.destroyTexture();
|
||||
m_bIsCreated = false;
|
||||
m_szQueued = "";
|
||||
g_pHyprRenderer->damageMonitor(&g_pCompositor->m_lMonitors.front());
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->m_vMonitors.front().get());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PMONITOR = &g_pCompositor->m_lMonitors.front();
|
||||
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
||||
|
||||
if (g_pHyprOpenGL->m_RenderData.pMonitor != PMONITOR)
|
||||
return; // wrong mon
|
||||
|
|
|
@ -88,6 +88,9 @@ extern "C" {
|
|||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_registry.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v1.h>
|
||||
#include <wlr/types/wlr_xdg_foreign_v2.h>
|
||||
}
|
||||
|
||||
#undef class
|
||||
|
@ -114,3 +117,5 @@ extern "C" {
|
|||
#include "helpers/Vector2D.hpp"
|
||||
|
||||
#include "ext-workspace-unstable-v1-protocol.h"
|
||||
|
||||
#include <algorithm>
|
|
@ -176,9 +176,11 @@ void CHyprDwindleLayout::applyNodeDataToWindow(SDwindleNodeData* pNode) {
|
|||
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, calcSize);
|
||||
}
|
||||
|
||||
PWINDOW->updateWindowDecos();
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
|
||||
void CHyprDwindleLayout::onWindowCreatedTiling(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsFloating)
|
||||
return;
|
||||
|
||||
|
@ -309,7 +311,7 @@ void CHyprDwindleLayout::onWindowCreated(CWindow* pWindow) {
|
|||
}
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onWindowRemoved(CWindow* pWindow) {
|
||||
void CHyprDwindleLayout::onWindowRemovedTiling(CWindow* pWindow) {
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
|
@ -399,145 +401,8 @@ void CHyprDwindleLayout::recalculateMonitor(const int& monid) {
|
|||
}
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
|
||||
if (pWindow->m_bIsFullscreen) {
|
||||
Debug::log(LOG, "Rejecting a change float order because window is fullscreen.");
|
||||
|
||||
// restore its' floating mode
|
||||
pWindow->m_bIsFloating = !pWindow->m_bIsFloating;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto PNODE = getNodeFromWindow(pWindow);
|
||||
|
||||
if (!PNODE) {
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f);
|
||||
pWindow->m_iMonitorID = PNEWMON->ID;
|
||||
pWindow->m_iWorkspaceID = PNEWMON->activeWorkspace;
|
||||
|
||||
// save real pos cuz the func applies the default 5,5 mid
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition.vec();
|
||||
const auto PSAVEDSIZE = pWindow->m_vRealSize.vec();
|
||||
|
||||
// if the window is pseudo, update its size
|
||||
pWindow->m_vPseudoSize = pWindow->m_vRealSize.vec();
|
||||
|
||||
onWindowCreated(pWindow);
|
||||
|
||||
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
|
||||
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
|
||||
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
} else {
|
||||
onWindowRemoved(pWindow);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onBeginDragWindow() {
|
||||
|
||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||
|
||||
m_vBeginDragSizeXY = Vector2D();
|
||||
|
||||
// Window will be floating. Let's check if it's valid. It should be, but I don't like crashing.
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW)) {
|
||||
Debug::log(ERR, "Dragging attempted on an invalid window!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DRAGGINGWINDOW->m_bIsFullscreen) {
|
||||
Debug::log(LOG, "Rejecting drag on a fullscreen window.");
|
||||
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) {
|
||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->m_bIsFloating = true;
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal();
|
||||
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.vec();
|
||||
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.vec();
|
||||
m_vLastDragXY = m_vBeginDragXY;
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onEndDragWindow() {
|
||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW))
|
||||
return;
|
||||
|
||||
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
||||
DRAGGINGWINDOW->m_bIsFloating = false;
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||
|
||||
// Window invalid or drag begin size 0,0 meaning we rejected it.
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW) || m_vBeginDragSizeXY == Vector2D()) {
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y);
|
||||
const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y);
|
||||
|
||||
if (abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f)
|
||||
return;
|
||||
|
||||
m_vLastDragXY = mousePos;
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
|
||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(m_vBeginDragSizeXY + DELTA);
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().x, (double)20, (double)999999), std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().y, (double)20, (double)999999)));
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
resizeActiveWindow(TICKDELTA, DRAGGINGWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
// get middle point
|
||||
Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.vec() + DRAGGINGWINDOW->m_vRealSize.vec() / 2.f;
|
||||
|
||||
// and check its monitor
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
|
||||
|
||||
if (PMONITOR) {
|
||||
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
DRAGGINGWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace;
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
bool CHyprDwindleLayout::isWindowTiled(CWindow* pWindow) {
|
||||
return getNodeFromWindow(pWindow) != nullptr;
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow* pWindow) {
|
||||
|
@ -551,6 +416,7 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
|||
|
||||
if (!PNODE) {
|
||||
PWINDOW->m_vRealSize = Vector2D(std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).x, (double)20, (double)999999), std::clamp((PWINDOW->m_vRealSize.goalv() + pixResize).y, (double)20, (double)999999));
|
||||
PWINDOW->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -627,55 +493,6 @@ void CHyprDwindleLayout::resizeActiveWindow(const Vector2D& pixResize, CWindow*
|
|||
TOPCONTAINER->recalcSizePosRecursive();
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
wlr_box desiredGeometry = {0};
|
||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
|
||||
if (!PMONITOR){
|
||||
Debug::log(ERR, "Window %x (%s) has an invalid monitor in onWindowCreatedFloating!!!", pWindow, pWindow->m_szTitle.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (desiredGeometry.width <= 0 || desiredGeometry.height <= 0) {
|
||||
const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||
pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height);
|
||||
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.vec().x) / 2.f, PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.vec().y) / 2.f);
|
||||
|
||||
} else {
|
||||
// we respect the size.
|
||||
pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
|
||||
// check if it's on the correct monitor!
|
||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||
|
||||
// TODO: detect a popup in a more consistent way.
|
||||
if (!g_pCompositor->isPointOnAnyMonitor(middlePoint) || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
// if it's not, fall back to the center placement
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
||||
} else {
|
||||
// if it is, we respect where it wants to put itself, but apply monitor offset if outside
|
||||
// most of these are popups
|
||||
|
||||
if (const auto POPENMON = g_pCompositor->getMonitorFromVector(middlePoint); POPENMON->ID != PMONITOR->ID) {
|
||||
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition;
|
||||
} else {
|
||||
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pWindow->m_bX11DoesntWantBorders) {
|
||||
pWindow->m_vRealPosition.setValue(pWindow->m_vRealPosition.goalv());
|
||||
pWindow->m_vRealSize.setValue(pWindow->m_vRealSize.goalv());
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscreenMode fullscreenMode, bool on) {
|
||||
if (!g_pCompositor->windowValidMapped(pWindow))
|
||||
return;
|
||||
|
@ -731,6 +548,8 @@ void CHyprDwindleLayout::fullscreenRequestForWindow(CWindow* pWindow, eFullscree
|
|||
fakeNode.position = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft;
|
||||
fakeNode.size = PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight;
|
||||
fakeNode.workspaceID = pWindow->m_iWorkspaceID;
|
||||
pWindow->m_vPosition = fakeNode.position;
|
||||
pWindow->m_vSize = fakeNode.size;
|
||||
|
||||
applyNodeDataToWindow(&fakeNode);
|
||||
}
|
||||
|
@ -1001,20 +820,4 @@ void CHyprDwindleLayout::toggleSplit(CWindow* pWindow) {
|
|||
|
||||
std::string CHyprDwindleLayout::getLayoutName() {
|
||||
return "dwindle";
|
||||
}
|
||||
|
||||
void CHyprDwindleLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
if (!PWINDOW->m_bIsFloating) {
|
||||
Debug::log(LOG, "Dwindle cannot move a tiled window in moveActiveWindow!");
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goalv() + delta;
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
|
@ -42,17 +42,12 @@ struct SDwindleNodeData {
|
|||
|
||||
class CHyprDwindleLayout : public IHyprLayout {
|
||||
public:
|
||||
virtual void onWindowCreated(CWindow*);
|
||||
virtual void onWindowRemoved(CWindow*);
|
||||
virtual void onWindowCreatedTiling(CWindow*);
|
||||
virtual void onWindowRemovedTiling(CWindow*);
|
||||
virtual bool isWindowTiled(CWindow*);
|
||||
virtual void recalculateMonitor(const int&);
|
||||
virtual void recalculateWindow(CWindow*);
|
||||
virtual void changeWindowFloatingMode(CWindow*);
|
||||
virtual void onBeginDragWindow();
|
||||
virtual void resizeActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
||||
virtual void moveActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
||||
virtual void onEndDragWindow();
|
||||
virtual void onMouseMove(const Vector2D&);
|
||||
virtual void onWindowCreatedFloating(CWindow*);
|
||||
virtual void fullscreenRequestForWindow(CWindow*, eFullscreenMode, bool);
|
||||
virtual std::any layoutMessage(SLayoutMessageHeader, std::string);
|
||||
virtual SWindowRenderLayoutHints requestRenderHints(CWindow*);
|
||||
|
@ -60,15 +55,10 @@ public:
|
|||
virtual void alterSplitRatioBy(CWindow*, float);
|
||||
virtual std::string getLayoutName();
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
std::list<SDwindleNodeData> m_lDwindleNodesData;
|
||||
|
||||
Vector2D m_vBeginDragXY;
|
||||
Vector2D m_vLastDragXY;
|
||||
Vector2D m_vBeginDragPositionXY;
|
||||
Vector2D m_vBeginDragSizeXY;
|
||||
|
||||
int getNodesOnWorkspace(const int&);
|
||||
void applyNodeDataToWindow(SDwindleNodeData*);
|
||||
SDwindleNodeData* getNodeFromWindow(CWindow*);
|
||||
|
|
233
src/layout/IHyprLayout.cpp
Normal file
233
src/layout/IHyprLayout.cpp
Normal file
|
@ -0,0 +1,233 @@
|
|||
#include "IHyprLayout.hpp"
|
||||
#include "../defines.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
void IHyprLayout::onWindowCreated(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsFloating) {
|
||||
onWindowCreatedFloating(pWindow);
|
||||
} else {
|
||||
onWindowCreatedTiling(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void IHyprLayout::onWindowRemoved(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsFloating) {
|
||||
onWindowRemovedFloating(pWindow);
|
||||
} else {
|
||||
onWindowRemovedTiling(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void IHyprLayout::onWindowRemovedFloating(CWindow* pWindow) {
|
||||
return; // no-op
|
||||
}
|
||||
|
||||
void IHyprLayout::onWindowCreatedFloating(CWindow* pWindow) {
|
||||
wlr_box desiredGeometry = {0};
|
||||
g_pXWaylandManager->getGeometryForWindow(pWindow, &desiredGeometry);
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||
|
||||
if (!PMONITOR) {
|
||||
Debug::log(ERR, "Window %x (%s) has an invalid monitor in onWindowCreatedFloating!!!", pWindow, pWindow->m_szTitle.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (desiredGeometry.width <= 0 || desiredGeometry.height <= 0) {
|
||||
const auto PWINDOWSURFACE = g_pXWaylandManager->getWindowSurface(pWindow);
|
||||
pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height);
|
||||
pWindow->m_vRealPosition = Vector2D(PMONITOR->vecPosition.x + (PMONITOR->vecSize.x - pWindow->m_vRealSize.vec().x) / 2.f, PMONITOR->vecPosition.y + (PMONITOR->vecSize.y - pWindow->m_vRealSize.vec().y) / 2.f);
|
||||
|
||||
} else {
|
||||
// we respect the size.
|
||||
pWindow->m_vRealSize = Vector2D(desiredGeometry.width, desiredGeometry.height);
|
||||
|
||||
// check if it's on the correct monitor!
|
||||
Vector2D middlePoint = Vector2D(desiredGeometry.x, desiredGeometry.y) + Vector2D(desiredGeometry.width, desiredGeometry.height) / 2.f;
|
||||
|
||||
// TODO: detect a popup in a more consistent way.
|
||||
if (!g_pCompositor->isPointOnAnyMonitor(middlePoint) || (desiredGeometry.x == 0 && desiredGeometry.y == 0)) {
|
||||
// if it's not, fall back to the center placement
|
||||
pWindow->m_vRealPosition = PMONITOR->vecPosition + Vector2D((PMONITOR->vecSize.x - desiredGeometry.width) / 2.f, (PMONITOR->vecSize.y - desiredGeometry.height) / 2.f);
|
||||
} else {
|
||||
// if it is, we respect where it wants to put itself, but apply monitor offset if outside
|
||||
// most of these are popups
|
||||
|
||||
if (const auto POPENMON = g_pCompositor->getMonitorFromVector(middlePoint); POPENMON->ID != PMONITOR->ID) {
|
||||
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y) - POPENMON->vecPosition + PMONITOR->vecPosition;
|
||||
} else {
|
||||
pWindow->m_vRealPosition = Vector2D(desiredGeometry.x, desiredGeometry.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pWindow->m_bX11DoesntWantBorders) {
|
||||
pWindow->m_vRealPosition.setValue(pWindow->m_vRealPosition.goalv());
|
||||
pWindow->m_vRealSize.setValue(pWindow->m_vRealSize.goalv());
|
||||
}
|
||||
|
||||
g_pXWaylandManager->setWindowSize(pWindow, pWindow->m_vRealSize.goalv());
|
||||
g_pCompositor->fixXWaylandWindowsOnWorkspace(PMONITOR->activeWorkspace);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
|
||||
void IHyprLayout::onBeginDragWindow() {
|
||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||
|
||||
m_vBeginDragSizeXY = Vector2D();
|
||||
|
||||
// Window will be floating. Let's check if it's valid. It should be, but I don't like crashing.
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW)) {
|
||||
Debug::log(ERR, "Dragging attempted on an invalid window!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (DRAGGINGWINDOW->m_bIsFullscreen) {
|
||||
Debug::log(LOG, "Rejecting drag on a fullscreen window.");
|
||||
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) {
|
||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
DRAGGINGWINDOW->m_bIsFloating = true;
|
||||
DRAGGINGWINDOW->m_bDraggingTiled = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_vBeginDragXY = g_pInputManager->getMouseCoordsInternal();
|
||||
m_vBeginDragPositionXY = DRAGGINGWINDOW->m_vRealPosition.vec();
|
||||
m_vBeginDragSizeXY = DRAGGINGWINDOW->m_vRealSize.vec();
|
||||
m_vLastDragXY = m_vBeginDragXY;
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
void IHyprLayout::onEndDragWindow() {
|
||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW))
|
||||
return;
|
||||
|
||||
if (DRAGGINGWINDOW->m_bDraggingTiled) {
|
||||
DRAGGINGWINDOW->m_bIsFloating = false;
|
||||
changeWindowFloatingMode(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
|
||||
const auto DRAGGINGWINDOW = g_pInputManager->currentlyDraggedWindow;
|
||||
|
||||
// Window invalid or drag begin size 0,0 meaning we rejected it.
|
||||
if (!g_pCompositor->windowValidMapped(DRAGGINGWINDOW) || m_vBeginDragSizeXY == Vector2D()) {
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto DELTA = Vector2D(mousePos.x - m_vBeginDragXY.x, mousePos.y - m_vBeginDragXY.y);
|
||||
const auto TICKDELTA = Vector2D(mousePos.x - m_vLastDragXY.x, mousePos.y - m_vLastDragXY.y);
|
||||
|
||||
if (abs(TICKDELTA.x) < 1.f && abs(TICKDELTA.y) < 1.f)
|
||||
return;
|
||||
|
||||
m_vLastDragXY = mousePos;
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
|
||||
if (g_pInputManager->dragButton == BTN_LEFT) {
|
||||
DRAGGINGWINDOW->m_vRealPosition.setValueAndWarp(m_vBeginDragPositionXY + DELTA);
|
||||
|
||||
DRAGGINGWINDOW->updateWindowDecos();
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
if (DRAGGINGWINDOW->m_bIsFloating) {
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(m_vBeginDragSizeXY + DELTA);
|
||||
DRAGGINGWINDOW->m_vRealSize.setValueAndWarp(Vector2D(std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().x, (double)20, (double)999999), std::clamp(DRAGGINGWINDOW->m_vRealSize.vec().y, (double)20, (double)999999)));
|
||||
|
||||
DRAGGINGWINDOW->updateWindowDecos();
|
||||
|
||||
g_pXWaylandManager->setWindowSize(DRAGGINGWINDOW, DRAGGINGWINDOW->m_vRealSize.goalv());
|
||||
} else {
|
||||
resizeActiveWindow(TICKDELTA, DRAGGINGWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
// get middle point
|
||||
Vector2D middle = DRAGGINGWINDOW->m_vRealPosition.vec() + DRAGGINGWINDOW->m_vRealSize.vec() / 2.f;
|
||||
|
||||
// and check its monitor
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(middle);
|
||||
|
||||
if (PMONITOR) {
|
||||
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
DRAGGINGWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace;
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageWindow(DRAGGINGWINDOW);
|
||||
}
|
||||
|
||||
void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
|
||||
|
||||
if (pWindow->m_bIsFullscreen) {
|
||||
Debug::log(LOG, "Rejecting a change float order because window is fullscreen.");
|
||||
|
||||
// restore its' floating mode
|
||||
pWindow->m_bIsFloating = !pWindow->m_bIsFloating;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto TILED = isWindowTiled(pWindow);
|
||||
|
||||
if (!TILED) {
|
||||
const auto PNEWMON = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.vec() + pWindow->m_vRealSize.vec() / 2.f);
|
||||
pWindow->m_iMonitorID = PNEWMON->ID;
|
||||
pWindow->m_iWorkspaceID = PNEWMON->activeWorkspace;
|
||||
|
||||
// save real pos cuz the func applies the default 5,5 mid
|
||||
const auto PSAVEDPOS = pWindow->m_vRealPosition.vec();
|
||||
const auto PSAVEDSIZE = pWindow->m_vRealSize.vec();
|
||||
|
||||
// if the window is pseudo, update its size
|
||||
pWindow->m_vPseudoSize = pWindow->m_vRealSize.vec();
|
||||
|
||||
onWindowCreatedTiling(pWindow);
|
||||
|
||||
pWindow->m_vRealPosition.setValue(PSAVEDPOS);
|
||||
pWindow->m_vRealSize.setValue(PSAVEDSIZE);
|
||||
|
||||
// fix pseudo leaving artifacts
|
||||
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID));
|
||||
} else {
|
||||
onWindowRemovedTiling(pWindow);
|
||||
|
||||
g_pCompositor->moveWindowToTop(pWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {
|
||||
const auto PWINDOW = pWindow ? pWindow : g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW))
|
||||
return;
|
||||
|
||||
if (!PWINDOW->m_bIsFloating) {
|
||||
Debug::log(LOG, "Dwindle cannot move a tiled window in moveActiveWindow!");
|
||||
return;
|
||||
}
|
||||
|
||||
PWINDOW->m_vRealPosition = PWINDOW->m_vRealPosition.goalv() + delta;
|
||||
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
}
|
|
@ -22,11 +22,21 @@ public:
|
|||
The layout HAS TO set the goal pos and size (anim mgr will use it)
|
||||
If !animationinprogress, then the anim mgr will not apply an anim.
|
||||
*/
|
||||
virtual void onWindowCreated(CWindow*) = 0;
|
||||
virtual void onWindowCreated(CWindow*);
|
||||
virtual void onWindowCreatedTiling(CWindow*) = 0;
|
||||
virtual void onWindowCreatedFloating(CWindow*);
|
||||
|
||||
/*
|
||||
Return tiled status
|
||||
*/
|
||||
virtual bool isWindowTiled(CWindow*) = 0;
|
||||
|
||||
/*
|
||||
Called when a window is removed (unmapped)
|
||||
*/
|
||||
virtual void onWindowRemoved(CWindow*) = 0;
|
||||
virtual void onWindowRemoved(CWindow*);
|
||||
virtual void onWindowRemovedTiling(CWindow*) = 0;
|
||||
virtual void onWindowRemovedFloating(CWindow*);
|
||||
/*
|
||||
Called when the monitor requires a layout recalculation
|
||||
this usually means reserved area changes
|
||||
|
@ -42,13 +52,13 @@ public:
|
|||
/*
|
||||
Called when a window is requested to be floated
|
||||
*/
|
||||
virtual void changeWindowFloatingMode(CWindow*) = 0;
|
||||
virtual void changeWindowFloatingMode(CWindow*);
|
||||
/*
|
||||
Called when a window is clicked on, beginning a drag
|
||||
this might be a resize, move, whatever the layout defines it
|
||||
as.
|
||||
*/
|
||||
virtual void onBeginDragWindow() = 0;
|
||||
virtual void onBeginDragWindow();
|
||||
/*
|
||||
Called when a user requests a resize of the current window by a vec
|
||||
Vector2D holds pixel values
|
||||
|
@ -60,24 +70,18 @@ public:
|
|||
Vector2D holds pixel values
|
||||
Optional pWindow for a specific window
|
||||
*/
|
||||
virtual void moveActiveWindow(const Vector2D&, CWindow* pWindow = nullptr) = 0;
|
||||
virtual void moveActiveWindow(const Vector2D&, CWindow* pWindow = nullptr);
|
||||
/*
|
||||
Called when a window is ended being dragged
|
||||
(mouse up)
|
||||
*/
|
||||
virtual void onEndDragWindow() = 0;
|
||||
virtual void onEndDragWindow();
|
||||
/*
|
||||
Called whenever the mouse moves, should the layout want to
|
||||
do anything with it.
|
||||
Useful for dragging.
|
||||
*/
|
||||
virtual void onMouseMove(const Vector2D&) = 0;
|
||||
/*
|
||||
Called when a window is created, but is requesting to be floated.
|
||||
Warning: this also includes stuff like popups, incorrect handling
|
||||
of which can result in a crash!
|
||||
*/
|
||||
virtual void onWindowCreatedFloating(CWindow*) = 0;
|
||||
virtual void onMouseMove(const Vector2D&);
|
||||
|
||||
/*
|
||||
Called when a window / the user requests to toggle the fullscreen state of a window
|
||||
|
@ -116,4 +120,10 @@ public:
|
|||
Called when something wants the current layout's name
|
||||
*/
|
||||
virtual std::string getLayoutName() = 0;
|
||||
|
||||
private:
|
||||
Vector2D m_vBeginDragXY;
|
||||
Vector2D m_vLastDragXY;
|
||||
Vector2D m_vBeginDragPositionXY;
|
||||
Vector2D m_vBeginDragSizeXY;
|
||||
};
|
|
@ -37,9 +37,18 @@ void CAnimationManager::tick() {
|
|||
DEFAULTBEZIER = m_mBezierCurves.find("default");
|
||||
|
||||
for (auto& av : m_lAnimatedVariables) {
|
||||
|
||||
// first of all, check if we need to update it at all
|
||||
if (!av->isBeingAnimated())
|
||||
continue;
|
||||
|
||||
// get speed
|
||||
const auto SPEED = *av->m_pSpeed == 0 ? *PANIMSPEED : *av->m_pSpeed;
|
||||
|
||||
// get the spent % (0 - 1)
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - av->animationBegin).count();
|
||||
const float SPENT = std::clamp((DURATIONPASSED / 100.f) / SPEED, 0.f, 1.f);
|
||||
|
||||
// window stuff
|
||||
const auto PWINDOW = (CWindow*)av->m_pWindow;
|
||||
const auto PWORKSPACE = (CWorkspace*)av->m_pWorkspace;
|
||||
|
@ -47,7 +56,7 @@ void CAnimationManager::tick() {
|
|||
|
||||
wlr_box WLRBOXPREV = {0,0,0,0};
|
||||
if (PWINDOW) {
|
||||
WLRBOXPREV = {(int)PWINDOW->m_vRealPosition.vec().x - (int)*PBORDERSIZE - 1, (int)PWINDOW->m_vRealPosition.vec().y - (int)*PBORDERSIZE - 1, (int)PWINDOW->m_vRealSize.vec().x + 2 * (int)*PBORDERSIZE + 2, (int)PWINDOW->m_vRealSize.vec().y + 2 * (int)*PBORDERSIZE + 2};
|
||||
WLRBOXPREV = PWINDOW->getFullWindowBoundingBox();
|
||||
} else if (PWORKSPACE) {
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWORKSPACE->m_iMonitorID);
|
||||
WLRBOXPREV = {(int)PMONITOR->vecPosition.x, (int)PMONITOR->vecPosition.y, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y};
|
||||
|
@ -58,84 +67,68 @@ void CAnimationManager::tick() {
|
|||
// beziers are with a switch unforto
|
||||
// TODO: maybe do something cleaner
|
||||
|
||||
// get the spent % (0 - 1)
|
||||
const auto DURATIONPASSED = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - av->animationBegin).count();
|
||||
const float SPENT = std::clamp((DURATIONPASSED / 100.f) / SPEED, 0.f, 1.f);
|
||||
|
||||
switch (av->m_eVarType) {
|
||||
case AVARTYPE_FLOAT: {
|
||||
if (!deltazero(av->m_fValue, av->m_fGoal)) {
|
||||
|
||||
// for disabled anims just warp
|
||||
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_fGoal - av->m_fBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_fValue = av->m_fBegun + BEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
else
|
||||
av->m_fValue = av->m_fBegun + DEFAULTBEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
}
|
||||
} else {
|
||||
continue; // dont process
|
||||
// for disabled anims just warp
|
||||
if (*av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_fGoal - av->m_fBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_fValue = av->m_fBegun + BEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
else
|
||||
av->m_fValue = av->m_fBegun + DEFAULTBEZIER->second.getYForPoint(SPENT) * DELTA;
|
||||
break;
|
||||
}
|
||||
case AVARTYPE_VECTOR: {
|
||||
if (!deltazero(av->m_vValue, av->m_vGoal)) {
|
||||
|
||||
// for disabled anims just warp
|
||||
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_vGoal - av->m_vBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_vValue = av->m_vBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
else
|
||||
av->m_vValue = av->m_vBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
}
|
||||
} else {
|
||||
continue; // dont process
|
||||
// for disabled anims just warp
|
||||
if (*av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_vGoal - av->m_vBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_vValue = av->m_vBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
else
|
||||
av->m_vValue = av->m_vBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
|
||||
break;
|
||||
}
|
||||
case AVARTYPE_COLOR: {
|
||||
if (!deltazero(av->m_cValue, av->m_cGoal)) {
|
||||
|
||||
// for disabled anims just warp
|
||||
if (av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_cGoal - av->m_cBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_cValue = av->m_cBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
else
|
||||
av->m_cValue = av->m_cBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
}
|
||||
} else {
|
||||
continue; // dont process
|
||||
// for disabled anims just warp
|
||||
if (*av->m_pEnabled == 0 || animationsDisabled) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
if (SPENT >= 1.f) {
|
||||
av->warp();
|
||||
break;
|
||||
}
|
||||
|
||||
const auto DELTA = av->m_cGoal - av->m_cBegun;
|
||||
const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
|
||||
|
||||
if (BEZIER != m_mBezierCurves.end())
|
||||
av->m_cValue = av->m_cBegun + DELTA * BEZIER->second.getYForPoint(SPENT);
|
||||
else
|
||||
av->m_cValue = av->m_cBegun + DELTA * DEFAULTBEZIER->second.getYForPoint(SPENT);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -150,8 +143,16 @@ void CAnimationManager::tick() {
|
|||
|
||||
if (PWINDOW) {
|
||||
g_pHyprRenderer->damageWindow(PWINDOW);
|
||||
for (auto& wd : PWINDOW->m_dWindowDecorations) {
|
||||
wd->updateWindow(PWINDOW);
|
||||
PWINDOW->updateWindowDecos();
|
||||
} else if (PWORKSPACE) {
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bHidden)
|
||||
continue;
|
||||
|
||||
if (w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||
continue;
|
||||
|
||||
w->updateWindowDecos();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -87,7 +87,7 @@ void CEventManager::startThread() {
|
|||
|
||||
// write all queued events
|
||||
for (auto& ev : m_dQueuedEvents) {
|
||||
std::string eventString = ev.event + ">>" + ev.data + "\n";
|
||||
std::string eventString = (ev.event + ">>" + ev.data).substr(0, 1022) + "\n";
|
||||
for (auto& fd : m_dAcceptedSocketFDs) {
|
||||
write(fd, eventString.c_str(), eventString.length());
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ void CEventManager::startThread() {
|
|||
}).detach();
|
||||
}
|
||||
|
||||
void CEventManager::postEvent(const SHyprIPCEvent event) {
|
||||
void CEventManager::postEvent(const SHyprIPCEvent event, bool force) {
|
||||
|
||||
if (m_bIgnoreEvents) {
|
||||
if (m_bIgnoreEvents && !force) {
|
||||
Debug::log(WARN, "Suppressed (ignoreevents true) event of type %s, content: %s",event.event.c_str(), event.data.c_str());
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class CEventManager {
|
|||
public:
|
||||
CEventManager();
|
||||
|
||||
void postEvent(const SHyprIPCEvent event);
|
||||
void postEvent(const SHyprIPCEvent event, bool force = false);
|
||||
|
||||
void startThread();
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ CKeybindManager::CKeybindManager() {
|
|||
m_mDispatchers["resizeactive"] = resizeActive;
|
||||
m_mDispatchers["moveactive"] = moveActive;
|
||||
m_mDispatchers["cyclenext"] = circleNext;
|
||||
m_mDispatchers["focuswindowbyclass"] = focusWindowByClass;
|
||||
m_mDispatchers["focuswindowbyclass"] = focusWindow;
|
||||
m_mDispatchers["focuswindow"] = focusWindow;
|
||||
m_mDispatchers["submap"] = setSubmap;
|
||||
}
|
||||
|
||||
|
@ -108,7 +109,7 @@ bool CKeybindManager::handleKeybinds(const uint32_t& modmask, const xkb_keysym_t
|
|||
return found;
|
||||
}
|
||||
|
||||
bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
||||
bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||
// Handles the CTRL+ALT+FX TTY keybinds
|
||||
if (!(keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12))
|
||||
return false;
|
||||
|
@ -118,20 +119,37 @@ bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
|||
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||
wlr_session_change_vt(PSESSION, TTY);
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
g_pHyprOpenGL->destroyMonitorResources(&m); // mark resources as unusable anymore
|
||||
m.noFrameSchedule = true;
|
||||
m.framesToSkip = 2;
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
g_pHyprOpenGL->destroyMonitorResources(m.get()); // mark resources as unusable anymore
|
||||
m->noFrameSchedule = true;
|
||||
m->framesToSkip = 2;
|
||||
}
|
||||
|
||||
Debug::log(LOG, "Switched to VT %i, destroyed all render data, frames to skip for each: 2", TTY);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CKeybindManager::handleInternalKeybinds(xkb_keysym_t keysym) {
|
||||
if (handleVT(keysym))
|
||||
return true;
|
||||
|
||||
// handle ESC while in kill mode
|
||||
if (g_pInputManager->getClickMode() == CLICKMODE_KILL) {
|
||||
const auto KBKEY = xkb_keysym_from_name("ESCAPE", XKB_KEYSYM_CASE_INSENSITIVE);
|
||||
|
||||
if (keysym == KBKEY) {
|
||||
g_pInputManager->setClickMode(CLICKMODE_DEFAULT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Dispatchers
|
||||
|
||||
void CKeybindManager::spawn(std::string args) {
|
||||
|
@ -204,6 +222,9 @@ void CKeybindManager::toggleActiveFloating(std::string args) {
|
|||
const auto ACTIVEWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (g_pCompositor->windowValidMapped(ACTIVEWINDOW)) {
|
||||
// remove drag status
|
||||
g_pInputManager->currentlyDraggedWindow = nullptr;
|
||||
|
||||
ACTIVEWINDOW->m_bIsFloating = !ACTIVEWINDOW->m_bIsFloating;
|
||||
|
||||
if (ACTIVEWINDOW->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) {
|
||||
|
@ -319,8 +340,7 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||
if (const auto POLDWORKSPACE = g_pCompositor->getWorkspaceByID(OLDWORKSPACE); POLDWORKSPACE)
|
||||
POLDWORKSPACE->startAnim(false, ANIMTOLEFT);
|
||||
|
||||
g_pCompositor->m_lWorkspaces.emplace_back(PMONITOR->ID, workspaceToChangeTo == SPECIAL_WORKSPACE_ID);
|
||||
const auto PWORKSPACE = &g_pCompositor->m_lWorkspaces.back();
|
||||
const auto PWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(PMONITOR->ID, workspaceName, workspaceToChangeTo == SPECIAL_WORKSPACE_ID)).get();
|
||||
|
||||
// start anim on new workspace
|
||||
PWORKSPACE->startAnim(true, ANIMTOLEFT);
|
||||
|
@ -331,7 +351,6 @@ void CKeybindManager::changeworkspace(std::string args) {
|
|||
|
||||
PWORKSPACE->m_iID = workspaceToChangeTo;
|
||||
PWORKSPACE->m_iMonitorID = PMONITOR->ID;
|
||||
PWORKSPACE->m_szName = workspaceName;
|
||||
|
||||
PMONITOR->specialWorkspaceOpen = false;
|
||||
|
||||
|
@ -437,8 +456,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
|
|||
toggleSpecialWorkspace("");
|
||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false, true);
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors)
|
||||
m.specialWorkspaceOpen = false;
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
m->specialWorkspaceOpen = false;
|
||||
}
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
@ -643,7 +662,7 @@ void CKeybindManager::focusMonitor(std::string arg) {
|
|||
Debug::log(ERR, "Error in focusMonitor: invalid num");
|
||||
}
|
||||
|
||||
if (monID > -1 && monID < (int)g_pCompositor->m_lMonitors.size()) {
|
||||
if (monID > -1 && monID < (int)g_pCompositor->m_vMonitors.size()) {
|
||||
changeworkspace(std::to_string(g_pCompositor->getMonitorFromID(monID)->activeWorkspace));
|
||||
} else {
|
||||
Debug::log(ERR, "Error in focusMonitor: invalid arg 1");
|
||||
|
@ -662,9 +681,9 @@ void CKeybindManager::focusMonitor(std::string arg) {
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (m.szName == arg) {
|
||||
changeworkspace(std::to_string(m.activeWorkspace));
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->szName == arg) {
|
||||
changeworkspace(std::to_string(m->activeWorkspace));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -724,11 +743,11 @@ void CKeybindManager::workspaceOpt(std::string args) {
|
|||
PWORKSPACE->m_bDefaultPseudo = !PWORKSPACE->m_bDefaultPseudo;
|
||||
|
||||
// apply
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (!w.m_bIsMapped || w.m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||
continue;
|
||||
|
||||
w.m_bIsPseudotiled = PWORKSPACE->m_bDefaultPseudo;
|
||||
w->m_bIsPseudotiled = PWORKSPACE->m_bDefaultPseudo;
|
||||
}
|
||||
} else if (args == "allfloat") {
|
||||
PWORKSPACE->m_bDefaultFloating = !PWORKSPACE->m_bDefaultFloating;
|
||||
|
@ -736,8 +755,8 @@ void CKeybindManager::workspaceOpt(std::string args) {
|
|||
|
||||
// we make a copy because changeWindowFloatingMode might invalidate the iterator
|
||||
std::deque<CWindow*> ptrs;
|
||||
for (auto& w : g_pCompositor->m_lWindows)
|
||||
ptrs.push_back(&w);
|
||||
for (auto& w : g_pCompositor->m_vWindows)
|
||||
ptrs.push_back(w.get());
|
||||
|
||||
for (auto& w : ptrs) {
|
||||
if (!w->m_bIsMapped || w->m_iWorkspaceID != PWORKSPACE->m_iID)
|
||||
|
@ -841,8 +860,8 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||
|
||||
bool open = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (m.specialWorkspaceOpen) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->specialWorkspaceOpen) {
|
||||
open = true;
|
||||
break;
|
||||
}
|
||||
|
@ -854,10 +873,10 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||
Debug::log(LOG, "Toggling special workspace to open");
|
||||
|
||||
if (open) {
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (m.specialWorkspaceOpen != !open) {
|
||||
m.specialWorkspaceOpen = !open;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m.ID);
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (m->specialWorkspaceOpen != !open) {
|
||||
m->specialWorkspaceOpen = !open;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m->ID);
|
||||
|
||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(false, false);
|
||||
}
|
||||
|
@ -866,17 +885,28 @@ void CKeybindManager::toggleSpecialWorkspace(std::string args) {
|
|||
g_pCompositor->m_pLastMonitor->specialWorkspaceOpen = true;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(g_pCompositor->m_pLastMonitor->ID);
|
||||
|
||||
g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID)->startAnim(true, true);
|
||||
const auto PSPECIALWORKSPACE = g_pCompositor->getWorkspaceByID(SPECIAL_WORKSPACE_ID);
|
||||
|
||||
PSPECIALWORKSPACE->startAnim(true, true);
|
||||
PSPECIALWORKSPACE->m_iMonitorID = g_pCompositor->m_pLastMonitor->ID;
|
||||
}
|
||||
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
void CKeybindManager::forceRendererReload(std::string args) {
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m.szName);
|
||||
g_pHyprRenderer->applyMonitorRule(&m, &rule, true);
|
||||
bool overAgain = false;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
auto rule = g_pConfigManager->getMonitorRuleFor(m->szName);
|
||||
if (!g_pHyprRenderer->applyMonitorRule(m.get(), &rule, true)) {
|
||||
overAgain = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (overAgain)
|
||||
forceRendererReload(args);
|
||||
}
|
||||
|
||||
void CKeybindManager::resizeActive(std::string args) {
|
||||
|
@ -988,25 +1018,36 @@ void CKeybindManager::circleNext(std::string) {
|
|||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, MIDPOINT.x, MIDPOINT.y);
|
||||
}
|
||||
|
||||
void CKeybindManager::focusWindowByClass(std::string clazz) {
|
||||
std::regex classCheck(clazz);
|
||||
void CKeybindManager::focusWindow(std::string regexp) {
|
||||
bool titleRegex = false;
|
||||
std::regex regexCheck(regexp);
|
||||
if (regexp.find("title:") == 0) {
|
||||
titleRegex = true;
|
||||
regexCheck = std::regex(regexp.substr(6));
|
||||
}
|
||||
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (!w.m_bIsMapped || w.m_bHidden)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!w->m_bIsMapped || w->m_bHidden)
|
||||
continue;
|
||||
|
||||
const auto windowClass = g_pXWaylandManager->getAppIDClass(&w);
|
||||
if (titleRegex) {
|
||||
const auto windowTitle = g_pXWaylandManager->getTitle(w.get());
|
||||
if (!std::regex_search(windowTitle, regexCheck))
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
const auto windowClass = g_pXWaylandManager->getAppIDClass(w.get());
|
||||
if (!std::regex_search(windowClass, regexCheck))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!std::regex_search(windowClass, classCheck))
|
||||
continue;
|
||||
Debug::log(LOG, "Focusing to window name: %s", w->m_szTitle.c_str());
|
||||
|
||||
Debug::log(LOG, "Focusing to window name: %s", w.m_szTitle.c_str());
|
||||
changeworkspace(std::to_string(w->m_iWorkspaceID));
|
||||
|
||||
changeworkspace(std::to_string(w.m_iWorkspaceID));
|
||||
g_pCompositor->focusWindow(w.get());
|
||||
|
||||
g_pCompositor->focusWindow(&w);
|
||||
|
||||
const auto MIDPOINT = w.m_vRealPosition.goalv() + w.m_vRealSize.goalv() / 2.f;
|
||||
const auto MIDPOINT = w->m_vRealPosition.goalv() + w->m_vRealSize.goalv() / 2.f;
|
||||
|
||||
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, nullptr, MIDPOINT.x, MIDPOINT.y);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ private:
|
|||
inline static std::string m_szCurrentSelectedSubmap = "";
|
||||
|
||||
bool handleInternalKeybinds(xkb_keysym_t);
|
||||
bool handleVT(xkb_keysym_t);
|
||||
|
||||
// -------------- Dispatchers -------------- //
|
||||
static void killActive(std::string);
|
||||
|
@ -60,7 +61,7 @@ private:
|
|||
static void resizeActive(std::string);
|
||||
static void moveActive(std::string);
|
||||
static void circleNext(std::string);
|
||||
static void focusWindowByClass(std::string);
|
||||
static void focusWindow(std::string);
|
||||
static void setSubmap(std::string);
|
||||
|
||||
friend class CCompositor;
|
||||
|
|
|
@ -42,9 +42,6 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
|
|||
}
|
||||
|
||||
void CHyprXWaylandManager::activateWindow(CWindow* pWindow, bool activate) {
|
||||
if (pWindow == g_pCompositor->m_pLastWindow)
|
||||
return;
|
||||
|
||||
if (pWindow->m_bIsX11) {
|
||||
if (pWindow->m_uSurface.xwayland->minimized)
|
||||
wlr_xwayland_surface_set_minimized(pWindow->m_uSurface.xwayland, false);
|
||||
|
@ -146,8 +143,10 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
|
|||
if (pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DIALOG"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_SPLASH"] ||
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLBAR"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_UTILITY"] ||
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_TOOLTIP"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_POPUP_MENU"] ||
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"])
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DOCK"] || pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"] ||
|
||||
pWindow->m_uSurface.xwayland->window_type[i] == HYPRATOMS["_NET_WM_WINDOW_TYPE_MENU"])
|
||||
{
|
||||
pWindow->m_bNoInitialFocus = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,13 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
}
|
||||
|
||||
Vector2D mouseCoords = getMouseCoordsInternal();
|
||||
const auto MOUSECOORDSFLOORED = mouseCoords.floor();
|
||||
|
||||
if (MOUSECOORDSFLOORED == m_vLastCursorPosFloored)
|
||||
return;
|
||||
|
||||
m_vLastCursorPosFloored = MOUSECOORDSFLOORED;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromCursor();
|
||||
|
||||
bool didConstraintOnCursor = false;
|
||||
|
@ -110,10 +117,11 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
Vector2D surfaceCoords;
|
||||
Vector2D surfacePos = Vector2D(-1337, -1337);
|
||||
CWindow* pFoundWindow = nullptr;
|
||||
SLayerSurface* pFoundLayerSurface = nullptr;
|
||||
|
||||
// overlay is above fullscreen
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords);
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
// then, we check if the workspace doesnt have a fullscreen window
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(PMONITOR->activeWorkspace);
|
||||
|
@ -123,10 +131,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
surfacePos = pFoundWindow->m_vRealPosition.vec();
|
||||
|
||||
// only check floating because tiled cant be over fullscreen
|
||||
for (auto w = g_pCompositor->m_lWindows.rbegin(); w != g_pCompositor->m_lWindows.rend(); w++) {
|
||||
wlr_box box = {w->m_vRealPosition.vec().x, w->m_vRealPosition.vec().y, w->m_vRealSize.vec().x, w->m_vRealSize.vec().y};
|
||||
if (((w->m_bIsFloating && w->m_bIsMapped && w->m_bCreatedOverFullscreen) || (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible(w->m_iWorkspaceID) && !w->m_bHidden) {
|
||||
pFoundWindow = &(*w);
|
||||
for (auto w = g_pCompositor->m_vWindows.rbegin(); w != g_pCompositor->m_vWindows.rend(); w++) {
|
||||
wlr_box box = {(*w)->m_vRealPosition.vec().x, (*w)->m_vRealPosition.vec().y, (*w)->m_vRealSize.vec().x, (*w)->m_vRealSize.vec().y};
|
||||
if ((((*w)->m_bIsFloating && (*w)->m_bIsMapped && (*w)->m_bCreatedOverFullscreen) || ((*w)->m_iWorkspaceID == SPECIAL_WORKSPACE_ID && PMONITOR->specialWorkspaceOpen)) && wlr_box_contains_point(&box, mouseCoords.x, mouseCoords.y) && g_pCompositor->isWorkspaceVisible((*w)->m_iWorkspaceID) && !(*w)->m_bHidden) {
|
||||
pFoundWindow = (*w).get();
|
||||
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
|
@ -141,11 +149,15 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
}
|
||||
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords);
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
// then windows
|
||||
if (!foundSurface) {
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
if (PWORKSPACE->m_bHasFullscreenWindow && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_MAXIMIZED)
|
||||
pFoundWindow = g_pCompositor->getFullscreenWindowOnWorkspace(PWORKSPACE->m_iID);
|
||||
else
|
||||
pFoundWindow = g_pCompositor->vectorToWindowIdeal(mouseCoords);
|
||||
|
||||
if (pFoundWindow) {
|
||||
if (!pFoundWindow->m_bIsX11) {
|
||||
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
|
||||
|
@ -158,13 +170,16 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
|
||||
// then surfaces below
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &surfaceCoords);
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
if (!foundSurface)
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords);
|
||||
foundSurface = g_pCompositor->vectorToLayerSurface(mouseCoords, &PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &surfaceCoords, &pFoundLayerSurface);
|
||||
|
||||
if (!foundSurface) {
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||
if (m_ecbClickBehavior == CLICKMODE_KILL)
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "crosshair", g_pCompositor->m_sWLRCursor);
|
||||
else
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||
|
||||
wlr_seat_pointer_clear_focus(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
|
@ -199,7 +214,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
|
|||
} else {
|
||||
g_pCompositor->focusWindow(pFoundWindow, foundSurface);
|
||||
}
|
||||
} else
|
||||
} else if (pFoundLayerSurface && pFoundLayerSurface->layerSurface->current.keyboard_interactive)
|
||||
g_pCompositor->focusSurface(foundSurface);
|
||||
|
||||
wlr_seat_pointer_notify_enter(g_pCompositor->m_sSeat.seat, foundSurface, surfaceLocal.x, surfaceLocal.y);
|
||||
|
@ -211,10 +226,70 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
|
|||
|
||||
m_tmrLastCursorMovement.reset();
|
||||
|
||||
switch (m_ecbClickBehavior) {
|
||||
case CLICKMODE_DEFAULT:
|
||||
processMouseDownNormal(e);
|
||||
break;
|
||||
case CLICKMODE_KILL:
|
||||
processMouseDownKill(e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::processMouseRequest(wlr_seat_pointer_request_set_cursor_event* e) {
|
||||
if (!g_pHyprRenderer->shouldRenderCursor())
|
||||
return;
|
||||
|
||||
if (!e->surface) {
|
||||
g_pHyprRenderer->m_bWindowRequestedCursorHide = true;
|
||||
} else {
|
||||
g_pHyprRenderer->m_bWindowRequestedCursorHide = false;
|
||||
}
|
||||
|
||||
if (m_ecbClickBehavior == CLICKMODE_KILL) {
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "crosshair", g_pCompositor->m_sWLRCursor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->seat_client == g_pCompositor->m_sSeat.seat->pointer_state.focused_client)
|
||||
wlr_cursor_set_surface(g_pCompositor->m_sWLRCursor, e->surface, e->hotspot_x, e->hotspot_y);
|
||||
}
|
||||
|
||||
eClickBehaviorMode CInputManager::getClickMode() {
|
||||
return m_ecbClickBehavior;
|
||||
}
|
||||
|
||||
void CInputManager::setClickMode(eClickBehaviorMode mode) {
|
||||
switch (mode) {
|
||||
case CLICKMODE_DEFAULT:
|
||||
Debug::log(LOG, "SetClickMode: DEFAULT");
|
||||
m_ecbClickBehavior = CLICKMODE_DEFAULT;
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", g_pCompositor->m_sWLRCursor);
|
||||
break;
|
||||
|
||||
case CLICKMODE_KILL:
|
||||
Debug::log(LOG, "SetClickMode: KILL");
|
||||
m_ecbClickBehavior = CLICKMODE_KILL;
|
||||
|
||||
// remove constraints
|
||||
g_pCompositor->m_sSeat.mouse->constraintActive = false;
|
||||
refocus();
|
||||
|
||||
// set cursor
|
||||
wlr_xcursor_manager_set_cursor_image(g_pCompositor->m_sWLRXCursorMgr, "crosshair", g_pCompositor->m_sWLRCursor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::processMouseDownNormal(wlr_pointer_button_event* e) {
|
||||
const auto PKEYBOARD = wlr_seat_get_keyboard(g_pCompositor->m_sSeat.seat);
|
||||
|
||||
if (!PKEYBOARD) { // ???
|
||||
Debug::log(ERR, "No active keyboard in onMouseButton??");
|
||||
if (!PKEYBOARD) { // ???
|
||||
Debug::log(ERR, "No active keyboard in processMouseDownNormal??");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -242,7 +317,7 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
|
|||
currentlyDraggedWindow = nullptr;
|
||||
dragButton = -1;
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -250,7 +325,30 @@ void CInputManager::onMouseButton(wlr_pointer_button_event* e) {
|
|||
if (g_pCompositor->doesSeatAcceptInput(g_pCompositor->m_pLastFocus)) {
|
||||
wlr_seat_pointer_notify_button(g_pCompositor->m_sSeat.seat, e->time_msec, e->button, e->state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CInputManager::processMouseDownKill(wlr_pointer_button_event* e) {
|
||||
switch (e->state) {
|
||||
case WLR_BUTTON_PRESSED: {
|
||||
const auto PWINDOW = g_pCompositor->m_pLastWindow;
|
||||
|
||||
if (!g_pCompositor->windowValidMapped(PWINDOW)){
|
||||
Debug::log(ERR, "Cannot kill invalid window!");
|
||||
break;
|
||||
}
|
||||
|
||||
// kill the mf
|
||||
kill(PWINDOW->getPID(), SIGKILL);
|
||||
break;
|
||||
}
|
||||
case WLR_BUTTON_RELEASED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// reset click behavior mode
|
||||
m_ecbClickBehavior = CLICKMODE_DEFAULT;
|
||||
}
|
||||
|
||||
void CInputManager::onMouseWheel(wlr_pointer_axis_event* e) {
|
||||
|
@ -276,16 +374,15 @@ Vector2D CInputManager::getMouseCoordsInternal() {
|
|||
}
|
||||
|
||||
void CInputManager::newKeyboard(wlr_input_device* keyboard) {
|
||||
m_lKeyboards.push_back(SKeyboard());
|
||||
|
||||
const auto PNEWKEYBOARD = &m_lKeyboards.back();
|
||||
const auto PNEWKEYBOARD = &m_lKeyboards.emplace_back();
|
||||
|
||||
PNEWKEYBOARD->keyboard = keyboard;
|
||||
|
||||
const auto REPEATRATE = g_pConfigManager->getInt("input:repeat_rate");
|
||||
const auto REPEATDELAY = g_pConfigManager->getInt("input:repeat_delay");
|
||||
|
||||
wlr_keyboard_set_repeat_info(keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
try {
|
||||
PNEWKEYBOARD->name = std::string(keyboard->name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Keyboard had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWKEYBOARD->hyprListener_keyboardMod.initCallback(&keyboard->keyboard->events.modifiers, &Events::listener_keyboardMod, PNEWKEYBOARD, "Keyboard");
|
||||
PNEWKEYBOARD->hyprListener_keyboardKey.initCallback(&keyboard->keyboard->events.key, &Events::listener_keyboardKey, PNEWKEYBOARD, "Keyboard");
|
||||
|
@ -308,20 +405,37 @@ void CInputManager::setKeyboardLayout() {
|
|||
}
|
||||
|
||||
void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(pKeyboard->name);
|
||||
|
||||
ASSERT(pKeyboard);
|
||||
|
||||
const auto RULES = g_pConfigManager->getString("input:kb_rules");
|
||||
const auto MODEL = g_pConfigManager->getString("input:kb_model");
|
||||
const auto LAYOUT = g_pConfigManager->getString("input:kb_layout");
|
||||
const auto VARIANT = g_pConfigManager->getString("input:kb_variant");
|
||||
const auto OPTIONS = g_pConfigManager->getString("input:kb_options");
|
||||
const auto REPEATRATE = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_rate") : g_pConfigManager->getInt("input:repeat_rate");
|
||||
const auto REPEATDELAY = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "repeat_delay") : g_pConfigManager->getInt("input:repeat_delay");
|
||||
|
||||
if (RULES != "" && RULES == pKeyboard->currentRules.rules && MODEL == pKeyboard->currentRules.model && LAYOUT == pKeyboard->currentRules.layout && VARIANT == pKeyboard->currentRules.variant && OPTIONS == pKeyboard->currentRules.options) {
|
||||
Debug::log(LOG, "Not applying config to keyboard, it did not change.");
|
||||
return;
|
||||
const auto NUMLOCKON = HASCONFIG ? g_pConfigManager->getDeviceInt(pKeyboard->name, "numlock_by_default") : g_pConfigManager->getInt("input:numlock_by_default");
|
||||
|
||||
const auto RULES = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_rules") : g_pConfigManager->getString("input:kb_rules");
|
||||
const auto MODEL = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_model") : g_pConfigManager->getString("input:kb_model");
|
||||
const auto LAYOUT = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_layout") : g_pConfigManager->getString("input:kb_layout");
|
||||
const auto VARIANT = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_variant") : g_pConfigManager->getString("input:kb_variant");
|
||||
const auto OPTIONS = HASCONFIG ? g_pConfigManager->getDeviceString(pKeyboard->name, "kb_options") : g_pConfigManager->getString("input:kb_options");
|
||||
|
||||
try {
|
||||
if (NUMLOCKON == pKeyboard->numlockOn && REPEATDELAY == pKeyboard->repeatDelay && REPEATRATE == pKeyboard->repeatRate && RULES != "" && RULES == std::string(pKeyboard->currentRules.rules) && MODEL == std::string(pKeyboard->currentRules.model) && LAYOUT == std::string(pKeyboard->currentRules.layout) && VARIANT == std::string(pKeyboard->currentRules.variant) && OPTIONS == std::string(pKeyboard->currentRules.options)) {
|
||||
Debug::log(LOG, "Not applying config to keyboard, it did not change.");
|
||||
return;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
// can be libc errors for null std::string
|
||||
// we can ignore those and just apply
|
||||
}
|
||||
|
||||
wlr_keyboard_set_repeat_info(pKeyboard->keyboard->keyboard, std::max(0, REPEATRATE), std::max(0, REPEATDELAY));
|
||||
|
||||
pKeyboard->repeatDelay = REPEATDELAY;
|
||||
pKeyboard->repeatRate = REPEATRATE;
|
||||
pKeyboard->numlockOn = NUMLOCKON;
|
||||
|
||||
xkb_rule_names rules = {
|
||||
.rules = RULES.c_str(),
|
||||
.model = MODEL.c_str(),
|
||||
|
@ -355,7 +469,7 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
|
|||
|
||||
wlr_keyboard_modifiers wlrMods = {0};
|
||||
|
||||
if (g_pConfigManager->getInt("input:numlock_by_default") == 1) {
|
||||
if (NUMLOCKON == 1) {
|
||||
// lock numlock
|
||||
const auto IDX = xkb_map_mod_get_index(KEYMAP, XKB_MOD_NAME_NUM);
|
||||
|
||||
|
@ -378,37 +492,44 @@ void CInputManager::newMouse(wlr_input_device* mouse) {
|
|||
const auto PMOUSE = &m_lMice.back();
|
||||
|
||||
PMOUSE->mouse = mouse;
|
||||
try {
|
||||
PMOUSE->name = std::string(mouse->name);
|
||||
} catch(std::exception& e) {
|
||||
Debug::log(ERR, "Mouse had no name???"); // logic error
|
||||
}
|
||||
|
||||
const auto HASCONFIG = g_pConfigManager->deviceConfigExists(PMOUSE->name);
|
||||
|
||||
if (wlr_input_device_is_libinput(mouse)) {
|
||||
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(mouse);
|
||||
|
||||
if (g_pConfigManager->getInt("input:touchpad:clickfinger_behavior") == 0) // toggle software buttons or clickfinger
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "clickfinger_behavior") : g_pConfigManager->getInt("input:touchpad:clickfinger_behavior")) == 0) // toggle software buttons or clickfinger
|
||||
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
|
||||
else
|
||||
libinput_device_config_click_set_method(LIBINPUTDEV, LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
|
||||
|
||||
if (libinput_device_config_middle_emulation_is_available(LIBINPUTDEV)) { // middleclick on r+l mouse button pressed
|
||||
if (g_pConfigManager->getInt("input:touchpad:middle_button_emulation") == 1)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "middle_button_emulation") : g_pConfigManager->getInt("input:touchpad:middle_button_emulation")) == 1)
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
|
||||
else
|
||||
libinput_device_config_middle_emulation_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED);
|
||||
}
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count(LIBINPUTDEV)) // this is for tapping (like on a laptop)
|
||||
if (g_pConfigManager->getInt("input:touchpad:tap-to-click") == 1)
|
||||
if ((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "tap-to-click") : g_pConfigManager->getInt("input:touchpad:tap-to-click")) == 1)
|
||||
libinput_device_config_tap_set_enabled(LIBINPUTDEV, LIBINPUT_CONFIG_TAP_ENABLED);
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll(LIBINPUTDEV)) {
|
||||
double w = 0, h = 0;
|
||||
|
||||
if (libinput_device_has_capability(LIBINPUTDEV, LIBINPUT_DEVICE_CAP_POINTER) && libinput_device_get_size(LIBINPUTDEV, &w, &h) == 0) // pointer with size is a touchpad
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, g_pConfigManager->getInt("input:touchpad:natural_scroll"));
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, (HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "natural_scroll") : g_pConfigManager->getInt("input:touchpad:natural_scroll")));
|
||||
else
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, g_pConfigManager->getInt("input:natural_scroll"));
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled(LIBINPUTDEV, (HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "natural_scroll") : g_pConfigManager->getInt("input:natural_scroll")));
|
||||
}
|
||||
|
||||
if (libinput_device_config_dwt_is_available(LIBINPUTDEV)) {
|
||||
const auto DWT = static_cast<enum libinput_config_dwt_state>(g_pConfigManager->getInt("input:touchpad:disable_while_typing") != 0);
|
||||
const auto DWT = static_cast<enum libinput_config_dwt_state>((HASCONFIG ? g_pConfigManager->getDeviceInt(PMOUSE->name, "disable_while_typing") : g_pConfigManager->getInt("input:touchpad:disable_while_typing")) != 0);
|
||||
libinput_device_config_dwt_set_enabled(LIBINPUTDEV, DWT);
|
||||
}
|
||||
}
|
||||
|
@ -497,9 +618,12 @@ void CInputManager::updateDragIcon() {
|
|||
switch (g_pInputManager->m_sDrag.dragIcon->drag->grab_type) {
|
||||
case WLR_DRAG_GRAB_KEYBOARD:
|
||||
break;
|
||||
case WLR_DRAG_GRAB_KEYBOARD_POINTER:
|
||||
case WLR_DRAG_GRAB_KEYBOARD_POINTER: {
|
||||
wlr_box box = {g_pInputManager->m_sDrag.pos.x - 2, g_pInputManager->m_sDrag.pos.y - 2, g_pInputManager->m_sDrag.dragIcon->surface->current.width + 4, g_pInputManager->m_sDrag.dragIcon->surface->current.height + 4};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
g_pInputManager->m_sDrag.pos = g_pInputManager->getMouseCoordsInternal();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
#include "../../Window.hpp"
|
||||
#include "../../helpers/Timer.hpp"
|
||||
|
||||
enum eClickBehaviorMode {
|
||||
CLICKMODE_DEFAULT = 0,
|
||||
CLICKMODE_KILL
|
||||
};
|
||||
|
||||
class CInputManager {
|
||||
public:
|
||||
|
||||
|
@ -32,6 +37,10 @@ public:
|
|||
void updateDragIcon();
|
||||
void updateCapabilities(wlr_input_device*);
|
||||
|
||||
void setClickMode(eClickBehaviorMode);
|
||||
eClickBehaviorMode getClickMode();
|
||||
void processMouseRequest(wlr_seat_pointer_request_set_cursor_event*);
|
||||
|
||||
|
||||
// for dragging floating windows
|
||||
CWindow* currentlyDraggedWindow = nullptr;
|
||||
|
@ -58,6 +67,13 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
// for click behavior override
|
||||
eClickBehaviorMode m_ecbClickBehavior = CLICKMODE_DEFAULT;
|
||||
Vector2D m_vLastCursorPosFloored = Vector2D();
|
||||
|
||||
void processMouseDownNormal(wlr_pointer_button_event* e);
|
||||
void processMouseDownKill(wlr_pointer_button_event* e);
|
||||
|
||||
uint32_t m_uiCapabilities = 0;
|
||||
|
||||
void mouseMoveUnified(uint32_t, bool refocus = false);
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
void CInputManager::newTabletTool(wlr_input_device* pDevice) {
|
||||
const auto PNEWTABLET = &m_lTablets.emplace_back();
|
||||
|
||||
try {
|
||||
PNEWTABLET->name = std::string(pDevice->name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Tablet had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWTABLET->wlrTablet = pDevice->tablet;
|
||||
PNEWTABLET->wlrDevice = pDevice;
|
||||
PNEWTABLET->wlrTabletV2 = wlr_tablet_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||
|
@ -151,6 +157,12 @@ STabletTool* CInputManager::ensureTabletToolPresent(wlr_tablet_tool* pTool) {
|
|||
void CInputManager::newTabletPad(wlr_input_device* pDevice) {
|
||||
const auto PNEWPAD = &m_lTabletPads.emplace_back();
|
||||
|
||||
try {
|
||||
PNEWPAD->name = std::string(pDevice->name);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(ERR, "Pad had no name???"); // logic error
|
||||
}
|
||||
|
||||
PNEWPAD->wlrTabletPadV2 = wlr_tablet_pad_create(g_pCompositor->m_sWLRTabletManager, g_pCompositor->m_sSeat.seat, pDevice);
|
||||
|
||||
PNEWPAD->hyprListener_Button.initCallback(&pDevice->tablet_pad->events.button, [](void* owner, void* data) {
|
||||
|
|
|
@ -81,6 +81,12 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
|||
m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
|
||||
prog = createProgram(QUADVERTSRC, FRAGBORDER1);
|
||||
m_shBORDER1.program = prog;
|
||||
m_shBORDER1.proj = glGetUniformLocation(prog, "proj");
|
||||
m_shBORDER1.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_shBORDER1.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
|
||||
Debug::log(LOG, "Shaders initialized successfully.");
|
||||
|
||||
// End shaders
|
||||
|
@ -138,7 +144,9 @@ void CHyprOpenGLImpl::begin(SMonitor* pMonitor, pixman_region32_t* pDamage, bool
|
|||
|
||||
glViewport(0, 0, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
|
||||
wlr_matrix_projection(m_RenderData.projection, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, WL_OUTPUT_TRANSFORM_NORMAL); // TODO: this is deprecated
|
||||
matrixProjection(m_RenderData.projection, pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
|
||||
m_RenderData.pCurrentMonData = &m_mMonitorRenderResources[pMonitor];
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
@ -146,22 +154,22 @@ void CHyprOpenGLImpl::begin(SMonitor* pMonitor, pixman_region32_t* pDamage, bool
|
|||
m_iWLROutputFb = m_iCurrentOutputFb;
|
||||
|
||||
// ensure a framebuffer for the monitor exists
|
||||
if (m_mMonitorRenderResources.find(pMonitor) == m_mMonitorRenderResources.end() || m_mMonitorRenderResources[pMonitor].primaryFB.m_Size != pMonitor->vecPixelSize) {
|
||||
m_mMonitorRenderResources[pMonitor].stencilTex.allocate();
|
||||
if (m_mMonitorRenderResources.find(pMonitor) == m_mMonitorRenderResources.end() || m_RenderData.pCurrentMonData->primaryFB.m_Size != pMonitor->vecPixelSize) {
|
||||
m_RenderData.pCurrentMonData->stencilTex.allocate();
|
||||
|
||||
m_mMonitorRenderResources[pMonitor].primaryFB.m_pStencilTex = &m_mMonitorRenderResources[pMonitor].stencilTex;
|
||||
m_mMonitorRenderResources[pMonitor].mirrorFB.m_pStencilTex = &m_mMonitorRenderResources[pMonitor].stencilTex;
|
||||
m_mMonitorRenderResources[pMonitor].mirrorSwapFB.m_pStencilTex = &m_mMonitorRenderResources[pMonitor].stencilTex;
|
||||
m_RenderData.pCurrentMonData->primaryFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||
m_RenderData.pCurrentMonData->mirrorFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||
m_RenderData.pCurrentMonData->mirrorSwapFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
|
||||
|
||||
m_mMonitorRenderResources[pMonitor].primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_mMonitorRenderResources[pMonitor].mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_mMonitorRenderResources[pMonitor].mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
|
||||
|
||||
createBGTextureForMonitor(pMonitor);
|
||||
}
|
||||
|
||||
// bind the primary Hypr Framebuffer
|
||||
m_mMonitorRenderResources[pMonitor].primaryFB.bind();
|
||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||
|
||||
m_RenderData.pDamage = pDamage;
|
||||
|
||||
|
@ -180,7 +188,7 @@ void CHyprOpenGLImpl::end() {
|
|||
|
||||
m_bEndFrame = true;
|
||||
|
||||
renderTexture(m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex, &monbox, 255.f, 0);
|
||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &monbox, 255.f, 0);
|
||||
|
||||
m_bEndFrame = false;
|
||||
}
|
||||
|
@ -277,11 +285,11 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
|
|||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(glGetUniformLocation(m_shQUAD.program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(glGetUniformLocation(m_shQUAD.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(glGetUniformLocation(m_shQUAD.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(glGetUniformLocation(m_shQUAD.program, "radius"), round);
|
||||
glUniform1i(glGetUniformLocation(m_shQUAD.program, "primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0));
|
||||
glUniform2f(m_shQUAD.getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shQUAD.getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shQUAD.getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shQUAD.getUniformLocation("radius"), round);
|
||||
glUniform1i(m_shQUAD.getUniformLocation("primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 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);
|
||||
|
@ -309,15 +317,15 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha
|
|||
renderTexture(CTexture(tex), pBox, alpha, round);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool border, bool allowPrimary) {
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowPrimary) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, border, false, allowPrimary);
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowPrimary);
|
||||
|
||||
scissor((wlr_box*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool border, bool noAA, bool allowPrimary) {
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowPrimary) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
||||
|
@ -351,23 +359,6 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||
RASSERT(false, "tex.m_iTarget unsupported!");
|
||||
}
|
||||
|
||||
// stencil for when we want a border
|
||||
if (border) {
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 1, -1);
|
||||
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
|
||||
// hacky fix to fix broken borders.
|
||||
// TODO: this is kinda slow... question mark?
|
||||
renderRect(pBox, CColor(0, 0, 0, 0), round);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(tex.m_iTarget, tex.m_iTexID);
|
||||
|
||||
|
@ -389,11 +380,11 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||
static auto *const PMULTISAMPLEEDGES = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(glGetUniformLocation(shader->program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
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)(*PMULTISAMPLEEDGES == 1 && round != 0 && !border && !noAA));
|
||||
glUniform2f(shader->getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(shader->getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(shader->getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(shader->getUniformLocation("radius"), round);
|
||||
glUniform1i(shader->getUniformLocation("primitiveMultisample"), (int)(*PMULTISAMPLEEDGES == 1 && round != 0 && !noAA));
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
|
@ -421,30 +412,10 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
|
|||
}
|
||||
}
|
||||
|
||||
if (border) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, -1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(shader->posAttrib);
|
||||
glDisableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
glBindTexture(tex.m_iTarget, 0);
|
||||
|
||||
// if border draw
|
||||
// we dont disable stencil here if we havent touched it.
|
||||
// some other func might be using it.
|
||||
if (border) {
|
||||
auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col();
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
BORDERCOL.a *= alpha / 255.f;
|
||||
renderBorder(pBox, BORDERCOL, *PBORDERSIZE, round);
|
||||
glStencilMask(-1);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
// This probably isn't the fastest
|
||||
|
@ -478,10 +449,10 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||
wlr_region_expand(&damage, &damage, pow(2, *PBLURPASSES) * *PBLURSIZE);
|
||||
|
||||
// helper
|
||||
const auto PMIRRORFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB;
|
||||
const auto PMIRRORSWAPFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorSwapFB;
|
||||
const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB;
|
||||
const auto PMIRRORSWAPFB = &m_RenderData.pCurrentMonData->mirrorSwapFB;
|
||||
|
||||
CFramebuffer* currentRenderToFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB;
|
||||
CFramebuffer* currentRenderToFB = &m_RenderData.pCurrentMonData->primaryFB;
|
||||
|
||||
// declare the draw func
|
||||
auto drawPass = [&](CShader* pShader, pixman_region32_t* pDamage) {
|
||||
|
@ -500,11 +471,11 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||
|
||||
// prep two shaders
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform1f(glGetUniformLocation(pShader->program, "radius"), *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
||||
glUniform1f(pShader->getUniformLocation("radius"), *PBLURSIZE * (a / 255.f)); // this makes the blursize change with a
|
||||
if (pShader == &m_shBLUR1)
|
||||
glUniform2f(glGetUniformLocation(m_shBLUR1.program, "halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||
glUniform2f(m_shBLUR1.getUniformLocation("halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||
else
|
||||
glUniform2f(glGetUniformLocation(m_shBLUR2.program, "halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
|
||||
glUniform2f(m_shBLUR2.getUniformLocation("halfpixel"), 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f), 0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
|
||||
glUniform1i(pShader->tex, 0);
|
||||
|
||||
glVertexAttribPointer(pShader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
@ -534,7 +505,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||
// draw the things.
|
||||
// first draw is prim -> mirr
|
||||
PMIRRORFB->bind();
|
||||
glBindTexture(m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex.m_iTarget, m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex.m_iTexID);
|
||||
glBindTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTarget, m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTexID);
|
||||
|
||||
// damage region will be scaled, make a temp
|
||||
pixman_region32_t tempDamage;
|
||||
|
@ -566,14 +537,14 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
|
|||
return currentRenderToFB;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round, bool border) {
|
||||
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
||||
|
||||
static auto *const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||
static auto* const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
|
||||
|
||||
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur)) {
|
||||
renderTexture(tex, pBox, a, round, false, border, true);
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -596,7 +567,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||
}
|
||||
|
||||
if (!pixman_region32_not_empty(&inverseOpaque)) {
|
||||
renderTexture(tex, pBox, a, round, false, border); // reject blurring a fully opaque window
|
||||
renderTexture(tex, pBox, a, round, false); // reject blurring a fully opaque window
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -606,7 +577,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||
pixman_region32_fini(&inverseOpaque);
|
||||
|
||||
// bind primary
|
||||
m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.bind();
|
||||
m_RenderData.pCurrentMonData->primaryFB.bind();
|
||||
|
||||
// make a stencil for rounded corners to work with blur
|
||||
scissor((wlr_box*)nullptr); // allow the entire window and stencil to render
|
||||
|
@ -630,7 +601,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||
if (pixman_region32_not_empty(&damage)) {
|
||||
// render our great blurred FB
|
||||
static auto *const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage, 0, false, false, false, true);
|
||||
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 255.f : a, &damage, 0, false, false, true);
|
||||
|
||||
// render the window, but clear stencil
|
||||
glClearStencil(0);
|
||||
|
@ -638,36 +609,11 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
|
|||
|
||||
// draw window
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true, true);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
// prep stencil for border
|
||||
glStencilFunc(GL_ALWAYS, 1, -1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
if (border) {
|
||||
// hacky fix to fix broken borders.
|
||||
// TODO: this is kinda slow... question mark?
|
||||
renderRectWithDamage(pBox, CColor(0,0,0,0), &damage, round);
|
||||
}
|
||||
|
||||
// then stop
|
||||
glStencilFunc(GL_EQUAL, 1, -1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true);
|
||||
}
|
||||
|
||||
// disable the stencil (if no border), finalize everything
|
||||
if (!border) {
|
||||
glStencilMask(-1);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
} else {
|
||||
auto BORDERCOL = m_pCurrentWindow->m_cRealBorderColor.col();
|
||||
BORDERCOL.a *= a / 255.f;
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
renderBorder(pBox, BORDERCOL, *PBORDERSIZE, round);
|
||||
}
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glStencilMask(-1);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
pixman_region32_fini(&damage);
|
||||
scissor((wlr_box*)nullptr);
|
||||
}
|
||||
|
@ -679,23 +625,67 @@ void pushVert2D(float x, float y, float* arr, int& counter, wlr_box* box) {
|
|||
counter++;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int thick, int round) {
|
||||
void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
|
||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
// this method assumes a set stencil and scaled box
|
||||
box->x -= thick;
|
||||
box->y -= thick;
|
||||
box->width += 2 * thick;
|
||||
box->height += 2 * thick;
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
static auto *const PMULTISAMPLE = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
|
||||
|
||||
round += thick; // cuz yeah
|
||||
// adjust box
|
||||
box->x -= *PBORDERSIZE;
|
||||
box->y -= *PBORDERSIZE;
|
||||
box->width += 2 * *PBORDERSIZE;
|
||||
box->height += 2 * *PBORDERSIZE;
|
||||
|
||||
// only draw on non-stencild.
|
||||
glStencilFunc(GL_NOTEQUAL, 1, -1);
|
||||
round += *PBORDERSIZE;
|
||||
|
||||
// draw a rounded rect
|
||||
renderRect(box, col, round);
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
|
||||
|
||||
float glMatrix[9];
|
||||
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||
|
||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glUseProgram(m_shBORDER1.program);
|
||||
|
||||
glUniformMatrix3fv(m_shBORDER1.proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform4f(m_shBORDER1.getUniformLocation("color"), col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||
|
||||
const auto TOPLEFT = Vector2D(round, round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - round, box->height - round);
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
|
||||
glUniform2f(m_shBORDER1.getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shBORDER1.getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shBORDER1.getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shBORDER1.getUniformLocation("radius"), round);
|
||||
glUniform1f(m_shBORDER1.getUniformLocation("thick"), *PBORDERSIZE);
|
||||
glUniform1i(m_shBORDER1.getUniformLocation("primitiveMultisample"), *PMULTISAMPLE);
|
||||
|
||||
glVertexAttribPointer(m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shBORDER1.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(m_shBORDER1.posAttrib);
|
||||
glEnableVertexAttribArray(m_shBORDER1.texAttrib);
|
||||
|
||||
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
||||
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
scissor(&RECT);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(m_shBORDER1.posAttrib);
|
||||
glDisableVertexAttribArray(m_shBORDER1.texAttrib);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
||||
|
@ -744,7 +734,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
|
|||
clear(CColor(0, 0, 0, 0)); // JIC
|
||||
|
||||
wlr_box fullMonBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
||||
renderTexture(m_mMonitorRenderResources[m_RenderData.pMonitor].primaryFB.m_cTex, &fullMonBox, 255.f, 0);
|
||||
renderTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex, &fullMonBox, 255.f, 0);
|
||||
|
||||
// restore original fb
|
||||
#ifndef GLES2
|
||||
|
@ -823,12 +813,13 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
|
|||
|
||||
wlr_box windowBox;
|
||||
// some mafs to figure out the correct box
|
||||
Vector2D scaleXY = Vector2D((PWINDOW->m_vRealSize.vec().x / PWINDOW->m_vOriginalClosedSize.x), (PWINDOW->m_vRealSize.vec().y / PWINDOW->m_vOriginalClosedSize.y));
|
||||
// the originalClosedPos is relative to the monitor's pos
|
||||
Vector2D scaleXY = Vector2D((PMONITOR->scale * PWINDOW->m_vRealSize.vec().x / (PWINDOW->m_vOriginalClosedSize.x * PMONITOR->scale)), (PMONITOR->scale * PWINDOW->m_vRealSize.vec().y / (PWINDOW->m_vOriginalClosedSize.y * PMONITOR->scale)));
|
||||
|
||||
windowBox.width = PMONITOR->vecPixelSize.x * scaleXY.x;
|
||||
windowBox.height = PMONITOR->vecPixelSize.y * scaleXY.y;
|
||||
windowBox.x = (PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) - ((PWINDOW->m_vOriginalClosedPos.x - PMONITOR->vecPosition.x) * scaleXY.x);
|
||||
windowBox.y = (PWINDOW->m_vRealPosition.vec().y - PMONITOR->vecPosition.y) - ((PWINDOW->m_vOriginalClosedPos.y - PMONITOR->vecPosition.y) * scaleXY.y);
|
||||
windowBox.x = ((PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x);
|
||||
windowBox.y = ((PWINDOW->m_vRealPosition.vec().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y);
|
||||
|
||||
pixman_region32_t fakeDamage;
|
||||
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
||||
|
@ -870,7 +861,6 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
|||
|
||||
static auto *const PSHADOWCOL = &g_pConfigManager->getConfigValuePtr("decoration:col.shadow")->intValue;
|
||||
static auto *const PSHADOWPOWER = &g_pConfigManager->getConfigValuePtr("decoration:shadow_render_power")->intValue;
|
||||
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||
|
||||
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
|
||||
|
||||
|
@ -891,20 +881,19 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
|
|||
glUseProgram(m_shSHADOW.program);
|
||||
|
||||
glUniformMatrix3fv(m_shSHADOW.proj, 1, GL_FALSE, glMatrix);
|
||||
glUniform4f(glGetUniformLocation(m_shSHADOW.program, "color"), col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f * a);
|
||||
glUniform4f(m_shSHADOW.getUniformLocation("color"), col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f * a);
|
||||
|
||||
const auto TOPLEFT = Vector2D(range + round, range + round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - (range + round), box->height - (range + round));
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(glGetUniformLocation(m_shSHADOW.program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(glGetUniformLocation(m_shSHADOW.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(glGetUniformLocation(m_shSHADOW.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(glGetUniformLocation(m_shSHADOW.program, "radius"), range + round);
|
||||
glUniform1f(glGetUniformLocation(m_shSHADOW.program, "range"), range);
|
||||
glUniform1f(glGetUniformLocation(m_shSHADOW.program, "shadowPower"), SHADOWPOWER);
|
||||
glUniform1i(glGetUniformLocation(m_shSHADOW.program, "ignoreWindow"), *PSHADOWIGNOREWINDOW);
|
||||
glUniform2f(m_shSHADOW.getUniformLocation("topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_shSHADOW.getUniformLocation("bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_shSHADOW.getUniformLocation("fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_shSHADOW.getUniformLocation("radius"), range + round);
|
||||
glUniform1f(m_shSHADOW.getUniformLocation("range"), range);
|
||||
glUniform1f(m_shSHADOW.getUniformLocation("shadowPower"), SHADOWPOWER);
|
||||
|
||||
glVertexAttribPointer(m_shSHADOW.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(m_shSHADOW.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
|
|
@ -29,17 +29,6 @@ inline const float fanVertsFull[] = {
|
|||
-1.0f, 1.0f
|
||||
};
|
||||
|
||||
struct SCurrentRenderData {
|
||||
SMonitor* pMonitor = nullptr;
|
||||
float projection[9];
|
||||
|
||||
pixman_region32_t* pDamage = nullptr;
|
||||
|
||||
bool renderingPrimarySurface = false;
|
||||
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
};
|
||||
|
||||
struct SMonitorRenderData {
|
||||
CFramebuffer primaryFB;
|
||||
CFramebuffer mirrorFB;
|
||||
|
@ -48,6 +37,19 @@ struct SMonitorRenderData {
|
|||
CTexture stencilTex;
|
||||
};
|
||||
|
||||
struct SCurrentRenderData {
|
||||
SMonitor* pMonitor = nullptr;
|
||||
float projection[9];
|
||||
|
||||
SMonitorRenderData* pCurrentMonData = nullptr;
|
||||
|
||||
pixman_region32_t* pDamage = nullptr;
|
||||
|
||||
bool renderingPrimarySurface = false;
|
||||
Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1);
|
||||
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
|
||||
};
|
||||
|
||||
class CHyprOpenGLImpl {
|
||||
public:
|
||||
|
||||
|
@ -59,9 +61,10 @@ public:
|
|||
void renderRect(wlr_box*, const CColor&, int round = 0);
|
||||
void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0);
|
||||
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
|
||||
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false, bool allowPrimary = false);
|
||||
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);
|
||||
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowPrimary = false);
|
||||
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0);
|
||||
void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0);
|
||||
void renderBorder(wlr_box*, const CColor&, int round);
|
||||
|
||||
void makeWindowSnapshot(CWindow*);
|
||||
void makeLayerSnapshot(SLayerSurface*);
|
||||
|
@ -101,13 +104,14 @@ private:
|
|||
bool m_bEndFrame = false;
|
||||
|
||||
// Shaders
|
||||
SQuad m_shQUAD;
|
||||
CShader m_shQUAD;
|
||||
CShader m_shRGBA;
|
||||
CShader m_shRGBX;
|
||||
CShader m_shEXT;
|
||||
CShader m_shBLUR1;
|
||||
CShader m_shBLUR2;
|
||||
CShader m_shSHADOW;
|
||||
CShader m_shBORDER1;
|
||||
//
|
||||
|
||||
GLuint createProgram(const std::string&, const std::string&);
|
||||
|
@ -117,8 +121,7 @@ private:
|
|||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage);
|
||||
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool border = false, bool noAA = false, bool allowPrimary = false);
|
||||
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
|
||||
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowPrimary = false);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
|
|
@ -27,7 +27,13 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
|||
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = true;
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, RDATA->decorate);
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding);
|
||||
|
||||
if (RDATA->decorate) {
|
||||
auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col();
|
||||
col.a *= RDATA->fadeAlpha * RDATA->alpha / 255.f;
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, col, rounding);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false);
|
||||
|
@ -68,11 +74,11 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
|||
if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID))
|
||||
return true;
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == m.ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()))
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (PWORKSPACE && PWORKSPACE->m_iMonitorID == m->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()))
|
||||
return true;
|
||||
|
||||
if (m.specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
if (m->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -82,37 +88,37 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow) {
|
|||
void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWorkspace* pWorkspace, timespec* time) {
|
||||
CWindow* pWorkspaceWindow = nullptr;
|
||||
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (w.m_iWorkspaceID != pWorkspace->m_iID || !w.m_bIsFullscreen)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pWorkspace->m_iID || !w->m_bIsFullscreen)
|
||||
continue;
|
||||
|
||||
// found it!
|
||||
renderWindow(&w, pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
|
||||
pWorkspaceWindow = &w;
|
||||
pWorkspaceWindow = w.get();
|
||||
}
|
||||
|
||||
// then render windows over fullscreen
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (w.m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w.m_bCreatedOverFullscreen || !w.m_bIsMapped)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped)
|
||||
continue;
|
||||
|
||||
renderWindow(&w, pMonitor, time, true);
|
||||
renderWindow(w.get(), pMonitor, time, true);
|
||||
}
|
||||
|
||||
// and then special windows
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (!g_pCompositor->windowValidMapped(&w) && !w.m_bFadingOut)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (!g_pCompositor->windowValidMapped(w.get()) && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w.m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
|
||||
if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
|
||||
continue;
|
||||
|
||||
if (!shouldRenderWindow(&w, pMonitor))
|
||||
if (!shouldRenderWindow(w.get(), pMonitor))
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(&w, pMonitor, time, true);
|
||||
renderWindow(w.get(), pMonitor, time, true);
|
||||
}
|
||||
|
||||
// and the overlay layers
|
||||
|
@ -130,7 +136,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor
|
|||
renderDragIcon(pMonitor, time);
|
||||
|
||||
// if correct monitor draw hyprerror
|
||||
if (pMonitor == &g_pCompositor->m_lMonitors.front())
|
||||
if (pMonitor == g_pCompositor->m_vMonitors.front().get())
|
||||
g_pHyprError->draw();
|
||||
}
|
||||
|
||||
|
@ -155,7 +161,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
|||
renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL;
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f);
|
||||
renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity");
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true);
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding;
|
||||
|
||||
// apply window special data
|
||||
|
@ -166,8 +172,8 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
|
|||
|
||||
g_pHyprOpenGL->m_pCurrentWindow = pWindow;
|
||||
|
||||
// render window decorations first
|
||||
for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
// render window decorations first, if not fullscreen full
|
||||
if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations)
|
||||
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f);
|
||||
|
||||
if (!pWindow->m_bIsX11) {
|
||||
|
@ -238,54 +244,54 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
|||
}
|
||||
|
||||
// Non-floating
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (!g_pCompositor->windowValidMapped(&w) && !w.m_bFadingOut)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w.m_bIsFloating)
|
||||
if (w->m_bIsFloating)
|
||||
continue; // floating are in the second pass
|
||||
|
||||
if (w.m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
continue; // special are in the third pass
|
||||
|
||||
if (!shouldRenderWindow(&w, PMONITOR))
|
||||
if (!shouldRenderWindow(w.get(), PMONITOR))
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(&w, PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
}
|
||||
|
||||
// floating on top
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (!g_pCompositor->windowValidMapped(&w) && !w.m_bFadingOut)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (!w.m_bIsFloating)
|
||||
if (!w->m_bIsFloating)
|
||||
continue;
|
||||
|
||||
if (w.m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID)
|
||||
continue;
|
||||
|
||||
if (!shouldRenderWindow(&w, PMONITOR))
|
||||
if (!shouldRenderWindow(w.get(), PMONITOR))
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(&w, PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
}
|
||||
|
||||
// and then special
|
||||
for (auto& w : g_pCompositor->m_lWindows) {
|
||||
if (!g_pCompositor->windowValidMapped(&w) && !w.m_bFadingOut)
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut)
|
||||
continue;
|
||||
|
||||
if (w.m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
|
||||
if (w->m_iWorkspaceID != SPECIAL_WORKSPACE_ID)
|
||||
continue;
|
||||
|
||||
if (!shouldRenderWindow(&w, PMONITOR))
|
||||
if (!shouldRenderWindow(w.get(), PMONITOR))
|
||||
continue;
|
||||
|
||||
// render the bad boy
|
||||
renderWindow(&w, PMONITOR, time, true);
|
||||
renderWindow(w.get(), PMONITOR, time, true);
|
||||
}
|
||||
|
||||
// Render surfaces above windows for monitor
|
||||
|
@ -545,14 +551,19 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
|||
pixman_region32_init(&damageBox);
|
||||
wlr_surface_get_effective_damage(pSurface, &damageBox);
|
||||
|
||||
if (!pixman_region32_not_empty(&damageBox)) {
|
||||
pixman_region32_fini(&damageBox);
|
||||
return;
|
||||
}
|
||||
|
||||
pixman_region32_translate(&damageBox, x, y);
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
double lx = 0, ly = 0;
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m.output, &lx, &ly);
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly);
|
||||
pixman_region32_translate(&damageBox, lx, ly);
|
||||
wlr_region_scale(&damageBox, &damageBox, m.scale);
|
||||
wlr_output_damage_add(m.damage, &damageBox);
|
||||
wlr_region_scale(&damageBox, &damageBox, m->scale);
|
||||
wlr_output_damage_add(m->damage, &damageBox);
|
||||
pixman_region32_translate(&damageBox, -lx, -ly);
|
||||
}
|
||||
|
||||
|
@ -565,39 +576,17 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
|||
}
|
||||
|
||||
void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||
if (!pWindow->m_bIsFloating) {
|
||||
// damage by size & pos
|
||||
// TODO TEMP: revise when added shadows/etc
|
||||
|
||||
wlr_box damageBox = pWindow->getFullWindowBoundingBox();
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
wlr_box fixedDamageBox = damageBox;
|
||||
fixedDamageBox.x -= m.vecPosition.x;
|
||||
fixedDamageBox.y -= m.vecPosition.y;
|
||||
scaleBox(&fixedDamageBox, m.scale);
|
||||
wlr_output_damage_add_box(m.damage, &fixedDamageBox);
|
||||
}
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Damage: Window floated (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||
} else {
|
||||
// damage by real size & pos + border size * 2 (JIC)
|
||||
wlr_box damageBox = pWindow->getFullWindowBoundingBox();
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
wlr_box fixedDamageBox = damageBox;
|
||||
fixedDamageBox.x -= m.vecPosition.x;
|
||||
fixedDamageBox.y -= m.vecPosition.y;
|
||||
scaleBox(&fixedDamageBox, m.scale);
|
||||
wlr_output_damage_add_box(m.damage, &fixedDamageBox);
|
||||
}
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Damage: Window tiled (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||
wlr_box damageBox = pWindow->getFullWindowBoundingBox();
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
wlr_box fixedDamageBox = {damageBox.x - m->vecPosition.x, damageBox.y - m->vecPosition.y, damageBox.width, damageBox.height};
|
||||
scaleBox(&fixedDamageBox, m->scale);
|
||||
wlr_output_damage_add_box(m->damage, &fixedDamageBox);
|
||||
}
|
||||
|
||||
static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Damage: Window (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageMonitor(SMonitor* pMonitor) {
|
||||
|
@ -611,10 +600,10 @@ void CHyprRenderer::damageMonitor(SMonitor* pMonitor) {
|
|||
}
|
||||
|
||||
void CHyprRenderer::damageBox(wlr_box* pBox) {
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
wlr_box damageBox = {pBox->x - m.vecPosition.x, pBox->y - m.vecPosition.y, pBox->width, pBox->height};
|
||||
scaleBox(&damageBox, m.scale);
|
||||
wlr_output_damage_add_box(m.damage, &damageBox);
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
wlr_box damageBox = {pBox->x - m->vecPosition.x, pBox->y - m->vecPosition.y, pBox->width, pBox->height};
|
||||
scaleBox(&damageBox, m->scale);
|
||||
wlr_output_damage_add_box(m->damage, &damageBox);
|
||||
}
|
||||
|
||||
static auto *const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
@ -638,6 +627,9 @@ void CHyprRenderer::renderDragIcon(SMonitor* pMonitor, timespec* time) {
|
|||
renderdata.h = g_pInputManager->m_sDrag.dragIcon->surface->current.height;
|
||||
|
||||
wlr_surface_for_each_surface(g_pInputManager->m_sDrag.dragIcon->surface, renderSurface, &renderdata);
|
||||
|
||||
wlr_box box = {g_pInputManager->m_sDrag.pos.x - 2, g_pInputManager->m_sDrag.pos.y - 2, g_pInputManager->m_sDrag.dragIcon->surface->current.width + 4, g_pInputManager->m_sDrag.dragIcon->surface->current.height + 4};
|
||||
g_pHyprRenderer->damageBox(&box);
|
||||
}
|
||||
|
||||
DAMAGETRACKINGMODES CHyprRenderer::damageTrackingModeFromStr(const std::string& mode) {
|
||||
|
@ -651,14 +643,23 @@ DAMAGETRACKINGMODES CHyprRenderer::damageTrackingModeFromStr(const std::string&
|
|||
return DAMAGE_TRACKING_INVALID;
|
||||
}
|
||||
|
||||
void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorRule, bool force) {
|
||||
bool CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorRule, bool force) {
|
||||
|
||||
Debug::log(LOG, "Applying monitor rule for %s", pMonitor->szName.c_str());
|
||||
|
||||
// if it's disabled, disable and ignore
|
||||
if (pMonitorRule->disabled) {
|
||||
wlr_output_enable(pMonitor->output, 0);
|
||||
wlr_output_commit(pMonitor->output);
|
||||
|
||||
Events::listener_monitorDestroy(nullptr, pMonitor->output);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the rule isn't already applied
|
||||
if (!force && DELTALESSTHAN(pMonitor->vecPixelSize.x, pMonitorRule->resolution.x, 1) && DELTALESSTHAN(pMonitor->vecPixelSize.y, pMonitorRule->resolution.y, 1) && DELTALESSTHAN(pMonitor->refreshRate, pMonitorRule->refreshRate, 1) && pMonitor->scale == pMonitorRule->scale && DELTALESSTHAN(pMonitor->vecPosition.x, pMonitorRule->offset.x, 1) && DELTALESSTHAN(pMonitor->vecPosition.y, pMonitorRule->offset.y, 1) && pMonitor->transform == pMonitorRule->transform) {
|
||||
Debug::log(LOG, "Not applying a new rule to %s because it's already applied!", pMonitor->szName.c_str());
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_output_set_scale(pMonitor->output, pMonitorRule->scale);
|
||||
|
@ -697,23 +698,32 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||
}
|
||||
|
||||
if (!found) {
|
||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
pMonitor->vecSize = pMonitorRule->resolution;
|
||||
|
||||
if (!PREFERREDMODE) {
|
||||
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f",
|
||||
(int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
return;
|
||||
if (!wlr_output_test(pMonitor->output)) {
|
||||
Debug::log(ERR, "Custom resolution FAILED, falling back to preferred");
|
||||
|
||||
const auto PREFERREDMODE = wlr_output_preferred_mode(pMonitor->output);
|
||||
|
||||
if (!PREFERREDMODE) {
|
||||
Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f",
|
||||
(int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preferred is valid
|
||||
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||
|
||||
Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
|
||||
|
||||
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||
} else {
|
||||
Debug::log(LOG, "Set a custom mode %ix%i@%2f (mode not found in monitor modes)", (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate);
|
||||
}
|
||||
|
||||
// Preferred is valid
|
||||
wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
|
||||
|
||||
Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f",
|
||||
pMonitor->output->name, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (float)pMonitorRule->refreshRate,
|
||||
PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f);
|
||||
|
||||
pMonitor->refreshRate = PREFERREDMODE->refresh / 1000.f;
|
||||
pMonitor->vecSize = Vector2D(PREFERREDMODE->width, PREFERREDMODE->height);
|
||||
}
|
||||
} else {
|
||||
wlr_output_set_custom_mode(pMonitor->output, (int)pMonitorRule->resolution.x, (int)pMonitorRule->resolution.y, (int)pMonitorRule->refreshRate * 1000);
|
||||
|
@ -730,7 +740,7 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||
|
||||
if (!wlr_output_commit(pMonitor->output)) {
|
||||
Debug::log(ERR, "Couldn't commit output named %s", pMonitor->output->name);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
|
@ -752,6 +762,8 @@ void CHyprRenderer::applyMonitorRule(SMonitor* pMonitor, SMonitorRule* pMonitorR
|
|||
|
||||
// frame skip
|
||||
pMonitor->framesToSkip = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHyprRenderer::ensureCursorRenderingMode() {
|
||||
|
@ -767,8 +779,8 @@ void CHyprRenderer::ensureCursorRenderingMode() {
|
|||
|
||||
Debug::log(LOG, "Hiding the cursor (timeout)");
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors)
|
||||
g_pHyprRenderer->damageMonitor(&m); // TODO: maybe just damage the cursor area?
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area?
|
||||
} else if (*PCURSORTIMEOUT > PASSEDCURSORSECONDS && !m_bHasARenderedCursor) {
|
||||
m_bHasARenderedCursor = true;
|
||||
|
||||
|
@ -777,8 +789,8 @@ void CHyprRenderer::ensureCursorRenderingMode() {
|
|||
|
||||
Debug::log(LOG, "Showing the cursor (timeout)");
|
||||
|
||||
for (auto& m : g_pCompositor->m_lMonitors)
|
||||
g_pHyprRenderer->damageMonitor(&m); // TODO: maybe just damage the cursor area?
|
||||
for (auto& m : g_pCompositor->m_vMonitors)
|
||||
g_pHyprRenderer->damageMonitor(m.get()); // TODO: maybe just damage the cursor area?
|
||||
}
|
||||
} else {
|
||||
m_bHasARenderedCursor = true;
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
void damageBox(wlr_box*);
|
||||
void damageBox(const int& x, const int& y, const int& w, const int& h);
|
||||
void damageMonitor(SMonitor*);
|
||||
void applyMonitorRule(SMonitor*, SMonitorRule*, bool force = false);
|
||||
bool applyMonitorRule(SMonitor*, SMonitorRule*, bool force = false);
|
||||
bool shouldRenderWindow(CWindow*, SMonitor*);
|
||||
bool shouldRenderWindow(CWindow*);
|
||||
void ensureCursorRenderingMode();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "Shader.hpp"
|
||||
|
||||
GLint CShader::getUniformLocation(const std::string& unif) {
|
||||
const auto itpos = m_muUniforms.find(unif);
|
||||
|
||||
if (itpos == m_muUniforms.end()) {
|
||||
const auto unifLoc = glGetUniformLocation(program, unif.c_str());
|
||||
m_muUniforms[unif] = unifLoc;
|
||||
return unifLoc;
|
||||
}
|
||||
|
||||
return itpos->second;
|
||||
}
|
|
@ -1,22 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
|
||||
struct SQuad {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint posAttrib;
|
||||
GLint texAttrib;
|
||||
};
|
||||
#include <unordered_map>
|
||||
|
||||
class CShader {
|
||||
public:
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint color;
|
||||
GLint tex;
|
||||
GLint alpha;
|
||||
GLint posAttrib;
|
||||
GLint texAttrib;
|
||||
GLint discardOpaque;
|
||||
|
||||
GLint getUniformLocation(const std::string&);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, GLint> m_muUniforms;
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "shaders/Textures.hpp"
|
||||
#include "shaders/Shadow.hpp"
|
||||
#include "shaders/Shadow.hpp"
|
||||
#include "shaders/Border.hpp"
|
|
@ -35,6 +35,17 @@ void CHyprDropShadowDecoration::damageEntire() {
|
|||
|
||||
void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||
damageEntire();
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
||||
|
||||
damageEntire();
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprDropShadowDecoration::draw(SMonitor* pMonitor, float a) {
|
||||
|
@ -45,22 +56,70 @@ void CHyprDropShadowDecoration::draw(SMonitor* pMonitor, float a) {
|
|||
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||
static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
|
||||
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||
static auto *const PSHADOWOFFSET = &g_pConfigManager->getConfigValuePtr("decoration:shadow_offset")->strValue;
|
||||
|
||||
if (*PSHADOWS != 1)
|
||||
return; // disabled
|
||||
|
||||
// update the extents if needed
|
||||
if (*PSHADOWSIZE != m_seExtents.topLeft.x)
|
||||
m_seExtents = {{*PSHADOWSIZE + 2, *PSHADOWSIZE + 2}, {*PSHADOWSIZE + 2, *PSHADOWSIZE + 2}};
|
||||
// get the real offset
|
||||
Vector2D offset;
|
||||
try {
|
||||
if (const auto SPACEPOS = PSHADOWOFFSET->find(' '); SPACEPOS != std::string::npos) {
|
||||
const auto X = PSHADOWOFFSET->substr(0, SPACEPOS);
|
||||
const auto Y = PSHADOWOFFSET->substr(SPACEPOS + 1);
|
||||
|
||||
m_vLastWindowPos = m_pWindow->m_vRealPosition.vec();
|
||||
m_vLastWindowSize = m_pWindow->m_vRealSize.vec();
|
||||
if (isNumber(X, true) && isNumber(Y, true)) {
|
||||
offset = Vector2D(std::stof(X), std::stof(Y));
|
||||
}
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
return; // cannot parse
|
||||
}
|
||||
|
||||
// update the extents
|
||||
m_seExtents = {{*PSHADOWSIZE + 2 - offset.x, *PSHADOWSIZE + 2 - offset.y}, {*PSHADOWSIZE + 2 + offset.x, *PSHADOWSIZE + 2 + offset.y}};
|
||||
|
||||
// draw the shadow
|
||||
wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4};
|
||||
|
||||
fullBox.x -= pMonitor->vecPosition.x;
|
||||
fullBox.y -= pMonitor->vecPosition.y;
|
||||
|
||||
|
||||
if (fullBox.width < 1 || fullBox.height < 1)
|
||||
return; // don't draw invisible shadows
|
||||
|
||||
if (*PSHADOWIGNOREWINDOW) {
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 1, -1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
wlr_box windowBox = {m_vLastWindowPos.x - pMonitor->vecPosition.x, m_vLastWindowPos.y - pMonitor->vecPosition.y, m_vLastWindowSize.x, m_vLastWindowSize.y};
|
||||
|
||||
scaleBox(&windowBox, pMonitor->scale);
|
||||
|
||||
if (windowBox.width < 1 || windowBox.height < 1) {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
return; // prevent assert failed
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->renderRect(&windowBox, CColor(0,0,0,0), *PROUNDING);
|
||||
|
||||
glStencilFunc(GL_NOTEQUAL, 1, -1);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
}
|
||||
|
||||
scaleBox(&fullBox, pMonitor->scale);
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, *PROUNDING, *PSHADOWSIZE, a);
|
||||
|
||||
if (*PSHADOWIGNOREWINDOW) {
|
||||
// cleanup
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,18 @@ eDecorationType CHyprGroupBarDecoration::getDecorationType() {
|
|||
void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) {
|
||||
damageEntire();
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID);
|
||||
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
|
||||
if (pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET != m_vLastWindowPos || pWindow->m_vRealSize.vec() != m_vLastWindowSize) {
|
||||
// we draw 3px above the window's border with 3px
|
||||
const auto BORDERSIZE = g_pConfigManager->getInt("general:border_size");
|
||||
|
||||
m_seExtents.topLeft = Vector2D(0, BORDERSIZE + 3 + 3);
|
||||
m_seExtents.bottomRight = Vector2D();
|
||||
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec();
|
||||
m_vLastWindowPos = pWindow->m_vRealPosition.vec() + WORKSPACEOFFSET;
|
||||
m_vLastWindowSize = pWindow->m_vRealSize.vec();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ struct SWindowDecorationExtents {
|
|||
class CWindow;
|
||||
struct SMonitor;
|
||||
|
||||
class IHyprWindowDecoration {
|
||||
interface IHyprWindowDecoration {
|
||||
public:
|
||||
virtual ~IHyprWindowDecoration() = 0;
|
||||
|
||||
|
|
91
src/render/shaders/Border.hpp
Normal file
91
src/render/shaders/Border.hpp
Normal file
|
@ -0,0 +1,91 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
// makes a stencil without corners
|
||||
inline const std::string FRAGBORDER1 = R"#(
|
||||
precision mediump float;
|
||||
varying vec4 v_color;
|
||||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform float thick;
|
||||
uniform int primitiveMultisample;
|
||||
|
||||
float getOpacityForPixAndCorner(vec2 pix, vec2 corner) {
|
||||
|
||||
if (primitiveMultisample == 0) {
|
||||
float dis = distance(pix + vec2(0.5, 0.5), corner);
|
||||
return dis < radius && dis > radius - thick ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
float distance1 = distance(pix + vec2(0.25, 0.25), corner);
|
||||
float distance2 = distance(pix + vec2(0.75, 0.25), corner);
|
||||
float distance3 = distance(pix + vec2(0.25, 0.75), corner);
|
||||
float distance4 = distance(pix + vec2(0.75, 0.75), corner);
|
||||
|
||||
float v1 = distance1 < radius && distance1 > radius - thick ? 1.0 : 0.0;
|
||||
float v2 = distance2 < radius && distance2 > radius - thick ? 1.0 : 0.0;
|
||||
float v3 = distance3 < radius && distance3 > radius - thick ? 1.0 : 0.0;
|
||||
float v4 = distance4 < radius && distance4 > radius - thick ? 1.0 : 0.0;
|
||||
|
||||
return (v1 + v2 + v3 + v4) / 4.0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
bool done = false;
|
||||
|
||||
// check for edges
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top left
|
||||
pixColor[3] = pixColor[3] * getOpacityForPixAndCorner(pixCoord, topLeft + vec2(1,1));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom left
|
||||
pixColor[3] = pixColor[3] * getOpacityForPixAndCorner(pixCoord, vec2(topLeft[0] + 1.0, bottomRight[1]));
|
||||
done = true;
|
||||
}
|
||||
} else if (pixCoord[0] > bottomRight[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top right
|
||||
pixColor[3] = pixColor[3] * getOpacityForPixAndCorner(pixCoord, vec2(bottomRight[0], topLeft[1] + 1.0));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom right
|
||||
pixColor[3] = pixColor[3] * getOpacityForPixAndCorner(pixCoord, bottomRight);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// now check for other shit
|
||||
if (!done) {
|
||||
// distance to all straight bb borders
|
||||
float distanceT = pixCoord[1];
|
||||
float distanceB = fullSize[1] - pixCoord[1];
|
||||
float distanceL = pixCoord[0];
|
||||
float distanceR = fullSize[0] - pixCoord[0];
|
||||
|
||||
// get the smallest
|
||||
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
|
||||
|
||||
if (smallest > thick) {
|
||||
discard; return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pixColor[3] == 0.0) {
|
||||
discard; return;
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor;
|
||||
}
|
||||
)#";
|
|
@ -13,7 +13,6 @@ uniform vec2 fullSize;
|
|||
uniform float radius;
|
||||
uniform float range;
|
||||
uniform float shadowPower;
|
||||
uniform int ignoreWindow;
|
||||
|
||||
float pixAlphaRoundedDistance(float distanceToCorner) {
|
||||
if (distanceToCorner > radius) {
|
||||
|
@ -75,7 +74,7 @@ void main() {
|
|||
}
|
||||
}
|
||||
|
||||
if (pixColor[3] == 0.0 || (ignoreWindow == 1 && pixColor[3] == originalAlpha)) {
|
||||
if (pixColor[3] == 0.0) {
|
||||
discard; return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b89ed9015c3fbe8d339e9d65cf70fdca6e5645bc
|
||||
Subproject commit 5c4384a1330faedf975c8b8644881d50390f3613
|
Loading…
Reference in a new issue