diff --git a/CMakeLists.txt b/CMakeLists.txt
index e42a530a..43cbb50c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -116,7 +116,7 @@ pkg_check_modules(deps REQUIRED IMPORTED_TARGET
hyprlang>=0.3.2 hyprcursor>=0.1.7
)
-find_package(hyprwayland-scanner 0.3.8 REQUIRED)
+find_package(hyprwayland-scanner 0.3.10 REQUIRED)
file(GLOB_RECURSE SRCFILES "src/*.cpp")
@@ -277,7 +277,6 @@ target_link_libraries(Hyprland
protocol("protocols/wlr-screencopy-unstable-v1.xml" "wlr-screencopy-unstable-v1" true)
protocol("subprojects/hyprland-protocols/protocols/hyprland-global-shortcuts-v1.xml" "hyprland-global-shortcuts-v1" true)
protocol("subprojects/hyprland-protocols/protocols/hyprland-toplevel-export-v1.xml" "hyprland-toplevel-export-v1" true)
-protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-v1" false)
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
protocolNew("protocols" "wlr-gamma-control-unstable-v1" true)
@@ -291,6 +290,7 @@ protocolNew("protocols" "kde-server-decoration" true)
protocolNew("protocols" "wlr-data-control-unstable-v1" true)
protocolNew("subprojects/hyprland-protocols/protocols" "hyprland-focus-grab-v1" true)
protocolNew("protocols" "wlr-layer-shell-unstable-v1" true)
+protocolNew("protocols" "wayland-drm" true)
protocolNew("staging/tearing-control" "tearing-control-v1" false)
protocolNew("staging/fractional-scale" "fractional-scale-v1" false)
protocolNew("unstable/xdg-output" "xdg-output-unstable-v1" false)
@@ -312,6 +312,8 @@ protocolNew("stable/presentation-time" "presentation-time" false)
protocolNew("stable/xdg-shell" "xdg-shell" false)
protocolNew("unstable/primary-selection" "primary-selection-unstable-v1" false)
protocolNew("staging/xwayland-shell" "xwayland-shell-v1" false)
+protocolNew("stable/viewporter" "viewporter" false)
+protocolNew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
protocolWayland()
diff --git a/flake.lock b/flake.lock
index 8fc80b1d..83598b36 100644
--- a/flake.lock
+++ b/flake.lock
@@ -84,11 +84,11 @@
]
},
"locked": {
- "lastModified": 1716058375,
- "narHash": "sha256-CwjWoVnBZE5SBpRx9dgSQGCr4Goxyfcyv3zZbOhVqzk=",
+ "lastModified": 1717173128,
+ "narHash": "sha256-E5s+yEDIxsMTiCX0qwMuPzKQ4ME+73U9flxq6hM6Cw8=",
"owner": "hyprwm",
"repo": "hyprwayland-scanner",
- "rev": "3afed4364790aebe0426077631af1e164a9650cc",
+ "rev": "89b337424bfdf8e4698837632085d415ca41b8fc",
"type": "github"
},
"original": {
@@ -99,11 +99,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1716330097,
- "narHash": "sha256-8BO3B7e3BiyIDsaKA0tY8O88rClYRTjvAp66y+VBUeU=",
+ "lastModified": 1716948383,
+ "narHash": "sha256-SzDKxseEcHR5KzPXLwsemyTR/kaM9whxeiJohbL04rs=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "5710852ba686cc1fd0d3b8e22b3117d43ba374c2",
+ "rev": "ad57eef4ef0659193044870c731987a6df5cf56b",
"type": "github"
},
"original": {
diff --git a/protocols/meson.build b/protocols/meson.build
index f491bb09..f4978c23 100644
--- a/protocols/meson.build
+++ b/protocols/meson.build
@@ -24,7 +24,6 @@ hyprwayland_scanner = find_program(
)
protocols = [
- [wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
['wlr-screencopy-unstable-v1.xml'],
[hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'],
@@ -41,6 +40,7 @@ new_protocols = [
['wlr-output-management-unstable-v1.xml'],
['kde-server-decoration.xml'],
['wlr-layer-shell-unstable-v1.xml'],
+ ['wayland-drm.xml'],
['wlr-data-control-unstable-v1.xml'],
[hl_protocol_dir, 'protocols/hyprland-focus-grab-v1.xml'],
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
@@ -64,6 +64,8 @@ new_protocols = [
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.xml'],
[wl_protocol_dir, 'staging/xwayland-shell/xwayland-shell-v1.xml'],
+ [wl_protocol_dir, 'stable/viewporter/viewporter.xml'],
+ [wl_protocol_dir, 'stable/linux-dmabuf/linux-dmabuf-v1.xml'],
]
wl_protos_src = []
diff --git a/protocols/wayland-drm.xml b/protocols/wayland-drm.xml
new file mode 100644
index 00000000..eaf2654a
--- /dev/null
+++ b/protocols/wayland-drm.xml
@@ -0,0 +1,189 @@
+
+
+
+
+ Copyright © 2008-2011 Kristian Høgsberg
+ Copyright © 2010-2011 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that\n the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Bitmask of capabilities.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 254abd92..33f3eaa7 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -19,6 +19,8 @@
#include "protocols/PointerConstraints.hpp"
#include "protocols/LayerShell.hpp"
#include "protocols/XDGShell.hpp"
+#include "protocols/core/Compositor.hpp"
+#include "protocols/core/Subcompositor.hpp"
#include "desktop/LayerSurface.hpp"
#include "xwayland/XWayland.hpp"
@@ -184,7 +186,7 @@ void CCompositor::initServer() {
&isHeadlessOnly);
if (isHeadlessOnly) {
- m_sWLRRenderer = wlr_renderer_autocreate(m_sWLRBackend);
+ m_sWLRRenderer = wlr_renderer_autocreate(m_sWLRBackend); // TODO: remove this, it's barely needed now.
} else {
m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend);
if (m_iDRMFD < 0) {
@@ -200,15 +202,6 @@ void CCompositor::initServer() {
throwError("wlr_gles2_renderer_create_with_drm_fd() failed!");
}
- wlr_renderer_init_wl_shm(m_sWLRRenderer, m_sWLDisplay);
-
- if (wlr_renderer_get_dmabuf_texture_formats(m_sWLRRenderer)) {
- if (wlr_renderer_get_drm_fd(m_sWLRRenderer) >= 0)
- wlr_drm_create(m_sWLDisplay, m_sWLRRenderer);
-
- m_sWLRLinuxDMABuf = wlr_linux_dmabuf_v1_create_with_renderer(m_sWLDisplay, 4, m_sWLRRenderer);
- }
-
m_sWLRAllocator = wlr_allocator_autocreate(m_sWLRBackend, m_sWLRRenderer);
if (!m_sWLRAllocator) {
@@ -223,13 +216,7 @@ void CCompositor::initServer() {
throwError("wlr_gles2_renderer_get_egl() failed!");
}
- m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, 6, m_sWLRRenderer);
- m_sWLRSubCompositor = wlr_subcompositor_create(m_sWLDisplay);
- // m_sWLRDataDevMgr = wlr_data_device_manager_create(m_sWLDisplay);
-
- // wlr_data_control_manager_v1_create(m_sWLDisplay);
- // wlr_primary_selection_v1_device_manager_create(m_sWLDisplay);
- wlr_viewporter_create(m_sWLDisplay);
+ initManagers(STAGE_BASICINIT);
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
if (!m_sWRLDRMLeaseMgr) {
@@ -244,8 +231,6 @@ void CCompositor::initServer() {
throwError("wlr_headless_backend_create() failed!");
}
- wlr_single_pixel_buffer_manager_v1_create(m_sWLDisplay);
-
wlr_multi_backend_add(m_sWLRBackend, m_sWLRHeadlessBackend);
initManagers(STAGE_LATE);
@@ -320,7 +305,7 @@ void CCompositor::cleanup() {
// still in a normal working state.
g_pPluginSystem->unloadAllPlugins();
- m_pLastFocus = nullptr;
+ m_pLastFocus.reset();
m_pLastWindow.reset();
m_vWorkspaces.clear();
@@ -390,12 +375,6 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the HookSystem!");
g_pHookSystem = std::make_unique();
- Debug::log(LOG, "Creating the ProtocolManager!");
- g_pProtocolManager = std::make_unique();
-
- Debug::log(LOG, "Creating the SeatManager!");
- g_pSeatManager = std::make_unique();
-
Debug::log(LOG, "Creating the KeybindManager!");
g_pKeybindManager = std::make_unique();
@@ -420,6 +399,13 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the PointerManager!");
g_pPointerManager = std::make_unique();
} break;
+ case STAGE_BASICINIT: {
+ Debug::log(LOG, "Creating the ProtocolManager!");
+ g_pProtocolManager = std::make_unique();
+
+ Debug::log(LOG, "Creating the SeatManager!");
+ g_pSeatManager = std::make_unique();
+ } break;
case STAGE_LATE: {
Debug::log(LOG, "Creating the ThreadManager!");
g_pThreadManager = std::make_unique();
@@ -571,6 +557,8 @@ void CCompositor::startCompositor() {
createLockFile();
+ EMIT_HOOK_EVENT("ready", nullptr);
+
// This blocks until we are done.
Debug::log(LOG, "Hyprland is ready, running the event loop!");
g_pEventLoopManager->enterLoop(m_sWLDisplay, m_sWLEventLoop);
@@ -786,47 +774,32 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
return windowForWorkspace(false);
}
-wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, PHLWINDOW pWindow, Vector2D& sl) {
+SP CCompositor::vectorWindowToSurface(const Vector2D& pos, PHLWINDOW pWindow, Vector2D& sl) {
if (!validMapped(pWindow))
return nullptr;
RASSERT(!pWindow->m_bIsX11, "Cannot call vectorWindowToSurface on an X11 window!");
- double subx, suby;
-
- CBox geom = pWindow->m_pXDGSurface->current.geometry;
-
// try popups first
- const auto PPOPUP = pWindow->m_pPopupHead->at(pos);
+ const auto PPOPUP = pWindow->m_pPopupHead->at(pos);
- wlr_surface* found = PPOPUP ? PPOPUP->m_sWLSurface.wlr() : nullptr;
-
- if (!PPOPUP)
- found = wlr_surface_surface_at(pWindow->m_pWLSurface.wlr(), pos.x - pWindow->m_vRealPosition.value().x + geom.x, pos.y - pWindow->m_vRealPosition.value().y + geom.y, &subx,
- &suby);
- else {
+ if (PPOPUP) {
const auto OFF = PPOPUP->coordsRelativeToParent();
- subx = pos.x - OFF.x + geom.x - pWindow->m_vRealPosition.goal().x;
- suby = pos.y - OFF.y + geom.y - pWindow->m_vRealPosition.goal().y;
+ sl = pos - pWindow->m_vRealPosition.goal() - OFF;
+ return PPOPUP->m_pWLSurface->resource();
}
- if (found) {
- sl.x = subx;
- sl.y = suby;
- return found;
+ auto [surf, local] = pWindow->m_pWLSurface->resource()->at(pos - pWindow->m_vRealPosition.goal(), true);
+ if (surf) {
+ sl = local;
+ return surf;
}
- sl.x = pos.x - pWindow->m_vRealPosition.value().x;
- sl.y = pos.y - pWindow->m_vRealPosition.value().y;
-
- sl.x += geom.x;
- sl.y += geom.y;
-
- return pWindow->m_pWLSurface.wlr();
+ return nullptr;
}
-Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindow, wlr_surface* pSurface) {
+Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindow, SP pSurface) {
if (!validMapped(pWindow))
return {};
@@ -837,25 +810,22 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo
if (PPOPUP)
return vec - PPOPUP->coordsGlobal();
- std::tuple iterData = {pSurface, -1337, -1337};
+ std::tuple, Vector2D> iterData = {pSurface, {-1337, -1337}};
- wlr_surface_for_each_surface(
- pWindow->m_pWLSurface.wlr(),
- [](wlr_surface* surf, int x, int y, void* data) {
- const auto PDATA = (std::tuple*)data;
- if (surf == std::get<0>(*PDATA)) {
- std::get<1>(*PDATA) = x;
- std::get<2>(*PDATA) = y;
- }
+ pWindow->m_pWLSurface->resource()->breadthfirst(
+ [](SP surf, const Vector2D& offset, void* data) {
+ const auto PDATA = (std::tuple, Vector2D>*)data;
+ if (surf == std::get<0>(*PDATA))
+ std::get<1>(*PDATA) = offset;
},
&iterData);
CBox geom = pWindow->m_pXDGSurface->current.geometry;
- if (std::get<1>(iterData) == -1337 && std::get<2>(iterData) == -1337)
+ if (std::get<1>(iterData) == Vector2D{-1337, -1337})
return vec - pWindow->m_vRealPosition.goal();
- return vec - pWindow->m_vRealPosition.goal() - Vector2D{std::get<1>(iterData), std::get<2>(iterData)} + Vector2D{geom.x, geom.y};
+ return vec - pWindow->m_vRealPosition.goal() - std::get<1>(iterData) + Vector2D{geom.x, geom.y};
}
CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
@@ -878,7 +848,7 @@ CMonitor* CCompositor::getRealMonitorFromOutput(wlr_output* out) {
return nullptr;
}
-void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
+void CCompositor::focusWindow(PHLWINDOW pWindow, SP pSurface) {
static auto PFOLLOWMOUSE = CConfigValue("input:follow_mouse");
static auto PSPECIALFALLTHROUGH = CConfigValue("input:special_fallthrough");
@@ -921,7 +891,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
- m_pLastFocus = nullptr;
+ m_pLastFocus.reset();
g_pInputManager->recheckIdleInhibitorStatus();
return;
@@ -973,7 +943,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
m_pLastWindow = PLASTWINDOW;
- const auto PWINDOWSURFACE = pSurface ? pSurface : pWindow->m_pWLSurface.wlr();
+ const auto PWINDOWSURFACE = pSurface ? pSurface : pWindow->m_pWLSurface->resource();
focusSurface(PWINDOWSURFACE, pWindow);
@@ -1008,9 +978,9 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
g_pInputManager->sendMotionEventsToFocused();
}
-void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
+void CCompositor::focusSurface(SP pSurface, PHLWINDOW pWindowOwner) {
- if (g_pSeatManager->state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->state.keyboardFocus == pWindowOwner->m_pWLSurface.wlr()))
+ if (g_pSeatManager->state.keyboardFocus == pSurface || (pWindowOwner && g_pSeatManager->state.keyboardFocus == pWindowOwner->m_pWLSurface->resource()))
return; // Don't focus when already focused on this.
if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
@@ -1021,18 +991,18 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
return;
}
- const auto PLASTSURF = m_pLastFocus;
+ const auto PLASTSURF = m_pLastFocus.lock();
// Unfocus last surface if should
if (m_pLastFocus && !pWindowOwner)
- g_pXWaylandManager->activateSurface(m_pLastFocus, false);
+ g_pXWaylandManager->activateSurface(m_pLastFocus.lock(), false);
if (!pSurface) {
g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
- EMIT_HOOK_EVENT("keyboardFocus", (wlr_surface*)nullptr);
- m_pLastFocus = nullptr;
+ EMIT_HOOK_EVENT("keyboardFocus", (SP)nullptr);
+ m_pLastFocus.reset();
return;
}
@@ -1049,8 +1019,8 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
EMIT_HOOK_EVENT("keyboardFocus", pSurface);
- const auto SURF = CWLSurface::surfaceFromWlr(pSurface);
- const auto OLDSURF = CWLSurface::surfaceFromWlr(PLASTSURF);
+ const auto SURF = CWLSurface::fromResource(pSurface);
+ const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
if (OLDSURF && OLDSURF->constraint())
OLDSURF->constraint()->deactivate();
@@ -1059,7 +1029,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
SURF->constraint()->activate();
}
-wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
+SP CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
for (auto& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) {
for (auto& ls : lsl | std::views::reverse) {
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha.value() == 0.f)
@@ -1070,7 +1040,7 @@ wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonito
if (SURFACEAT) {
*ppLayerSurfaceFound = ls.lock();
*sCoords = pos - SURFACEAT->coordsGlobal();
- return SURFACEAT->m_sWLSurface.wlr();
+ return SURFACEAT->m_pWLSurface->resource();
}
}
}
@@ -1078,31 +1048,34 @@ wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonito
return nullptr;
}
-wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
+SP CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
for (auto& ls : *layerSurfaces | std::views::reverse) {
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f)
continue;
- auto SURFACEAT = wlr_surface_surface_at(ls->layerSurface->surface, pos.x - ls->geometry.x, pos.y - ls->geometry.y, &sCoords->x, &sCoords->y);
+ auto [surf, local] = ls->layerSurface->surface->at(pos - ls->geometry.pos());
- if (SURFACEAT) {
- if (!pixman_region32_not_empty(&SURFACEAT->input_region))
+ if (surf) {
+ if (surf->current.input.empty())
continue;
*ppLayerSurfaceFound = ls.lock();
- return SURFACEAT;
+
+ *sCoords = local;
+
+ return surf;
}
}
return nullptr;
}
-PHLWINDOW CCompositor::getWindowFromSurface(wlr_surface* pSurface) {
+PHLWINDOW CCompositor::getWindowFromSurface(SP pSurface) {
for (auto& w : m_vWindows) {
if (!w->m_bIsMapped || w->m_bFadingOut)
continue;
- if (w->m_pWLSurface.wlr() == pSurface)
+ if (w->m_pWLSurface->resource() == pSurface)
return w;
}
@@ -1241,7 +1214,7 @@ bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
if (!pWindow->m_bIsMapped)
return false;
- const auto PSURFACE = pWindow->m_pWLSurface.wlr();
+ const auto PSURFACE = pWindow->m_pWLSurface->resource();
return PSURFACE == m_pLastFocus || pWindow == m_pLastWindow.lock();
}
@@ -1643,11 +1616,6 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const CMonitor* p
return !VECINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y);
}
-void checkFocusSurfaceIter(wlr_surface* pSurface, int x, int y, void* data) {
- auto pair = (std::pair*)data;
- pair->second = pair->second || pSurface == pair->first;
-}
-
CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
return this->getMonitorInDirection(m_pLastMonitor.get(), dir);
}
@@ -2386,24 +2354,24 @@ void CCompositor::closeWindow(PHLWINDOW pWindow) {
}
}
-PHLLS CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) {
- std::pair result = {pSurface, false};
+PHLLS CCompositor::getLayerSurfaceFromSurface(SP pSurface) {
+ std::pair, bool> result = {pSurface, false};
for (auto& ls : m_vLayers) {
if (ls->layerSurface && ls->layerSurface->surface == pSurface)
return ls;
- static auto iter = [](wlr_surface* surf, int x, int y, void* data) -> void {
- if (surf == ((std::pair*)data)->first) {
- *(bool*)data = true;
- return;
- }
- };
-
if (!ls->layerSurface || !ls->mapped)
continue;
- wlr_surface_for_each_surface(ls->layerSurface->surface, iter, &result);
+ ls->layerSurface->surface->breadthfirst(
+ [](SP surf, const Vector2D& offset, void* data) {
+ if (surf == ((std::pair, bool>*)data)->first) {
+ *(bool*)data = true;
+ return;
+ }
+ },
+ &result);
if (result.second)
return ls;
@@ -2735,13 +2703,13 @@ void CCompositor::leaveUnsafeState() {
}
}
-void CCompositor::setPreferredScaleForSurface(wlr_surface* pSurface, double scale) {
+void CCompositor::setPreferredScaleForSurface(SP pSurface, double scale) {
PROTO::fractional->sendScale(pSurface, scale);
- wlr_surface_set_preferred_buffer_scale(pSurface, static_cast(std::ceil(scale)));
+ pSurface->sendPreferredScale(std::ceil(scale));
- const auto PSURFACE = CWLSurface::surfaceFromWlr(pSurface);
+ const auto PSURFACE = CWLSurface::fromResource(pSurface);
if (!PSURFACE) {
- Debug::log(WARN, "Orphaned wlr_surface {:x} in setPreferredScaleForSurface", (uintptr_t)pSurface);
+ Debug::log(WARN, "Orphaned CWLSurfaceResource {:x} in setPreferredScaleForSurface", (uintptr_t)pSurface);
return;
}
@@ -2749,12 +2717,12 @@ void CCompositor::setPreferredScaleForSurface(wlr_surface* pSurface, double scal
PSURFACE->m_iLastScale = static_cast(std::ceil(scale));
}
-void CCompositor::setPreferredTransformForSurface(wlr_surface* pSurface, wl_output_transform transform) {
- wlr_surface_set_preferred_buffer_transform(pSurface, transform);
+void CCompositor::setPreferredTransformForSurface(SP pSurface, wl_output_transform transform) {
+ pSurface->sendPreferredTransform(transform);
- const auto PSURFACE = CWLSurface::surfaceFromWlr(pSurface);
+ const auto PSURFACE = CWLSurface::fromResource(pSurface);
if (!PSURFACE) {
- Debug::log(WARN, "Orphaned wlr_surface {:x} in setPreferredTransformForSurface", (uintptr_t)pSurface);
+ Debug::log(WARN, "Orphaned CWLSurfaceResource {:x} in setPreferredTransformForSurface", (uintptr_t)pSurface);
return;
}
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 94d9e4d0..c155ed39 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -29,8 +29,11 @@
#include "plugins/PluginSystem.hpp"
#include "helpers/Watchdog.hpp"
+class CWLSurfaceResource;
+
enum eManagersInitStage {
STAGE_PRIORITY = 0,
+ STAGE_BASICINIT,
STAGE_LATE
};
@@ -79,7 +82,7 @@ class CCompositor {
void createLockFile();
void removeLockFile();
- wlr_surface* m_pLastFocus = nullptr;
+ WP m_pLastFocus;
PHLWINDOWREF m_pLastWindow;
WP m_pLastMonitor;
@@ -96,86 +99,86 @@ class CCompositor {
// ------------------------------------------------- //
- CMonitor* getMonitorFromID(const int&);
- CMonitor* getMonitorFromName(const std::string&);
- CMonitor* getMonitorFromDesc(const std::string&);
- CMonitor* getMonitorFromCursor();
- CMonitor* getMonitorFromVector(const Vector2D&);
- void removeWindowFromVectorSafe(PHLWINDOW);
- void focusWindow(PHLWINDOW, wlr_surface* pSurface = nullptr);
- void focusSurface(wlr_surface*, PHLWINDOW pWindowOwner = nullptr);
- bool monitorExists(CMonitor*);
- PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
- wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector*, Vector2D*, PHLLS*);
- wlr_surface* vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
- wlr_surface* vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
- Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, wlr_surface*);
- CMonitor* getMonitorFromOutput(wlr_output*);
- CMonitor* getRealMonitorFromOutput(wlr_output*);
- PHLWINDOW getWindowFromSurface(wlr_surface*);
- PHLWINDOW getWindowFromHandle(uint32_t);
- bool isWorkspaceVisible(PHLWORKSPACE);
- PHLWORKSPACE getWorkspaceByID(const int&);
- PHLWORKSPACE getWorkspaceByName(const std::string&);
- PHLWORKSPACE getWorkspaceByString(const std::string&);
- void sanityCheckWorkspaces();
- void updateWorkspaceWindowDecos(const int&);
- void updateWorkspaceSpecialRenderData(const int&);
- int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {});
- int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {});
- PHLWINDOW getUrgentWindow();
- bool hasUrgentWindowOnWorkspace(const int&);
- PHLWINDOW getFirstWindowOnWorkspace(const int&);
- PHLWINDOW getTopLeftWindowOnWorkspace(const int&);
- PHLWINDOW getFullscreenWindowOnWorkspace(const int&);
- bool isWindowActive(PHLWINDOW);
- void changeWindowZOrder(PHLWINDOW, bool);
- void cleanupFadingOut(const int& monid);
- PHLWINDOW getWindowInDirection(PHLWINDOW, char);
- PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {});
- PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {});
- int getNextAvailableNamedWorkspace();
- bool isPointOnAnyMonitor(const Vector2D&);
- bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
- CMonitor* getMonitorInDirection(const char&);
- CMonitor* getMonitorInDirection(CMonitor*, const char&);
- void updateAllWindowsAnimatedDecorationValues();
- void updateWorkspaceWindows(const int64_t& id);
- void updateWindowAnimatedDecorationValues(PHLWINDOW);
- int getNextAvailableMonitorID(std::string const& name);
- void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
- void swapActiveWorkspaces(CMonitor*, CMonitor*);
- CMonitor* getMonitorFromString(const std::string&);
- bool workspaceIDOutOfBounds(const int64_t&);
- void setWindowFullscreen(PHLWINDOW, bool, eFullscreenMode mode = FULLSCREEN_INVALID);
- void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
- PHLWINDOW getX11Parent(PHLWINDOW);
- void scheduleFrameForMonitor(CMonitor*);
- void addToFadingOutSafe(PHLLS);
- void addToFadingOutSafe(PHLWINDOW);
- PHLWINDOW getWindowByRegex(const std::string&);
- void warpCursorTo(const Vector2D&, bool force = false);
- PHLLS getLayerSurfaceFromSurface(wlr_surface*);
- void closeWindow(PHLWINDOW);
- Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
- void forceReportSizesToWindowsOnWorkspace(const int&);
- PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
- void renameWorkspace(const int&, const std::string& name = "");
- void setActiveMonitor(CMonitor*);
- bool isWorkspaceSpecial(const int&);
- int getNewSpecialID();
- void performUserChecks();
- void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
- PHLWINDOW getForceFocus();
- void arrangeMonitors();
- void enterUnsafeState();
- void leaveUnsafeState();
- void setPreferredScaleForSurface(wlr_surface* pSurface, double scale);
- void setPreferredTransformForSurface(wlr_surface* pSurface, wl_output_transform transform);
- void updateSuspendedStates();
- PHLWINDOW windowForCPointer(CWindow*);
+ CMonitor* getMonitorFromID(const int&);
+ CMonitor* getMonitorFromName(const std::string&);
+ CMonitor* getMonitorFromDesc(const std::string&);
+ CMonitor* getMonitorFromCursor();
+ CMonitor* getMonitorFromVector(const Vector2D&);
+ void removeWindowFromVectorSafe(PHLWINDOW);
+ void focusWindow(PHLWINDOW, SP pSurface = nullptr);
+ void focusSurface(SP, PHLWINDOW pWindowOwner = nullptr);
+ bool monitorExists(CMonitor*);
+ PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
+ SP vectorToLayerSurface(const Vector2D&, std::vector*, Vector2D*, PHLLS*);
+ SP vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
+ SP vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
+ Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP);
+ CMonitor* getMonitorFromOutput(wlr_output*);
+ CMonitor* getRealMonitorFromOutput(wlr_output*);
+ PHLWINDOW getWindowFromSurface(SP);
+ PHLWINDOW getWindowFromHandle(uint32_t);
+ bool isWorkspaceVisible(PHLWORKSPACE);
+ PHLWORKSPACE getWorkspaceByID(const int&);
+ PHLWORKSPACE getWorkspaceByName(const std::string&);
+ PHLWORKSPACE getWorkspaceByString(const std::string&);
+ void sanityCheckWorkspaces();
+ void updateWorkspaceWindowDecos(const int&);
+ void updateWorkspaceSpecialRenderData(const int&);
+ int getWindowsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {});
+ int getGroupsOnWorkspace(const int& id, std::optional onlyTiled = {}, std::optional onlyVisible = {});
+ PHLWINDOW getUrgentWindow();
+ bool hasUrgentWindowOnWorkspace(const int&);
+ PHLWINDOW getFirstWindowOnWorkspace(const int&);
+ PHLWINDOW getTopLeftWindowOnWorkspace(const int&);
+ PHLWINDOW getFullscreenWindowOnWorkspace(const int&);
+ bool isWindowActive(PHLWINDOW);
+ void changeWindowZOrder(PHLWINDOW, bool);
+ void cleanupFadingOut(const int& monid);
+ PHLWINDOW getWindowInDirection(PHLWINDOW, char);
+ PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {});
+ PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional floating = {});
+ int getNextAvailableNamedWorkspace();
+ bool isPointOnAnyMonitor(const Vector2D&);
+ bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
+ CMonitor* getMonitorInDirection(const char&);
+ CMonitor* getMonitorInDirection(CMonitor*, const char&);
+ void updateAllWindowsAnimatedDecorationValues();
+ void updateWorkspaceWindows(const int64_t& id);
+ void updateWindowAnimatedDecorationValues(PHLWINDOW);
+ int getNextAvailableMonitorID(std::string const& name);
+ void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
+ void swapActiveWorkspaces(CMonitor*, CMonitor*);
+ CMonitor* getMonitorFromString(const std::string&);
+ bool workspaceIDOutOfBounds(const int64_t&);
+ void setWindowFullscreen(PHLWINDOW, bool, eFullscreenMode mode = FULLSCREEN_INVALID);
+ void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
+ PHLWINDOW getX11Parent(PHLWINDOW);
+ void scheduleFrameForMonitor(CMonitor*);
+ void addToFadingOutSafe(PHLLS);
+ void addToFadingOutSafe(PHLWINDOW);
+ PHLWINDOW getWindowByRegex(const std::string&);
+ void warpCursorTo(const Vector2D&, bool force = false);
+ PHLLS getLayerSurfaceFromSurface(SP);
+ void closeWindow(PHLWINDOW);
+ Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
+ void forceReportSizesToWindowsOnWorkspace(const int&);
+ PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
+ void renameWorkspace(const int&, const std::string& name = "");
+ void setActiveMonitor(CMonitor*);
+ bool isWorkspaceSpecial(const int&);
+ int getNewSpecialID();
+ void performUserChecks();
+ void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
+ PHLWINDOW getForceFocus();
+ void arrangeMonitors();
+ void enterUnsafeState();
+ void leaveUnsafeState();
+ void setPreferredScaleForSurface(SP pSurface, double scale);
+ void setPreferredTransformForSurface(SP pSurface, wl_output_transform transform);
+ void updateSuspendedStates();
+ PHLWINDOW windowForCPointer(CWindow*);
- std::string explicitConfigPath;
+ std::string explicitConfigPath;
private:
void initAllSignals();
diff --git a/src/debug/HyprDebugOverlay.cpp b/src/debug/HyprDebugOverlay.cpp
index 6d3ec907..889be8ea 100644
--- a/src/debug/HyprDebugOverlay.cpp
+++ b/src/debug/HyprDebugOverlay.cpp
@@ -3,6 +3,10 @@
#include "config/ConfigValue.hpp"
#include "../Compositor.hpp"
+CHyprDebugOverlay::CHyprDebugOverlay() {
+ m_pTexture = makeShared();
+}
+
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
m_dLastRenderTimes.push_back(µs / 1000.f);
@@ -222,8 +226,8 @@ void CHyprDebugOverlay::draw() {
// copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(m_pCairoSurface);
- m_tTexture.allocate();
- glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID);
+ m_pTexture->allocate();
+ glBindTexture(GL_TEXTURE_2D, m_pTexture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -235,5 +239,5 @@ void CHyprDebugOverlay::draw() {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
CBox pMonBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
- g_pHyprOpenGL->renderTexture(m_tTexture, &pMonBox, 1.f);
+ g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
}
diff --git a/src/debug/HyprDebugOverlay.hpp b/src/debug/HyprDebugOverlay.hpp
index f3beab45..a6063ee9 100644
--- a/src/debug/HyprDebugOverlay.hpp
+++ b/src/debug/HyprDebugOverlay.hpp
@@ -31,6 +31,7 @@ class CHyprMonitorDebugOverlay {
class CHyprDebugOverlay {
public:
+ CHyprDebugOverlay();
void draw();
void renderData(CMonitor*, float µs);
void renderDataNoOverlay(CMonitor*, float µs);
@@ -42,7 +43,7 @@ class CHyprDebugOverlay {
cairo_surface_t* m_pCairoSurface = nullptr;
cairo_t* m_pCairo = nullptr;
- CTexture m_tTexture;
+ SP m_pTexture;
friend class CHyprMonitorDebugOverlay;
friend class CHyprRenderer;
diff --git a/src/debug/HyprNotificationOverlay.cpp b/src/debug/HyprNotificationOverlay.cpp
index e1fc810b..aec3853e 100644
--- a/src/debug/HyprNotificationOverlay.cpp
+++ b/src/debug/HyprNotificationOverlay.cpp
@@ -23,6 +23,8 @@ CHyprNotificationOverlay::CHyprNotificationOverlay() {
g_pHyprRenderer->damageBox(&m_bLastDamage);
});
+
+ m_pTexture = makeShared();
}
CHyprNotificationOverlay::~CHyprNotificationOverlay() {
@@ -227,8 +229,8 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
// copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(m_pCairoSurface);
- m_tTexture.allocate();
- glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID);
+ m_pTexture->allocate();
+ glBindTexture(GL_TEXTURE_2D, m_pTexture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -240,7 +242,7 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MONSIZE.x, MONSIZE.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
CBox pMonBox = {0, 0, MONSIZE.x, MONSIZE.y};
- g_pHyprOpenGL->renderTexture(m_tTexture, &pMonBox, 1.f);
+ g_pHyprOpenGL->renderTexture(m_pTexture, &pMonBox, 1.f);
}
bool CHyprNotificationOverlay::hasAny() {
diff --git a/src/debug/HyprNotificationOverlay.hpp b/src/debug/HyprNotificationOverlay.hpp
index 5c978089..352c44c9 100644
--- a/src/debug/HyprNotificationOverlay.hpp
+++ b/src/debug/HyprNotificationOverlay.hpp
@@ -58,7 +58,7 @@ class CHyprNotificationOverlay {
CMonitor* m_pLastMonitor = nullptr;
Vector2D m_vecLastSize = Vector2D(-1, -1);
- CTexture m_tTexture;
+ SP m_pTexture;
};
inline std::unique_ptr g_pHyprNotificationOverlay;
diff --git a/src/desktop/LayerSurface.cpp b/src/desktop/LayerSurface.cpp
index 759eb09f..62cae8f6 100644
--- a/src/desktop/LayerSurface.cpp
+++ b/src/desktop/LayerSurface.cpp
@@ -2,6 +2,7 @@
#include "../Compositor.hpp"
#include "../events/Events.hpp"
#include "../protocols/LayerShell.hpp"
+#include "../protocols/core/Compositor.hpp"
#include "../managers/SeatManager.hpp"
PHLLS CLayerSurface::create(SP resource) {
@@ -9,6 +10,8 @@ PHLLS CLayerSurface::create(SP resource) {
CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
+ pLS->surface->assign(resource->surface.lock(), pLS);
+
if (!pMonitor) {
Debug::log(ERR, "New LS has no monitor??");
return pLS;
@@ -39,8 +42,6 @@ PHLLS CLayerSurface::create(SP resource) {
pLS->alpha.setValueAndWarp(0.f);
- pLS->surface.assign(resource->surface, pLS);
-
Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName);
return pLS;
@@ -58,13 +59,16 @@ CLayerSurface::CLayerSurface(SP resource_) : layerSurface(r
listeners.map = layerSurface->events.map.registerListener([this](std::any d) { onMap(); });
listeners.unmap = layerSurface->events.unmap.registerListener([this](std::any d) { onUnmap(); });
listeners.destroy = layerSurface->events.destroy.registerListener([this](std::any d) { onDestroy(); });
+
+ surface = CWLSurface::create();
}
CLayerSurface::~CLayerSurface() {
if (!g_pHyprOpenGL)
return;
- surface.unassign();
+ if (surface)
+ surface->unassign();
g_pHyprRenderer->makeEGLCurrent();
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); });
}
@@ -105,7 +109,8 @@ void CLayerSurface::onDestroy() {
readyToDelete = true;
layerSurface.reset();
- surface.unassign();
+ if (surface)
+ surface->unassign();
}
void CLayerSurface::onMap() {
@@ -126,7 +131,7 @@ void CLayerSurface::onMap() {
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID);
- wlr_surface_send_enter(surface.wlr(), PMONITOR->output);
+ surface->resource()->enter(PMONITOR->self.lock());
if (layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
g_pInputManager->m_dExclusiveLSes.push_back(self);
@@ -139,10 +144,10 @@ void CLayerSurface::onMap() {
// TODO: use the new superb really very cool grab
g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons();
- g_pCompositor->focusSurface(surface.wlr());
+ g_pCompositor->focusSurface(surface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y);
- g_pSeatManager->setPointerFocus(surface.wlr(), LOCAL);
+ g_pSeatManager->setPointerFocus(surface->resource(), LOCAL);
g_pInputManager->m_bEmptyFocusCursorSet = false;
}
@@ -160,8 +165,8 @@ void CLayerSurface::onMap() {
g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", szNamespace});
EMIT_HOOK_EVENT("openLayer", self.lock());
- g_pCompositor->setPreferredScaleForSurface(surface.wlr(), PMONITOR->scale);
- g_pCompositor->setPreferredTransformForSurface(surface.wlr(), PMONITOR->transform);
+ g_pCompositor->setPreferredScaleForSurface(surface->resource(), PMONITOR->scale);
+ g_pCompositor->setPreferredTransformForSurface(surface->resource(), PMONITOR->transform);
}
void CLayerSurface::onUnmap() {
@@ -173,7 +178,7 @@ void CLayerSurface::onUnmap() {
std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
if (!g_pInputManager->m_dExclusiveLSes.empty())
- g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->layerSurface->surface);
+ g_pCompositor->focusSurface(g_pInputManager->m_dExclusiveLSes[0]->surface->resource());
if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring.");
@@ -197,9 +202,9 @@ void CLayerSurface::onUnmap() {
const auto PMONITOR = g_pCompositor->getMonitorFromID(monitorID);
- const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == layerSurface->surface;
+ const bool WASLASTFOCUS = g_pCompositor->m_pLastFocus == surface->resource();
- surface = nullptr;
+ surface.reset();
if (!PMONITOR)
return;
@@ -208,11 +213,11 @@ void CLayerSurface::onUnmap() {
if (WASLASTFOCUS) {
g_pInputManager->releaseAllMouseButtons();
- Vector2D surfaceCoords;
- PHLLS pFoundLayerSurface;
- wlr_surface* foundSurface = nullptr;
+ Vector2D surfaceCoords;
+ PHLLS pFoundLayerSurface;
+ SP foundSurface = nullptr;
- g_pCompositor->m_pLastFocus = nullptr;
+ g_pCompositor->m_pLastFocus.reset();
// find LS-es to focus
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY],
@@ -236,8 +241,8 @@ void CLayerSurface::onUnmap() {
CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
g_pHyprRenderer->damageBox(&geomFixed);
- geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.width,
- (int)layerSurface->surface->current.height};
+ geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.size.x,
+ (int)layerSurface->surface->current.size.y};
g_pHyprRenderer->damageBox(&geomFixed);
g_pInputManager->sendMotionEventsToFocused();
@@ -284,12 +289,12 @@ void CLayerSurface::onCommit() {
position = Vector2D(geometry.x, geometry.y);
// update geom if it changed
- if (layerSurface->surface->current.scale == 1 && PMONITOR->scale != 1.f && layerSurface->surface->current.viewport.has_dst) {
+ if (layerSurface->surface->current.scale == 1 && PMONITOR->scale != 1.f && layerSurface->surface->current.viewport.hasDestination) {
// fractional scaling. Dirty hack.
- geometry = {geometry.x, geometry.y, (int)(layerSurface->surface->current.viewport.dst_width), (int)(layerSurface->surface->current.viewport.dst_height)};
+ geometry = {geometry.pos(), layerSurface->surface->current.viewport.destination};
} else {
// this is because some apps like e.g. rofi-lbonn can't fucking use the protocol correctly.
- geometry = {geometry.x, geometry.y, (int)layerSurface->surface->current.width, (int)layerSurface->surface->current.height};
+ geometry = {geometry.pos(), layerSurface->surface->current.size};
}
}
@@ -308,10 +313,10 @@ void CLayerSurface::onCommit() {
if (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained
&& !keyboardExclusive && mapped) {
- g_pCompositor->focusSurface(layerSurface->surface);
+ g_pCompositor->focusSurface(surface->resource());
const auto LOCAL = g_pInputManager->getMouseCoordsInternal() - Vector2D(geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y);
- g_pSeatManager->setPointerFocus(layerSurface->surface, LOCAL);
+ g_pSeatManager->setPointerFocus(surface->resource(), LOCAL);
g_pInputManager->m_bEmptyFocusCursorSet = false;
} else if (!layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) {
g_pInputManager->refocus();
@@ -319,10 +324,10 @@ void CLayerSurface::onCommit() {
keyboardExclusive = layerSurface->current.interactivity;
- g_pHyprRenderer->damageSurface(layerSurface->surface, position.x, position.y);
+ g_pHyprRenderer->damageSurface(surface->resource(), position.x, position.y);
- g_pCompositor->setPreferredScaleForSurface(layerSurface->surface, PMONITOR->scale);
- g_pCompositor->setPreferredTransformForSurface(layerSurface->surface, PMONITOR->transform);
+ g_pCompositor->setPreferredScaleForSurface(surface->resource(), PMONITOR->scale);
+ g_pCompositor->setPreferredTransformForSurface(surface->resource(), PMONITOR->transform);
}
void CLayerSurface::applyRules() {
diff --git a/src/desktop/LayerSurface.hpp b/src/desktop/LayerSurface.hpp
index d60a6dd0..9fa96d2d 100644
--- a/src/desktop/LayerSurface.hpp
+++ b/src/desktop/LayerSurface.hpp
@@ -36,7 +36,7 @@ class CLayerSurface {
bool keyboardExclusive = false;
- CWLSurface surface;
+ SP surface;
bool mapped = false;
uint32_t layer = 0;
diff --git a/src/desktop/Popup.cpp b/src/desktop/Popup.cpp
index d42a0ef0..f0fd556c 100644
--- a/src/desktop/Popup.cpp
+++ b/src/desktop/Popup.cpp
@@ -3,6 +3,7 @@
#include "../Compositor.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp"
+#include "../protocols/core/Compositor.hpp"
#include
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
@@ -14,7 +15,8 @@ CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) {
}
CPopup::CPopup(SP popup, CPopup* pOwner) : m_pParent(pOwner), m_pResource(popup) {
- m_sWLSurface.assign(popup->surface->surface, this);
+ m_pWLSurface = CWLSurface::create();
+ m_pWLSurface->assign(popup->surface->surface.lock(), this);
m_pLayerOwner = pOwner->m_pLayerOwner;
m_pWindowOwner = pOwner->m_pWindowOwner;
@@ -26,7 +28,8 @@ CPopup::CPopup(SP popup, CPopup* pOwner) : m_pParent(pOwner),
}
CPopup::~CPopup() {
- m_sWLSurface.unassign();
+ if (m_pWLSurface)
+ m_pWLSurface->unassign();
}
void CPopup::initAllSignals() {
@@ -69,14 +72,14 @@ void CPopup::onMap() {
if (m_bMapped)
return;
- m_bMapped = true;
- m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
+ m_bMapped = true;
+ m_vLastSize = m_pResource->surface->surface->current.size;
+
const auto COORDS = coordsGlobal();
const auto PMONITOR = g_pCompositor->getMonitorFromVector(COORDS);
- CBox box;
- wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr());
- box.applyFromWlr().translate(COORDS).expand(4);
+ CBox box = m_pWLSurface->resource()->extends();
+ box.translate(COORDS).expand(4);
g_pHyprRenderer->damageBox(&box);
m_vLastPos = coordsRelativeToParent();
@@ -87,7 +90,7 @@ void CPopup::onMap() {
//unconstrain();
sendScale();
- wlr_surface_send_enter(m_pResource->surface->surface, PMONITOR->output);
+ m_pResource->surface->surface->enter(PMONITOR->self.lock());
if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
@@ -103,12 +106,12 @@ void CPopup::onUnmap() {
return;
}
- m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
+ m_vLastSize = m_pResource->surface->surface->current.size;
+
const auto COORDS = coordsGlobal();
- CBox box;
- wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr());
- box.applyFromWlr().translate(COORDS).expand(4);
+ CBox box = m_pWLSurface->resource()->extends();
+ box.translate(COORDS).expand(4);
g_pHyprRenderer->damageBox(&box);
m_pSubsurfaceHead.reset();
@@ -136,14 +139,14 @@ void CPopup::onCommit(bool ignoreSiblings) {
onDestroy();
return;
}
-
+
if (m_pResource->surface->initialCommit) {
m_pResource->surface->scheduleConfigure();
return;
}
if (!m_pWindowOwner.expired() && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) {
- m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
+ m_vLastSize = m_pResource->surface->surface->current.size;
static auto PLOGDAMAGE = CConfigValue("debug:log_damage");
if (*PLOGDAMAGE)
@@ -157,11 +160,10 @@ void CPopup::onCommit(bool ignoreSiblings) {
const auto COORDS = coordsGlobal();
const auto COORDSLOCAL = coordsRelativeToParent();
- if (m_vLastSize != Vector2D{m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height} || m_bRequestedReposition ||
- m_vLastPos != COORDSLOCAL) {
+ if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
g_pHyprRenderer->damageBox(&box);
- m_vLastSize = {m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height};
+ m_vLastSize = m_pResource->surface->surface->current.size;
box = {COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box);
@@ -171,7 +173,7 @@ void CPopup::onCommit(bool ignoreSiblings) {
if (!ignoreSiblings && m_pSubsurfaceHead)
m_pSubsurfaceHead->recheckDamageForSubsurfaces();
- g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
+ g_pHyprRenderer->damageSurface(m_pWLSurface->resource(), COORDS.x, COORDS.y);
m_bRequestedReposition = false;
@@ -211,7 +213,7 @@ Vector2D CPopup::coordsRelativeToParent() {
while (current->m_pParent && current->m_pResource) {
- offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
+ offset += current->m_pWLSurface->resource()->current.offset;
offset += current->m_pResource->geometry.pos();
current = current->m_pParent;
@@ -260,9 +262,9 @@ Vector2D CPopup::size() {
void CPopup::sendScale() {
if (!m_pWindowOwner.expired())
- g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pWindowOwner->m_pWLSurface.m_fLastScale);
+ g_pCompositor->setPreferredScaleForSurface(m_pWLSurface->resource(), m_pWindowOwner->m_pWLSurface->m_fLastScale);
else if (!m_pLayerOwner.expired())
- g_pCompositor->setPreferredScaleForSurface(m_sWLSurface.wlr(), m_pLayerOwner->surface.m_fLastScale);
+ g_pCompositor->setPreferredScaleForSurface(m_pWLSurface->resource(), m_pLayerOwner->surface->m_fLastScale);
else
UNREACHABLE();
}
@@ -318,9 +320,8 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
return p;
} else {
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{};
- const auto REGION = CRegion{&p->m_sWLSurface.wlr()->current.input}
- .intersect(CBox{{}, {p->m_sWLSurface.wlr()->current.width, p->m_sWLSurface.wlr()->current.height}})
- .translate(p->coordsGlobal() + offset);
+ const auto REGION =
+ CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset);
if (REGION.containsPoint(globalCoords))
return p;
}
diff --git a/src/desktop/Popup.hpp b/src/desktop/Popup.hpp
index 7fdabee6..91e569e7 100644
--- a/src/desktop/Popup.hpp
+++ b/src/desktop/Popup.hpp
@@ -39,7 +39,7 @@ class CPopup {
CPopup* at(const Vector2D& globalCoords, bool allowsInput = false);
//
- CWLSurface m_sWLSurface;
+ SP m_pWLSurface;
private:
// T1 owners, each popup has to have one of these
diff --git a/src/desktop/Subsurface.cpp b/src/desktop/Subsurface.cpp
index 21482ff7..71ee16f0 100644
--- a/src/desktop/Subsurface.cpp
+++ b/src/desktop/Subsurface.cpp
@@ -2,29 +2,31 @@
#include "../events/Events.hpp"
#include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
-
-static void onNewSubsurface(void* owner, void* data);
+#include "../protocols/core/Compositor.hpp"
+#include "../protocols/core/Subcompositor.hpp"
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
initSignals();
- initExistingSubsurfaces(pOwner->m_pWLSurface.wlr());
+ initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
}
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
initSignals();
- initExistingSubsurfaces(pOwner->m_sWLSurface.wlr());
+ initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
}
-CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
- m_sWLSurface.assign(pSubsurface->surface, this);
+CSubsurface::CSubsurface(SP pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
+ m_pWLSurface = CWLSurface::create();
+ m_pWLSurface->assign(pSubsurface->surface.lock(), this);
initSignals();
- initExistingSubsurfaces(pSubsurface->surface);
+ initExistingSubsurfaces(pSubsurface->surface.lock());
}
-CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
- m_sWLSurface.assign(pSubsurface->surface, this);
+CSubsurface::CSubsurface(SP pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
+ m_pWLSurface = CWLSurface::create();
+ m_pWLSurface->assign(pSubsurface->surface.lock(), this);
initSignals();
- initExistingSubsurfaces(pSubsurface->surface);
+ initExistingSubsurfaces(pSubsurface->surface.lock());
}
CSubsurface::~CSubsurface() {
@@ -33,52 +35,27 @@ CSubsurface::~CSubsurface() {
if (!m_pSubsurface)
return;
- m_pSubsurface->data = nullptr;
-
hyprListener_commitSubsurface.removeCallback();
hyprListener_destroySubsurface.removeCallback();
}
-static void onNewSubsurface(void* owner, void* data) {
- const auto PSUBSURFACE = (CSubsurface*)owner;
- PSUBSURFACE->onNewSubsurface((wlr_subsurface*)data);
-}
-
-static void onDestroySubsurface(void* owner, void* data) {
- const auto PSUBSURFACE = (CSubsurface*)owner;
- PSUBSURFACE->onDestroy();
-}
-
-static void onCommitSubsurface(void* owner, void* data) {
- const auto PSUBSURFACE = (CSubsurface*)owner;
- PSUBSURFACE->onCommit();
-}
-
-static void onMapSubsurface(void* owner, void* data) {
- const auto PSUBSURFACE = (CSubsurface*)owner;
- PSUBSURFACE->onMap();
-}
-
-static void onUnmapSubsurface(void* owner, void* data) {
- const auto PSUBSURFACE = (CSubsurface*)owner;
- PSUBSURFACE->onUnmap();
-}
-
void CSubsurface::initSignals() {
if (m_pSubsurface) {
- m_pSubsurface->data = this;
- hyprListener_commitSubsurface.initCallback(&m_pSubsurface->surface->events.commit, &onCommitSubsurface, this, "CSubsurface");
- hyprListener_destroySubsurface.initCallback(&m_pSubsurface->events.destroy, &onDestroySubsurface, this, "CSubsurface");
- hyprListener_newSubsurface.initCallback(&m_pSubsurface->surface->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface");
- hyprListener_mapSubsurface.initCallback(&m_pSubsurface->surface->events.map, &onMapSubsurface, this, "CSubsurface");
- hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface");
+ listeners.commitSubsurface = m_pSubsurface->surface->events.commit.registerListener([this](std::any d) { onCommit(); });
+ listeners.destroySubsurface = m_pSubsurface->events.destroy.registerListener([this](std::any d) { onDestroy(); });
+ listeners.mapSubsurface = m_pSubsurface->surface->events.map.registerListener([this](std::any d) { onMap(); });
+ listeners.unmapSubsurface = m_pSubsurface->surface->events.unmap.registerListener([this](std::any d) { onUnmap(); });
+ listeners.newSubsurface =
+ m_pSubsurface->surface->events.newSubsurface.registerListener([this](std::any d) { onNewSubsurface(std::any_cast>(d)); });
} else {
- if (!m_pWindowParent.expired())
- hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
+ if (m_pWindowParent)
+ listeners.newSubsurface = m_pWindowParent->m_pWLSurface->resource()->events.newSubsurface.registerListener(
+ [this](std::any d) { onNewSubsurface(std::any_cast>(d)); });
else if (m_pPopupParent)
- hyprListener_newSubsurface.initCallback(&m_pPopupParent->m_sWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head");
+ listeners.newSubsurface = m_pPopupParent->m_pWLSurface->resource()->events.newSubsurface.registerListener(
+ [this](std::any d) { onNewSubsurface(std::any_cast>(d)); });
else
- RASSERT(false, "CSubsurface::initSignals empty subsurface");
+ ASSERT(false);
}
}
@@ -93,21 +70,21 @@ void CSubsurface::checkSiblingDamage() {
continue;
const auto COORDS = n->coordsGlobal();
- g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y, SCALE);
+ g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y, SCALE);
}
}
void CSubsurface::recheckDamageForSubsurfaces() {
for (auto& n : m_vChildren) {
const auto COORDS = n->coordsGlobal();
- g_pHyprRenderer->damageSurface(n->m_sWLSurface.wlr(), COORDS.x, COORDS.y);
+ g_pHyprRenderer->damageSurface(n->m_pWLSurface->resource(), COORDS.x, COORDS.y);
}
}
void CSubsurface::onCommit() {
// no damaging if it's not visible
if (!m_pWindowParent.expired() && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) {
- m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
+ m_vLastSize = m_pWLSurface->resource()->current.size;
static auto PLOGDAMAGE = CConfigValue("debug:log_damage");
if (*PLOGDAMAGE)
@@ -117,7 +94,7 @@ void CSubsurface::onCommit() {
const auto COORDS = coordsGlobal();
- g_pHyprRenderer->damageSurface(m_sWLSurface.wlr(), COORDS.x, COORDS.y);
+ g_pHyprRenderer->damageSurface(m_pWLSurface->resource(), COORDS.x, COORDS.y);
if (m_pPopupParent)
m_pPopupParent->recheckTree();
@@ -127,10 +104,10 @@ void CSubsurface::onCommit() {
// I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
checkSiblingDamage();
- if (m_vLastSize != Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}) {
+ if (m_vLastSize != m_pWLSurface->resource()->current.size) {
CBox box{COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box);
- m_vLastSize = Vector2D{m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
+ m_vLastSize = m_pWLSurface->resource()->current.size;
box = {COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box);
}
@@ -149,20 +126,21 @@ void CSubsurface::onDestroy() {
std::erase_if(m_pParent->m_vChildren, [this](const auto& other) { return other.get() == this; });
}
-void CSubsurface::onNewSubsurface(wlr_subsurface* pSubsurface) {
+void CSubsurface::onNewSubsurface(SP pSubsurface) {
CSubsurface* PSUBSURFACE = nullptr;
if (!m_pWindowParent.expired())
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique(pSubsurface, m_pWindowParent.lock())).get();
else if (m_pPopupParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique(pSubsurface, m_pPopupParent)).get();
- PSUBSURFACE->m_pParent = this;
ASSERT(PSUBSURFACE);
+
+ PSUBSURFACE->m_pParent = this;
}
void CSubsurface::onMap() {
- m_vLastSize = {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
+ m_vLastSize = m_pWLSurface->resource()->current.size;
const auto COORDS = coordsGlobal();
CBox box{COORDS, m_vLastSize};
@@ -179,7 +157,7 @@ void CSubsurface::onUnmap() {
box.expand(4);
g_pHyprRenderer->damageBox(&box);
- if (m_sWLSurface.wlr() == g_pCompositor->m_pLastFocus)
+ if (m_pWLSurface->resource() == g_pCompositor->m_pLastFocus)
g_pInputManager->releaseAllMouseButtons();
g_pInputManager->simulateMouseMovement();
@@ -188,19 +166,9 @@ void CSubsurface::onUnmap() {
}
Vector2D CSubsurface::coordsRelativeToParent() {
- Vector2D offset;
-
- CSubsurface* current = this;
-
- while (current->m_pParent) {
-
- offset += {current->m_sWLSurface.wlr()->current.dx, current->m_sWLSurface.wlr()->current.dy};
- offset += {current->m_pSubsurface->current.x, current->m_pSubsurface->current.y};
-
- current = current->m_pParent;
- }
-
- return offset;
+ if (!m_pSubsurface)
+ return {};
+ return m_pSubsurface->posRelativeToParent();
}
Vector2D CSubsurface::coordsGlobal() {
@@ -214,18 +182,16 @@ Vector2D CSubsurface::coordsGlobal() {
return coords;
}
-void CSubsurface::initExistingSubsurfaces(wlr_surface* pSurface) {
- wlr_subsurface* wlrSubsurface;
- wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_below, current.link) {
- ::onNewSubsurface(this, wlrSubsurface);
- }
- wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_above, current.link) {
- ::onNewSubsurface(this, wlrSubsurface);
+void CSubsurface::initExistingSubsurfaces(SP pSurface) {
+ for (auto& s : pSurface->subsurfaces) {
+ if (!s || s->surface->hlSurface /* already assigned */)
+ continue;
+ onNewSubsurface(s.lock());
}
}
Vector2D CSubsurface::size() {
- return {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height};
+ return m_pWLSurface->resource()->current.size;
}
bool CSubsurface::visible() {
diff --git a/src/desktop/Subsurface.hpp b/src/desktop/Subsurface.hpp
index f3a5ea4b..101f4f19 100644
--- a/src/desktop/Subsurface.hpp
+++ b/src/desktop/Subsurface.hpp
@@ -5,6 +5,7 @@
#include "WLSurface.hpp"
class CPopup;
+class CWLSubsurfaceResource;
class CSubsurface {
public:
@@ -13,8 +14,8 @@ class CSubsurface {
CSubsurface(CPopup* pOwner);
// real nodes
- CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner);
- CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner);
+ CSubsurface(SP pSubsurface, PHLWINDOW pOwner);
+ CSubsurface(SP pSubsurface, CPopup* pOwner);
~CSubsurface();
@@ -25,7 +26,7 @@ class CSubsurface {
void onCommit();
void onDestroy();
- void onNewSubsurface(wlr_subsurface* pSubsurface);
+ void onNewSubsurface(SP pSubsurface);
void onMap();
void onUnmap();
@@ -37,12 +38,18 @@ class CSubsurface {
DYNLISTENER(destroySubsurface);
DYNLISTENER(commitSubsurface);
DYNLISTENER(newSubsurface);
- DYNLISTENER(mapSubsurface);
- DYNLISTENER(unmapSubsurface);
- wlr_subsurface* m_pSubsurface = nullptr;
- CWLSurface m_sWLSurface;
- Vector2D m_vLastSize = {};
+ struct {
+ CHyprSignalListener destroySubsurface;
+ CHyprSignalListener commitSubsurface;
+ CHyprSignalListener mapSubsurface;
+ CHyprSignalListener unmapSubsurface;
+ CHyprSignalListener newSubsurface;
+ } listeners;
+
+ WP m_pSubsurface;
+ SP m_pWLSurface;
+ Vector2D m_vLastSize = {};
// if nullptr, means it's a dummy node
CSubsurface* m_pParent = nullptr;
@@ -55,6 +62,6 @@ class CSubsurface {
bool m_bInert = false;
void initSignals();
- void initExistingSubsurfaces(wlr_surface* pSurface);
+ void initExistingSubsurfaces(SP pSurface);
void checkSiblingDamage();
};
\ No newline at end of file
diff --git a/src/desktop/WLSurface.cpp b/src/desktop/WLSurface.cpp
index 78b50d45..c7a09b40 100644
--- a/src/desktop/WLSurface.cpp
+++ b/src/desktop/WLSurface.cpp
@@ -1,36 +1,37 @@
#include "WLSurface.hpp"
#include "../Compositor.hpp"
+#include "../protocols/core/Compositor.hpp"
-void CWLSurface::assign(wlr_surface* pSurface) {
- m_pWLRSurface = pSurface;
+void CWLSurface::assign(SP pSurface) {
+ m_pResource = pSurface;
init();
m_bInert = false;
}
-void CWLSurface::assign(wlr_surface* pSurface, PHLWINDOW pOwner) {
+void CWLSurface::assign(SP pSurface, PHLWINDOW pOwner) {
m_pWindowOwner = pOwner;
- m_pWLRSurface = pSurface;
+ m_pResource = pSurface;
init();
m_bInert = false;
}
-void CWLSurface::assign(wlr_surface* pSurface, PHLLS pOwner) {
+void CWLSurface::assign(SP pSurface, PHLLS pOwner) {
m_pLayerOwner = pOwner;
- m_pWLRSurface = pSurface;
+ m_pResource = pSurface;
init();
m_bInert = false;
}
-void CWLSurface::assign(wlr_surface* pSurface, CSubsurface* pOwner) {
+void CWLSurface::assign(SP pSurface, CSubsurface* pOwner) {
m_pSubsurfaceOwner = pOwner;
- m_pWLRSurface = pSurface;
+ m_pResource = pSurface;
init();
m_bInert = false;
}
-void CWLSurface::assign(wlr_surface* pSurface, CPopup* pOwner) {
+void CWLSurface::assign(SP pSurface, CPopup* pOwner) {
m_pPopupOwner = pOwner;
- m_pWLRSurface = pSurface;
+ m_pResource = pSurface;
init();
m_bInert = false;
}
@@ -44,20 +45,23 @@ CWLSurface::~CWLSurface() {
}
bool CWLSurface::exists() const {
- return m_pWLRSurface;
+ return m_pResource;
}
-wlr_surface* CWLSurface::wlr() const {
- return m_pWLRSurface;
+SP CWLSurface::resource() const {
+ return m_pResource.lock();
}
bool CWLSurface::small() const {
if (!validMapped(m_pWindowOwner) || !exists())
return false;
+ if (!m_pResource->current.buffer)
+ return false;
+
const auto O = m_pWindowOwner.lock();
- return O->m_vReportedSize.x > m_pWLRSurface->current.buffer_width + 1 || O->m_vReportedSize.y > m_pWLRSurface->current.buffer_height + 1;
+ return O->m_vReportedSize.x > m_pResource->current.buffer->size.x + 1 || O->m_vReportedSize.y > m_pResource->current.buffer->size.y + 1;
}
Vector2D CWLSurface::correctSmallVec() const {
@@ -71,29 +75,28 @@ Vector2D CWLSurface::correctSmallVec() const {
}
Vector2D CWLSurface::getViewporterCorrectedSize() const {
- if (!exists())
+ if (!exists() || !m_pResource->current.buffer)
return {};
- return m_pWLRSurface->current.viewport.has_dst ? Vector2D{m_pWLRSurface->current.viewport.dst_width, m_pWLRSurface->current.viewport.dst_height} :
- Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height};
+ return m_pResource->current.viewport.hasDestination ? m_pResource->current.viewport.destination : m_pResource->current.buffer->size;
}
CRegion CWLSurface::logicalDamage() const {
- CRegion damage{&m_pWLRSurface->buffer_damage};
- damage.transform(m_pWLRSurface->current.transform, m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height);
- damage.scale(1.0 / m_pWLRSurface->current.scale);
+ if (!m_pResource->current.buffer)
+ return {};
+
+ CRegion damage = m_pResource->accumulateCurrentBufferDamage();
+ damage.transform(m_pResource->current.transform, m_pResource->current.buffer->size.x, m_pResource->current.buffer->size.y);
+ damage.scale(1.0 / m_pResource->current.scale);
const auto VPSIZE = getViewporterCorrectedSize();
const auto CORRECTVEC = correctSmallVec();
- if (m_pWLRSurface->current.viewport.has_src) {
- damage.intersect(CBox{std::floor(m_pWLRSurface->current.viewport.src.x), std::floor(m_pWLRSurface->current.viewport.src.y),
- std::ceil(m_pWLRSurface->current.viewport.src.width), std::ceil(m_pWLRSurface->current.viewport.src.height)});
- }
+ if (m_pResource->current.viewport.hasSource)
+ damage.intersect(m_pResource->current.viewport.source);
- const auto SCALEDSRCSIZE = m_pWLRSurface->current.viewport.has_src ?
- Vector2D{m_pWLRSurface->current.viewport.src.width, m_pWLRSurface->current.viewport.src.height} * m_pWLRSurface->current.scale :
- Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height};
+ const auto SCALEDSRCSIZE =
+ m_pResource->current.viewport.hasSource ? m_pResource->current.viewport.source.size() * m_pResource->current.scale : m_pResource->current.buffer->size;
damage.scale({VPSIZE.x / SCALEDSRCSIZE.x, VPSIZE.y / SCALEDSRCSIZE.y});
damage.translate(CORRECTVEC);
@@ -102,48 +105,38 @@ CRegion CWLSurface::logicalDamage() const {
}
void CWLSurface::destroy() {
- if (!m_pWLRSurface)
+ if (!m_pResource)
return;
events.destroy.emit();
m_pConstraint.reset();
- hyprListener_destroy.removeCallback();
- hyprListener_commit.removeCallback();
- m_pWLRSurface->data = nullptr;
+ listeners.destroy.reset();
+ m_pResource->hlSurface.reset();
m_pWindowOwner.reset();
m_pLayerOwner.reset();
m_pPopupOwner = nullptr;
m_pSubsurfaceOwner = nullptr;
m_bInert = true;
- if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface)
- g_pCompositor->m_pLastFocus = nullptr;
- if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf == this)
+ if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf && g_pHyprRenderer->m_sLastCursorData.surf->get() == this)
g_pHyprRenderer->m_sLastCursorData.surf.reset();
- m_pWLRSurface = nullptr;
+ m_pResource.reset();
Debug::log(LOG, "CWLSurface {:x} called destroy()", (uintptr_t)this);
}
-static void onCommit(void* owner, void* data) {
- const auto SURF = (CWLSurface*)owner;
- SURF->onCommit();
-}
-
void CWLSurface::init() {
- if (!m_pWLRSurface)
+ if (!m_pResource)
return;
- RASSERT(!m_pWLRSurface->data, "Attempted to duplicate CWLSurface ownership!");
+ RASSERT(!m_pResource->hlSurface, "Attempted to duplicate CWLSurface ownership!");
- m_pWLRSurface->data = this;
+ m_pResource->hlSurface = self.lock();
- hyprListener_destroy.initCallback(
- &m_pWLRSurface->events.destroy, [&](void* owner, void* data) { destroy(); }, this, "CWLSurface");
- hyprListener_commit.initCallback(&m_pWLRSurface->events.commit, ::onCommit, this, "CWLSurface");
+ listeners.destroy = m_pResource->events.destroy.registerListener([this](std::any d) { destroy(); });
Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this);
}
@@ -188,10 +181,6 @@ void CWLSurface::appendConstraint(WP constraint) {
m_pConstraint = constraint;
}
-void CWLSurface::onCommit() {
- ;
-}
-
SP CWLSurface::constraint() {
return m_pConstraint.lock();
}
@@ -207,3 +196,9 @@ bool CWLSurface::visible() {
return m_pSubsurfaceOwner->visible();
return true; // non-desktop, we don't know much.
}
+
+SP CWLSurface::fromResource(SP pSurface) {
+ if (!pSurface)
+ return nullptr;
+ return pSurface->hlSurface.lock();
+}
diff --git a/src/desktop/WLSurface.hpp b/src/desktop/WLSurface.hpp
index 03e81b45..4ba381a9 100644
--- a/src/desktop/WLSurface.hpp
+++ b/src/desktop/WLSurface.hpp
@@ -7,33 +7,37 @@
class CSubsurface;
class CPopup;
class CPointerConstraint;
+class CWLSurfaceResource;
class CWLSurface {
public:
- CWLSurface() = default;
+ static SP create() {
+ auto p = SP(new CWLSurface);
+ p->self = p;
+ return p;
+ }
~CWLSurface();
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
- void assign(wlr_surface* pSurface);
- void assign(wlr_surface* pSurface, PHLWINDOW pOwner);
- void assign(wlr_surface* pSurface, PHLLS pOwner);
- void assign(wlr_surface* pSurface, CSubsurface* pOwner);
- void assign(wlr_surface* pSurface, CPopup* pOwner);
+ void assign(SP pSurface);
+ void assign(SP pSurface, PHLWINDOW pOwner);
+ void assign(SP pSurface, PHLLS pOwner);
+ void assign(SP pSurface, CSubsurface* pOwner);
+ void assign(SP pSurface, CPopup* pOwner);
void unassign();
- CWLSurface(const CWLSurface&) = delete;
- CWLSurface(CWLSurface&&) = delete;
- CWLSurface& operator=(const CWLSurface&) = delete;
- CWLSurface& operator=(CWLSurface&&) = delete;
+ CWLSurface(const CWLSurface&) = delete;
+ CWLSurface(CWLSurface&&) = delete;
+ CWLSurface& operator=(const CWLSurface&) = delete;
+ CWLSurface& operator=(CWLSurface&&) = delete;
- wlr_surface* wlr() const;
- bool exists() const;
- bool small() const; // means surface is smaller than the requested size
- Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
- Vector2D getViewporterCorrectedSize() const;
- CRegion logicalDamage() const;
- void onCommit();
- bool visible();
+ SP resource() const;
+ bool exists() const;
+ bool small() const; // means surface is smaller than the requested size
+ Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
+ Vector2D getViewporterCorrectedSize() const;
+ CRegion logicalDamage() const;
+ bool visible();
// getters for owners.
PHLWINDOW getWindow();
@@ -55,31 +59,27 @@ class CWLSurface {
wl_output_transform m_eLastTransform = (wl_output_transform)-1;
//
- CWLSurface& operator=(wlr_surface* pSurface) {
+ CWLSurface& operator=(SP pSurface) {
destroy();
- m_pWLRSurface = pSurface;
+ m_pResource = pSurface;
init();
return *this;
}
bool operator==(const CWLSurface& other) const {
- return other.wlr() == wlr();
+ return other.resource() == resource();
}
- bool operator==(const wlr_surface* other) const {
- return other == wlr();
+ bool operator==(const SP other) const {
+ return other == resource();
}
explicit operator bool() const {
return exists();
}
- static CWLSurface* surfaceFromWlr(wlr_surface* pSurface) {
- if (!pSurface)
- return nullptr;
- return (CWLSurface*)pSurface->data;
- }
+ static SP fromResource(SP pSurface);
// used by the alpha-modifier protocol
float m_pAlphaModifier = 1.F;
@@ -88,15 +88,19 @@ class CWLSurface {
CSignal destroy;
} events;
+ WP self;
+
private:
- bool m_bInert = true;
+ CWLSurface() = default;
- wlr_surface* m_pWLRSurface = nullptr;
+ bool m_bInert = true;
- PHLWINDOWREF m_pWindowOwner;
- PHLLSREF m_pLayerOwner;
- CPopup* m_pPopupOwner = nullptr;
- CSubsurface* m_pSubsurfaceOwner = nullptr;
+ WP m_pResource;
+
+ PHLWINDOWREF m_pWindowOwner;
+ PHLLSREF m_pLayerOwner;
+ CPopup* m_pPopupOwner = nullptr;
+ CSubsurface* m_pSubsurfaceOwner = nullptr;
//
WP m_pConstraint;
@@ -105,8 +109,9 @@ class CWLSurface {
void init();
bool desktopComponent();
- DYNLISTENER(destroy);
- DYNLISTENER(commit);
+ struct {
+ CHyprSignalListener destroy;
+ } listeners;
friend class CPointerConstraint;
};
\ No newline at end of file
diff --git a/src/desktop/Window.cpp b/src/desktop/Window.cpp
index 9f5f9dd3..b1e993e0 100644
--- a/src/desktop/Window.cpp
+++ b/src/desktop/Window.cpp
@@ -9,6 +9,7 @@
#include "../config/ConfigValue.hpp"
#include "../managers/TokenManager.hpp"
#include "../protocols/XDGShell.hpp"
+#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XWayland.hpp"
PHLWINDOW CWindow::create(SP surface) {
@@ -51,12 +52,14 @@ PHLWINDOW CWindow::create(SP resource) {
pWindow->addWindowDeco(std::make_unique(pWindow));
pWindow->addWindowDeco(std::make_unique(pWindow));
- pWindow->m_pWLSurface.assign(pWindow->m_pXDGSurface->surface, pWindow);
+ pWindow->m_pWLSurface->assign(pWindow->m_pXDGSurface->surface.lock(), pWindow);
return pWindow;
}
CWindow::CWindow(SP resource) : m_pXDGSurface(resource) {
+ m_pWLSurface = CWLSurface::create();
+
listeners.map = m_pXDGSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
listeners.ack = m_pXDGSurface->events.ack.registerListener([this](std::any d) { onAck(std::any_cast(d)); });
listeners.unmap = m_pXDGSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
@@ -67,6 +70,8 @@ CWindow::CWindow(SP resource) : m_pXDGSurface(resource) {
}
CWindow::CWindow(SP surface) : m_pXWaylandSurface(surface) {
+ m_pWLSurface = CWLSurface::create();
+
listeners.map = m_pXWaylandSurface->events.map.registerListener([this](std::any d) { Events::listener_mapWindow(this, nullptr); });
listeners.unmap = m_pXWaylandSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
@@ -83,7 +88,7 @@ CWindow::CWindow(SP surface) : m_pXWaylandSurface(surface) {
CWindow::~CWindow() {
if (g_pCompositor->m_pLastWindow.lock().get() == this) {
- g_pCompositor->m_pLastFocus = nullptr;
+ g_pCompositor->m_pLastFocus.reset();
g_pCompositor->m_pLastWindow.reset();
}
@@ -124,12 +129,12 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
maxExtents.bottomRight.y = EXTENTS.bottomRight.y;
- if (m_pWLSurface.exists() && !m_bIsX11 && m_pPopupHead) {
+ if (m_pWLSurface->exists() && !m_bIsX11 && m_pPopupHead) {
CBox surfaceExtents = {0, 0, 0, 0};
// TODO: this could be better, perhaps make a getFullWindowRegion?
m_pPopupHead->breadthfirst(
[](CPopup* popup, void* data) {
- if (!popup->m_sWLSurface.wlr())
+ if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource())
return;
CBox* pSurfaceExtents = (CBox*)data;
@@ -151,11 +156,11 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
if (-surfaceExtents.y > maxExtents.topLeft.y)
maxExtents.topLeft.y = -surfaceExtents.y;
- if (surfaceExtents.x + surfaceExtents.width > m_pWLSurface.wlr()->current.width + maxExtents.bottomRight.x)
- maxExtents.bottomRight.x = surfaceExtents.x + surfaceExtents.width - m_pWLSurface.wlr()->current.width;
+ if (surfaceExtents.x + surfaceExtents.width > m_pWLSurface->resource()->current.size.x + maxExtents.bottomRight.x)
+ maxExtents.bottomRight.x = surfaceExtents.x + surfaceExtents.width - m_pWLSurface->resource()->current.size.x;
- if (surfaceExtents.y + surfaceExtents.height > m_pWLSurface.wlr()->current.height + maxExtents.bottomRight.y)
- maxExtents.bottomRight.y = surfaceExtents.y + surfaceExtents.height - m_pWLSurface.wlr()->current.height;
+ if (surfaceExtents.y + surfaceExtents.height > m_pWLSurface->resource()->current.size.y + maxExtents.bottomRight.y)
+ maxExtents.bottomRight.y = surfaceExtents.y + surfaceExtents.height - m_pWLSurface->resource()->current.size.y;
}
return maxExtents;
@@ -340,17 +345,7 @@ void CWindow::updateToplevel() {
updateSurfaceScaleTransformDetails();
}
-void sendEnterIter(wlr_surface* pSurface, int x, int y, void* data) {
- const auto OUTPUT = (wlr_output*)data;
- wlr_surface_send_enter(pSurface, OUTPUT);
-}
-
-void sendLeaveIter(wlr_surface* pSurface, int x, int y, void* data) {
- const auto OUTPUT = (wlr_output*)data;
- wlr_surface_send_leave(pSurface, OUTPUT);
-}
-
-void CWindow::updateSurfaceScaleTransformDetails() {
+void CWindow::updateSurfaceScaleTransformDetails(bool force) {
if (!m_bIsMapped || m_bHidden || g_pCompositor->m_bUnsafeState)
return;
@@ -363,26 +358,25 @@ void CWindow::updateSurfaceScaleTransformDetails() {
if (!PNEWMONITOR)
return;
- if (PNEWMONITOR != PLASTMONITOR) {
- if (PLASTMONITOR && PLASTMONITOR->m_bEnabled)
- wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendLeaveIter, PLASTMONITOR->output);
+ if (PNEWMONITOR != PLASTMONITOR || force) {
+ if (PLASTMONITOR && PLASTMONITOR->m_bEnabled && PNEWMONITOR != PLASTMONITOR)
+ m_pWLSurface->resource()->breadthfirst([PLASTMONITOR](SP s, const Vector2D& offset, void* d) { s->leave(PLASTMONITOR->self.lock()); }, nullptr);
- wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendEnterIter, PNEWMONITOR->output);
+ m_pWLSurface->resource()->breadthfirst([PNEWMONITOR](SP s, const Vector2D& offset, void* d) { s->enter(PNEWMONITOR->self.lock()); }, nullptr);
}
- wlr_surface_for_each_surface(
- m_pWLSurface.wlr(),
- [](wlr_surface* surf, int x, int y, void* data) {
- const auto PMONITOR = g_pCompositor->getMonitorFromID(((CWindow*)data)->m_iMonitorID);
+ m_pWLSurface->resource()->breadthfirst(
+ [this](SP s, const Vector2D& offset, void* d) {
+ const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
- const auto PSURFACE = CWLSurface::surfaceFromWlr(surf);
+ const auto PSURFACE = CWLSurface::fromResource(s);
if (PSURFACE && PSURFACE->m_fLastScale == PMONITOR->scale)
return;
- g_pCompositor->setPreferredScaleForSurface(surf, PMONITOR->scale);
- g_pCompositor->setPreferredTransformForSurface(surf, PMONITOR->transform);
+ g_pCompositor->setPreferredScaleForSurface(s, PMONITOR->scale);
+ g_pCompositor->setPreferredTransformForSurface(s, PMONITOR->transform);
},
- this);
+ nullptr);
}
void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
@@ -568,6 +562,8 @@ void CWindow::onMap() {
m_vReportedSize = m_vPendingReportedSize;
m_bAnimatingIn = true;
+ updateSurfaceScaleTransformDetails(true);
+
if (m_bIsX11)
return;
@@ -860,7 +856,7 @@ bool CWindow::hasPopupAt(const Vector2D& pos) {
CPopup* popup = m_pPopupHead->at(pos);
- return popup && popup->m_sWLSurface.wlr();
+ return popup && popup->m_pWLSurface->resource();
}
void CWindow::applyGroupRules() {
@@ -1135,23 +1131,24 @@ bool CWindow::opaque() {
const auto PWORKSPACE = m_pWorkspace;
- if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall)
+ if (m_pWLSurface->small() && !m_pWLSurface->m_bFillIgnoreSmall)
return false;
if (PWORKSPACE->m_fAlpha.value() != 1.f)
return false;
- if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface)
- return m_pXWaylandSurface->surface->opaque;
+ if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface && m_pXWaylandSurface->surface->current.buffer)
+ return m_pXWaylandSurface->surface->current.buffer->opaque;
- if (m_pXDGSurface && m_pXDGSurface->surface->opaque)
+ if (!m_pWLSurface->resource() || !m_pWLSurface->resource()->current.buffer)
+ return false;
+
+ // TODO: this is wrong
+ const auto EXTENTS = m_pXDGSurface->surface->current.opaque.getExtents();
+ if (EXTENTS.w >= m_pXDGSurface->surface->current.buffer->size.x && EXTENTS.h >= m_pXDGSurface->surface->current.buffer->size.y)
return true;
- const auto EXTENTS = pixman_region32_extents(&m_pXDGSurface->surface->opaque_region);
- if (EXTENTS->x2 - EXTENTS->x1 >= m_pXDGSurface->surface->current.buffer_width && EXTENTS->y2 - EXTENTS->y1 >= m_pXDGSurface->surface->current.buffer_height)
- return true;
-
- return false;
+ return m_pWLSurface->resource()->current.buffer->opaque;
}
float CWindow::rounding() {
@@ -1282,8 +1279,7 @@ int CWindow::surfacesCount() {
return 1;
int no = 0;
- wlr_surface_for_each_surface(
- m_pWLSurface.wlr(), [](wlr_surface* surf, int x, int y, void* data) { *((int*)data) += 1; }, &no);
+ m_pWLSurface->resource()->breadthfirst([](SP r, const Vector2D& offset, void* d) { *((int*)d) += 1; }, &no);
return no;
}
@@ -1456,16 +1452,16 @@ void CWindow::onAck(uint32_t serial) {
}
void CWindow::onResourceChangeX11() {
- if (m_pXWaylandSurface->surface && !m_pWLSurface.wlr())
- m_pWLSurface.assign(m_pXWaylandSurface->surface, m_pSelf.lock());
- else if (!m_pXWaylandSurface->surface && m_pWLSurface.wlr())
- m_pWLSurface.unassign();
+ if (m_pXWaylandSurface->surface && !m_pWLSurface->resource())
+ m_pWLSurface->assign(m_pXWaylandSurface->surface.lock(), m_pSelf.lock());
+ else if (!m_pXWaylandSurface->surface && m_pWLSurface->resource())
+ m_pWLSurface->unassign();
// update metadata as well,
// could be first assoc and we need to catch the class
onUpdateMeta();
- Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface.wlr());
+ Debug::log(LOG, "xwayland window {:x} -> association to {:x}", (uintptr_t)m_pXWaylandSurface.get(), (uintptr_t)m_pWLSurface->resource().get());
}
void CWindow::onX11Configure(CBox box) {
diff --git a/src/desktop/Window.hpp b/src/desktop/Window.hpp
index d4e26d5d..a5a321ab 100644
--- a/src/desktop/Window.hpp
+++ b/src/desktop/Window.hpp
@@ -213,7 +213,7 @@ class CWindow {
public:
~CWindow();
- CWLSurface m_pWLSurface;
+ SP m_pWLSurface;
struct {
CSignal destroy;
@@ -393,7 +393,7 @@ class CWindow {
IHyprWindowDecoration* getDecorationByType(eDecorationType);
void removeDecorationByType(eDecorationType);
void updateToplevel();
- void updateSurfaceScaleTransformDetails();
+ void updateSurfaceScaleTransformDetails(bool force = false);
void moveToWorkspace(PHLWORKSPACE);
PHLWINDOW X11TransientFor();
void onUnmap();
diff --git a/src/devices/Tablet.cpp b/src/devices/Tablet.cpp
index f5b610a9..b5ab16c1 100644
--- a/src/devices/Tablet.cpp
+++ b/src/devices/Tablet.cpp
@@ -1,6 +1,7 @@
#include "Tablet.hpp"
#include "../defines.hpp"
#include "../protocols/Tablet.hpp"
+#include "../protocols/core/Compositor.hpp"
SP CTablet::create(wlr_tablet* tablet) {
SP pTab = SP(new CTablet(tablet));
@@ -295,32 +296,29 @@ CTabletTool::~CTabletTool() {
void CTabletTool::disconnectCallbacks() {
hyprListener_destroy.removeCallback();
- hyprListener_destroySurface.removeCallback();
+ listeners.destroySurface.reset();
}
-wlr_surface* CTabletTool::getSurface() {
- return pSurface;
+SP CTabletTool::getSurface() {
+ return pSurface.lock();
}
-void CTabletTool::setSurface(wlr_surface* surf) {
+void CTabletTool::setSurface(SP surf) {
if (surf == pSurface)
return;
if (pSurface) {
- hyprListener_destroySurface.removeCallback();
- pSurface = nullptr;
+ listeners.destroySurface.reset();
+ pSurface.reset();
}
pSurface = surf;
if (surf) {
- hyprListener_destroySurface.initCallback(
- &surf->events.destroy,
- [this](void* owner, void* data) {
- PROTO::tablet->proximityOut(self.lock());
- pSurface = nullptr;
- hyprListener_destroySurface.removeCallback();
- },
- this, "CTabletTool");
+ listeners.destroySurface = surf->events.destroy.registerListener([this](std::any d) {
+ PROTO::tablet->proximityOut(self.lock());
+ pSurface.reset();
+ listeners.destroySurface.reset();
+ });
}
}
diff --git a/src/devices/Tablet.hpp b/src/devices/Tablet.hpp
index f2444972..1805f3ba 100644
--- a/src/devices/Tablet.hpp
+++ b/src/devices/Tablet.hpp
@@ -12,6 +12,7 @@ struct wlr_tablet_pad;
class CTabletTool;
class CTabletPad;
+class CWLSurfaceResource;
/*
A tablet device
@@ -197,32 +198,35 @@ class CTabletTool : public IHID {
HID_TABLET_TOOL_CAPABILITY_WHEEL = (1 << 5),
};
- virtual uint32_t getCapabilities();
- wlr_tablet_tool* wlr();
- virtual eHIDType getType();
- wlr_surface* getSurface();
- void setSurface(wlr_surface*);
+ virtual uint32_t getCapabilities();
+ wlr_tablet_tool* wlr();
+ virtual eHIDType getType();
+ SP getSurface();
+ void setSurface(SP);
- WP self;
- Vector2D tilt;
- bool active = false; // true if in proximity
- uint32_t toolCapabilities = 0;
+ WP self;
+ Vector2D tilt;
+ bool active = false; // true if in proximity
+ uint32_t toolCapabilities = 0;
- bool isDown = false;
- std::vector buttonsDown;
- Vector2D absolutePos; // last known absolute position.
+ bool isDown = false;
+ std::vector buttonsDown;
+ Vector2D absolutePos; // last known absolute position.
- std::string hlName;
+ std::string hlName;
private:
CTabletTool(wlr_tablet_tool* tool);
- void disconnectCallbacks();
+ void disconnectCallbacks();
- wlr_surface* pSurface = nullptr;
+ WP pSurface;
- wlr_tablet_tool* tool = nullptr;
+ wlr_tablet_tool* tool = nullptr;
DYNLISTENER(destroy);
- DYNLISTENER(destroySurface);
+
+ struct {
+ CHyprSignalListener destroySurface;
+ } listeners;
};
\ No newline at end of file
diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp
index 5372a105..88b28c87 100644
--- a/src/events/Windows.cpp
+++ b/src/events/Windows.cpp
@@ -9,6 +9,7 @@
#include "../config/ConfigValue.hpp"
#include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp"
+#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp"
// ------------------------------------------------------------ //
@@ -104,7 +105,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// registers the animated vars and stuff
PWINDOW->onMap();
- const auto PWINDOWSURFACE = PWINDOW->m_pWLSurface.wlr();
+ const auto PWINDOWSURFACE = PWINDOW->m_pWLSurface->resource();
if (!PWINDOWSURFACE) {
g_pCompositor->removeWindowFromVectorSafe(PWINDOW);
@@ -463,7 +464,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// check LS focus grab
const auto PFORCEFOCUS = g_pCompositor->getForceFocus();
- const auto PLSFROMFOCUS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus);
+ const auto PLSFROMFOCUS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus.lock());
if (PLSFROMFOCUS && PLSFROMFOCUS->layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
PWINDOW->m_bNoInitialFocus = true;
if (PWINDOW->m_pWorkspace->m_bHasFullscreenWindow && !requestsFullscreen && !PWINDOW->m_bIsFloating) {
@@ -618,8 +619,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->m_bIsFullscreen && !PWINDOW->m_bIsFloating)
PWINDOW->m_fAlpha.setValueAndWarp(0.f);
- g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale);
- g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform);
+ g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->scale);
+ g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->transform);
if (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())
g_pInputManager->sendMotionEventsToFocused();
@@ -638,7 +639,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
Debug::log(LOG, "{:c} unmapped", PWINDOW);
- if (!PWINDOW->m_pWLSurface.exists() || !PWINDOW->m_bIsMapped) {
+ if (!PWINDOW->m_pWLSurface->exists() || !PWINDOW->m_bIsMapped) {
Debug::log(WARN, "{} unmapped without being mapped??", PWINDOW);
PWINDOW->m_bFadingOut = false;
return;
@@ -674,7 +675,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) {
wasLastWindow = true;
g_pCompositor->m_pLastWindow.reset();
- g_pCompositor->m_pLastFocus = nullptr;
+ g_pCompositor->m_pLastFocus.reset();
g_pInputManager->releaseAllMouseButtons();
}
@@ -788,7 +789,7 @@ void Events::listener_commitWindow(void* owner, void* data) {
if (!PWINDOW->m_pWorkspace->m_bVisible)
return;
- g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface.wlr(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
+ g_pHyprRenderer->damageSurface(PWINDOW->m_pWLSurface->resource(), PWINDOW->m_vRealPosition.goal().x, PWINDOW->m_vRealPosition.goal().y,
PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
if (!PWINDOW->m_bIsX11) {
@@ -798,9 +799,8 @@ void Events::listener_commitWindow(void* owner, void* data) {
// tearing: if solitary, redraw it. This still might be a single surface window
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
- if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear &&
- PWINDOW->m_pWLSurface.wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) {
- CRegion damageBox{&PWINDOW->m_pWLSurface.wlr()->buffer_damage};
+ if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear && PWINDOW->m_pWLSurface->resource()->current.buffer) {
+ CRegion damageBox{PWINDOW->m_pWLSurface->resource()->current.bufferDamage};
if (!damageBox.empty()) {
if (PMONITOR->tearingState.busy) {
@@ -820,10 +820,10 @@ void Events::listener_destroyWindow(void* owner, void* data) {
if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) {
g_pCompositor->m_pLastWindow.reset();
- g_pCompositor->m_pLastFocus = nullptr;
+ g_pCompositor->m_pLastFocus.reset();
}
- PWINDOW->m_pWLSurface.unassign();
+ PWINDOW->m_pWLSurface->unassign();
PWINDOW->listeners = {};
diff --git a/src/helpers/Format.cpp b/src/helpers/Format.cpp
new file mode 100644
index 00000000..3d6b7cc3
--- /dev/null
+++ b/src/helpers/Format.cpp
@@ -0,0 +1,271 @@
+#include "Format.hpp"
+#include
+#include "../includes.hpp"
+
+/*
+ DRM formats are LE, while OGL is BE. The two primary formats
+ will be flipped, so we will set flipRB which will later use swizzle
+ to flip the red and blue channels.
+ This will not work on GLES2, but I want to drop support for it one day anyways.
+*/
+inline const std::vector GLES3_FORMATS = {
+ {
+ .drmFormat = DRM_FORMAT_ARGB8888,
+ .flipRB = true,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_BYTE,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_XRGB8888,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_XRGB8888,
+ .flipRB = true,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_BYTE,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_XRGB8888,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_XBGR8888,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_BYTE,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_XBGR8888,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_ABGR8888,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_BYTE,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_XBGR8888,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_BGR888,
+ .glFormat = GL_RGB,
+ .glType = GL_UNSIGNED_BYTE,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_BGR888,
+ .bytesPerBlock = 3,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGBX4444,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_SHORT_4_4_4_4,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_RGBX4444,
+ .bytesPerBlock = 2,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGBA4444,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_SHORT_4_4_4_4,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_RGBX4444,
+ .bytesPerBlock = 2,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGBX5551,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_SHORT_5_5_5_1,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_RGBX5551,
+ .bytesPerBlock = 2,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGBA5551,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_SHORT_5_5_5_1,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_RGBX5551,
+ .bytesPerBlock = 2,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGB565,
+ .glFormat = GL_RGB,
+ .glType = GL_UNSIGNED_SHORT_5_6_5,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_RGB565,
+ .bytesPerBlock = 2,
+ },
+ {
+ .drmFormat = DRM_FORMAT_XBGR2101010,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_XBGR2101010,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_ABGR2101010,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_XBGR2101010,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_XRGB2101010,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_XRGB2101010,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_ARGB2101010,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_XRGB2101010,
+ .bytesPerBlock = 4,
+ },
+ {
+ .drmFormat = DRM_FORMAT_XBGR16161616F,
+ .glFormat = GL_RGBA,
+ .glType = GL_HALF_FLOAT,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_XBGR16161616F,
+ .bytesPerBlock = 8,
+ },
+ {
+ .drmFormat = DRM_FORMAT_ABGR16161616F,
+ .glFormat = GL_RGBA,
+ .glType = GL_HALF_FLOAT,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_XBGR16161616F,
+ .bytesPerBlock = 8,
+ },
+ {
+ .drmFormat = DRM_FORMAT_XBGR16161616,
+ .glInternalFormat = GL_RGBA16UI,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_SHORT,
+ .withAlpha = false,
+ .alphaStripped = DRM_FORMAT_XBGR16161616,
+ .bytesPerBlock = 8,
+ },
+ {
+ .drmFormat = DRM_FORMAT_ABGR16161616,
+ .glInternalFormat = GL_RGBA16UI,
+ .glFormat = GL_RGBA,
+ .glType = GL_UNSIGNED_SHORT,
+ .withAlpha = true,
+ .alphaStripped = DRM_FORMAT_XBGR16161616,
+ .bytesPerBlock = 8,
+ },
+ {
+ .drmFormat = DRM_FORMAT_YVYU,
+ .bytesPerBlock = 4,
+ .blockSize = {2, 1},
+ },
+ {
+ .drmFormat = DRM_FORMAT_VYUY,
+ .bytesPerBlock = 4,
+ .blockSize = {2, 1},
+ },
+ {
+ .drmFormat = DRM_FORMAT_R8,
+ .bytesPerBlock = 1,
+ },
+ {
+ .drmFormat = DRM_FORMAT_GR88,
+ .bytesPerBlock = 2,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGB888,
+ .bytesPerBlock = 3,
+ },
+ {
+ .drmFormat = DRM_FORMAT_BGR888,
+ .bytesPerBlock = 3,
+ },
+ {
+ .drmFormat = DRM_FORMAT_RGBX4444,
+ .bytesPerBlock = 2,
+ },
+};
+
+SHMFormat FormatUtils::drmToShm(DRMFormat drm) {
+ switch (drm) {
+ case DRM_FORMAT_XRGB8888: return WL_SHM_FORMAT_XRGB8888;
+ case DRM_FORMAT_ARGB8888: return WL_SHM_FORMAT_ARGB8888;
+ default: return drm;
+ }
+
+ return drm;
+}
+
+DRMFormat FormatUtils::shmToDRM(SHMFormat shm) {
+ switch (shm) {
+ case WL_SHM_FORMAT_XRGB8888: return DRM_FORMAT_XRGB8888;
+ case WL_SHM_FORMAT_ARGB8888: return DRM_FORMAT_ARGB8888;
+ default: return shm;
+ }
+
+ return shm;
+}
+
+const SPixelFormat* FormatUtils::getPixelFormatFromDRM(DRMFormat drm) {
+ for (auto& fmt : GLES3_FORMATS) {
+ if (fmt.drmFormat == drm)
+ return &fmt;
+ }
+
+ return nullptr;
+}
+
+const SPixelFormat* FormatUtils::getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha) {
+ for (auto& fmt : GLES3_FORMATS) {
+ if (fmt.glFormat == (int)glFormat && fmt.glType == (int)glType && fmt.withAlpha == alpha)
+ return &fmt;
+ }
+
+ return nullptr;
+}
+
+bool FormatUtils::isFormatOpaque(DRMFormat drm) {
+ const auto FMT = FormatUtils::getPixelFormatFromDRM(drm);
+ if (!FMT)
+ return false;
+
+ return !FMT->withAlpha;
+}
+
+int FormatUtils::pixelsPerBlock(const SPixelFormat* const fmt) {
+ return fmt->blockSize.x * fmt->blockSize.y > 0 ? fmt->blockSize.x * fmt->blockSize.y : 1;
+}
+
+int FormatUtils::minStride(const SPixelFormat* const fmt, int32_t width) {
+ return std::ceil((width * fmt->bytesPerBlock) / pixelsPerBlock(fmt));
+}
+
+uint32_t FormatUtils::drmFormatToGL(DRMFormat drm) {
+ switch (drm) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888: return GL_RGBA; // doesn't matter, opengl is gucci in this case.
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+#ifdef GLES2
+ return GL_RGB10_A2_EXT;
+#else
+ return GL_RGB10_A2;
+#endif
+ default: return GL_RGBA;
+ }
+ UNREACHABLE();
+ return GL_RGBA;
+}
+
+uint32_t FormatUtils::glFormatToType(uint32_t gl) {
+ return gl != GL_RGBA ?
+#ifdef GLES2
+ GL_UNSIGNED_INT_2_10_10_10_REV_EXT :
+#else
+ GL_UNSIGNED_INT_2_10_10_10_REV :
+#endif
+ GL_UNSIGNED_BYTE;
+}
diff --git a/src/helpers/Format.hpp b/src/helpers/Format.hpp
new file mode 100644
index 00000000..b86f44dd
--- /dev/null
+++ b/src/helpers/Format.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include
+#include "Vector2D.hpp"
+
+typedef uint32_t DRMFormat;
+typedef uint32_t SHMFormat;
+
+struct SPixelFormat {
+ DRMFormat drmFormat = 0; /* DRM_FORMAT_INVALID */
+ bool flipRB = false;
+ int glInternalFormat = 0;
+ int glFormat = 0;
+ int glType = 0;
+ bool withAlpha = true;
+ DRMFormat alphaStripped = 0; /* DRM_FORMAT_INVALID */
+ uint32_t bytesPerBlock = 0;
+ Vector2D blockSize;
+};
+
+struct SDRMFormat {
+ uint32_t format = 0;
+ std::vector mods;
+};
+
+namespace FormatUtils {
+ SHMFormat drmToShm(DRMFormat drm);
+ DRMFormat shmToDRM(SHMFormat shm);
+
+ const SPixelFormat* getPixelFormatFromDRM(DRMFormat drm);
+ const SPixelFormat* getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha);
+ bool isFormatOpaque(DRMFormat drm);
+ int pixelsPerBlock(const SPixelFormat* const fmt);
+ int minStride(const SPixelFormat* const fmt, int32_t width);
+ uint32_t drmFormatToGL(DRMFormat drm);
+ uint32_t glFormatToType(uint32_t gl);
+};
diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp
index a520c9d4..32cd9868 100644
--- a/src/helpers/MiscFunctions.cpp
+++ b/src/helpers/MiscFunctions.cpp
@@ -857,33 +857,6 @@ void throwError(const std::string& err) {
throw std::runtime_error(err);
}
-uint32_t drmFormatToGL(uint32_t drm) {
- switch (drm) {
- case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_XBGR8888: return GL_RGBA; // doesn't matter, opengl is gucci in this case.
- case DRM_FORMAT_XRGB2101010:
- case DRM_FORMAT_XBGR2101010:
-#ifdef GLES2
- return GL_RGB10_A2_EXT;
-#else
- return GL_RGB10_A2;
-#endif
- default: return GL_RGBA;
- }
- UNREACHABLE();
- return GL_RGBA;
-}
-
-uint32_t glFormatToType(uint32_t gl) {
- return gl != GL_RGBA ?
-#ifdef GLES2
- GL_UNSIGNED_INT_2_10_10_10_REV_EXT :
-#else
- GL_UNSIGNED_INT_2_10_10_10_REV :
-#endif
- GL_UNSIGNED_BYTE;
-}
-
bool envEnabled(const std::string& env) {
const auto ENV = getenv(env.c_str());
if (!ENV)
@@ -922,3 +895,42 @@ int allocateSHMFile(size_t len) {
return fd;
}
+
+bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr) {
+ auto [fd, name] = openExclusiveShm();
+ if (fd < 0) {
+ return false;
+ }
+
+ // CLOEXEC is guaranteed to be set by shm_open
+ int ro_fd = shm_open(name.c_str(), O_RDONLY, 0);
+ if (ro_fd < 0) {
+ shm_unlink(name.c_str());
+ close(fd);
+ return false;
+ }
+
+ shm_unlink(name.c_str());
+
+ // Make sure the file cannot be re-opened in read-write mode (e.g. via
+ // "/proc/self/fd/" on Linux)
+ if (fchmod(fd, 0) != 0) {
+ close(fd);
+ close(ro_fd);
+ return false;
+ }
+
+ int ret;
+ do {
+ ret = ftruncate(fd, size);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0) {
+ close(fd);
+ close(ro_fd);
+ return false;
+ }
+
+ *rw_fd_ptr = fd;
+ *ro_fd_ptr = ro_fd;
+ return true;
+}
diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp
index 80103eac..9d34174c 100644
--- a/src/helpers/MiscFunctions.hpp
+++ b/src/helpers/MiscFunctions.hpp
@@ -35,10 +35,9 @@ double normalizeAngleRad(double ang);
std::string replaceInString(std::string subject, const std::string& search, const std::string& replace);
std::vector getBacktrace();
void throwError(const std::string& err);
-uint32_t drmFormatToGL(uint32_t drm);
-uint32_t glFormatToType(uint32_t gl);
bool envEnabled(const std::string& env);
int allocateSHMFile(size_t len);
+bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr);
template
[[deprecated("use std::format instead")]] std::string getFormat(std::format_string fmt, Args&&... args) {
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp
index d13acf0c..5962b73d 100644
--- a/src/helpers/Monitor.cpp
+++ b/src/helpers/Monitor.cpp
@@ -216,7 +216,6 @@ void CMonitor::onConnect(bool noRule) {
PROTO::gamma->applyGammaToState(this);
events.connect.emit();
- updateGlobal();
}
void CMonitor::onDisconnect(bool destroy) {
@@ -284,8 +283,6 @@ void CMonitor::onDisconnect(bool destroy) {
m_bEnabled = false;
m_bRenderingInitPassed = false;
- updateGlobal();
-
if (BACKUPMON) {
// snap cursor
g_pCompositor->warpCursorTo(BACKUPMON->vecPosition + BACKUPMON->vecTransformedSize / 2.F, true);
@@ -304,7 +301,7 @@ void CMonitor::onDisconnect(bool destroy) {
w->startAnim(true, true, true);
}
} else {
- g_pCompositor->m_pLastFocus = nullptr;
+ g_pCompositor->m_pLastFocus.reset();
g_pCompositor->m_pLastWindow.reset();
g_pCompositor->m_pLastMonitor.reset();
}
@@ -750,13 +747,6 @@ CBox CMonitor::logicalBox() {
return {vecPosition, vecSize};
}
-void CMonitor::updateGlobal() {
- if (output->width > 0 && output->height > 0 && m_bEnabled)
- wlr_output_create_global(output, g_pCompositor->m_sWLDisplay);
- else
- wlr_output_destroy_global(output);
-}
-
CMonitorState::CMonitorState(CMonitor* owner) {
m_pOwner = owner;
wlr_output_state_init(&m_state);
diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp
index e4456084..4bfbf53c 100644
--- a/src/helpers/Monitor.hpp
+++ b/src/helpers/Monitor.hpp
@@ -172,7 +172,6 @@ class CMonitor {
int64_t activeWorkspaceID();
int64_t activeSpecialWorkspaceID();
CBox logicalBox();
- void updateGlobal();
bool m_bEnabled = false;
bool m_bRenderingInitPassed = false;
diff --git a/src/helpers/Region.cpp b/src/helpers/Region.cpp
index 20eaf452..9e572b34 100644
--- a/src/helpers/Region.cpp
+++ b/src/helpers/Region.cpp
@@ -4,6 +4,8 @@ extern "C" {
#include
}
+constexpr const int64_t MAX_REGION_SIDE = 10000000;
+
CRegion::CRegion() {
pixman_region32_init(&m_rRegion);
}
@@ -103,6 +105,11 @@ CRegion& CRegion::transform(const wl_output_transform t, double w, double h) {
return *this;
}
+CRegion& CRegion::rationalize() {
+ intersect(CBox{-MAX_REGION_SIDE, -MAX_REGION_SIDE, MAX_REGION_SIDE * 2, MAX_REGION_SIDE * 2});
+ return *this;
+}
+
CRegion CRegion::copy() const {
return CRegion(*this);
}
diff --git a/src/helpers/Region.hpp b/src/helpers/Region.hpp
index 27f460f4..42693c21 100644
--- a/src/helpers/Region.hpp
+++ b/src/helpers/Region.hpp
@@ -50,6 +50,7 @@ class CRegion {
CRegion& invert(const CBox& box);
CRegion& scale(float scale);
CRegion& scale(const Vector2D& scale);
+ CRegion& rationalize();
CBox getExtents();
bool containsPoint(const Vector2D& vec) const;
bool empty() const;
diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp
index 30f5aebf..d5be9f40 100644
--- a/src/helpers/WLClasses.hpp
+++ b/src/helpers/WLClasses.hpp
@@ -13,6 +13,7 @@
class CMonitor;
class IPointer;
class IKeyboard;
+class CWLSurfaceResource;
struct SRenderData {
CMonitor* pMonitor;
@@ -20,9 +21,9 @@ struct SRenderData {
double x, y;
// for iters
- void* data = nullptr;
- wlr_surface* surface = nullptr;
- double w, h;
+ void* data = nullptr;
+ SP surface = nullptr;
+ double w, h;
// for rounding
bool dontRound = true;
@@ -52,12 +53,6 @@ struct SRenderData {
bool popup = false;
};
-struct SExtensionFindingData {
- Vector2D origin;
- Vector2D vec;
- wlr_surface** found;
-};
-
struct SSwipeGesture {
PHLWORKSPACE pWorkspaceBegin = nullptr;
diff --git a/src/helpers/memory/SharedPtr.hpp b/src/helpers/memory/SharedPtr.hpp
index 77f5164a..02900911 100644
--- a/src/helpers/memory/SharedPtr.hpp
+++ b/src/helpers/memory/SharedPtr.hpp
@@ -60,7 +60,7 @@ namespace CSharedPointer_ {
bool _destroying = false;
void _destroy() {
- if (!_data)
+ if (!_data || _destroying)
return;
// first, we destroy the data, but keep the pointer.
@@ -297,6 +297,6 @@ static CSharedPointer makeShared(Args&&... args) {
template
struct std::hash> {
std::size_t operator()(const CSharedPointer& p) const noexcept {
- return std::hash{}(p->impl_);
+ return std::hash{}(p.impl_);
}
};
diff --git a/src/helpers/memory/WeakPtr.hpp b/src/helpers/memory/WeakPtr.hpp
index f0e72146..872f8e55 100644
--- a/src/helpers/memory/WeakPtr.hpp
+++ b/src/helpers/memory/WeakPtr.hpp
@@ -185,6 +185,6 @@ class CWeakPointer {
template
struct std::hash> {
std::size_t operator()(const CWeakPointer& p) const noexcept {
- return std::hash{}(p->impl_);
+ return std::hash{}(p.impl_);
}
};
diff --git a/src/helpers/signal/Signal.cpp b/src/helpers/signal/Signal.cpp
index fdd2cc23..fd2d11c8 100644
--- a/src/helpers/signal/Signal.cpp
+++ b/src/helpers/signal/Signal.cpp
@@ -2,19 +2,40 @@
#include
void CSignal::emit(std::any data) {
- bool dirty = false;
+ bool dirty = false;
+ std::vector> listeners;
for (auto& l : m_vListeners) {
- if (const CHyprSignalListener L = l.lock())
- L->emit(data);
- else
+ if (l.expired()) {
dirty = true;
+ continue;
+ }
+
+ listeners.emplace_back(l.lock());
}
+ std::vector statics;
for (auto& l : m_vStaticListeners) {
+ statics.emplace_back(l.get());
+ }
+
+ for (auto& l : listeners) {
+ // if there is only one lock, it means the event is only held by the listeners
+ // vector and was removed during our iteration
+ if (l.strongRef() == 1) {
+ dirty = true;
+ continue;
+ }
l->emit(data);
}
+ for (auto& l : statics) {
+ l->emit(data);
+ }
+
+ // release SPs
+ listeners.clear();
+
if (dirty)
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
}
diff --git a/src/hyprerror/HyprError.cpp b/src/hyprerror/HyprError.cpp
index d147a6bb..a325d858 100644
--- a/src/hyprerror/HyprError.cpp
+++ b/src/hyprerror/HyprError.cpp
@@ -22,6 +22,8 @@ CHyprError::CHyprError() {
if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged)
g_pHyprRenderer->damageBox(&m_bDamageBox);
});
+
+ m_pTexture = makeShared();
}
CHyprError::~CHyprError() {
@@ -34,9 +36,8 @@ void CHyprError::queueCreate(std::string message, const CColor& color) {
}
void CHyprError::createQueued() {
- if (m_bIsCreated) {
- m_tTexture.destroyTexture();
- }
+ if (m_bIsCreated)
+ m_pTexture->destroyTexture();
m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
@@ -136,8 +137,8 @@ void CHyprError::createQueued() {
// copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
- m_tTexture.allocate();
- glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID);
+ m_pTexture->allocate();
+ glBindTexture(GL_TEXTURE_2D, m_pTexture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -170,7 +171,7 @@ void CHyprError::draw() {
if (!m_fFadeOpacity.isBeingAnimated()) {
if (m_fFadeOpacity.value() == 0.f) {
m_bQueuedDestroy = false;
- m_tTexture.destroyTexture();
+ m_pTexture->destroyTexture();
m_bIsCreated = false;
m_szQueued = "";
return;
@@ -193,7 +194,7 @@ void CHyprError::draw() {
m_bMonitorChanged = false;
- g_pHyprOpenGL->renderTexture(m_tTexture, &monbox, m_fFadeOpacity.value(), 0);
+ g_pHyprOpenGL->renderTexture(m_pTexture, &monbox, m_fFadeOpacity.value(), 0);
}
void CHyprError::destroy() {
diff --git a/src/hyprerror/HyprError.hpp b/src/hyprerror/HyprError.hpp
index aaa8bd12..8dbb4521 100644
--- a/src/hyprerror/HyprError.hpp
+++ b/src/hyprerror/HyprError.hpp
@@ -21,7 +21,7 @@ class CHyprError {
CColor m_cQueued;
bool m_bQueuedDestroy = false;
bool m_bIsCreated = false;
- CTexture m_tTexture;
+ SP m_pTexture;
CAnimatedVariable m_fFadeOpacity;
CBox m_bDamageBox = {0, 0, 0, 0};
diff --git a/src/layout/IHyprLayout.cpp b/src/layout/IHyprLayout.cpp
index 7fadf188..b4270bb8 100644
--- a/src/layout/IHyprLayout.cpp
+++ b/src/layout/IHyprLayout.cpp
@@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp"
#include "../desktop/Window.hpp"
#include "../protocols/XDGShell.hpp"
+#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp"
void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
@@ -99,8 +100,8 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
}
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
- const auto PWINDOWSURFACE = pWindow->m_pWLSurface.wlr();
- pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height);
+ const auto PWINDOWSURFACE = pWindow->m_pWLSurface->resource();
+ pWindow->m_vRealSize = PWINDOWSURFACE->current.size;
if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 &&
pWindow->m_iX11Type == 2) { // XDG windows should be fine. TODO: check for weird atoms?
diff --git a/src/macros.hpp b/src/macros.hpp
index 66dfe783..4c6d621c 100644
--- a/src/macros.hpp
+++ b/src/macros.hpp
@@ -89,4 +89,14 @@
}
#else
#define UNREACHABLE() std::unreachable();
-#endif
\ No newline at end of file
+#endif
+
+#define GLCALL(__CALL__) \
+ { \
+ __CALL__; \
+ auto err = glGetError(); \
+ if (err != GL_NO_ERROR) { \
+ Debug::log(ERR, "[GLES] Error in call at {}@{}: 0x{:x}", __LINE__, \
+ ([]() constexpr -> std::string { return std::string(__FILE__).substr(std::string(__FILE__).find_last_of('/') + 1); })(), err); \
+ } \
+ }
diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp
index cb43f0b9..c3c48d2f 100644
--- a/src/managers/CursorManager.cpp
+++ b/src/managers/CursorManager.cpp
@@ -114,8 +114,8 @@ wlr_buffer* CCursorManager::getCursorBuffer() {
return !m_vCursorBuffers.empty() ? &m_vCursorBuffers.back()->wlrBuffer.base : nullptr;
}
-void CCursorManager::setCursorSurface(CWLSurface* surf, const Vector2D& hotspot) {
- if (!surf || !surf->wlr())
+void CCursorManager::setCursorSurface(SP surf, const Vector2D& hotspot) {
+ if (!surf || !surf->resource())
g_pPointerManager->resetCursorImage();
else
g_pPointerManager->setCursorSurface(surf, hotspot);
diff --git a/src/managers/CursorManager.hpp b/src/managers/CursorManager.hpp
index e76b6829..6fbff636 100644
--- a/src/managers/CursorManager.hpp
+++ b/src/managers/CursorManager.hpp
@@ -18,7 +18,7 @@ class CCursorManager {
wlr_buffer* getCursorBuffer();
void setCursorFromName(const std::string& name);
- void setCursorSurface(CWLSurface* surf, const Vector2D& hotspot);
+ void setCursorSurface(SP surf, const Vector2D& hotspot);
void setXCursor(const std::string& name);
bool changeTheme(const std::string& name, const int size);
diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp
index 905a9d48..260548c0 100644
--- a/src/managers/KeybindManager.cpp
+++ b/src/managers/KeybindManager.cpp
@@ -1984,14 +1984,14 @@ void CKeybindManager::pass(std::string regexp) {
}
const auto XWTOXW = PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow.lock() && g_pCompositor->m_pLastWindow->m_bIsX11;
- const auto LASTSRF = g_pCompositor->m_pLastFocus;
+ const auto LASTSRF = g_pCompositor->m_pLastFocus.lock();
// pass all mf shit
if (!XWTOXW) {
if (g_pKeybindManager->m_uLastCode != 0)
- g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface.wlr());
+ g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface->resource());
else
- g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), {1, 1});
+ g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface->resource(), {1, 1});
}
g_pSeatManager->sendKeyboardMods(g_pInputManager->accumulateModsFromAllKBs(), 0, 0, 0);
@@ -2025,10 +2025,10 @@ void CKeybindManager::pass(std::string regexp) {
// please kill me
if (PWINDOW->m_bIsX11) {
if (g_pKeybindManager->m_uLastCode != 0) {
- g_pSeatManager->state.keyboardFocus = nullptr;
+ g_pSeatManager->state.keyboardFocus.reset();
g_pSeatManager->state.keyboardFocusResource.reset();
} else {
- g_pSeatManager->state.pointerFocus = nullptr;
+ g_pSeatManager->state.pointerFocus.reset();
g_pSeatManager->state.pointerFocusResource.reset();
}
}
@@ -2038,7 +2038,7 @@ void CKeybindManager::pass(std::string regexp) {
if (g_pKeybindManager->m_uLastCode != 0)
g_pSeatManager->setKeyboardFocus(LASTSRF);
else
- g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), SL);
+ g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface->resource(), SL);
}
void CKeybindManager::sendshortcut(std::string args) {
@@ -2117,7 +2117,7 @@ void CKeybindManager::sendshortcut(std::string args) {
const std::string regexp = ARGS[2];
PHLWINDOW PWINDOW = nullptr;
- const auto LASTSURFACE = g_pCompositor->m_pLastFocus;
+ const auto LASTSURFACE = g_pCompositor->m_pLastFocus.lock();
//if regexp is not empty, send shortcut to current window
//else, dont change focus
@@ -2135,15 +2135,15 @@ void CKeybindManager::sendshortcut(std::string args) {
}
if (!isMouse)
- g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface.wlr());
+ g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface->resource());
else
- g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), {1, 1});
+ g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface->resource(), {1, 1});
}
//copied the rest from pass and modified it
// if wl -> xwl, activate destination
if (PWINDOW && PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsX11)
- g_pXWaylandManager->activateSurface(PWINDOW->m_pWLSurface.wlr(), true);
+ g_pXWaylandManager->activateSurface(PWINDOW->m_pWLSurface->resource(), true);
// if xwl -> xwl, send to current. Timing issues make this not work.
if (PWINDOW && PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsX11)
PWINDOW = nullptr;
@@ -2176,10 +2176,10 @@ void CKeybindManager::sendshortcut(std::string args) {
if (PWINDOW->m_bIsX11) { //xwayland hack, see pass
if (!isMouse) {
- g_pSeatManager->state.keyboardFocus = nullptr;
+ g_pSeatManager->state.keyboardFocus.reset();
g_pSeatManager->state.keyboardFocusResource.reset();
} else {
- g_pSeatManager->state.pointerFocus = nullptr;
+ g_pSeatManager->state.pointerFocus.reset();
g_pSeatManager->state.pointerFocusResource.reset();
}
}
diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp
index 66d12076..80a7ee76 100644
--- a/src/managers/PointerManager.cpp
+++ b/src/managers/PointerManager.cpp
@@ -3,6 +3,7 @@
#include "../config/ConfigValue.hpp"
#include "../protocols/PointerGestures.hpp"
#include "../protocols/FractionalScale.hpp"
+#include "../protocols/core/Compositor.hpp"
#include "SeatManager.hpp"
#include
#include
@@ -212,13 +213,13 @@ void CPointerManager::setCursorBuffer(wlr_buffer* buf, const Vector2D& hotspot,
damageIfSoftware();
}
-void CPointerManager::setCursorSurface(CWLSurface* surf, const Vector2D& hotspot) {
+void CPointerManager::setCursorSurface(SP surf, const Vector2D& hotspot) {
damageIfSoftware();
if (surf == currentCursorImage.surface) {
- if (hotspot != currentCursorImage.hotspot || (surf && surf->wlr() ? surf->wlr()->current.scale : 1.F) != currentCursorImage.scale) {
+ if (hotspot != currentCursorImage.hotspot || (surf && surf->resource() ? surf->resource()->current.scale : 1.F) != currentCursorImage.scale) {
currentCursorImage.hotspot = hotspot;
- currentCursorImage.scale = surf && surf->wlr() ? surf->wlr()->current.scale : 1.F;
+ currentCursorImage.scale = surf && surf->resource() ? surf->resource()->current.scale : 1.F;
updateCursorBackend();
damageIfSoftware();
}
@@ -229,27 +230,24 @@ void CPointerManager::setCursorSurface(CWLSurface* surf, const Vector2D& hotspot
resetCursorImage(false);
if (surf) {
- currentCursorImage.size = {surf->wlr()->current.buffer_width, surf->wlr()->current.buffer_height};
currentCursorImage.surface = surf;
- currentCursorImage.scale = surf->wlr()->current.scale;
+ currentCursorImage.scale = surf->resource()->current.scale;
currentCursorImage.destroySurface = surf->events.destroy.registerListener([this](std::any data) { resetCursorImage(); });
- currentCursorImage.hyprListener_commitSurface.initCallback(
- &surf->wlr()->events.commit,
- [this](void* owner, void* data) {
- damageIfSoftware();
- currentCursorImage.size = {currentCursorImage.surface->wlr()->current.buffer_width, currentCursorImage.surface->wlr()->current.buffer_height};
- currentCursorImage.scale = currentCursorImage.surface && currentCursorImage.surface->wlr() ? currentCursorImage.surface->wlr()->current.scale : 1.F;
- recheckEnteredOutputs();
- updateCursorBackend();
- damageIfSoftware();
- },
- nullptr, "CPointerManager");
+ currentCursorImage.commitSurface = surf->resource()->events.commit.registerListener([this](std::any data) {
+ damageIfSoftware();
+ currentCursorImage.size = currentCursorImage.surface->resource()->current.buffer ? currentCursorImage.surface->resource()->current.buffer->size : Vector2D{};
+ currentCursorImage.scale = currentCursorImage.surface ? currentCursorImage.surface->resource()->current.scale : 1.F;
+ recheckEnteredOutputs();
+ updateCursorBackend();
+ damageIfSoftware();
+ });
- if (wlr_surface_has_buffer(surf->wlr())) {
+ if (surf->resource()->current.buffer) {
+ currentCursorImage.size = surf->resource()->current.buffer->size;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
- wlr_surface_send_frame_done(surf->wlr(), &now);
+ surf->resource()->frame(&now);
}
}
@@ -278,9 +276,9 @@ void CPointerManager::recheckEnteredOutputs() {
if (!currentCursorImage.surface)
continue;
- wlr_surface_send_enter(currentCursorImage.surface->wlr(), s->monitor->output);
- PROTO::fractional->sendScale(currentCursorImage.surface->wlr(), s->monitor->scale);
- g_pCompositor->setPreferredScaleForSurface(currentCursorImage.surface->wlr(), s->monitor->scale);
+ currentCursorImage.surface->resource()->enter(s->monitor.lock());
+ PROTO::fractional->sendScale(currentCursorImage.surface->resource(), s->monitor->scale);
+ g_pCompositor->setPreferredScaleForSurface(currentCursorImage.surface->resource(), s->monitor->scale);
} else if (s->entered && !overlaps) {
s->entered = false;
@@ -293,7 +291,7 @@ void CPointerManager::recheckEnteredOutputs() {
if (!currentCursorImage.surface)
continue;
- wlr_surface_send_leave(currentCursorImage.surface->wlr(), s->monitor->output);
+ currentCursorImage.surface->resource()->leave(s->monitor.lock());
}
}
}
@@ -303,12 +301,12 @@ void CPointerManager::resetCursorImage(bool apply) {
if (currentCursorImage.surface) {
for (auto& m : g_pCompositor->m_vMonitors) {
- wlr_surface_send_leave(currentCursorImage.surface->wlr(), m->output);
+ currentCursorImage.surface->resource()->leave(m);
}
currentCursorImage.destroySurface.reset();
- currentCursorImage.hyprListener_commitSurface.removeCallback();
- currentCursorImage.surface = nullptr;
+ currentCursorImage.commitSurface.reset();
+ currentCursorImage.surface.reset();
} else if (currentCursorImage.pBuffer) {
wlr_buffer_unlock(currentCursorImage.pBuffer);
currentCursorImage.hyprListener_destroyBuffer.removeCallback();
@@ -451,7 +449,7 @@ bool CPointerManager::setHWCursorBuffer(SP state, wlr_buff
return true;
}
-wlr_buffer* CPointerManager::renderHWCursorBuffer(SP state, wlr_texture* texture) {
+wlr_buffer* CPointerManager::renderHWCursorBuffer(SP state, SP texture) {
auto output = state->monitor->output;
int w = currentCursorImage.size.x, h = currentCursorImage.size.y;
@@ -528,7 +526,7 @@ void CPointerManager::renderSoftwareCursorsFor(SP pMonitor, timespec*
if ((!state->hardwareFailed && state->softwareLocks == 0)) {
if (currentCursorImage.surface)
- wlr_surface_send_frame_done(currentCursorImage.surface->wlr(), now);
+ currentCursorImage.surface->resource()->frame(now);
return;
}
@@ -550,7 +548,7 @@ void CPointerManager::renderSoftwareCursorsFor(SP pMonitor, timespec*
g_pHyprOpenGL->renderTextureWithDamage(texture, &box, &damage, 1.F);
if (currentCursorImage.surface)
- wlr_surface_send_frame_done(currentCursorImage.surface->wlr(), now);
+ currentCursorImage.surface->resource()->frame(now);
}
Vector2D CPointerManager::getCursorPosForMonitor(SP pMonitor) {
@@ -762,17 +760,19 @@ void CPointerManager::onMonitorLayoutChange() {
damageIfSoftware();
}
-wlr_texture* CPointerManager::getCurrentCursorTexture() {
- if (!currentCursorImage.pBuffer && (!currentCursorImage.surface || !wlr_surface_get_texture(currentCursorImage.surface->wlr())))
+SP CPointerManager::getCurrentCursorTexture() {
+ if (!currentCursorImage.pBuffer && (!currentCursorImage.surface || !currentCursorImage.surface->resource()->current.buffer))
return nullptr;
if (currentCursorImage.pBuffer) {
- if (!currentCursorImage.pBufferTexture)
+ if (!currentCursorImage.pBufferTexture) {
currentCursorImage.pBufferTexture = wlr_texture_from_buffer(g_pCompositor->m_sWLRRenderer, currentCursorImage.pBuffer);
- return currentCursorImage.pBufferTexture;
+ currentCursorImage.bufferTex = makeShared(currentCursorImage.pBufferTexture);
+ }
+ return currentCursorImage.bufferTex;
}
- return wlr_surface_get_texture(currentCursorImage.surface->wlr());
+ return currentCursorImage.surface->resource()->current.buffer->texture;
}
void CPointerManager::attachPointer(SP pointer) {
diff --git a/src/managers/PointerManager.hpp b/src/managers/PointerManager.hpp
index b6cb0c7a..d9c75e7b 100644
--- a/src/managers/PointerManager.hpp
+++ b/src/managers/PointerManager.hpp
@@ -11,6 +11,7 @@
class CMonitor;
struct wlr_input_device;
class IHID;
+class CTexture;
/*
The naming here is a bit confusing.
@@ -37,7 +38,7 @@ class CPointerManager {
void warpAbsolute(Vector2D abs, SP dev);
void setCursorBuffer(wlr_buffer* buf, const Vector2D& hotspot, const float& scale);
- void setCursorSurface(CWLSurface* buf, const Vector2D& hotspot);
+ void setCursorSurface(SP buf, const Vector2D& hotspot);
void resetCursorImage(bool apply = true);
void lockSoftwareForMonitor(SP pMonitor);
@@ -76,7 +77,7 @@ class CPointerManager {
Vector2D transformedHotspot(SP pMonitor);
- wlr_texture* getCurrentCursorTexture();
+ SP getCurrentCursorTexture();
struct SPointerListener {
CHyprSignalListener destroy;
@@ -129,8 +130,9 @@ class CPointerManager {
} currentMonitorLayout;
struct {
- wlr_buffer* pBuffer = nullptr;
- CWLSurface* surface = nullptr;
+ wlr_buffer* pBuffer = nullptr;
+ SP bufferTex;
+ WP surface;
wlr_texture* pBufferTexture = nullptr;
Vector2D hotspot;
@@ -138,7 +140,7 @@ class CPointerManager {
float scale = 1.F;
CHyprSignalListener destroySurface;
- DYNLISTENER(commitSurface);
+ CHyprSignalListener commitSurface;
DYNLISTENER(destroyBuffer);
} currentCursorImage; // TODO: support various sizes per-output so we can have pixel-perfect cursors
@@ -160,7 +162,7 @@ class CPointerManager {
std::vector> monitorStates;
SP stateFor(SP mon);
bool attemptHardwareCursor(SP state);
- wlr_buffer* renderHWCursorBuffer(SP state, wlr_texture* texture);
+ wlr_buffer* renderHWCursorBuffer(SP state, SP texture);
bool setHWCursorBuffer(SP state, wlr_buffer* buf);
struct {
diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp
index feff69e0..bd435b27 100644
--- a/src/managers/ProtocolManager.cpp
+++ b/src/managers/ProtocolManager.cpp
@@ -32,17 +32,45 @@
#include "../protocols/DataDeviceWlr.hpp"
#include "../protocols/PrimarySelection.hpp"
#include "../protocols/XWaylandShell.hpp"
+#include "../protocols/Viewporter.hpp"
+#include "../protocols/MesaDRM.hpp"
+#include "../protocols/LinuxDMABUF.hpp"
#include "../protocols/core/Seat.hpp"
#include "../protocols/core/DataDevice.hpp"
+#include "../protocols/core/Compositor.hpp"
+#include "../protocols/core/Subcompositor.hpp"
+#include "../protocols/core/Output.hpp"
+#include "../protocols/core/Shm.hpp"
+
+#include "../helpers/Monitor.hpp"
CProtocolManager::CProtocolManager() {
+ // Outputs are a bit dumb, we have to agree.
+ static auto P = g_pHookSystem->hookDynamic("monitorAdded", [](void* self, SCallbackInfo& info, std::any param) {
+ auto M = std::any_cast(param);
+ if (PROTO::outputs.contains(M->szName))
+ PROTO::outputs.erase(M->szName);
+ PROTO::outputs.emplace(M->szName, std::make_unique(&wl_output_interface, 4, std::format("WLOutput ({})", M->szName), M->self.lock()));
+ });
+
+ static auto P2 = g_pHookSystem->hookDynamic("monitorRemoved", [](void* self, SCallbackInfo& info, std::any param) {
+ auto M = std::any_cast(param);
+ if (!PROTO::outputs.contains(M->szName))
+ return;
+ PROTO::outputs.at(M->szName)->remove();
+ });
+
// Core
- PROTO::seat = std::make_unique(&wl_seat_interface, 9, "WLSeat");
- PROTO::data = std::make_unique(&wl_data_device_manager_interface, 3, "WLDataDevice");
+ PROTO::seat = std::make_unique(&wl_seat_interface, 9, "WLSeat");
+ PROTO::data = std::make_unique(&wl_data_device_manager_interface, 3, "WLDataDevice");
+ PROTO::compositor = std::make_unique(&wl_compositor_interface, 6, "WLCompositor");
+ PROTO::subcompositor = std::make_unique(&wl_subcompositor_interface, 1, "WLSubcompositor");
+ PROTO::shm = std::make_unique(&wl_shm_interface, 1, "WLSHM");
// Extensions
+ PROTO::viewport = std::make_unique(&wp_viewporter_interface, 1, "Viewporter");
PROTO::tearing = std::make_unique(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
PROTO::fractional = std::make_unique(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
PROTO::xdgOutput = std::make_unique(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
@@ -75,6 +103,8 @@ CProtocolManager::CProtocolManager() {
PROTO::dataWlr = std::make_unique(&zwlr_data_control_manager_v1_interface, 2, "DataDeviceWlr");
PROTO::primarySelection = std::make_unique(&zwp_primary_selection_device_manager_v1_interface, 1, "PrimarySelection");
PROTO::xwaylandShell = std::make_unique(&xwayland_shell_v1_interface, 1, "XWaylandShell");
+ PROTO::mesaDRM = std::make_unique(&wl_drm_interface, 2, "MesaDRM");
+ PROTO::linuxDma = std::make_unique(&zwp_linux_dmabuf_v1_interface, 5, "LinuxDMABUF");
// Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner.
diff --git a/src/managers/SeatManager.cpp b/src/managers/SeatManager.cpp
index 5fa3d1ae..6ccf1dfd 100644
--- a/src/managers/SeatManager.cpp
+++ b/src/managers/SeatManager.cpp
@@ -3,6 +3,7 @@
#include "../protocols/core/DataDevice.hpp"
#include "../protocols/DataDeviceWlr.hpp"
#include "../protocols/PrimarySelection.hpp"
+#include "../protocols/core/Compositor.hpp"
#include "../Compositor.hpp"
#include "../devices/IKeyboard.hpp"
#include
@@ -98,7 +99,7 @@ void CSeatManager::updateActiveKeyboardData() {
PROTO::seat->updateKeymap();
}
-void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
+void CSeatManager::setKeyboardFocus(SP surf) {
if (state.keyboardFocus == surf)
return;
@@ -107,7 +108,7 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
return;
}
- hyprListener_keyboardSurfaceDestroy.removeCallback();
+ listeners.keyboardSurfaceDestroy.reset();
if (state.keyboardFocusResource) {
// we will iterate over all bound wl_seat
@@ -138,7 +139,7 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
return;
}
- auto client = wl_resource_get_client(surf->resource);
+ auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client)
continue;
@@ -153,8 +154,7 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
}
}
- hyprListener_keyboardSurfaceDestroy.initCallback(
- &surf->events.destroy, [this](void* owner, void* data) { setKeyboardFocus(nullptr); }, nullptr, "CSeatManager");
+ listeners.keyboardSurfaceDestroy = surf->events.destroy.registerListener([this](std::any d) { setKeyboardFocus(nullptr); });
events.keyboardFocusChange.emit();
}
@@ -183,7 +183,7 @@ void CSeatManager::sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32
}
}
-void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
+void CSeatManager::setPointerFocus(SP surf, const Vector2D& local) {
if (state.pointerFocus == surf)
return;
@@ -192,7 +192,7 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
return;
}
- hyprListener_pointerSurfaceDestroy.removeCallback();
+ listeners.pointerSurfaceDestroy.reset();
if (state.pointerFocusResource) {
auto client = state.pointerFocusResource->client();
@@ -220,7 +220,7 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
return;
}
- auto client = wl_resource_get_client(surf->resource);
+ auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client)
continue;
@@ -239,8 +239,7 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
sendPointerFrame();
- hyprListener_pointerSurfaceDestroy.initCallback(
- &surf->events.destroy, [this](void* owner, void* data) { setPointerFocus(nullptr, {}); }, nullptr, "CSeatManager");
+ listeners.pointerSurfaceDestroy = surf->events.destroy.registerListener([this](std::any d) { setPointerFocus(nullptr, {}); });
events.pointerFocusChange.emit();
}
@@ -313,11 +312,11 @@ void CSeatManager::sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double
}
}
-void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id, const Vector2D& local) {
+void CSeatManager::sendTouchDown(SP surf, uint32_t timeMs, int32_t id, const Vector2D& local) {
if (state.touchFocus == surf)
return;
- hyprListener_touchSurfaceDestroy.removeCallback();
+ listeners.touchSurfaceDestroy.reset();
if (state.touchFocusResource) {
auto client = state.touchFocusResource->client();
@@ -342,7 +341,7 @@ void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id,
return;
}
- auto client = wl_resource_get_client(surf->resource);
+ auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client)
continue;
@@ -356,8 +355,7 @@ void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id,
}
}
- hyprListener_touchSurfaceDestroy.initCallback(
- &surf->events.destroy, [this, timeMs, id](void* owner, void* data) { sendTouchUp(timeMs + 10, id); }, nullptr, "CSeatManager");
+ listeners.touchSurfaceDestroy = surf->events.destroy.registerListener([this, timeMs, id](std::any d) { sendTouchUp(timeMs + 10, id); });
events.touchFocusChange.emit();
}
@@ -434,7 +432,7 @@ void CSeatManager::refocusGrab() {
// try to find a surf in focus first
const auto MOUSE = g_pInputManager->getMouseCoordsInternal();
for (auto& s : seatGrab->surfs) {
- auto hlSurf = CWLSurface::surfaceFromWlr(s);
+ auto hlSurf = CWLSurface::fromResource(s.lock());
if (!hlSurf)
continue;
@@ -446,13 +444,13 @@ void CSeatManager::refocusGrab() {
continue;
if (seatGrab->keyboard)
- setKeyboardFocus(s);
+ setKeyboardFocus(s.lock());
if (seatGrab->pointer)
- setPointerFocus(s, MOUSE - b->pos());
+ setPointerFocus(s.lock(), MOUSE - b->pos());
return;
}
- wlr_surface* surf = seatGrab->surfs.at(0);
+ SP surf = seatGrab->surfs.at(0).lock();
if (seatGrab->keyboard)
setKeyboardFocus(surf);
if (seatGrab->pointer)
@@ -460,7 +458,7 @@ void CSeatManager::refocusGrab() {
}
}
-void CSeatManager::onSetCursor(SP seatResource, uint32_t serial, wlr_surface* surf, const Vector2D& hotspot) {
+void CSeatManager::onSetCursor(SP seatResource, uint32_t serial, SP surf, const Vector2D& hotspot) {
if (!state.pointerFocusResource || !seatResource || seatResource->client() != state.pointerFocusResource->client()) {
Debug::log(LOG, "[seatmgr] Rejecting a setCursor because the client ain't in focus");
return;
@@ -547,10 +545,10 @@ void CSeatManager::setGrab(SP grab) {
}
void CSeatManager::resendEnterEvents() {
- wlr_surface* kb = state.keyboardFocus;
- wlr_surface* pt = state.pointerFocus;
+ SP kb = state.keyboardFocus.lock();
+ SP pt = state.pointerFocus.lock();
- auto last = lastLocalCoords;
+ auto last = lastLocalCoords;
setKeyboardFocus(nullptr);
setPointerFocus(nullptr, {});
@@ -559,15 +557,15 @@ void CSeatManager::resendEnterEvents() {
setPointerFocus(pt, last);
}
-bool CSeatGrab::accepts(wlr_surface* surf) {
+bool CSeatGrab::accepts(SP surf) {
return std::find(surfs.begin(), surfs.end(), surf) != surfs.end();
}
-void CSeatGrab::add(wlr_surface* surf) {
+void CSeatGrab::add(SP surf) {
surfs.push_back(surf);
}
-void CSeatGrab::remove(wlr_surface* surf) {
+void CSeatGrab::remove(SP surf) {
std::erase(surfs, surf);
if ((keyboard && g_pSeatManager->state.keyboardFocus == surf) || (pointer && g_pSeatManager->state.pointerFocus == surf))
g_pSeatManager->refocusGrab();
diff --git a/src/managers/SeatManager.hpp b/src/managers/SeatManager.hpp
index 35456cb3..e74d9ace 100644
--- a/src/managers/SeatManager.hpp
+++ b/src/managers/SeatManager.hpp
@@ -11,7 +11,7 @@
constexpr size_t MAX_SERIAL_STORE_LEN = 100;
-struct wlr_surface;
+class CWLSurfaceResource;
class CWLSeatResource;
class IPointer;
class IKeyboard;
@@ -29,9 +29,9 @@ class IKeyboard;
*/
class CSeatGrab {
public:
- bool accepts(wlr_surface* surf);
- void add(wlr_surface* surf);
- void remove(wlr_surface* surf);
+ bool accepts(SP surf);
+ void add(SP surf);
+ void remove(SP surf);
void setCallback(std::function onEnd_);
void clear();
@@ -42,8 +42,8 @@ class CSeatGrab {
bool removeOnInput = true; // on hard input e.g. click outside, remove
private:
- std::vector surfs; // read-only
- std::function onEnd;
+ std::vector> surfs;
+ std::function onEnd;
friend class CSeatManager;
};
@@ -57,11 +57,11 @@ class CSeatManager {
void setKeyboard(SP keeb);
void updateActiveKeyboardData(); // updates the clients with the keymap and repeat info
- void setKeyboardFocus(wlr_surface* surf);
+ void setKeyboardFocus(SP surf);
void sendKeyboardKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state);
void sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
- void setPointerFocus(wlr_surface* surf, const Vector2D& local);
+ void setPointerFocus(SP surf, const Vector2D& local);
void sendPointerMotion(uint32_t timeMs, const Vector2D& local);
void sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state);
void sendPointerFrame();
@@ -69,7 +69,7 @@ class CSeatManager {
void sendPointerAxis(uint32_t timeMs, wl_pointer_axis axis, double value, int32_t discrete, int32_t value120, wl_pointer_axis_source source,
wl_pointer_axis_relative_direction relative);
- void sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id, const Vector2D& local);
+ void sendTouchDown(SP surf, uint32_t timeMs, int32_t id, const Vector2D& local);
void sendTouchUp(uint32_t timeMs, int32_t id);
void sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local);
void sendTouchFrame();
@@ -83,24 +83,24 @@ class CSeatManager {
// pops the serial if it was valid, meaning it is consumed.
bool serialValid(SP seatResource, uint32_t serial);
- void onSetCursor(SP seatResource, uint32_t serial, wlr_surface* surf, const Vector2D& hotspot);
+ void onSetCursor(SP seatResource, uint32_t serial, SP surf, const Vector2D& hotspot);
SP seatResourceForClient(wl_client* client);
struct {
- wlr_surface* keyboardFocus = nullptr;
- WP keyboardFocusResource;
+ WP keyboardFocus;
+ WP keyboardFocusResource;
- wlr_surface* pointerFocus = nullptr;
- WP