summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorxDarksome <dev@darkso.me>2022-07-02 19:43:52 +0300
committerGitHub <noreply@github.com>2022-07-02 19:43:52 +0300
commit185c4d6ea13ad5f4483aa2e389e43bd09106002f (patch)
treea7bc4a9510c39e367317b5ce64d2ee0e0a72d4f0 /src
parentfc4b10d13c14c4eb08febb0637f27177cb6a1940 (diff)
parentb7b3344188e3ebd2baed14bc288ee42a1ae8d6f2 (diff)
Merge branch 'hyprwm:main' into main
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp417
-rw-r--r--src/Compositor.hpp20
-rw-r--r--src/Window.cpp19
-rw-r--r--src/Window.hpp4
-rw-r--r--src/config/ConfigManager.cpp151
-rw-r--r--src/config/ConfigManager.hpp19
-rw-r--r--src/config/defaultConfig.hpp1
-rw-r--r--src/debug/HyprCtl.cpp36
-rw-r--r--src/debug/HyprDebugOverlay.cpp8
-rw-r--r--src/debug/Log.cpp3
-rw-r--r--src/debug/Log.hpp1
-rw-r--r--src/events/Devices.cpp12
-rw-r--r--src/events/Layers.cpp9
-rw-r--r--src/events/Monitors.cpp84
-rw-r--r--src/events/Popups.cpp11
-rw-r--r--src/events/Windows.cpp56
-rw-r--r--src/helpers/AnimatedVariable.hpp15
-rw-r--r--src/helpers/MiscFunctions.cpp76
-rw-r--r--src/helpers/MiscFunctions.hpp6
-rw-r--r--src/helpers/SubsurfaceTree.cpp15
-rw-r--r--src/helpers/WLClasses.hpp15
-rw-r--r--src/helpers/Workspace.cpp8
-rw-r--r--src/helpers/Workspace.hpp2
-rw-r--r--src/hyprerror/HyprError.cpp6
-rw-r--r--src/includes.hpp5
-rw-r--r--src/layout/DwindleLayout.cpp215
-rw-r--r--src/layout/DwindleLayout.hpp18
-rw-r--r--src/layout/IHyprLayout.cpp233
-rw-r--r--src/layout/IHyprLayout.hpp36
-rw-r--r--src/managers/AnimationManager.cpp129
-rw-r--r--src/managers/EventManager.cpp6
-rw-r--r--src/managers/EventManager.hpp2
-rw-r--r--src/managers/KeybindManager.cpp127
-rw-r--r--src/managers/KeybindManager.hpp3
-rw-r--r--src/managers/XWaylandManager.cpp7
-rw-r--r--src/managers/input/InputManager.cpp200
-rw-r--r--src/managers/input/InputManager.hpp16
-rw-r--r--src/managers/input/Tablets.cpp12
-rw-r--r--src/render/OpenGL.cpp239
-rw-r--r--src/render/OpenGL.hpp29
-rw-r--r--src/render/Renderer.cpp204
-rw-r--r--src/render/Renderer.hpp2
-rw-r--r--src/render/Shader.cpp13
-rw-r--r--src/render/Shader.hpp15
-rw-r--r--src/render/Shaders.hpp3
-rw-r--r--src/render/decorations/CHyprDropShadowDecoration.cpp71
-rw-r--r--src/render/decorations/CHyprGroupBarDecoration.cpp8
-rw-r--r--src/render/decorations/IHyprWindowDecoration.hpp2
-rw-r--r--src/render/shaders/Border.hpp91
-rw-r--r--src/render/shaders/Shadow.hpp3
50 files changed, 1698 insertions, 985 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index a3fd3b93..0d8698a6 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -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;
} \ No newline at end of file
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 16632006..7ad3b7f8 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -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();
diff --git a/src/Window.cpp b/src/Window.cpp
index fbd06417..fc09b330 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -72,4 +72,21 @@ wlr_box CWindow::getWindowIdealBoundingBoxIgnoreReserved() {
}
return wlr_box{(int)POS.x, (int)POS.y, (int)SIZE.x, (int)SIZE.y};
-} \ No newline at end of file
+}
+
+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;
+}
diff --git a/src/Window.hpp b/src/Window.hpp
index 9f92432a..ca6bcbf6 100644
--- a/src/Window.hpp
+++ b/src/Window.hpp
@@ -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();
};
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index fb3aae1f..f313b155 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -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;
+
+ 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;
- auto& CONFIGENTRY = configValues.at(COMMAND);
- if (CONFIGENTRY.intValue != -1) {
+ 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();
+}
+
diff --git a/src/config/ConfigManager.hpp b/src/config/ConfigManager.hpp
index 8c0bd857..bcb2fbe5 100644
--- a/src/config/ConfigManager.hpp
+++ b/src/config/ConfigManager.hpp
@@ -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);
diff --git a/src/config/defaultConfig.hpp b/src/config/defaultConfig.hpp
index 0395fd30..e8afb296 100644
--- a/src/config/defaultConfig.hpp
+++ b/src/config/defaultConfig.hpp
@@ -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
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 66a8128d..eb6c085c 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -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")
diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp
index 0eb3ba17..b8d7c32b 100644
--- a/src/debug/HyprDebugOverlay.cpp
+++ b/src/debug/HyprDebugOverlay.cpp
@@ -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
}
diff --git a/src/debug/Log.cpp b/src/debug/Log.cpp
index a864f0d2..2fa4a127 100644
--- a/src/debug/Log.cpp
+++ b/src/debug/Log.cpp
@@ -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);
diff --git a/src/debug/Log.hpp b/src/debug/Log.hpp
index 814da421..bde9b820 100644
--- a/src/debug/Log.hpp
+++ b/src/debug/Log.hpp
@@ -17,4 +17,5 @@ namespace Debug {
void log(LogLevel level, const char* fmt, ...);
inline std::string logFile;
+ inline int64_t* disableLogs = nullptr;
}; \ No newline at end of file
diff --git a/src/events/Devices.cpp b/src/events/Devices.cpp
index d8b1ff89..04763be1 100644
--- a/src/events/Devices.cpp
+++ b/src/events/Devices.cpp
@@ -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) {
diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp
index 01cc25cc..773ba909 100644
--- a/src/events/Layers.cpp
+++ b/src/events/Layers.cpp
@@ -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);
} \ No newline at end of file
diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp
index 9da5f779..11527cee 100644
--- a/src/events/Monitors.cpp
+++ b/src/events/Monitors.cpp
@@ -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;
}
}
diff --git a/src/events/Popups.cpp b/src/events/Popups.cpp
index 7e619632..cfb92f9b 100644
--- a/src/events/Popups.cpp
+++ b/src/events/Popups.cpp
@@ -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; }));
} \ No newline at end of file
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index 76dfadda..3c1d83f5 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -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");
diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp
index bb04869f..ceda2c57 100644
--- a/src/helpers/AnimatedVariable.hpp
+++ b/src/helpers/AnimatedVariable.hpp
@@ -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();
}
diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp
index ce9dd788..cb1d88d6 100644
--- a/src/helpers/MiscFunctions.cpp
+++ b/src/helpers/MiscFunctions.cpp
@@ -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());
-} \ No newline at end of file
+}
+
+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;
+}
diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp
index 8470eb81..108ac7f7 100644
--- a/src/helpers/MiscFunctions.hpp
+++ b/src/helpers/MiscFunctions.hpp
@@ -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); \ No newline at end of file
+float getPlusMinusKeywordResult(std::string in, float relative);
+
+void matrixProjection(float mat[9], int w, int h, wl_output_transform tr); \ No newline at end of file
diff --git a/src/helpers/SubsurfaceTree.cpp b/src/helpers/SubsurfaceTree.cpp
index 064ca181..c511b900 100644
--- a/src/helpers/SubsurfaceTree.cpp
+++ b/src/helpers/SubsurfaceTree.cpp
@@ -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);
}
diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp
index d6282224..33278053 100644
--- a/src/helpers/WLClasses.hpp
+++ b/src/helpers/WLClasses.hpp
@@ -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);
diff --git a/src/helpers/Workspace.cpp b/src/helpers/Workspace.cpp
index 90d234cb..7a6ad070 100644
--- a/src/helpers/Workspace.cpp
+++ b/src/helpers/Workspace.cpp
@@ -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) {
diff --git a/src/helpers/Workspace.hpp b/src/helpers/Workspace.hpp
index 21b36e9f..2d0c5941 100644
--- a/src/helpers/Workspace.hpp
+++ b/src/helpers/Workspace.hpp
@@ -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
diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp
index 135f9635..7255aae9 100644
--- a/src/hyprerror/HyprError.cpp
+++ b/src/hyprerror/HyprError.cpp
@@ -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
diff --git a/src/includes.hpp b/src/includes.hpp
index 3aca4331..2455171d 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -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> \ No newline at end of file
diff --git a/src/layout/DwindleLayout.cpp b/src/layout/DwindleLayout.cpp
index c72dbb99..33af48a3 100644
--- a/src/layout/DwindleLayout.cpp
+++ b/src/layout/DwindleLayout.cpp
@@ -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);
} \ No newline at end of file
diff --git a/src/layout/DwindleLayout.hpp b/src/layout/DwindleLayout.hpp
index 3f32ff0b..bd73a315 100644
--- a/src/layout/DwindleLayout.hpp
+++ b/src/layout/DwindleLayout.hpp
@@ -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*);
diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp
new file mode 100644
index 00000000..a7f2facf
--- /dev/null
+++ b/src/layout/IHyprLayout.cpp
@@ -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);
+} \ No newline at end of file
diff --git a/src/layout/IHyprLayout.hpp b/src/layout/IHyprLayout.hpp
index d7102761..d214bf73 100644
--- a/src/layout/IHyprLayout.hpp
+++ b/src/layout/IHyprLayout.hpp
@@ -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;
}; \ No newline at end of file
diff --git a/src/managers/AnimationManager.cpp b/src/managers/AnimationManager.cpp
index 2ceefdd4..e48b4d1e 100644
--- a/src/managers/AnimationManager.cpp
+++ b/src/managers/AnimationManager.cpp
@@ -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;
- }
+ // 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 (SPENT >= 1.f) {
+ av->warp();
+ break;
+ }
- 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;
+ const auto DELTA = av->m_fGoal - av->m_fBegun;
+ const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
- if (SPENT >= 1.f) {
- av->warp();
- }
- } else {
- continue; // dont process
- }
+ 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;
- }
+ // 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 (SPENT >= 1.f) {
+ av->warp();
+ break;
+ }
- 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);
+ const auto DELTA = av->m_vGoal - av->m_vBegun;
+ const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
- if (SPENT >= 1.f) {
- av->warp();
- }
- } else {
- continue; // dont process
- }
+ 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;
- }
+ // 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 (SPENT >= 1.f) {
+ av->warp();
+ break;
+ }
- 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);
+ const auto DELTA = av->m_cGoal - av->m_cBegun;
+ const auto BEZIER = m_mBezierCurves.find(*av->m_pBezier);
- if (SPENT >= 1.f) {
- av->warp();
- }
- } else {
- continue; // dont process
- }
+ 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;
diff --git a/src/managers/EventManager.cpp b/src/managers/EventManager.cpp
index e42e87c2..22299a01 100644
--- a/src/managers/EventManager.cpp
+++ b/src/managers/EventManager.cpp
@@ -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;
}
diff --git a/src/managers/EventManager.hpp b/src/managers/EventManager.hpp
index ae630ce8..b9598bca 100644
--- a/src/managers/EventManager.hpp
+++ b/src/managers/EventManager.hpp
@@ -15,7 +15,7 @@ class CEventManager {
public:
CEventManager();
- void postEvent(const SHyprIPCEvent event);
+ void postEvent(const SHyprIPCEvent event, bool force = false);
void startThread();
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 10694e1b..cb091c9f 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -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,15 +119,32 @@ 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;
@@ -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 (!std::regex_search(windowClass, classCheck))
- continue;
+ 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;
+ }
- 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);
+ g_pCompositor->focusWindow(w.get());
- 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);
diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp
index c9132a11..31498677 100644
--- a/src/managers/KeybindManager.hpp
+++ b/src/managers/KeybindManager.hpp
@@ -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;
diff --git a/src/managers/XWaylandManager.cpp b/src/managers/XWaylandManager.cpp
index 65f5ddd8..48687163 100644
--- a/src/managers/XWaylandManager.cpp
+++ b/src/managers/XWaylandManager.cpp
@@ -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;
}
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index 4019a188..94d4b8c8 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -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;
}
diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp
index 06e6cb07..1a50c585 100644
--- a/src/managers/input/InputManager.hpp
+++ b/src/managers/input/InputManager.hpp
@@ -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);
diff --git a/src/managers/input/Tablets.cpp b/src/managers/input/Tablets.cpp
index 4285d06b..6a62e58e 100644
--- a/src/managers/input/Tablets.cpp
+++ b/src/managers/input/Tablets.cpp
@@ -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) {
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index e44e108b..793901aa 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -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);
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 9d6e098d..292eba36 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -29,10 +29,20 @@ inline const float fanVertsFull[] = {
-1.0f, 1.0f
};
+struct SMonitorRenderData {
+ CFramebuffer primaryFB;
+ CFramebuffer mirrorFB;
+ CFramebuffer mirrorSwapFB;
+
+ CTexture stencilTex;
+};
+
struct SCurrentRenderData {
SMonitor* pMonitor = nullptr;
float projection[9];
+ SMonitorRenderData* pCurrentMonData = nullptr;
+
pixman_region32_t* pDamage = nullptr;
bool renderingPrimarySurface = false;
@@ -40,14 +50,6 @@ struct SCurrentRenderData {
Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1);
};
-struct SMonitorRenderData {
- CFramebuffer primaryFB;
- CFramebuffer mirrorFB;
- CFramebuffer mirrorSwapFB;
-
- CTexture stencilTex;
-};
-
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; \ No newline at end of file
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index f7328997..eaa3cd90 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -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);
- }
+ 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;
+ 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);
- }
+ 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);
- // Preferred is valid
- wlr_output_set_mode(pMonitor->output, PREFERREDMODE);
+ 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);
+ 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);
+ 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);
+ }
}
} 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;
diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp
index 43a241ed..ff9fd4ea 100644
--- a/src/render/Renderer.hpp
+++ b/src/render/Renderer.hpp
@@ -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();
diff --git a/src/render/Shader.cpp b/src/render/Shader.cpp
index e69de29b..96b3caf7 100644
--- a/src/render/Shader.cpp
+++ b/src/render/Shader.cpp
@@ -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;
+} \ No newline at end of file
diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp
index 4d94358e..f996894b 100644
--- a/src/render/Shader.hpp
+++ b/src/render/Shader.hpp
@@ -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;
}; \ No newline at end of file
diff --git a/src/render/Shaders.hpp b/src/render/Shaders.hpp
index ac7f9424..1849c621 100644
--- a/src/render/Shaders.hpp
+++ b/src/render/Shaders.hpp
@@ -1,4 +1,5 @@
#pragma once
#include "shaders/Textures.hpp"
-#include "shaders/Shadow.hpp" \ No newline at end of file
+#include "shaders/Shadow.hpp"
+#include "shaders/Border.hpp" \ No newline at end of file
diff --git a/src/render/decorations/CHyprDropShadowDecoration.cpp b/src/render/decorations/CHyprDropShadowDecoration.cpp
index 6933e687..40051942 100644
--- a/src/render/decorations/CHyprDropShadowDecoration.cpp
+++ b/src/render/decorations/CHyprDropShadowDecoration.cpp
@@ -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);
+ }
}
diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp
index 2bb486ee..abb5d90c 100644
--- a/src/render/decorations/CHyprGroupBarDecoration.cpp
+++ b/src/render/decorations/CHyprGroupBarDecoration.cpp
@@ -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();
}
diff --git a/src/render/decorations/IHyprWindowDecoration.hpp b/src/render/decorations/IHyprWindowDecoration.hpp
index 21219b36..4066b6f3 100644
--- a/src/render/decorations/IHyprWindowDecoration.hpp
+++ b/src/render/decorations/IHyprWindowDecoration.hpp
@@ -16,7 +16,7 @@ struct SWindowDecorationExtents {
class CWindow;
struct SMonitor;
-class IHyprWindowDecoration {
+interface IHyprWindowDecoration {
public:
virtual ~IHyprWindowDecoration() = 0;
diff --git a/src/render/shaders/Border.hpp b/src/render/shaders/Border.hpp
new file mode 100644
index 00000000..69f1ad5b
--- /dev/null
+++ b/src/render/shaders/Border.hpp
@@ -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;
+}
+)#"; \ No newline at end of file
diff --git a/src/render/shaders/Shadow.hpp b/src/render/shaders/Shadow.hpp
index f54124fa..dca194c0 100644
--- a/src/render/shaders/Shadow.hpp
+++ b/src/render/shaders/Shadow.hpp
@@ -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;
}