wayland/core: move to new impl (#6268)

* wayland/core/dmabuf: move to new impl

it's the final countdown
This commit is contained in:
Vaxry 2024-06-08 10:07:59 +02:00 committed by GitHub
parent c31d9ef417
commit 6967a31450
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
147 changed files with 5388 additions and 2226 deletions

View file

@ -116,7 +116,7 @@ pkg_check_modules(deps REQUIRED IMPORTED_TARGET
hyprlang>=0.3.2 hyprcursor>=0.1.7 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") 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("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-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("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) protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
protocolNew("protocols" "wlr-gamma-control-unstable-v1" true) 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("protocols" "wlr-data-control-unstable-v1" true)
protocolNew("subprojects/hyprland-protocols/protocols" "hyprland-focus-grab-v1" true) protocolNew("subprojects/hyprland-protocols/protocols" "hyprland-focus-grab-v1" true)
protocolNew("protocols" "wlr-layer-shell-unstable-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/tearing-control" "tearing-control-v1" false)
protocolNew("staging/fractional-scale" "fractional-scale-v1" false) protocolNew("staging/fractional-scale" "fractional-scale-v1" false)
protocolNew("unstable/xdg-output" "xdg-output-unstable-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("stable/xdg-shell" "xdg-shell" false)
protocolNew("unstable/primary-selection" "primary-selection-unstable-v1" false) protocolNew("unstable/primary-selection" "primary-selection-unstable-v1" false)
protocolNew("staging/xwayland-shell" "xwayland-shell-v1" false) protocolNew("staging/xwayland-shell" "xwayland-shell-v1" false)
protocolNew("stable/viewporter" "viewporter" false)
protocolNew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
protocolWayland() protocolWayland()

View file

@ -13,11 +13,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1716576411, "lastModified": 1717181720,
"narHash": "sha256-FIN1wMoyePBTtibCbaeJaoKNLuAYIGwLCWAYC1DJanw=", "narHash": "sha256-yv+QZWsusu/NWjydkxixHC2g+tIJ9v+xkE2EiVpJj6g=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprcursor", "repo": "hyprcursor",
"rev": "57298fc4f13c807e50ada2c986a3114b7fc2e621", "rev": "9e27a2c2ceb1e0b85bd55b0afefad196056fe87c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -84,11 +84,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1716058375, "lastModified": 1717784906,
"narHash": "sha256-CwjWoVnBZE5SBpRx9dgSQGCr4Goxyfcyv3zZbOhVqzk=", "narHash": "sha256-YxmfxHfWed1fosaa7fC1u7XoKp1anEZU+7Lh/ojRKoM=",
"owner": "hyprwm", "owner": "hyprwm",
"repo": "hyprwayland-scanner", "repo": "hyprwayland-scanner",
"rev": "3afed4364790aebe0426077631af1e164a9650cc", "rev": "0f30f9eca6e404130988554accbb64d1c9ec877d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -99,11 +99,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1716330097, "lastModified": 1717602782,
"narHash": "sha256-8BO3B7e3BiyIDsaKA0tY8O88rClYRTjvAp66y+VBUeU=", "narHash": "sha256-pL9jeus5QpX5R+9rsp3hhZ+uplVHscNJh8n8VpqscM0=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "5710852ba686cc1fd0d3b8e22b3117d43ba374c2", "rev": "e8057b67ebf307f01bdcc8fba94d94f75039d1f6",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -24,7 +24,6 @@ hyprwayland_scanner = find_program(
) )
protocols = [ protocols = [
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'], [wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
['wlr-screencopy-unstable-v1.xml'], ['wlr-screencopy-unstable-v1.xml'],
[hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'], [hl_protocol_dir, 'protocols/hyprland-toplevel-export-v1.xml'],
@ -41,6 +40,7 @@ new_protocols = [
['wlr-output-management-unstable-v1.xml'], ['wlr-output-management-unstable-v1.xml'],
['kde-server-decoration.xml'], ['kde-server-decoration.xml'],
['wlr-layer-shell-unstable-v1.xml'], ['wlr-layer-shell-unstable-v1.xml'],
['wayland-drm.xml'],
['wlr-data-control-unstable-v1.xml'], ['wlr-data-control-unstable-v1.xml'],
[hl_protocol_dir, 'protocols/hyprland-focus-grab-v1.xml'], [hl_protocol_dir, 'protocols/hyprland-focus-grab-v1.xml'],
[wl_protocol_dir, 'staging/tearing-control/tearing-control-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, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/primary-selection/primary-selection-unstable-v1.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, '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 = [] wl_protos_src = []

189
protocols/wayland-drm.xml Normal file
View file

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="drm">
<copyright>
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.
</copyright>
<!-- drm support. This object is created by the server and published
using the display's global event. -->
<interface name="wl_drm" version="2">
<enum name="error">
<entry name="authenticate_fail" value="0"/>
<entry name="invalid_format" value="1"/>
<entry name="invalid_name" value="2"/>
</enum>
<enum name="format">
<!-- The drm format codes match the #defines in drm_fourcc.h.
The formats actually supported by the compositor will be
reported by the format event. New codes must not be added,
unless directly taken from drm_fourcc.h. -->
<entry name="c8" value="0x20203843"/>
<entry name="rgb332" value="0x38424752"/>
<entry name="bgr233" value="0x38524742"/>
<entry name="xrgb4444" value="0x32315258"/>
<entry name="xbgr4444" value="0x32314258"/>
<entry name="rgbx4444" value="0x32315852"/>
<entry name="bgrx4444" value="0x32315842"/>
<entry name="argb4444" value="0x32315241"/>
<entry name="abgr4444" value="0x32314241"/>
<entry name="rgba4444" value="0x32314152"/>
<entry name="bgra4444" value="0x32314142"/>
<entry name="xrgb1555" value="0x35315258"/>
<entry name="xbgr1555" value="0x35314258"/>
<entry name="rgbx5551" value="0x35315852"/>
<entry name="bgrx5551" value="0x35315842"/>
<entry name="argb1555" value="0x35315241"/>
<entry name="abgr1555" value="0x35314241"/>
<entry name="rgba5551" value="0x35314152"/>
<entry name="bgra5551" value="0x35314142"/>
<entry name="rgb565" value="0x36314752"/>
<entry name="bgr565" value="0x36314742"/>
<entry name="rgb888" value="0x34324752"/>
<entry name="bgr888" value="0x34324742"/>
<entry name="xrgb8888" value="0x34325258"/>
<entry name="xbgr8888" value="0x34324258"/>
<entry name="rgbx8888" value="0x34325852"/>
<entry name="bgrx8888" value="0x34325842"/>
<entry name="argb8888" value="0x34325241"/>
<entry name="abgr8888" value="0x34324241"/>
<entry name="rgba8888" value="0x34324152"/>
<entry name="bgra8888" value="0x34324142"/>
<entry name="xrgb2101010" value="0x30335258"/>
<entry name="xbgr2101010" value="0x30334258"/>
<entry name="rgbx1010102" value="0x30335852"/>
<entry name="bgrx1010102" value="0x30335842"/>
<entry name="argb2101010" value="0x30335241"/>
<entry name="abgr2101010" value="0x30334241"/>
<entry name="rgba1010102" value="0x30334152"/>
<entry name="bgra1010102" value="0x30334142"/>
<entry name="yuyv" value="0x56595559"/>
<entry name="yvyu" value="0x55595659"/>
<entry name="uyvy" value="0x59565955"/>
<entry name="vyuy" value="0x59555956"/>
<entry name="ayuv" value="0x56555941"/>
<entry name="xyuv8888" value="0x56555958"/>
<entry name="nv12" value="0x3231564e"/>
<entry name="nv21" value="0x3132564e"/>
<entry name="nv16" value="0x3631564e"/>
<entry name="nv61" value="0x3136564e"/>
<entry name="yuv410" value="0x39565559"/>
<entry name="yvu410" value="0x39555659"/>
<entry name="yuv411" value="0x31315559"/>
<entry name="yvu411" value="0x31315659"/>
<entry name="yuv420" value="0x32315559"/>
<entry name="yvu420" value="0x32315659"/>
<entry name="yuv422" value="0x36315559"/>
<entry name="yvu422" value="0x36315659"/>
<entry name="yuv444" value="0x34325559"/>
<entry name="yvu444" value="0x34325659"/>
<entry name="abgr16f" value="0x48344241"/>
<entry name="xbgr16f" value="0x48344258"/>
</enum>
<!-- Call this request with the magic received from drmGetMagic().
It will be passed on to the drmAuthMagic() or
DRIAuthConnection() call. This authentication must be
completed before create_buffer could be used. -->
<request name="authenticate">
<arg name="id" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_buffer">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="stride" type="uint"/>
<arg name="format" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_planar_buffer">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="format" type="uint"/>
<arg name="offset0" type="int"/>
<arg name="stride0" type="int"/>
<arg name="offset1" type="int"/>
<arg name="stride1" type="int"/>
<arg name="offset2" type="int"/>
<arg name="stride2" type="int"/>
</request>
<!-- Notification of the path of the drm device which is used by
the server. The client should use this device for creating
local buffers. Only buffers created from this device should
be be passed to the server using this drm object's
create_buffer request. -->
<event name="device">
<arg name="name" type="string"/>
</event>
<event name="format">
<arg name="format" type="uint"/>
</event>
<!-- Raised if the authenticate request succeeded -->
<event name="authenticated"/>
<enum name="capability" since="2">
<description summary="wl_drm capability bitmask">
Bitmask of capabilities.
</description>
<entry name="prime" value="1" summary="wl_drm prime available"/>
</enum>
<event name="capabilities">
<arg name="value" type="uint"/>
</event>
<!-- Version 2 additions -->
<!-- Create a wayland buffer for the prime fd. Use for regular and planar
buffers. Pass 0 for offset and stride for unused planes. -->
<request name="create_prime_buffer" since="2">
<arg name="id" type="new_id" interface="wl_buffer"/>
<arg name="name" type="fd"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="format" type="uint"/>
<arg name="offset0" type="int"/>
<arg name="stride0" type="int"/>
<arg name="offset1" type="int"/>
<arg name="stride1" type="int"/>
<arg name="offset2" type="int"/>
<arg name="stride2" type="int"/>
</request>
</interface>
</protocol>

View file

@ -19,6 +19,8 @@
#include "protocols/PointerConstraints.hpp" #include "protocols/PointerConstraints.hpp"
#include "protocols/LayerShell.hpp" #include "protocols/LayerShell.hpp"
#include "protocols/XDGShell.hpp" #include "protocols/XDGShell.hpp"
#include "protocols/core/Compositor.hpp"
#include "protocols/core/Subcompositor.hpp"
#include "desktop/LayerSurface.hpp" #include "desktop/LayerSurface.hpp"
#include "xwayland/XWayland.hpp" #include "xwayland/XWayland.hpp"
@ -184,7 +186,7 @@ void CCompositor::initServer() {
&isHeadlessOnly); &isHeadlessOnly);
if (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 { } else {
m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend); m_iDRMFD = wlr_backend_get_drm_fd(m_sWLRBackend);
if (m_iDRMFD < 0) { if (m_iDRMFD < 0) {
@ -200,15 +202,6 @@ void CCompositor::initServer() {
throwError("wlr_gles2_renderer_create_with_drm_fd() failed!"); 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); m_sWLRAllocator = wlr_allocator_autocreate(m_sWLRBackend, m_sWLRRenderer);
if (!m_sWLRAllocator) { if (!m_sWLRAllocator) {
@ -223,13 +216,7 @@ void CCompositor::initServer() {
throwError("wlr_gles2_renderer_get_egl() failed!"); throwError("wlr_gles2_renderer_get_egl() failed!");
} }
m_sWLRCompositor = wlr_compositor_create(m_sWLDisplay, 6, m_sWLRRenderer); initManagers(STAGE_BASICINIT);
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);
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend); m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
if (!m_sWRLDRMLeaseMgr) { if (!m_sWRLDRMLeaseMgr) {
@ -244,8 +231,6 @@ void CCompositor::initServer() {
throwError("wlr_headless_backend_create() failed!"); throwError("wlr_headless_backend_create() failed!");
} }
wlr_single_pixel_buffer_manager_v1_create(m_sWLDisplay);
wlr_multi_backend_add(m_sWLRBackend, m_sWLRHeadlessBackend); wlr_multi_backend_add(m_sWLRBackend, m_sWLRHeadlessBackend);
initManagers(STAGE_LATE); initManagers(STAGE_LATE);
@ -320,7 +305,7 @@ void CCompositor::cleanup() {
// still in a normal working state. // still in a normal working state.
g_pPluginSystem->unloadAllPlugins(); g_pPluginSystem->unloadAllPlugins();
m_pLastFocus = nullptr; m_pLastFocus.reset();
m_pLastWindow.reset(); m_pLastWindow.reset();
m_vWorkspaces.clear(); m_vWorkspaces.clear();
@ -393,12 +378,6 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the HookSystem!"); Debug::log(LOG, "Creating the HookSystem!");
g_pHookSystem = std::make_unique<CHookSystemManager>(); g_pHookSystem = std::make_unique<CHookSystemManager>();
Debug::log(LOG, "Creating the ProtocolManager!");
g_pProtocolManager = std::make_unique<CProtocolManager>();
Debug::log(LOG, "Creating the SeatManager!");
g_pSeatManager = std::make_unique<CSeatManager>();
Debug::log(LOG, "Creating the KeybindManager!"); Debug::log(LOG, "Creating the KeybindManager!");
g_pKeybindManager = std::make_unique<CKeybindManager>(); g_pKeybindManager = std::make_unique<CKeybindManager>();
@ -423,6 +402,13 @@ void CCompositor::initManagers(eManagersInitStage stage) {
Debug::log(LOG, "Creating the PointerManager!"); Debug::log(LOG, "Creating the PointerManager!");
g_pPointerManager = std::make_unique<CPointerManager>(); g_pPointerManager = std::make_unique<CPointerManager>();
} break; } break;
case STAGE_BASICINIT: {
Debug::log(LOG, "Creating the ProtocolManager!");
g_pProtocolManager = std::make_unique<CProtocolManager>();
Debug::log(LOG, "Creating the SeatManager!");
g_pSeatManager = std::make_unique<CSeatManager>();
} break;
case STAGE_LATE: { case STAGE_LATE: {
Debug::log(LOG, "Creating the ThreadManager!"); Debug::log(LOG, "Creating the ThreadManager!");
g_pThreadManager = std::make_unique<CThreadManager>(); g_pThreadManager = std::make_unique<CThreadManager>();
@ -574,6 +560,8 @@ void CCompositor::startCompositor() {
createLockFile(); createLockFile();
EMIT_HOOK_EVENT("ready", nullptr);
// This blocks until we are done. // This blocks until we are done.
Debug::log(LOG, "Hyprland is ready, running the event loop!"); Debug::log(LOG, "Hyprland is ready, running the event loop!");
g_pEventLoopManager->enterLoop(m_sWLDisplay, m_sWLEventLoop); g_pEventLoopManager->enterLoop(m_sWLDisplay, m_sWLEventLoop);
@ -789,47 +777,32 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
return windowForWorkspace(false); return windowForWorkspace(false);
} }
wlr_surface* CCompositor::vectorWindowToSurface(const Vector2D& pos, PHLWINDOW pWindow, Vector2D& sl) { SP<CWLSurfaceResource> CCompositor::vectorWindowToSurface(const Vector2D& pos, PHLWINDOW pWindow, Vector2D& sl) {
if (!validMapped(pWindow)) if (!validMapped(pWindow))
return nullptr; return nullptr;
RASSERT(!pWindow->m_bIsX11, "Cannot call vectorWindowToSurface on an X11 window!"); RASSERT(!pWindow->m_bIsX11, "Cannot call vectorWindowToSurface on an X11 window!");
double subx, suby;
CBox geom = pWindow->m_pXDGSurface->current.geometry;
// try popups first // 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) {
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 {
const auto OFF = PPOPUP->coordsRelativeToParent(); const auto OFF = PPOPUP->coordsRelativeToParent();
subx = pos.x - OFF.x + geom.x - pWindow->m_vRealPosition.goal().x; sl = pos - pWindow->m_vRealPosition.goal() - OFF;
suby = pos.y - OFF.y + geom.y - pWindow->m_vRealPosition.goal().y; return PPOPUP->m_pWLSurface->resource();
} }
if (found) { auto [surf, local] = pWindow->m_pWLSurface->resource()->at(pos - pWindow->m_vRealPosition.goal(), true);
sl.x = subx; if (surf) {
sl.y = suby; sl = local;
return found; return surf;
} }
sl.x = pos.x - pWindow->m_vRealPosition.value().x; return nullptr;
sl.y = pos.y - pWindow->m_vRealPosition.value().y;
sl.x += geom.x;
sl.y += geom.y;
return pWindow->m_pWLSurface.wlr();
} }
Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindow, wlr_surface* pSurface) { Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface) {
if (!validMapped(pWindow)) if (!validMapped(pWindow))
return {}; return {};
@ -840,25 +813,22 @@ Vector2D CCompositor::vectorToSurfaceLocal(const Vector2D& vec, PHLWINDOW pWindo
if (PPOPUP) if (PPOPUP)
return vec - PPOPUP->coordsGlobal(); return vec - PPOPUP->coordsGlobal();
std::tuple<wlr_surface*, int, int> iterData = {pSurface, -1337, -1337}; std::tuple<SP<CWLSurfaceResource>, Vector2D> iterData = {pSurface, {-1337, -1337}};
wlr_surface_for_each_surface( pWindow->m_pWLSurface->resource()->breadthfirst(
pWindow->m_pWLSurface.wlr(), [](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) {
[](wlr_surface* surf, int x, int y, void* data) { const auto PDATA = (std::tuple<SP<CWLSurfaceResource>, Vector2D>*)data;
const auto PDATA = (std::tuple<wlr_surface*, int, int>*)data; if (surf == std::get<0>(*PDATA))
if (surf == std::get<0>(*PDATA)) { std::get<1>(*PDATA) = offset;
std::get<1>(*PDATA) = x;
std::get<2>(*PDATA) = y;
}
}, },
&iterData); &iterData);
CBox geom = pWindow->m_pXDGSurface->current.geometry; 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();
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) { CMonitor* CCompositor::getMonitorFromOutput(wlr_output* out) {
@ -881,7 +851,7 @@ CMonitor* CCompositor::getRealMonitorFromOutput(wlr_output* out) {
return nullptr; return nullptr;
} }
void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) { void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface) {
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse"); static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough"); static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
@ -924,7 +894,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr); g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(nullptr);
m_pLastFocus = nullptr; m_pLastFocus.reset();
g_pInputManager->recheckIdleInhibitorStatus(); g_pInputManager->recheckIdleInhibitorStatus();
return; return;
@ -976,7 +946,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
m_pLastWindow = PLASTWINDOW; m_pLastWindow = PLASTWINDOW;
const auto PWINDOWSURFACE = pSurface ? pSurface : pWindow->m_pWLSurface.wlr(); const auto PWINDOWSURFACE = pSurface ? pSurface : pWindow->m_pWLSurface->resource();
focusSurface(PWINDOWSURFACE, pWindow); focusSurface(PWINDOWSURFACE, pWindow);
@ -1011,9 +981,9 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, wlr_surface* pSurface) {
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
} }
void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) { void CCompositor::focusSurface(SP<CWLSurfaceResource> 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. return; // Don't focus when already focused on this.
if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface)) if (g_pSessionLockManager->isSessionLocked() && !g_pSessionLockManager->isSurfaceSessionLock(pSurface))
@ -1024,18 +994,18 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
return; return;
} }
const auto PLASTSURF = m_pLastFocus; const auto PLASTSURF = m_pLastFocus.lock();
// Unfocus last surface if should // Unfocus last surface if should
if (m_pLastFocus && !pWindowOwner) if (m_pLastFocus && !pWindowOwner)
g_pXWaylandManager->activateSurface(m_pLastFocus, false); g_pXWaylandManager->activateSurface(m_pLastFocus.lock(), false);
if (!pSurface) { if (!pSurface) {
g_pSeatManager->setKeyboardFocus(nullptr); g_pSeatManager->setKeyboardFocus(nullptr);
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // unfocused
g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""}); g_pEventManager->postEvent(SHyprIPCEvent{"activewindowv2", ""});
EMIT_HOOK_EVENT("keyboardFocus", (wlr_surface*)nullptr); EMIT_HOOK_EVENT("keyboardFocus", (SP<CWLSurfaceResource>)nullptr);
m_pLastFocus = nullptr; m_pLastFocus.reset();
return; return;
} }
@ -1052,8 +1022,8 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
EMIT_HOOK_EVENT("keyboardFocus", pSurface); EMIT_HOOK_EVENT("keyboardFocus", pSurface);
const auto SURF = CWLSurface::surfaceFromWlr(pSurface); const auto SURF = CWLSurface::fromResource(pSurface);
const auto OLDSURF = CWLSurface::surfaceFromWlr(PLASTSURF); const auto OLDSURF = CWLSurface::fromResource(PLASTSURF);
if (OLDSURF && OLDSURF->constraint()) if (OLDSURF && OLDSURF->constraint())
OLDSURF->constraint()->deactivate(); OLDSURF->constraint()->deactivate();
@ -1062,7 +1032,7 @@ void CCompositor::focusSurface(wlr_surface* pSurface, PHLWINDOW pWindowOwner) {
SURF->constraint()->activate(); SURF->constraint()->activate();
} }
wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { SP<CWLSurfaceResource> CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonitor* monitor, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
for (auto& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) { for (auto& lsl : monitor->m_aLayerSurfaceLayers | std::views::reverse) {
for (auto& ls : lsl | 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) if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->mapped) || ls->alpha.value() == 0.f)
@ -1073,7 +1043,7 @@ wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonito
if (SURFACEAT) { if (SURFACEAT) {
*ppLayerSurfaceFound = ls.lock(); *ppLayerSurfaceFound = ls.lock();
*sCoords = pos - SURFACEAT->coordsGlobal(); *sCoords = pos - SURFACEAT->coordsGlobal();
return SURFACEAT->m_sWLSurface.wlr(); return SURFACEAT->m_pWLSurface->resource();
} }
} }
} }
@ -1081,31 +1051,34 @@ wlr_surface* CCompositor::vectorToLayerPopupSurface(const Vector2D& pos, CMonito
return nullptr; return nullptr;
} }
wlr_surface* CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<PHLLSREF>* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) { SP<CWLSurfaceResource> CCompositor::vectorToLayerSurface(const Vector2D& pos, std::vector<PHLLSREF>* layerSurfaces, Vector2D* sCoords, PHLLS* ppLayerSurfaceFound) {
for (auto& ls : *layerSurfaces | std::views::reverse) { for (auto& ls : *layerSurfaces | std::views::reverse) {
if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f) if (ls->fadingOut || !ls->layerSurface || (ls->layerSurface && !ls->layerSurface->surface->mapped) || ls->alpha.value() == 0.f)
continue; 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 (surf) {
if (!pixman_region32_not_empty(&SURFACEAT->input_region)) if (surf->current.input.empty())
continue; continue;
*ppLayerSurfaceFound = ls.lock(); *ppLayerSurfaceFound = ls.lock();
return SURFACEAT;
*sCoords = local;
return surf;
} }
} }
return nullptr; return nullptr;
} }
PHLWINDOW CCompositor::getWindowFromSurface(wlr_surface* pSurface) { PHLWINDOW CCompositor::getWindowFromSurface(SP<CWLSurfaceResource> pSurface) {
for (auto& w : m_vWindows) { for (auto& w : m_vWindows) {
if (!w->m_bIsMapped || w->m_bFadingOut) if (!w->m_bIsMapped || w->m_bFadingOut)
continue; continue;
if (w->m_pWLSurface.wlr() == pSurface) if (w->m_pWLSurface->resource() == pSurface)
return w; return w;
} }
@ -1244,7 +1217,7 @@ bool CCompositor::isWindowActive(PHLWINDOW pWindow) {
if (!pWindow->m_bIsMapped) if (!pWindow->m_bIsMapped)
return false; return false;
const auto PSURFACE = pWindow->m_pWLSurface.wlr(); const auto PSURFACE = pWindow->m_pWLSurface->resource();
return PSURFACE == m_pLastFocus || pWindow == m_pLastWindow.lock(); return PSURFACE == m_pLastFocus || pWindow == m_pLastWindow.lock();
} }
@ -1646,11 +1619,6 @@ bool CCompositor::isPointOnReservedArea(const Vector2D& point, const CMonitor* p
return !VECINRECT(point, XY1.x, XY1.y, XY2.x, XY2.y); 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<wlr_surface*, bool>*)data;
pair->second = pair->second || pSurface == pair->first;
}
CMonitor* CCompositor::getMonitorInDirection(const char& dir) { CMonitor* CCompositor::getMonitorInDirection(const char& dir) {
return this->getMonitorInDirection(m_pLastMonitor.get(), dir); return this->getMonitorInDirection(m_pLastMonitor.get(), dir);
} }
@ -2389,24 +2357,24 @@ void CCompositor::closeWindow(PHLWINDOW pWindow) {
} }
} }
PHLLS CCompositor::getLayerSurfaceFromSurface(wlr_surface* pSurface) { PHLLS CCompositor::getLayerSurfaceFromSurface(SP<CWLSurfaceResource> pSurface) {
std::pair<wlr_surface*, bool> result = {pSurface, false}; std::pair<SP<CWLSurfaceResource>, bool> result = {pSurface, false};
for (auto& ls : m_vLayers) { for (auto& ls : m_vLayers) {
if (ls->layerSurface && ls->layerSurface->surface == pSurface) if (ls->layerSurface && ls->layerSurface->surface == pSurface)
return ls; return ls;
static auto iter = [](wlr_surface* surf, int x, int y, void* data) -> void {
if (surf == ((std::pair<wlr_surface*, bool>*)data)->first) {
*(bool*)data = true;
return;
}
};
if (!ls->layerSurface || !ls->mapped) if (!ls->layerSurface || !ls->mapped)
continue; continue;
wlr_surface_for_each_surface(ls->layerSurface->surface, iter, &result); ls->layerSurface->surface->breadthfirst(
[](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) {
if (surf == ((std::pair<SP<CWLSurfaceResource>, bool>*)data)->first) {
*(bool*)data = true;
return;
}
},
&result);
if (result.second) if (result.second)
return ls; return ls;
@ -2738,13 +2706,13 @@ void CCompositor::leaveUnsafeState() {
} }
} }
void CCompositor::setPreferredScaleForSurface(wlr_surface* pSurface, double scale) { void CCompositor::setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale) {
PROTO::fractional->sendScale(pSurface, scale); PROTO::fractional->sendScale(pSurface, scale);
wlr_surface_set_preferred_buffer_scale(pSurface, static_cast<int32_t>(std::ceil(scale))); pSurface->sendPreferredScale(std::ceil(scale));
const auto PSURFACE = CWLSurface::surfaceFromWlr(pSurface); const auto PSURFACE = CWLSurface::fromResource(pSurface);
if (!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; return;
} }
@ -2752,12 +2720,12 @@ void CCompositor::setPreferredScaleForSurface(wlr_surface* pSurface, double scal
PSURFACE->m_iLastScale = static_cast<int32_t>(std::ceil(scale)); PSURFACE->m_iLastScale = static_cast<int32_t>(std::ceil(scale));
} }
void CCompositor::setPreferredTransformForSurface(wlr_surface* pSurface, wl_output_transform transform) { void CCompositor::setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform) {
wlr_surface_set_preferred_buffer_transform(pSurface, transform); pSurface->sendPreferredTransform(transform);
const auto PSURFACE = CWLSurface::surfaceFromWlr(pSurface); const auto PSURFACE = CWLSurface::fromResource(pSurface);
if (!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; return;
} }

View file

@ -29,8 +29,11 @@
#include "plugins/PluginSystem.hpp" #include "plugins/PluginSystem.hpp"
#include "helpers/Watchdog.hpp" #include "helpers/Watchdog.hpp"
class CWLSurfaceResource;
enum eManagersInitStage { enum eManagersInitStage {
STAGE_PRIORITY = 0, STAGE_PRIORITY = 0,
STAGE_BASICINIT,
STAGE_LATE STAGE_LATE
}; };
@ -79,7 +82,7 @@ class CCompositor {
void createLockFile(); void createLockFile();
void removeLockFile(); void removeLockFile();
wlr_surface* m_pLastFocus = nullptr; WP<CWLSurfaceResource> m_pLastFocus;
PHLWINDOWREF m_pLastWindow; PHLWINDOWREF m_pLastWindow;
WP<CMonitor> m_pLastMonitor; WP<CMonitor> m_pLastMonitor;
@ -102,17 +105,17 @@ class CCompositor {
CMonitor* getMonitorFromCursor(); CMonitor* getMonitorFromCursor();
CMonitor* getMonitorFromVector(const Vector2D&); CMonitor* getMonitorFromVector(const Vector2D&);
void removeWindowFromVectorSafe(PHLWINDOW); void removeWindowFromVectorSafe(PHLWINDOW);
void focusWindow(PHLWINDOW, wlr_surface* pSurface = nullptr); void focusWindow(PHLWINDOW, SP<CWLSurfaceResource> pSurface = nullptr);
void focusSurface(wlr_surface*, PHLWINDOW pWindowOwner = nullptr); void focusSurface(SP<CWLSurfaceResource>, PHLWINDOW pWindowOwner = nullptr);
bool monitorExists(CMonitor*); bool monitorExists(CMonitor*);
PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr); PHLWINDOW vectorToWindowUnified(const Vector2D&, uint8_t properties, PHLWINDOW pIgnoreWindow = nullptr);
wlr_surface* vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*); SP<CWLSurfaceResource> vectorToLayerSurface(const Vector2D&, std::vector<PHLLSREF>*, Vector2D*, PHLLS*);
wlr_surface* vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*); SP<CWLSurfaceResource> vectorToLayerPopupSurface(const Vector2D&, CMonitor* monitor, Vector2D*, PHLLS*);
wlr_surface* vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl); SP<CWLSurfaceResource> vectorWindowToSurface(const Vector2D&, PHLWINDOW, Vector2D& sl);
Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, wlr_surface*); Vector2D vectorToSurfaceLocal(const Vector2D&, PHLWINDOW, SP<CWLSurfaceResource>);
CMonitor* getMonitorFromOutput(wlr_output*); CMonitor* getMonitorFromOutput(wlr_output*);
CMonitor* getRealMonitorFromOutput(wlr_output*); CMonitor* getRealMonitorFromOutput(wlr_output*);
PHLWINDOW getWindowFromSurface(wlr_surface*); PHLWINDOW getWindowFromSurface(SP<CWLSurfaceResource>);
PHLWINDOW getWindowFromHandle(uint32_t); PHLWINDOW getWindowFromHandle(uint32_t);
bool isWorkspaceVisible(PHLWORKSPACE); bool isWorkspaceVisible(PHLWORKSPACE);
PHLWORKSPACE getWorkspaceByID(const int&); PHLWORKSPACE getWorkspaceByID(const int&);
@ -155,7 +158,7 @@ class CCompositor {
void addToFadingOutSafe(PHLWINDOW); void addToFadingOutSafe(PHLWINDOW);
PHLWINDOW getWindowByRegex(const std::string&); PHLWINDOW getWindowByRegex(const std::string&);
void warpCursorTo(const Vector2D&, bool force = false); void warpCursorTo(const Vector2D&, bool force = false);
PHLLS getLayerSurfaceFromSurface(wlr_surface*); PHLLS getLayerSurfaceFromSurface(SP<CWLSurfaceResource>);
void closeWindow(PHLWINDOW); void closeWindow(PHLWINDOW);
Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&); Vector2D parseWindowVectorArgsRelative(const std::string&, const Vector2D&);
void forceReportSizesToWindowsOnWorkspace(const int&); void forceReportSizesToWindowsOnWorkspace(const int&);
@ -170,8 +173,8 @@ class CCompositor {
void arrangeMonitors(); void arrangeMonitors();
void enterUnsafeState(); void enterUnsafeState();
void leaveUnsafeState(); void leaveUnsafeState();
void setPreferredScaleForSurface(wlr_surface* pSurface, double scale); void setPreferredScaleForSurface(SP<CWLSurfaceResource> pSurface, double scale);
void setPreferredTransformForSurface(wlr_surface* pSurface, wl_output_transform transform); void setPreferredTransformForSurface(SP<CWLSurfaceResource> pSurface, wl_output_transform transform);
void updateSuspendedStates(); void updateSuspendedStates();
PHLWINDOW windowForCPointer(CWindow*); PHLWINDOW windowForCPointer(CWindow*);

View file

@ -3,6 +3,10 @@
#include "config/ConfigValue.hpp" #include "config/ConfigValue.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
CHyprDebugOverlay::CHyprDebugOverlay() {
m_pTexture = makeShared<CTexture>();
}
void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) { void CHyprMonitorDebugOverlay::renderData(CMonitor* pMonitor, float µs) {
m_dLastRenderTimes.push_back(µs / 1000.f); m_dLastRenderTimes.push_back(µs / 1000.f);
@ -222,8 +226,8 @@ void CHyprDebugOverlay::draw() {
// copy the data to an OpenGL texture we have // copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(m_pCairoSurface); const auto DATA = cairo_image_surface_get_data(m_pCairoSurface);
m_tTexture.allocate(); m_pTexture->allocate();
glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID); glBindTexture(GL_TEXTURE_2D, m_pTexture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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); 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}; 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);
} }

View file

@ -31,6 +31,7 @@ class CHyprMonitorDebugOverlay {
class CHyprDebugOverlay { class CHyprDebugOverlay {
public: public:
CHyprDebugOverlay();
void draw(); void draw();
void renderData(CMonitor*, float µs); void renderData(CMonitor*, float µs);
void renderDataNoOverlay(CMonitor*, float µs); void renderDataNoOverlay(CMonitor*, float µs);
@ -42,7 +43,7 @@ class CHyprDebugOverlay {
cairo_surface_t* m_pCairoSurface = nullptr; cairo_surface_t* m_pCairoSurface = nullptr;
cairo_t* m_pCairo = nullptr; cairo_t* m_pCairo = nullptr;
CTexture m_tTexture; SP<CTexture> m_pTexture;
friend class CHyprMonitorDebugOverlay; friend class CHyprMonitorDebugOverlay;
friend class CHyprRenderer; friend class CHyprRenderer;

View file

@ -23,6 +23,8 @@ CHyprNotificationOverlay::CHyprNotificationOverlay() {
g_pHyprRenderer->damageBox(&m_bLastDamage); g_pHyprRenderer->damageBox(&m_bLastDamage);
}); });
m_pTexture = makeShared<CTexture>();
} }
CHyprNotificationOverlay::~CHyprNotificationOverlay() { CHyprNotificationOverlay::~CHyprNotificationOverlay() {
@ -227,8 +229,8 @@ void CHyprNotificationOverlay::draw(CMonitor* pMonitor) {
// copy the data to an OpenGL texture we have // copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(m_pCairoSurface); const auto DATA = cairo_image_surface_get_data(m_pCairoSurface);
m_tTexture.allocate(); m_pTexture->allocate();
glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID); glBindTexture(GL_TEXTURE_2D, m_pTexture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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); 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}; 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() { bool CHyprNotificationOverlay::hasAny() {

View file

@ -58,7 +58,7 @@ class CHyprNotificationOverlay {
CMonitor* m_pLastMonitor = nullptr; CMonitor* m_pLastMonitor = nullptr;
Vector2D m_vecLastSize = Vector2D(-1, -1); Vector2D m_vecLastSize = Vector2D(-1, -1);
CTexture m_tTexture; SP<CTexture> m_pTexture;
}; };
inline std::unique_ptr<CHyprNotificationOverlay> g_pHyprNotificationOverlay; inline std::unique_ptr<CHyprNotificationOverlay> g_pHyprNotificationOverlay;

View file

@ -2,6 +2,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) { PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
@ -9,6 +10,8 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor); CMonitor* pMonitor = resource->monitor.empty() ? g_pCompositor->getMonitorFromCursor() : g_pCompositor->getMonitorFromName(resource->monitor);
pLS->surface->assign(resource->surface.lock(), pLS);
if (!pMonitor) { if (!pMonitor) {
Debug::log(ERR, "New LS has no monitor??"); Debug::log(ERR, "New LS has no monitor??");
return pLS; return pLS;
@ -39,8 +42,6 @@ PHLLS CLayerSurface::create(SP<CLayerShellResource> resource) {
pLS->alpha.setValueAndWarp(0.f); 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); Debug::log(LOG, "LayerSurface {:x} (namespace {} layer {}) created on monitor {}", (uintptr_t)resource.get(), resource->layerNamespace, (int)pLS->layer, pMonitor->szName);
return pLS; return pLS;
@ -58,13 +59,16 @@ CLayerSurface::CLayerSurface(SP<CLayerShellResource> resource_) : layerSurface(r
listeners.map = layerSurface->events.map.registerListener([this](std::any d) { onMap(); }); listeners.map = layerSurface->events.map.registerListener([this](std::any d) { onMap(); });
listeners.unmap = layerSurface->events.unmap.registerListener([this](std::any d) { onUnmap(); }); listeners.unmap = layerSurface->events.unmap.registerListener([this](std::any d) { onUnmap(); });
listeners.destroy = layerSurface->events.destroy.registerListener([this](std::any d) { onDestroy(); }); listeners.destroy = layerSurface->events.destroy.registerListener([this](std::any d) { onDestroy(); });
surface = CWLSurface::create();
} }
CLayerSurface::~CLayerSurface() { CLayerSurface::~CLayerSurface() {
if (!g_pHyprOpenGL) if (!g_pHyprOpenGL)
return; return;
surface.unassign(); if (surface)
surface->unassign();
g_pHyprRenderer->makeEGLCurrent(); g_pHyprRenderer->makeEGLCurrent();
std::erase_if(g_pHyprOpenGL->m_mLayerFramebuffers, [&](const auto& other) { return other.first.expired() || other.first.lock() == self.lock(); }); 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; readyToDelete = true;
layerSurface.reset(); layerSurface.reset();
surface.unassign(); if (surface)
surface->unassign();
} }
void CLayerSurface::onMap() { void CLayerSurface::onMap() {
@ -126,7 +131,7 @@ void CLayerSurface::onMap() {
g_pHyprRenderer->arrangeLayersForMonitor(PMONITOR->ID); 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) if (layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
g_pInputManager->m_dExclusiveLSes.push_back(self); g_pInputManager->m_dExclusiveLSes.push_back(self);
@ -139,10 +144,10 @@ void CLayerSurface::onMap() {
// TODO: use the new superb really very cool grab // TODO: use the new superb really very cool grab
g_pSeatManager->setGrab(nullptr); g_pSeatManager->setGrab(nullptr);
g_pInputManager->releaseAllMouseButtons(); 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); 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; g_pInputManager->m_bEmptyFocusCursorSet = false;
} }
@ -160,8 +165,8 @@ void CLayerSurface::onMap() {
g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", szNamespace}); g_pEventManager->postEvent(SHyprIPCEvent{"openlayer", szNamespace});
EMIT_HOOK_EVENT("openLayer", self.lock()); EMIT_HOOK_EVENT("openLayer", self.lock());
g_pCompositor->setPreferredScaleForSurface(surface.wlr(), PMONITOR->scale); g_pCompositor->setPreferredScaleForSurface(surface->resource(), PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(surface.wlr(), PMONITOR->transform); g_pCompositor->setPreferredTransformForSurface(surface->resource(), PMONITOR->transform);
} }
void CLayerSurface::onUnmap() { 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(); }); std::erase_if(g_pInputManager->m_dExclusiveLSes, [this](const auto& other) { return !other.lock() || other.lock() == self.lock(); });
if (!g_pInputManager->m_dExclusiveLSes.empty()) 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) { if (!g_pCompositor->getMonitorFromID(monitorID) || g_pCompositor->m_bUnsafeState) {
Debug::log(WARN, "Layersurface unmapping on invalid monitor (removed?) ignoring."); 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 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) if (!PMONITOR)
return; return;
@ -210,9 +215,9 @@ void CLayerSurface::onUnmap() {
Vector2D surfaceCoords; Vector2D surfaceCoords;
PHLLS pFoundLayerSurface; PHLLS pFoundLayerSurface;
wlr_surface* foundSurface = nullptr; SP<CWLSurfaceResource> foundSurface = nullptr;
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
// find LS-es to focus // find LS-es to focus
foundSurface = g_pCompositor->vectorToLayerSurface(g_pInputManager->getMouseCoordsInternal(), &PMONITOR->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], 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}; CBox geomFixed = {geometry.x + PMONITOR->vecPosition.x, geometry.y + PMONITOR->vecPosition.y, geometry.width, geometry.height};
g_pHyprRenderer->damageBox(&geomFixed); g_pHyprRenderer->damageBox(&geomFixed);
geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.width, geomFixed = {geometry.x + (int)PMONITOR->vecPosition.x, geometry.y + (int)PMONITOR->vecPosition.y, (int)layerSurface->surface->current.size.x,
(int)layerSurface->surface->current.height}; (int)layerSurface->surface->current.size.y};
g_pHyprRenderer->damageBox(&geomFixed); g_pHyprRenderer->damageBox(&geomFixed);
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
@ -284,12 +289,12 @@ void CLayerSurface::onCommit() {
position = Vector2D(geometry.x, geometry.y); position = Vector2D(geometry.x, geometry.y);
// update geom if it changed // 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. // 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 { } else {
// this is because some apps like e.g. rofi-lbonn can't fucking use the protocol correctly. // 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 if (layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) // don't focus if constrained
&& !keyboardExclusive && mapped) { && !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); 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; g_pInputManager->m_bEmptyFocusCursorSet = false;
} else if (!layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) { } else if (!layerSurface->current.interactivity && (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) && keyboardExclusive) {
g_pInputManager->refocus(); g_pInputManager->refocus();
@ -319,10 +324,10 @@ void CLayerSurface::onCommit() {
keyboardExclusive = layerSurface->current.interactivity; 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->setPreferredScaleForSurface(surface->resource(), PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(layerSurface->surface, PMONITOR->transform); g_pCompositor->setPreferredTransformForSurface(surface->resource(), PMONITOR->transform);
} }
void CLayerSurface::applyRules() { void CLayerSurface::applyRules() {

View file

@ -36,7 +36,7 @@ class CLayerSurface {
bool keyboardExclusive = false; bool keyboardExclusive = false;
CWLSurface surface; SP<CWLSurface> surface;
bool mapped = false; bool mapped = false;
uint32_t layer = 0; uint32_t layer = 0;

View file

@ -3,6 +3,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include <ranges> #include <ranges>
CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) { CPopup::CPopup(PHLWINDOW pOwner) : m_pWindowOwner(pOwner) {
@ -14,7 +15,8 @@ CPopup::CPopup(PHLLS pOwner) : m_pLayerOwner(pOwner) {
} }
CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner), m_pResource(popup) { CPopup::CPopup(SP<CXDGPopupResource> 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_pLayerOwner = pOwner->m_pLayerOwner;
m_pWindowOwner = pOwner->m_pWindowOwner; m_pWindowOwner = pOwner->m_pWindowOwner;
@ -26,7 +28,8 @@ CPopup::CPopup(SP<CXDGPopupResource> popup, CPopup* pOwner) : m_pParent(pOwner),
} }
CPopup::~CPopup() { CPopup::~CPopup() {
m_sWLSurface.unassign(); if (m_pWLSurface)
m_pWLSurface->unassign();
} }
void CPopup::initAllSignals() { void CPopup::initAllSignals() {
@ -70,13 +73,13 @@ void CPopup::onMap() {
return; return;
m_bMapped = true; m_bMapped = true;
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(); const auto COORDS = coordsGlobal();
const auto PMONITOR = g_pCompositor->getMonitorFromVector(COORDS); const auto PMONITOR = g_pCompositor->getMonitorFromVector(COORDS);
CBox box; CBox box = m_pWLSurface->resource()->extends();
wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr()); box.translate(COORDS).expand(4);
box.applyFromWlr().translate(COORDS).expand(4);
g_pHyprRenderer->damageBox(&box); g_pHyprRenderer->damageBox(&box);
m_vLastPos = coordsRelativeToParent(); m_vLastPos = coordsRelativeToParent();
@ -87,7 +90,7 @@ void CPopup::onMap() {
//unconstrain(); //unconstrain();
sendScale(); 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) if (!m_pLayerOwner.expired() && m_pLayerOwner->layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP)
g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer)); g_pHyprOpenGL->markBlurDirtyForMonitor(g_pCompositor->getMonitorFromID(m_pLayerOwner->layer));
@ -103,12 +106,12 @@ void CPopup::onUnmap() {
return; 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(); const auto COORDS = coordsGlobal();
CBox box; CBox box = m_pWLSurface->resource()->extends();
wlr_surface_get_extends(m_sWLSurface.wlr(), box.pWlr()); box.translate(COORDS).expand(4);
box.applyFromWlr().translate(COORDS).expand(4);
g_pHyprRenderer->damageBox(&box); g_pHyprRenderer->damageBox(&box);
m_pSubsurfaceHead.reset(); m_pSubsurfaceHead.reset();
@ -143,7 +146,7 @@ void CPopup::onCommit(bool ignoreSiblings) {
} }
if (!m_pWindowOwner.expired() && (!m_pWindowOwner->m_bIsMapped || !m_pWindowOwner->m_pWorkspace->m_bVisible)) { 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<Hyprlang::INT>("debug:log_damage"); static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
if (*PLOGDAMAGE) if (*PLOGDAMAGE)
@ -157,11 +160,10 @@ void CPopup::onCommit(bool ignoreSiblings) {
const auto COORDS = coordsGlobal(); const auto COORDS = coordsGlobal();
const auto COORDSLOCAL = coordsRelativeToParent(); const auto COORDSLOCAL = coordsRelativeToParent();
if (m_vLastSize != Vector2D{m_pResource->surface->surface->current.width, m_pResource->surface->surface->current.height} || m_bRequestedReposition || if (m_vLastSize != m_pResource->surface->surface->current.size || m_bRequestedReposition || m_vLastPos != COORDSLOCAL) {
m_vLastPos != COORDSLOCAL) {
CBox box = {localToGlobal(m_vLastPos), m_vLastSize}; CBox box = {localToGlobal(m_vLastPos), m_vLastSize};
g_pHyprRenderer->damageBox(&box); 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}; box = {COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box); g_pHyprRenderer->damageBox(&box);
@ -171,7 +173,7 @@ void CPopup::onCommit(bool ignoreSiblings) {
if (!ignoreSiblings && m_pSubsurfaceHead) if (!ignoreSiblings && m_pSubsurfaceHead)
m_pSubsurfaceHead->recheckDamageForSubsurfaces(); 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; m_bRequestedReposition = false;
@ -211,7 +213,7 @@ Vector2D CPopup::coordsRelativeToParent() {
while (current->m_pParent && current->m_pResource) { 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(); offset += current->m_pResource->geometry.pos();
current = current->m_pParent; current = current->m_pParent;
@ -260,9 +262,9 @@ Vector2D CPopup::size() {
void CPopup::sendScale() { void CPopup::sendScale() {
if (!m_pWindowOwner.expired()) 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()) 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 else
UNREACHABLE(); UNREACHABLE();
} }
@ -318,9 +320,8 @@ CPopup* CPopup::at(const Vector2D& globalCoords, bool allowsInput) {
return p; return p;
} else { } else {
const Vector2D offset = p->m_pResource ? (p->size() - p->m_pResource->geometry.size()) / 2.F : Vector2D{}; 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} const auto REGION =
.intersect(CBox{{}, {p->m_sWLSurface.wlr()->current.width, p->m_sWLSurface.wlr()->current.height}}) CRegion{p->m_pWLSurface->resource()->current.input}.intersect(CBox{{}, p->m_pWLSurface->resource()->current.size}).translate(p->coordsGlobal() + offset);
.translate(p->coordsGlobal() + offset);
if (REGION.containsPoint(globalCoords)) if (REGION.containsPoint(globalCoords))
return p; return p;
} }

View file

@ -39,7 +39,7 @@ class CPopup {
CPopup* at(const Vector2D& globalCoords, bool allowsInput = false); CPopup* at(const Vector2D& globalCoords, bool allowsInput = false);
// //
CWLSurface m_sWLSurface; SP<CWLSurface> m_pWLSurface;
private: private:
// T1 owners, each popup has to have one of these // T1 owners, each popup has to have one of these

View file

@ -2,29 +2,31 @@
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/core/Compositor.hpp"
static void onNewSubsurface(void* owner, void* data); #include "../protocols/core/Subcompositor.hpp"
CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) { CSubsurface::CSubsurface(PHLWINDOW pOwner) : m_pWindowParent(pOwner) {
initSignals(); initSignals();
initExistingSubsurfaces(pOwner->m_pWLSurface.wlr()); initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
} }
CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) { CSubsurface::CSubsurface(CPopup* pOwner) : m_pPopupParent(pOwner) {
initSignals(); initSignals();
initExistingSubsurfaces(pOwner->m_sWLSurface.wlr()); initExistingSubsurfaces(pOwner->m_pWLSurface->resource());
} }
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) { CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner) : m_pSubsurface(pSubsurface), m_pWindowParent(pOwner) {
m_sWLSurface.assign(pSubsurface->surface, this); m_pWLSurface = CWLSurface::create();
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
initSignals(); initSignals();
initExistingSubsurfaces(pSubsurface->surface); initExistingSubsurfaces(pSubsurface->surface.lock());
} }
CSubsurface::CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) { CSubsurface::CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner) : m_pSubsurface(pSubsurface), m_pPopupParent(pOwner) {
m_sWLSurface.assign(pSubsurface->surface, this); m_pWLSurface = CWLSurface::create();
m_pWLSurface->assign(pSubsurface->surface.lock(), this);
initSignals(); initSignals();
initExistingSubsurfaces(pSubsurface->surface); initExistingSubsurfaces(pSubsurface->surface.lock());
} }
CSubsurface::~CSubsurface() { CSubsurface::~CSubsurface() {
@ -33,52 +35,27 @@ CSubsurface::~CSubsurface() {
if (!m_pSubsurface) if (!m_pSubsurface)
return; return;
m_pSubsurface->data = nullptr;
hyprListener_commitSubsurface.removeCallback(); hyprListener_commitSubsurface.removeCallback();
hyprListener_destroySubsurface.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() { void CSubsurface::initSignals() {
if (m_pSubsurface) { if (m_pSubsurface) {
m_pSubsurface->data = this; listeners.commitSubsurface = m_pSubsurface->surface->events.commit.registerListener([this](std::any d) { onCommit(); });
hyprListener_commitSubsurface.initCallback(&m_pSubsurface->surface->events.commit, &onCommitSubsurface, this, "CSubsurface"); listeners.destroySubsurface = m_pSubsurface->events.destroy.registerListener([this](std::any d) { onDestroy(); });
hyprListener_destroySubsurface.initCallback(&m_pSubsurface->events.destroy, &onDestroySubsurface, this, "CSubsurface"); listeners.mapSubsurface = m_pSubsurface->surface->events.map.registerListener([this](std::any d) { onMap(); });
hyprListener_newSubsurface.initCallback(&m_pSubsurface->surface->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface"); listeners.unmapSubsurface = m_pSubsurface->surface->events.unmap.registerListener([this](std::any d) { onUnmap(); });
hyprListener_mapSubsurface.initCallback(&m_pSubsurface->surface->events.map, &onMapSubsurface, this, "CSubsurface"); listeners.newSubsurface =
hyprListener_unmapSubsurface.initCallback(&m_pSubsurface->surface->events.unmap, &onUnmapSubsurface, this, "CSubsurface"); m_pSubsurface->surface->events.newSubsurface.registerListener([this](std::any d) { onNewSubsurface(std::any_cast<SP<CWLSubsurfaceResource>>(d)); });
} else { } else {
if (!m_pWindowParent.expired()) if (m_pWindowParent)
hyprListener_newSubsurface.initCallback(&m_pWindowParent->m_pWLSurface.wlr()->events.new_subsurface, &::onNewSubsurface, this, "CSubsurface Head"); listeners.newSubsurface = m_pWindowParent->m_pWLSurface->resource()->events.newSubsurface.registerListener(
[this](std::any d) { onNewSubsurface(std::any_cast<SP<CWLSubsurfaceResource>>(d)); });
else if (m_pPopupParent) 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<SP<CWLSubsurfaceResource>>(d)); });
else else
RASSERT(false, "CSubsurface::initSignals empty subsurface"); ASSERT(false);
} }
} }
@ -93,21 +70,21 @@ void CSubsurface::checkSiblingDamage() {
continue; continue;
const auto COORDS = n->coordsGlobal(); 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() { void CSubsurface::recheckDamageForSubsurfaces() {
for (auto& n : m_vChildren) { for (auto& n : m_vChildren) {
const auto COORDS = n->coordsGlobal(); 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() { void CSubsurface::onCommit() {
// no damaging if it's not visible // no damaging if it's not visible
if (!m_pWindowParent.expired() && (!m_pWindowParent->m_bIsMapped || !m_pWindowParent->m_pWorkspace->m_bVisible)) { 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<Hyprlang::INT>("debug:log_damage"); static auto PLOGDAMAGE = CConfigValue<Hyprlang::INT>("debug:log_damage");
if (*PLOGDAMAGE) if (*PLOGDAMAGE)
@ -117,7 +94,7 @@ void CSubsurface::onCommit() {
const auto COORDS = coordsGlobal(); 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) if (m_pPopupParent)
m_pPopupParent->recheckTree(); 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) // I do not think this is correct, but it solves a lot of issues with some apps (e.g. firefox)
checkSiblingDamage(); 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}; CBox box{COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box); 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}; box = {COORDS, m_vLastSize};
g_pHyprRenderer->damageBox(&box); 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; }); 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<CWLSubsurfaceResource> pSubsurface) {
CSubsurface* PSUBSURFACE = nullptr; CSubsurface* PSUBSURFACE = nullptr;
if (!m_pWindowParent.expired()) if (!m_pWindowParent.expired())
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get(); PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pWindowParent.lock())).get();
else if (m_pPopupParent) else if (m_pPopupParent)
PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get(); PSUBSURFACE = m_vChildren.emplace_back(std::make_unique<CSubsurface>(pSubsurface, m_pPopupParent)).get();
PSUBSURFACE->m_pParent = this;
ASSERT(PSUBSURFACE); ASSERT(PSUBSURFACE);
PSUBSURFACE->m_pParent = this;
} }
void CSubsurface::onMap() { 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(); const auto COORDS = coordsGlobal();
CBox box{COORDS, m_vLastSize}; CBox box{COORDS, m_vLastSize};
@ -179,7 +157,7 @@ void CSubsurface::onUnmap() {
box.expand(4); box.expand(4);
g_pHyprRenderer->damageBox(&box); 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->releaseAllMouseButtons();
g_pInputManager->simulateMouseMovement(); g_pInputManager->simulateMouseMovement();
@ -188,19 +166,9 @@ void CSubsurface::onUnmap() {
} }
Vector2D CSubsurface::coordsRelativeToParent() { Vector2D CSubsurface::coordsRelativeToParent() {
Vector2D offset; if (!m_pSubsurface)
return {};
CSubsurface* current = this; return m_pSubsurface->posRelativeToParent();
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;
} }
Vector2D CSubsurface::coordsGlobal() { Vector2D CSubsurface::coordsGlobal() {
@ -214,18 +182,16 @@ Vector2D CSubsurface::coordsGlobal() {
return coords; return coords;
} }
void CSubsurface::initExistingSubsurfaces(wlr_surface* pSurface) { void CSubsurface::initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface) {
wlr_subsurface* wlrSubsurface; for (auto& s : pSurface->subsurfaces) {
wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_below, current.link) { if (!s || s->surface->hlSurface /* already assigned */)
::onNewSubsurface(this, wlrSubsurface); continue;
} onNewSubsurface(s.lock());
wl_list_for_each(wlrSubsurface, &pSurface->current.subsurfaces_above, current.link) {
::onNewSubsurface(this, wlrSubsurface);
} }
} }
Vector2D CSubsurface::size() { Vector2D CSubsurface::size() {
return {m_sWLSurface.wlr()->current.width, m_sWLSurface.wlr()->current.height}; return m_pWLSurface->resource()->current.size;
} }
bool CSubsurface::visible() { bool CSubsurface::visible() {

View file

@ -5,6 +5,7 @@
#include "WLSurface.hpp" #include "WLSurface.hpp"
class CPopup; class CPopup;
class CWLSubsurfaceResource;
class CSubsurface { class CSubsurface {
public: public:
@ -13,8 +14,8 @@ class CSubsurface {
CSubsurface(CPopup* pOwner); CSubsurface(CPopup* pOwner);
// real nodes // real nodes
CSubsurface(wlr_subsurface* pSubsurface, PHLWINDOW pOwner); CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, PHLWINDOW pOwner);
CSubsurface(wlr_subsurface* pSubsurface, CPopup* pOwner); CSubsurface(SP<CWLSubsurfaceResource> pSubsurface, CPopup* pOwner);
~CSubsurface(); ~CSubsurface();
@ -25,7 +26,7 @@ class CSubsurface {
void onCommit(); void onCommit();
void onDestroy(); void onDestroy();
void onNewSubsurface(wlr_subsurface* pSubsurface); void onNewSubsurface(SP<CWLSubsurfaceResource> pSubsurface);
void onMap(); void onMap();
void onUnmap(); void onUnmap();
@ -37,11 +38,17 @@ class CSubsurface {
DYNLISTENER(destroySubsurface); DYNLISTENER(destroySubsurface);
DYNLISTENER(commitSubsurface); DYNLISTENER(commitSubsurface);
DYNLISTENER(newSubsurface); DYNLISTENER(newSubsurface);
DYNLISTENER(mapSubsurface);
DYNLISTENER(unmapSubsurface);
wlr_subsurface* m_pSubsurface = nullptr; struct {
CWLSurface m_sWLSurface; CHyprSignalListener destroySubsurface;
CHyprSignalListener commitSubsurface;
CHyprSignalListener mapSubsurface;
CHyprSignalListener unmapSubsurface;
CHyprSignalListener newSubsurface;
} listeners;
WP<CWLSubsurfaceResource> m_pSubsurface;
SP<CWLSurface> m_pWLSurface;
Vector2D m_vLastSize = {}; Vector2D m_vLastSize = {};
// if nullptr, means it's a dummy node // if nullptr, means it's a dummy node
@ -55,6 +62,6 @@ class CSubsurface {
bool m_bInert = false; bool m_bInert = false;
void initSignals(); void initSignals();
void initExistingSubsurfaces(wlr_surface* pSurface); void initExistingSubsurfaces(SP<CWLSurfaceResource> pSurface);
void checkSiblingDamage(); void checkSiblingDamage();
}; };

View file

@ -1,36 +1,37 @@
#include "WLSurface.hpp" #include "WLSurface.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../protocols/core/Compositor.hpp"
void CWLSurface::assign(wlr_surface* pSurface) { void CWLSurface::assign(SP<CWLSurfaceResource> pSurface) {
m_pWLRSurface = pSurface; m_pResource = pSurface;
init(); init();
m_bInert = false; m_bInert = false;
} }
void CWLSurface::assign(wlr_surface* pSurface, PHLWINDOW pOwner) { void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, PHLWINDOW pOwner) {
m_pWindowOwner = pOwner; m_pWindowOwner = pOwner;
m_pWLRSurface = pSurface; m_pResource = pSurface;
init(); init();
m_bInert = false; m_bInert = false;
} }
void CWLSurface::assign(wlr_surface* pSurface, PHLLS pOwner) { void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, PHLLS pOwner) {
m_pLayerOwner = pOwner; m_pLayerOwner = pOwner;
m_pWLRSurface = pSurface; m_pResource = pSurface;
init(); init();
m_bInert = false; m_bInert = false;
} }
void CWLSurface::assign(wlr_surface* pSurface, CSubsurface* pOwner) { void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, CSubsurface* pOwner) {
m_pSubsurfaceOwner = pOwner; m_pSubsurfaceOwner = pOwner;
m_pWLRSurface = pSurface; m_pResource = pSurface;
init(); init();
m_bInert = false; m_bInert = false;
} }
void CWLSurface::assign(wlr_surface* pSurface, CPopup* pOwner) { void CWLSurface::assign(SP<CWLSurfaceResource> pSurface, CPopup* pOwner) {
m_pPopupOwner = pOwner; m_pPopupOwner = pOwner;
m_pWLRSurface = pSurface; m_pResource = pSurface;
init(); init();
m_bInert = false; m_bInert = false;
} }
@ -44,20 +45,23 @@ CWLSurface::~CWLSurface() {
} }
bool CWLSurface::exists() const { bool CWLSurface::exists() const {
return m_pWLRSurface; return m_pResource;
} }
wlr_surface* CWLSurface::wlr() const { SP<CWLSurfaceResource> CWLSurface::resource() const {
return m_pWLRSurface; return m_pResource.lock();
} }
bool CWLSurface::small() const { bool CWLSurface::small() const {
if (!validMapped(m_pWindowOwner) || !exists()) if (!validMapped(m_pWindowOwner) || !exists())
return false; return false;
if (!m_pResource->current.buffer)
return false;
const auto O = m_pWindowOwner.lock(); 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 { Vector2D CWLSurface::correctSmallVec() const {
@ -71,29 +75,28 @@ Vector2D CWLSurface::correctSmallVec() const {
} }
Vector2D CWLSurface::getViewporterCorrectedSize() const { Vector2D CWLSurface::getViewporterCorrectedSize() const {
if (!exists()) if (!exists() || !m_pResource->current.buffer)
return {}; return {};
return m_pWLRSurface->current.viewport.has_dst ? Vector2D{m_pWLRSurface->current.viewport.dst_width, m_pWLRSurface->current.viewport.dst_height} : return m_pResource->current.viewport.hasDestination ? m_pResource->current.viewport.destination : m_pResource->current.buffer->size;
Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height};
} }
CRegion CWLSurface::logicalDamage() const { CRegion CWLSurface::logicalDamage() const {
CRegion damage{&m_pWLRSurface->buffer_damage}; if (!m_pResource->current.buffer)
damage.transform(m_pWLRSurface->current.transform, m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height); return {};
damage.scale(1.0 / m_pWLRSurface->current.scale);
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 VPSIZE = getViewporterCorrectedSize();
const auto CORRECTVEC = correctSmallVec(); const auto CORRECTVEC = correctSmallVec();
if (m_pWLRSurface->current.viewport.has_src) { if (m_pResource->current.viewport.hasSource)
damage.intersect(CBox{std::floor(m_pWLRSurface->current.viewport.src.x), std::floor(m_pWLRSurface->current.viewport.src.y), damage.intersect(m_pResource->current.viewport.source);
std::ceil(m_pWLRSurface->current.viewport.src.width), std::ceil(m_pWLRSurface->current.viewport.src.height)});
}
const auto SCALEDSRCSIZE = m_pWLRSurface->current.viewport.has_src ? const auto SCALEDSRCSIZE =
Vector2D{m_pWLRSurface->current.viewport.src.width, m_pWLRSurface->current.viewport.src.height} * m_pWLRSurface->current.scale : m_pResource->current.viewport.hasSource ? m_pResource->current.viewport.source.size() * m_pResource->current.scale : m_pResource->current.buffer->size;
Vector2D{m_pWLRSurface->current.buffer_width, m_pWLRSurface->current.buffer_height};
damage.scale({VPSIZE.x / SCALEDSRCSIZE.x, VPSIZE.y / SCALEDSRCSIZE.y}); damage.scale({VPSIZE.x / SCALEDSRCSIZE.x, VPSIZE.y / SCALEDSRCSIZE.y});
damage.translate(CORRECTVEC); damage.translate(CORRECTVEC);
@ -102,48 +105,38 @@ CRegion CWLSurface::logicalDamage() const {
} }
void CWLSurface::destroy() { void CWLSurface::destroy() {
if (!m_pWLRSurface) if (!m_pResource)
return; return;
events.destroy.emit(); events.destroy.emit();
m_pConstraint.reset(); m_pConstraint.reset();
hyprListener_destroy.removeCallback(); listeners.destroy.reset();
hyprListener_commit.removeCallback(); m_pResource->hlSurface.reset();
m_pWLRSurface->data = nullptr;
m_pWindowOwner.reset(); m_pWindowOwner.reset();
m_pLayerOwner.reset(); m_pLayerOwner.reset();
m_pPopupOwner = nullptr; m_pPopupOwner = nullptr;
m_pSubsurfaceOwner = nullptr; m_pSubsurfaceOwner = nullptr;
m_bInert = true; m_bInert = true;
if (g_pCompositor && g_pCompositor->m_pLastFocus == m_pWLRSurface) if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf && g_pHyprRenderer->m_sLastCursorData.surf->get() == this)
g_pCompositor->m_pLastFocus = nullptr;
if (g_pHyprRenderer && g_pHyprRenderer->m_sLastCursorData.surf == this)
g_pHyprRenderer->m_sLastCursorData.surf.reset(); g_pHyprRenderer->m_sLastCursorData.surf.reset();
m_pWLRSurface = nullptr; m_pResource.reset();
Debug::log(LOG, "CWLSurface {:x} called destroy()", (uintptr_t)this); 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() { void CWLSurface::init() {
if (!m_pWLRSurface) if (!m_pResource)
return; 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( listeners.destroy = m_pResource->events.destroy.registerListener([this](std::any d) { destroy(); });
&m_pWLRSurface->events.destroy, [&](void* owner, void* data) { destroy(); }, this, "CWLSurface");
hyprListener_commit.initCallback(&m_pWLRSurface->events.commit, ::onCommit, this, "CWLSurface");
Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this); Debug::log(LOG, "CWLSurface {:x} called init()", (uintptr_t)this);
} }
@ -188,10 +181,6 @@ void CWLSurface::appendConstraint(WP<CPointerConstraint> constraint) {
m_pConstraint = constraint; m_pConstraint = constraint;
} }
void CWLSurface::onCommit() {
;
}
SP<CPointerConstraint> CWLSurface::constraint() { SP<CPointerConstraint> CWLSurface::constraint() {
return m_pConstraint.lock(); return m_pConstraint.lock();
} }
@ -207,3 +196,9 @@ bool CWLSurface::visible() {
return m_pSubsurfaceOwner->visible(); return m_pSubsurfaceOwner->visible();
return true; // non-desktop, we don't know much. return true; // non-desktop, we don't know much.
} }
SP<CWLSurface> CWLSurface::fromResource(SP<CWLSurfaceResource> pSurface) {
if (!pSurface)
return nullptr;
return pSurface->hlSurface.lock();
}

View file

@ -7,18 +7,23 @@
class CSubsurface; class CSubsurface;
class CPopup; class CPopup;
class CPointerConstraint; class CPointerConstraint;
class CWLSurfaceResource;
class CWLSurface { class CWLSurface {
public: public:
CWLSurface() = default; static SP<CWLSurface> create() {
auto p = SP<CWLSurface>(new CWLSurface);
p->self = p;
return p;
}
~CWLSurface(); ~CWLSurface();
// anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD // anonymous surfaces are non-desktop components, e.g. a cursor surface or a DnD
void assign(wlr_surface* pSurface); void assign(SP<CWLSurfaceResource> pSurface);
void assign(wlr_surface* pSurface, PHLWINDOW pOwner); void assign(SP<CWLSurfaceResource> pSurface, PHLWINDOW pOwner);
void assign(wlr_surface* pSurface, PHLLS pOwner); void assign(SP<CWLSurfaceResource> pSurface, PHLLS pOwner);
void assign(wlr_surface* pSurface, CSubsurface* pOwner); void assign(SP<CWLSurfaceResource> pSurface, CSubsurface* pOwner);
void assign(wlr_surface* pSurface, CPopup* pOwner); void assign(SP<CWLSurfaceResource> pSurface, CPopup* pOwner);
void unassign(); void unassign();
CWLSurface(const CWLSurface&) = delete; CWLSurface(const CWLSurface&) = delete;
@ -26,13 +31,12 @@ class CWLSurface {
CWLSurface& operator=(const CWLSurface&) = delete; CWLSurface& operator=(const CWLSurface&) = delete;
CWLSurface& operator=(CWLSurface&&) = delete; CWLSurface& operator=(CWLSurface&&) = delete;
wlr_surface* wlr() const; SP<CWLSurfaceResource> resource() const;
bool exists() const; bool exists() const;
bool small() const; // means surface is smaller than the requested size bool small() const; // means surface is smaller than the requested size
Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces Vector2D correctSmallVec() const; // returns a corrective vector for small() surfaces
Vector2D getViewporterCorrectedSize() const; Vector2D getViewporterCorrectedSize() const;
CRegion logicalDamage() const; CRegion logicalDamage() const;
void onCommit();
bool visible(); bool visible();
// getters for owners. // getters for owners.
@ -55,31 +59,27 @@ class CWLSurface {
wl_output_transform m_eLastTransform = (wl_output_transform)-1; wl_output_transform m_eLastTransform = (wl_output_transform)-1;
// //
CWLSurface& operator=(wlr_surface* pSurface) { CWLSurface& operator=(SP<CWLSurfaceResource> pSurface) {
destroy(); destroy();
m_pWLRSurface = pSurface; m_pResource = pSurface;
init(); init();
return *this; return *this;
} }
bool operator==(const CWLSurface& other) const { bool operator==(const CWLSurface& other) const {
return other.wlr() == wlr(); return other.resource() == resource();
} }
bool operator==(const wlr_surface* other) const { bool operator==(const SP<CWLSurfaceResource> other) const {
return other == wlr(); return other == resource();
} }
explicit operator bool() const { explicit operator bool() const {
return exists(); return exists();
} }
static CWLSurface* surfaceFromWlr(wlr_surface* pSurface) { static SP<CWLSurface> fromResource(SP<CWLSurfaceResource> pSurface);
if (!pSurface)
return nullptr;
return (CWLSurface*)pSurface->data;
}
// used by the alpha-modifier protocol // used by the alpha-modifier protocol
float m_pAlphaModifier = 1.F; float m_pAlphaModifier = 1.F;
@ -88,10 +88,14 @@ class CWLSurface {
CSignal destroy; CSignal destroy;
} events; } events;
WP<CWLSurface> self;
private: private:
CWLSurface() = default;
bool m_bInert = true; bool m_bInert = true;
wlr_surface* m_pWLRSurface = nullptr; WP<CWLSurfaceResource> m_pResource;
PHLWINDOWREF m_pWindowOwner; PHLWINDOWREF m_pWindowOwner;
PHLLSREF m_pLayerOwner; PHLLSREF m_pLayerOwner;
@ -105,8 +109,9 @@ class CWLSurface {
void init(); void init();
bool desktopComponent(); bool desktopComponent();
DYNLISTENER(destroy); struct {
DYNLISTENER(commit); CHyprSignalListener destroy;
} listeners;
friend class CPointerConstraint; friend class CPointerConstraint;
}; };

View file

@ -9,6 +9,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../managers/TokenManager.hpp" #include "../managers/TokenManager.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XWayland.hpp" #include "../xwayland/XWayland.hpp"
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) { PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
@ -51,12 +52,14 @@ PHLWINDOW CWindow::create(SP<CXDGSurfaceResource> resource) {
pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow)); pWindow->addWindowDeco(std::make_unique<CHyprDropShadowDecoration>(pWindow));
pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow)); pWindow->addWindowDeco(std::make_unique<CHyprBorderDecoration>(pWindow));
pWindow->m_pWLSurface.assign(pWindow->m_pXDGSurface->surface, pWindow); pWindow->m_pWLSurface->assign(pWindow->m_pXDGSurface->surface.lock(), pWindow);
return pWindow; return pWindow;
} }
CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) { CWindow::CWindow(SP<CXDGSurfaceResource> 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.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<uint32_t>(d)); }); listeners.ack = m_pXDGSurface->events.ack.registerListener([this](std::any d) { onAck(std::any_cast<uint32_t>(d)); });
listeners.unmap = m_pXDGSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); }); listeners.unmap = m_pXDGSurface->events.unmap.registerListener([this](std::any d) { Events::listener_unmapWindow(this, nullptr); });
@ -67,6 +70,8 @@ CWindow::CWindow(SP<CXDGSurfaceResource> resource) : m_pXDGSurface(resource) {
} }
CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) { CWindow::CWindow(SP<CXWaylandSurface> 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.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.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); }); listeners.destroy = m_pXWaylandSurface->events.destroy.registerListener([this](std::any d) { Events::listener_destroyWindow(this, nullptr); });
@ -83,7 +88,7 @@ CWindow::CWindow(SP<CXWaylandSurface> surface) : m_pXWaylandSurface(surface) {
CWindow::~CWindow() { CWindow::~CWindow() {
if (g_pCompositor->m_pLastWindow.lock().get() == this) { if (g_pCompositor->m_pLastWindow.lock().get() == this) {
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
g_pCompositor->m_pLastWindow.reset(); g_pCompositor->m_pLastWindow.reset();
} }
@ -124,12 +129,12 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y) if (EXTENTS.bottomRight.y > maxExtents.bottomRight.y)
maxExtents.bottomRight.y = EXTENTS.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}; CBox surfaceExtents = {0, 0, 0, 0};
// TODO: this could be better, perhaps make a getFullWindowRegion? // TODO: this could be better, perhaps make a getFullWindowRegion?
m_pPopupHead->breadthfirst( m_pPopupHead->breadthfirst(
[](CPopup* popup, void* data) { [](CPopup* popup, void* data) {
if (!popup->m_sWLSurface.wlr()) if (!popup->m_pWLSurface || !popup->m_pWLSurface->resource())
return; return;
CBox* pSurfaceExtents = (CBox*)data; CBox* pSurfaceExtents = (CBox*)data;
@ -151,11 +156,11 @@ SWindowDecorationExtents CWindow::getFullWindowExtents() {
if (-surfaceExtents.y > maxExtents.topLeft.y) if (-surfaceExtents.y > maxExtents.topLeft.y)
maxExtents.topLeft.y = -surfaceExtents.y; maxExtents.topLeft.y = -surfaceExtents.y;
if (surfaceExtents.x + surfaceExtents.width > m_pWLSurface.wlr()->current.width + maxExtents.bottomRight.x) if (surfaceExtents.x + surfaceExtents.width > m_pWLSurface->resource()->current.size.x + maxExtents.bottomRight.x)
maxExtents.bottomRight.x = surfaceExtents.x + surfaceExtents.width - m_pWLSurface.wlr()->current.width; 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) if (surfaceExtents.y + surfaceExtents.height > m_pWLSurface->resource()->current.size.y + maxExtents.bottomRight.y)
maxExtents.bottomRight.y = surfaceExtents.y + surfaceExtents.height - m_pWLSurface.wlr()->current.height; maxExtents.bottomRight.y = surfaceExtents.y + surfaceExtents.height - m_pWLSurface->resource()->current.size.y;
} }
return maxExtents; return maxExtents;
@ -340,17 +345,7 @@ void CWindow::updateToplevel() {
updateSurfaceScaleTransformDetails(); updateSurfaceScaleTransformDetails();
} }
void sendEnterIter(wlr_surface* pSurface, int x, int y, void* data) { void CWindow::updateSurfaceScaleTransformDetails(bool force) {
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() {
if (!m_bIsMapped || m_bHidden || g_pCompositor->m_bUnsafeState) if (!m_bIsMapped || m_bHidden || g_pCompositor->m_bUnsafeState)
return; return;
@ -363,26 +358,25 @@ void CWindow::updateSurfaceScaleTransformDetails() {
if (!PNEWMONITOR) if (!PNEWMONITOR)
return; return;
if (PNEWMONITOR != PLASTMONITOR) { if (PNEWMONITOR != PLASTMONITOR || force) {
if (PLASTMONITOR && PLASTMONITOR->m_bEnabled) if (PLASTMONITOR && PLASTMONITOR->m_bEnabled && PNEWMONITOR != PLASTMONITOR)
wlr_surface_for_each_surface(m_pWLSurface.wlr(), sendLeaveIter, PLASTMONITOR->output); m_pWLSurface->resource()->breadthfirst([PLASTMONITOR](SP<CWLSurfaceResource> 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<CWLSurfaceResource> s, const Vector2D& offset, void* d) { s->enter(PNEWMONITOR->self.lock()); }, nullptr);
} }
wlr_surface_for_each_surface( m_pWLSurface->resource()->breadthfirst(
m_pWLSurface.wlr(), [this](SP<CWLSurfaceResource> s, const Vector2D& offset, void* d) {
[](wlr_surface* surf, int x, int y, void* data) { const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iMonitorID);
const auto PMONITOR = g_pCompositor->getMonitorFromID(((CWindow*)data)->m_iMonitorID);
const auto PSURFACE = CWLSurface::surfaceFromWlr(surf); const auto PSURFACE = CWLSurface::fromResource(s);
if (PSURFACE && PSURFACE->m_fLastScale == PMONITOR->scale) if (PSURFACE && PSURFACE->m_fLastScale == PMONITOR->scale)
return; return;
g_pCompositor->setPreferredScaleForSurface(surf, PMONITOR->scale); g_pCompositor->setPreferredScaleForSurface(s, PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(surf, PMONITOR->transform); g_pCompositor->setPreferredTransformForSurface(s, PMONITOR->transform);
}, },
this); nullptr);
} }
void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) { void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
@ -568,6 +562,8 @@ void CWindow::onMap() {
m_vReportedSize = m_vPendingReportedSize; m_vReportedSize = m_vPendingReportedSize;
m_bAnimatingIn = true; m_bAnimatingIn = true;
updateSurfaceScaleTransformDetails(true);
if (m_bIsX11) if (m_bIsX11)
return; return;
@ -860,7 +856,7 @@ bool CWindow::hasPopupAt(const Vector2D& pos) {
CPopup* popup = m_pPopupHead->at(pos); CPopup* popup = m_pPopupHead->at(pos);
return popup && popup->m_sWLSurface.wlr(); return popup && popup->m_pWLSurface->resource();
} }
void CWindow::applyGroupRules() { void CWindow::applyGroupRules() {
@ -1135,23 +1131,24 @@ bool CWindow::opaque() {
const auto PWORKSPACE = m_pWorkspace; const auto PWORKSPACE = m_pWorkspace;
if (m_pWLSurface.small() && !m_pWLSurface.m_bFillIgnoreSmall) if (m_pWLSurface->small() && !m_pWLSurface->m_bFillIgnoreSmall)
return false; return false;
if (PWORKSPACE->m_fAlpha.value() != 1.f) if (PWORKSPACE->m_fAlpha.value() != 1.f)
return false; return false;
if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface) if (m_bIsX11 && m_pXWaylandSurface && m_pXWaylandSurface->surface && m_pXWaylandSurface->surface->current.buffer)
return m_pXWaylandSurface->surface->opaque; return m_pXWaylandSurface->surface->current.buffer->opaque;
if (m_pXDGSurface && m_pXDGSurface->surface->opaque)
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;
if (!m_pWLSurface->resource() || !m_pWLSurface->resource()->current.buffer)
return false; 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;
return m_pWLSurface->resource()->current.buffer->opaque;
} }
float CWindow::rounding() { float CWindow::rounding() {
@ -1282,8 +1279,7 @@ int CWindow::surfacesCount() {
return 1; return 1;
int no = 0; int no = 0;
wlr_surface_for_each_surface( m_pWLSurface->resource()->breadthfirst([](SP<CWLSurfaceResource> r, const Vector2D& offset, void* d) { *((int*)d) += 1; }, &no);
m_pWLSurface.wlr(), [](wlr_surface* surf, int x, int y, void* data) { *((int*)data) += 1; }, &no);
return no; return no;
} }
@ -1456,16 +1452,16 @@ void CWindow::onAck(uint32_t serial) {
} }
void CWindow::onResourceChangeX11() { void CWindow::onResourceChangeX11() {
if (m_pXWaylandSurface->surface && !m_pWLSurface.wlr()) if (m_pXWaylandSurface->surface && !m_pWLSurface->resource())
m_pWLSurface.assign(m_pXWaylandSurface->surface, m_pSelf.lock()); m_pWLSurface->assign(m_pXWaylandSurface->surface.lock(), m_pSelf.lock());
else if (!m_pXWaylandSurface->surface && m_pWLSurface.wlr()) else if (!m_pXWaylandSurface->surface && m_pWLSurface->resource())
m_pWLSurface.unassign(); m_pWLSurface->unassign();
// update metadata as well, // update metadata as well,
// could be first assoc and we need to catch the class // could be first assoc and we need to catch the class
onUpdateMeta(); 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) { void CWindow::onX11Configure(CBox box) {

View file

@ -213,7 +213,7 @@ class CWindow {
public: public:
~CWindow(); ~CWindow();
CWLSurface m_pWLSurface; SP<CWLSurface> m_pWLSurface;
struct { struct {
CSignal destroy; CSignal destroy;
@ -396,7 +396,7 @@ class CWindow {
IHyprWindowDecoration* getDecorationByType(eDecorationType); IHyprWindowDecoration* getDecorationByType(eDecorationType);
void removeDecorationByType(eDecorationType); void removeDecorationByType(eDecorationType);
void updateToplevel(); void updateToplevel();
void updateSurfaceScaleTransformDetails(); void updateSurfaceScaleTransformDetails(bool force = false);
void moveToWorkspace(PHLWORKSPACE); void moveToWorkspace(PHLWORKSPACE);
PHLWINDOW X11TransientFor(); PHLWINDOW X11TransientFor();
void onUnmap(); void onUnmap();

View file

@ -1,6 +1,7 @@
#include "Tablet.hpp" #include "Tablet.hpp"
#include "../defines.hpp" #include "../defines.hpp"
#include "../protocols/Tablet.hpp" #include "../protocols/Tablet.hpp"
#include "../protocols/core/Compositor.hpp"
SP<CTablet> CTablet::create(wlr_tablet* tablet) { SP<CTablet> CTablet::create(wlr_tablet* tablet) {
SP<CTablet> pTab = SP<CTablet>(new CTablet(tablet)); SP<CTablet> pTab = SP<CTablet>(new CTablet(tablet));
@ -295,32 +296,29 @@ CTabletTool::~CTabletTool() {
void CTabletTool::disconnectCallbacks() { void CTabletTool::disconnectCallbacks() {
hyprListener_destroy.removeCallback(); hyprListener_destroy.removeCallback();
hyprListener_destroySurface.removeCallback(); listeners.destroySurface.reset();
} }
wlr_surface* CTabletTool::getSurface() { SP<CWLSurfaceResource> CTabletTool::getSurface() {
return pSurface; return pSurface.lock();
} }
void CTabletTool::setSurface(wlr_surface* surf) { void CTabletTool::setSurface(SP<CWLSurfaceResource> surf) {
if (surf == pSurface) if (surf == pSurface)
return; return;
if (pSurface) { if (pSurface) {
hyprListener_destroySurface.removeCallback(); listeners.destroySurface.reset();
pSurface = nullptr; pSurface.reset();
} }
pSurface = surf; pSurface = surf;
if (surf) { if (surf) {
hyprListener_destroySurface.initCallback( listeners.destroySurface = surf->events.destroy.registerListener([this](std::any d) {
&surf->events.destroy,
[this](void* owner, void* data) {
PROTO::tablet->proximityOut(self.lock()); PROTO::tablet->proximityOut(self.lock());
pSurface = nullptr; pSurface.reset();
hyprListener_destroySurface.removeCallback(); listeners.destroySurface.reset();
}, });
this, "CTabletTool");
} }
} }

View file

@ -12,6 +12,7 @@ struct wlr_tablet_pad;
class CTabletTool; class CTabletTool;
class CTabletPad; class CTabletPad;
class CWLSurfaceResource;
/* /*
A tablet device A tablet device
@ -200,8 +201,8 @@ class CTabletTool : public IHID {
virtual uint32_t getCapabilities(); virtual uint32_t getCapabilities();
wlr_tablet_tool* wlr(); wlr_tablet_tool* wlr();
virtual eHIDType getType(); virtual eHIDType getType();
wlr_surface* getSurface(); SP<CWLSurfaceResource> getSurface();
void setSurface(wlr_surface*); void setSurface(SP<CWLSurfaceResource>);
WP<CTabletTool> self; WP<CTabletTool> self;
Vector2D tilt; Vector2D tilt;
@ -219,10 +220,13 @@ class CTabletTool : public IHID {
void disconnectCallbacks(); void disconnectCallbacks();
wlr_surface* pSurface = nullptr; WP<CWLSurfaceResource> pSurface;
wlr_tablet_tool* tool = nullptr; wlr_tablet_tool* tool = nullptr;
DYNLISTENER(destroy); DYNLISTENER(destroy);
DYNLISTENER(destroySurface);
struct {
CHyprSignalListener destroySurface;
} listeners;
}; };

View file

@ -9,6 +9,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/LayerShell.hpp" #include "../protocols/LayerShell.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp" #include "../xwayland/XSurface.hpp"
// ------------------------------------------------------------ // // ------------------------------------------------------------ //
@ -104,7 +105,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// registers the animated vars and stuff // registers the animated vars and stuff
PWINDOW->onMap(); PWINDOW->onMap();
const auto PWINDOWSURFACE = PWINDOW->m_pWLSurface.wlr(); const auto PWINDOWSURFACE = PWINDOW->m_pWLSurface->resource();
if (!PWINDOWSURFACE) { if (!PWINDOWSURFACE) {
g_pCompositor->removeWindowFromVectorSafe(PWINDOW); g_pCompositor->removeWindowFromVectorSafe(PWINDOW);
@ -463,7 +464,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
// check LS focus grab // check LS focus grab
const auto PFORCEFOCUS = g_pCompositor->getForceFocus(); 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) if (PLSFROMFOCUS && PLSFROMFOCUS->layerSurface->current.interactivity != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE)
PWINDOW->m_bNoInitialFocus = true; PWINDOW->m_bNoInitialFocus = true;
if (PWINDOW->m_pWorkspace->m_bHasFullscreenWindow && !requestsFullscreen && !PWINDOW->m_bIsFloating) { 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) if (PWORKSPACE->m_bHasFullscreenWindow && !PWINDOW->m_bIsFullscreen && !PWINDOW->m_bIsFloating)
PWINDOW->m_fAlpha.setValueAndWarp(0.f); PWINDOW->m_fAlpha.setValueAndWarp(0.f);
g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->scale); g_pCompositor->setPreferredScaleForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->scale);
g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface.wlr(), PMONITOR->transform); g_pCompositor->setPreferredTransformForSurface(PWINDOW->m_pWLSurface->resource(), PMONITOR->transform);
if (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained()) if (g_pSeatManager->mouse.expired() || !g_pInputManager->isConstrained())
g_pInputManager->sendMotionEventsToFocused(); g_pInputManager->sendMotionEventsToFocused();
@ -638,7 +639,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
Debug::log(LOG, "{:c} unmapped", PWINDOW); 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); Debug::log(WARN, "{} unmapped without being mapped??", PWINDOW);
PWINDOW->m_bFadingOut = false; PWINDOW->m_bFadingOut = false;
return; return;
@ -674,7 +675,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) { if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) {
wasLastWindow = true; wasLastWindow = true;
g_pCompositor->m_pLastWindow.reset(); g_pCompositor->m_pLastWindow.reset();
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
g_pInputManager->releaseAllMouseButtons(); g_pInputManager->releaseAllMouseButtons();
} }
@ -788,7 +789,7 @@ void Events::listener_commitWindow(void* owner, void* data) {
if (!PWINDOW->m_pWorkspace->m_bVisible) if (!PWINDOW->m_pWorkspace->m_bVisible)
return; 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); PWINDOW->m_bIsX11 ? 1.0 / PWINDOW->m_fX11SurfaceScaledBy : 1.0);
if (!PWINDOW->m_bIsX11) { 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 // tearing: if solitary, redraw it. This still might be a single surface window
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear && if (PMONITOR && PMONITOR->solitaryClient.lock() == PWINDOW && PWINDOW->canBeTorn() && PMONITOR->tearingState.canTear && PWINDOW->m_pWLSurface->resource()->current.buffer) {
PWINDOW->m_pWLSurface.wlr()->current.committed & WLR_SURFACE_STATE_BUFFER) { CRegion damageBox{PWINDOW->m_pWLSurface->resource()->current.bufferDamage};
CRegion damageBox{&PWINDOW->m_pWLSurface.wlr()->buffer_damage};
if (!damageBox.empty()) { if (!damageBox.empty()) {
if (PMONITOR->tearingState.busy) { if (PMONITOR->tearingState.busy) {
@ -820,10 +820,10 @@ void Events::listener_destroyWindow(void* owner, void* data) {
if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) { if (PWINDOW == g_pCompositor->m_pLastWindow.lock()) {
g_pCompositor->m_pLastWindow.reset(); 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 = {}; PWINDOW->listeners = {};

271
src/helpers/Format.cpp Normal file
View file

@ -0,0 +1,271 @@
#include "Format.hpp"
#include <vector>
#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<SPixelFormat> 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;
}

37
src/helpers/Format.hpp Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include <cstdint>
#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<uint64_t> 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);
};

View file

@ -857,33 +857,6 @@ void throwError(const std::string& err) {
throw std::runtime_error(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) { bool envEnabled(const std::string& env) {
const auto ENV = getenv(env.c_str()); const auto ENV = getenv(env.c_str());
if (!ENV) if (!ENV)
@ -922,3 +895,42 @@ int allocateSHMFile(size_t len) {
return fd; 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;
}

View file

@ -35,10 +35,9 @@ double normalizeAngleRad(double ang);
std::string replaceInString(std::string subject, const std::string& search, const std::string& replace); std::string replaceInString(std::string subject, const std::string& search, const std::string& replace);
std::vector<SCallstackFrameInfo> getBacktrace(); std::vector<SCallstackFrameInfo> getBacktrace();
void throwError(const std::string& err); void throwError(const std::string& err);
uint32_t drmFormatToGL(uint32_t drm);
uint32_t glFormatToType(uint32_t gl);
bool envEnabled(const std::string& env); bool envEnabled(const std::string& env);
int allocateSHMFile(size_t len); int allocateSHMFile(size_t len);
bool allocateSHMFilePair(size_t size, int* rw_fd_ptr, int* ro_fd_ptr);
template <typename... Args> template <typename... Args>
[[deprecated("use std::format instead")]] std::string getFormat(std::format_string<Args...> fmt, Args&&... args) { [[deprecated("use std::format instead")]] std::string getFormat(std::format_string<Args...> fmt, Args&&... args) {

View file

@ -216,7 +216,6 @@ void CMonitor::onConnect(bool noRule) {
PROTO::gamma->applyGammaToState(this); PROTO::gamma->applyGammaToState(this);
events.connect.emit(); events.connect.emit();
updateGlobal();
} }
void CMonitor::onDisconnect(bool destroy) { void CMonitor::onDisconnect(bool destroy) {
@ -284,8 +283,6 @@ void CMonitor::onDisconnect(bool destroy) {
m_bEnabled = false; m_bEnabled = false;
m_bRenderingInitPassed = false; m_bRenderingInitPassed = false;
updateGlobal();
if (BACKUPMON) { if (BACKUPMON) {
// snap cursor // snap cursor
g_pCompositor->warpCursorTo(BACKUPMON->vecPosition + BACKUPMON->vecTransformedSize / 2.F, true); g_pCompositor->warpCursorTo(BACKUPMON->vecPosition + BACKUPMON->vecTransformedSize / 2.F, true);
@ -304,7 +301,7 @@ void CMonitor::onDisconnect(bool destroy) {
w->startAnim(true, true, true); w->startAnim(true, true, true);
} }
} else { } else {
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
g_pCompositor->m_pLastWindow.reset(); g_pCompositor->m_pLastWindow.reset();
g_pCompositor->m_pLastMonitor.reset(); g_pCompositor->m_pLastMonitor.reset();
} }
@ -750,13 +747,6 @@ CBox CMonitor::logicalBox() {
return {vecPosition, vecSize}; 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) { CMonitorState::CMonitorState(CMonitor* owner) {
m_pOwner = owner; m_pOwner = owner;
wlr_output_state_init(&m_state); wlr_output_state_init(&m_state);

View file

@ -172,7 +172,6 @@ class CMonitor {
int64_t activeWorkspaceID(); int64_t activeWorkspaceID();
int64_t activeSpecialWorkspaceID(); int64_t activeSpecialWorkspaceID();
CBox logicalBox(); CBox logicalBox();
void updateGlobal();
bool m_bEnabled = false; bool m_bEnabled = false;
bool m_bRenderingInitPassed = false; bool m_bRenderingInitPassed = false;

View file

@ -4,6 +4,8 @@ extern "C" {
#include <wlr/util/region.h> #include <wlr/util/region.h>
} }
constexpr const int64_t MAX_REGION_SIDE = 10000000;
CRegion::CRegion() { CRegion::CRegion() {
pixman_region32_init(&m_rRegion); pixman_region32_init(&m_rRegion);
} }
@ -103,6 +105,11 @@ CRegion& CRegion::transform(const wl_output_transform t, double w, double h) {
return *this; 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 { CRegion CRegion::copy() const {
return CRegion(*this); return CRegion(*this);
} }

View file

@ -50,6 +50,7 @@ class CRegion {
CRegion& invert(const CBox& box); CRegion& invert(const CBox& box);
CRegion& scale(float scale); CRegion& scale(float scale);
CRegion& scale(const Vector2D& scale); CRegion& scale(const Vector2D& scale);
CRegion& rationalize();
CBox getExtents(); CBox getExtents();
bool containsPoint(const Vector2D& vec) const; bool containsPoint(const Vector2D& vec) const;
bool empty() const; bool empty() const;

View file

@ -13,6 +13,7 @@
class CMonitor; class CMonitor;
class IPointer; class IPointer;
class IKeyboard; class IKeyboard;
class CWLSurfaceResource;
struct SRenderData { struct SRenderData {
CMonitor* pMonitor; CMonitor* pMonitor;
@ -21,7 +22,7 @@ struct SRenderData {
// for iters // for iters
void* data = nullptr; void* data = nullptr;
wlr_surface* surface = nullptr; SP<CWLSurfaceResource> surface = nullptr;
double w, h; double w, h;
// for rounding // for rounding
@ -52,12 +53,6 @@ struct SRenderData {
bool popup = false; bool popup = false;
}; };
struct SExtensionFindingData {
Vector2D origin;
Vector2D vec;
wlr_surface** found;
};
struct SSwipeGesture { struct SSwipeGesture {
PHLWORKSPACE pWorkspaceBegin = nullptr; PHLWORKSPACE pWorkspaceBegin = nullptr;

View file

@ -60,7 +60,7 @@ namespace CSharedPointer_ {
bool _destroying = false; bool _destroying = false;
void _destroy() { void _destroy() {
if (!_data) if (!_data || _destroying)
return; return;
// first, we destroy the data, but keep the pointer. // first, we destroy the data, but keep the pointer.
@ -297,6 +297,6 @@ static CSharedPointer<U> makeShared(Args&&... args) {
template <typename T> template <typename T>
struct std::hash<CSharedPointer<T>> { struct std::hash<CSharedPointer<T>> {
std::size_t operator()(const CSharedPointer<T>& p) const noexcept { std::size_t operator()(const CSharedPointer<T>& p) const noexcept {
return std::hash<void*>{}(p->impl_); return std::hash<void*>{}(p.impl_);
} }
}; };

View file

@ -185,6 +185,6 @@ class CWeakPointer {
template <typename T> template <typename T>
struct std::hash<CWeakPointer<T>> { struct std::hash<CWeakPointer<T>> {
std::size_t operator()(const CWeakPointer<T>& p) const noexcept { std::size_t operator()(const CWeakPointer<T>& p) const noexcept {
return std::hash<void*>{}(p->impl_); return std::hash<void*>{}(p.impl_);
} }
}; };

View file

@ -4,17 +4,38 @@
void CSignal::emit(std::any data) { void CSignal::emit(std::any data) {
bool dirty = false; bool dirty = false;
std::vector<SP<CSignalListener>> listeners;
for (auto& l : m_vListeners) { for (auto& l : m_vListeners) {
if (const CHyprSignalListener L = l.lock()) if (l.expired()) {
L->emit(data);
else
dirty = true; dirty = true;
continue;
} }
listeners.emplace_back(l.lock());
}
std::vector<CStaticSignalListener*> statics;
for (auto& l : m_vStaticListeners) { 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); l->emit(data);
} }
for (auto& l : statics) {
l->emit(data);
}
// release SPs
listeners.clear();
if (dirty) if (dirty)
std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); }); std::erase_if(m_vListeners, [](const auto& other) { return other.expired(); });
} }

View file

@ -22,6 +22,8 @@ CHyprError::CHyprError() {
if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged) if (m_fFadeOpacity.isBeingAnimated() || m_bMonitorChanged)
g_pHyprRenderer->damageBox(&m_bDamageBox); g_pHyprRenderer->damageBox(&m_bDamageBox);
}); });
m_pTexture = makeShared<CTexture>();
} }
CHyprError::~CHyprError() { CHyprError::~CHyprError() {
@ -34,9 +36,8 @@ void CHyprError::queueCreate(std::string message, const CColor& color) {
} }
void CHyprError::createQueued() { void CHyprError::createQueued() {
if (m_bIsCreated) { if (m_bIsCreated)
m_tTexture.destroyTexture(); m_pTexture->destroyTexture();
}
m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn")); m_fFadeOpacity.setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
@ -136,8 +137,8 @@ void CHyprError::createQueued() {
// copy the data to an OpenGL texture we have // copy the data to an OpenGL texture we have
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
m_tTexture.allocate(); m_pTexture->allocate();
glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID); glBindTexture(GL_TEXTURE_2D, m_pTexture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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.isBeingAnimated()) {
if (m_fFadeOpacity.value() == 0.f) { if (m_fFadeOpacity.value() == 0.f) {
m_bQueuedDestroy = false; m_bQueuedDestroy = false;
m_tTexture.destroyTexture(); m_pTexture->destroyTexture();
m_bIsCreated = false; m_bIsCreated = false;
m_szQueued = ""; m_szQueued = "";
return; return;
@ -193,7 +194,7 @@ void CHyprError::draw() {
m_bMonitorChanged = false; 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() { void CHyprError::destroy() {

View file

@ -21,7 +21,7 @@ class CHyprError {
CColor m_cQueued; CColor m_cQueued;
bool m_bQueuedDestroy = false; bool m_bQueuedDestroy = false;
bool m_bIsCreated = false; bool m_bIsCreated = false;
CTexture m_tTexture; SP<CTexture> m_pTexture;
CAnimatedVariable<float> m_fFadeOpacity; CAnimatedVariable<float> m_fFadeOpacity;
CBox m_bDamageBox = {0, 0, 0, 0}; CBox m_bDamageBox = {0, 0, 0, 0};

View file

@ -5,6 +5,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../desktop/Window.hpp" #include "../desktop/Window.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XSurface.hpp" #include "../xwayland/XSurface.hpp"
void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) { void IHyprLayout::onWindowCreated(PHLWINDOW pWindow, eDirection direction) {
@ -99,8 +100,8 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
} }
if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) { if (desiredGeometry.width <= 5 || desiredGeometry.height <= 5) {
const auto PWINDOWSURFACE = pWindow->m_pWLSurface.wlr(); const auto PWINDOWSURFACE = pWindow->m_pWLSurface->resource();
pWindow->m_vRealSize = Vector2D(PWINDOWSURFACE->current.width, PWINDOWSURFACE->current.height); pWindow->m_vRealSize = PWINDOWSURFACE->current.size;
if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 && if ((desiredGeometry.width <= 1 || desiredGeometry.height <= 1) && pWindow->m_bIsX11 &&
pWindow->m_iX11Type == 2) { // XDG windows should be fine. TODO: check for weird atoms? pWindow->m_iX11Type == 2) { // XDG windows should be fine. TODO: check for weird atoms?

View file

@ -90,3 +90,13 @@
#else #else
#define UNREACHABLE() std::unreachable(); #define UNREACHABLE() std::unreachable();
#endif #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); \
} \
}

View file

@ -117,8 +117,8 @@ wlr_buffer* CCursorManager::getCursorBuffer() {
return !m_vCursorBuffers.empty() ? &m_vCursorBuffers.back()->wlrBuffer.base : nullptr; return !m_vCursorBuffers.empty() ? &m_vCursorBuffers.back()->wlrBuffer.base : nullptr;
} }
void CCursorManager::setCursorSurface(CWLSurface* surf, const Vector2D& hotspot) { void CCursorManager::setCursorSurface(SP<CWLSurface> surf, const Vector2D& hotspot) {
if (!surf || !surf->wlr()) if (!surf || !surf->resource())
g_pPointerManager->resetCursorImage(); g_pPointerManager->resetCursorImage();
else else
g_pPointerManager->setCursorSurface(surf, hotspot); g_pPointerManager->setCursorSurface(surf, hotspot);

View file

@ -18,7 +18,7 @@ class CCursorManager {
wlr_buffer* getCursorBuffer(); wlr_buffer* getCursorBuffer();
void setCursorFromName(const std::string& name); void setCursorFromName(const std::string& name);
void setCursorSurface(CWLSurface* surf, const Vector2D& hotspot); void setCursorSurface(SP<CWLSurface> surf, const Vector2D& hotspot);
void setXCursor(const std::string& name); void setXCursor(const std::string& name);
bool changeTheme(const std::string& name, const int size); bool changeTheme(const std::string& name, const int size);

View file

@ -2003,14 +2003,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 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 // pass all mf shit
if (!XWTOXW) { if (!XWTOXW) {
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface.wlr()); g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface->resource());
else 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); g_pSeatManager->sendKeyboardMods(g_pInputManager->accumulateModsFromAllKBs(), 0, 0, 0);
@ -2044,10 +2044,10 @@ void CKeybindManager::pass(std::string regexp) {
// please kill me // please kill me
if (PWINDOW->m_bIsX11) { if (PWINDOW->m_bIsX11) {
if (g_pKeybindManager->m_uLastCode != 0) { if (g_pKeybindManager->m_uLastCode != 0) {
g_pSeatManager->state.keyboardFocus = nullptr; g_pSeatManager->state.keyboardFocus.reset();
g_pSeatManager->state.keyboardFocusResource.reset(); g_pSeatManager->state.keyboardFocusResource.reset();
} else { } else {
g_pSeatManager->state.pointerFocus = nullptr; g_pSeatManager->state.pointerFocus.reset();
g_pSeatManager->state.pointerFocusResource.reset(); g_pSeatManager->state.pointerFocusResource.reset();
} }
} }
@ -2057,7 +2057,7 @@ void CKeybindManager::pass(std::string regexp) {
if (g_pKeybindManager->m_uLastCode != 0) if (g_pKeybindManager->m_uLastCode != 0)
g_pSeatManager->setKeyboardFocus(LASTSRF); g_pSeatManager->setKeyboardFocus(LASTSRF);
else else
g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface.wlr(), SL); g_pSeatManager->setPointerFocus(PWINDOW->m_pWLSurface->resource(), SL);
} }
void CKeybindManager::sendshortcut(std::string args) { void CKeybindManager::sendshortcut(std::string args) {
@ -2136,7 +2136,7 @@ void CKeybindManager::sendshortcut(std::string args) {
const std::string regexp = ARGS[2]; const std::string regexp = ARGS[2];
PHLWINDOW PWINDOW = nullptr; 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 //if regexp is not empty, send shortcut to current window
//else, dont change focus //else, dont change focus
@ -2154,15 +2154,15 @@ void CKeybindManager::sendshortcut(std::string args) {
} }
if (!isMouse) if (!isMouse)
g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface.wlr()); g_pSeatManager->setKeyboardFocus(PWINDOW->m_pWLSurface->resource());
else 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 //copied the rest from pass and modified it
// if wl -> xwl, activate destination // if wl -> xwl, activate destination
if (PWINDOW && PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && !g_pCompositor->m_pLastWindow->m_bIsX11) 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 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) if (PWINDOW && PWINDOW->m_bIsX11 && g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_bIsX11)
PWINDOW = nullptr; PWINDOW = nullptr;
@ -2195,10 +2195,10 @@ void CKeybindManager::sendshortcut(std::string args) {
if (PWINDOW->m_bIsX11) { //xwayland hack, see pass if (PWINDOW->m_bIsX11) { //xwayland hack, see pass
if (!isMouse) { if (!isMouse) {
g_pSeatManager->state.keyboardFocus = nullptr; g_pSeatManager->state.keyboardFocus.reset();
g_pSeatManager->state.keyboardFocusResource.reset(); g_pSeatManager->state.keyboardFocusResource.reset();
} else { } else {
g_pSeatManager->state.pointerFocus = nullptr; g_pSeatManager->state.pointerFocus.reset();
g_pSeatManager->state.pointerFocusResource.reset(); g_pSeatManager->state.pointerFocusResource.reset();
} }
} }

View file

@ -3,6 +3,7 @@
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/PointerGestures.hpp" #include "../protocols/PointerGestures.hpp"
#include "../protocols/FractionalScale.hpp" #include "../protocols/FractionalScale.hpp"
#include "../protocols/core/Compositor.hpp"
#include "SeatManager.hpp" #include "SeatManager.hpp"
#include <wlr/interfaces/wlr_output.h> #include <wlr/interfaces/wlr_output.h>
#include <wlr/render/interface.h> #include <wlr/render/interface.h>
@ -212,13 +213,13 @@ void CPointerManager::setCursorBuffer(wlr_buffer* buf, const Vector2D& hotspot,
damageIfSoftware(); damageIfSoftware();
} }
void CPointerManager::setCursorSurface(CWLSurface* surf, const Vector2D& hotspot) { void CPointerManager::setCursorSurface(SP<CWLSurface> surf, const Vector2D& hotspot) {
damageIfSoftware(); damageIfSoftware();
if (surf == currentCursorImage.surface) { 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.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(); updateCursorBackend();
damageIfSoftware(); damageIfSoftware();
} }
@ -229,27 +230,24 @@ void CPointerManager::setCursorSurface(CWLSurface* surf, const Vector2D& hotspot
resetCursorImage(false); resetCursorImage(false);
if (surf) { if (surf) {
currentCursorImage.size = {surf->wlr()->current.buffer_width, surf->wlr()->current.buffer_height};
currentCursorImage.surface = surf; 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.destroySurface = surf->events.destroy.registerListener([this](std::any data) { resetCursorImage(); });
currentCursorImage.hyprListener_commitSurface.initCallback( currentCursorImage.commitSurface = surf->resource()->events.commit.registerListener([this](std::any data) {
&surf->wlr()->events.commit,
[this](void* owner, void* data) {
damageIfSoftware(); damageIfSoftware();
currentCursorImage.size = {currentCursorImage.surface->wlr()->current.buffer_width, currentCursorImage.surface->wlr()->current.buffer_height}; currentCursorImage.size = currentCursorImage.surface->resource()->current.buffer ? currentCursorImage.surface->resource()->current.buffer->size : Vector2D{};
currentCursorImage.scale = currentCursorImage.surface && currentCursorImage.surface->wlr() ? currentCursorImage.surface->wlr()->current.scale : 1.F; currentCursorImage.scale = currentCursorImage.surface ? currentCursorImage.surface->resource()->current.scale : 1.F;
recheckEnteredOutputs(); recheckEnteredOutputs();
updateCursorBackend(); updateCursorBackend();
damageIfSoftware(); damageIfSoftware();
}, });
nullptr, "CPointerManager");
if (wlr_surface_has_buffer(surf->wlr())) { if (surf->resource()->current.buffer) {
currentCursorImage.size = surf->resource()->current.buffer->size;
timespec now; timespec now;
clock_gettime(CLOCK_MONOTONIC, &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) if (!currentCursorImage.surface)
continue; continue;
wlr_surface_send_enter(currentCursorImage.surface->wlr(), s->monitor->output); currentCursorImage.surface->resource()->enter(s->monitor.lock());
PROTO::fractional->sendScale(currentCursorImage.surface->wlr(), s->monitor->scale); PROTO::fractional->sendScale(currentCursorImage.surface->resource(), s->monitor->scale);
g_pCompositor->setPreferredScaleForSurface(currentCursorImage.surface->wlr(), s->monitor->scale); g_pCompositor->setPreferredScaleForSurface(currentCursorImage.surface->resource(), s->monitor->scale);
} else if (s->entered && !overlaps) { } else if (s->entered && !overlaps) {
s->entered = false; s->entered = false;
@ -293,7 +291,7 @@ void CPointerManager::recheckEnteredOutputs() {
if (!currentCursorImage.surface) if (!currentCursorImage.surface)
continue; 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) { if (currentCursorImage.surface) {
for (auto& m : g_pCompositor->m_vMonitors) { 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.destroySurface.reset();
currentCursorImage.hyprListener_commitSurface.removeCallback(); currentCursorImage.commitSurface.reset();
currentCursorImage.surface = nullptr; currentCursorImage.surface.reset();
} else if (currentCursorImage.pBuffer) { } else if (currentCursorImage.pBuffer) {
wlr_buffer_unlock(currentCursorImage.pBuffer); wlr_buffer_unlock(currentCursorImage.pBuffer);
currentCursorImage.hyprListener_destroyBuffer.removeCallback(); currentCursorImage.hyprListener_destroyBuffer.removeCallback();
@ -451,7 +449,7 @@ bool CPointerManager::setHWCursorBuffer(SP<SMonitorPointerState> state, wlr_buff
return true; return true;
} }
wlr_buffer* CPointerManager::renderHWCursorBuffer(SP<CPointerManager::SMonitorPointerState> state, wlr_texture* texture) { wlr_buffer* CPointerManager::renderHWCursorBuffer(SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
auto output = state->monitor->output; auto output = state->monitor->output;
int w = currentCursorImage.size.x, h = currentCursorImage.size.y; int w = currentCursorImage.size.x, h = currentCursorImage.size.y;
@ -528,7 +526,7 @@ void CPointerManager::renderSoftwareCursorsFor(SP<CMonitor> pMonitor, timespec*
if ((!state->hardwareFailed && state->softwareLocks == 0)) { if ((!state->hardwareFailed && state->softwareLocks == 0)) {
if (currentCursorImage.surface) if (currentCursorImage.surface)
wlr_surface_send_frame_done(currentCursorImage.surface->wlr(), now); currentCursorImage.surface->resource()->frame(now);
return; return;
} }
@ -550,7 +548,7 @@ void CPointerManager::renderSoftwareCursorsFor(SP<CMonitor> pMonitor, timespec*
g_pHyprOpenGL->renderTextureWithDamage(texture, &box, &damage, 1.F); g_pHyprOpenGL->renderTextureWithDamage(texture, &box, &damage, 1.F);
if (currentCursorImage.surface) if (currentCursorImage.surface)
wlr_surface_send_frame_done(currentCursorImage.surface->wlr(), now); currentCursorImage.surface->resource()->frame(now);
} }
Vector2D CPointerManager::getCursorPosForMonitor(SP<CMonitor> pMonitor) { Vector2D CPointerManager::getCursorPosForMonitor(SP<CMonitor> pMonitor) {
@ -762,17 +760,19 @@ void CPointerManager::onMonitorLayoutChange() {
damageIfSoftware(); damageIfSoftware();
} }
wlr_texture* CPointerManager::getCurrentCursorTexture() { SP<CTexture> CPointerManager::getCurrentCursorTexture() {
if (!currentCursorImage.pBuffer && (!currentCursorImage.surface || !wlr_surface_get_texture(currentCursorImage.surface->wlr()))) if (!currentCursorImage.pBuffer && (!currentCursorImage.surface || !currentCursorImage.surface->resource()->current.buffer))
return nullptr; return nullptr;
if (currentCursorImage.pBuffer) { if (currentCursorImage.pBuffer) {
if (!currentCursorImage.pBufferTexture) if (!currentCursorImage.pBufferTexture) {
currentCursorImage.pBufferTexture = wlr_texture_from_buffer(g_pCompositor->m_sWLRRenderer, currentCursorImage.pBuffer); currentCursorImage.pBufferTexture = wlr_texture_from_buffer(g_pCompositor->m_sWLRRenderer, currentCursorImage.pBuffer);
return currentCursorImage.pBufferTexture; currentCursorImage.bufferTex = makeShared<CTexture>(currentCursorImage.pBufferTexture);
}
return currentCursorImage.bufferTex;
} }
return wlr_surface_get_texture(currentCursorImage.surface->wlr()); return currentCursorImage.surface->resource()->current.buffer->texture;
} }
void CPointerManager::attachPointer(SP<IPointer> pointer) { void CPointerManager::attachPointer(SP<IPointer> pointer) {

View file

@ -11,6 +11,7 @@
class CMonitor; class CMonitor;
struct wlr_input_device; struct wlr_input_device;
class IHID; class IHID;
class CTexture;
/* /*
The naming here is a bit confusing. The naming here is a bit confusing.
@ -37,7 +38,7 @@ class CPointerManager {
void warpAbsolute(Vector2D abs, SP<IHID> dev); void warpAbsolute(Vector2D abs, SP<IHID> dev);
void setCursorBuffer(wlr_buffer* buf, const Vector2D& hotspot, const float& scale); void setCursorBuffer(wlr_buffer* buf, const Vector2D& hotspot, const float& scale);
void setCursorSurface(CWLSurface* buf, const Vector2D& hotspot); void setCursorSurface(SP<CWLSurface> buf, const Vector2D& hotspot);
void resetCursorImage(bool apply = true); void resetCursorImage(bool apply = true);
void lockSoftwareForMonitor(SP<CMonitor> pMonitor); void lockSoftwareForMonitor(SP<CMonitor> pMonitor);
@ -76,7 +77,7 @@ class CPointerManager {
Vector2D transformedHotspot(SP<CMonitor> pMonitor); Vector2D transformedHotspot(SP<CMonitor> pMonitor);
wlr_texture* getCurrentCursorTexture(); SP<CTexture> getCurrentCursorTexture();
struct SPointerListener { struct SPointerListener {
CHyprSignalListener destroy; CHyprSignalListener destroy;
@ -130,7 +131,8 @@ class CPointerManager {
struct { struct {
wlr_buffer* pBuffer = nullptr; wlr_buffer* pBuffer = nullptr;
CWLSurface* surface = nullptr; SP<CTexture> bufferTex;
WP<CWLSurface> surface;
wlr_texture* pBufferTexture = nullptr; wlr_texture* pBufferTexture = nullptr;
Vector2D hotspot; Vector2D hotspot;
@ -138,7 +140,7 @@ class CPointerManager {
float scale = 1.F; float scale = 1.F;
CHyprSignalListener destroySurface; CHyprSignalListener destroySurface;
DYNLISTENER(commitSurface); CHyprSignalListener commitSurface;
DYNLISTENER(destroyBuffer); DYNLISTENER(destroyBuffer);
} currentCursorImage; // TODO: support various sizes per-output so we can have pixel-perfect cursors } currentCursorImage; // TODO: support various sizes per-output so we can have pixel-perfect cursors
@ -165,7 +167,7 @@ class CPointerManager {
std::vector<SP<SMonitorPointerState>> monitorStates; std::vector<SP<SMonitorPointerState>> monitorStates;
SP<SMonitorPointerState> stateFor(SP<CMonitor> mon); SP<SMonitorPointerState> stateFor(SP<CMonitor> mon);
bool attemptHardwareCursor(SP<SMonitorPointerState> state); bool attemptHardwareCursor(SP<SMonitorPointerState> state);
wlr_buffer* renderHWCursorBuffer(SP<SMonitorPointerState> state, wlr_texture* texture); wlr_buffer* renderHWCursorBuffer(SP<SMonitorPointerState> state, SP<CTexture> texture);
bool setHWCursorBuffer(SP<SMonitorPointerState> state, wlr_buffer* buf); bool setHWCursorBuffer(SP<SMonitorPointerState> state, wlr_buffer* buf);
struct { struct {

View file

@ -32,17 +32,45 @@
#include "../protocols/DataDeviceWlr.hpp" #include "../protocols/DataDeviceWlr.hpp"
#include "../protocols/PrimarySelection.hpp" #include "../protocols/PrimarySelection.hpp"
#include "../protocols/XWaylandShell.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/Seat.hpp"
#include "../protocols/core/DataDevice.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() { 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<CMonitor*>(param);
if (PROTO::outputs.contains(M->szName))
PROTO::outputs.erase(M->szName);
PROTO::outputs.emplace(M->szName, std::make_unique<CWLOutputProtocol>(&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<CMonitor*>(param);
if (!PROTO::outputs.contains(M->szName))
return;
PROTO::outputs.at(M->szName)->remove();
});
// Core // Core
PROTO::seat = std::make_unique<CWLSeatProtocol>(&wl_seat_interface, 9, "WLSeat"); PROTO::seat = std::make_unique<CWLSeatProtocol>(&wl_seat_interface, 9, "WLSeat");
PROTO::data = std::make_unique<CWLDataDeviceProtocol>(&wl_data_device_manager_interface, 3, "WLDataDevice"); PROTO::data = std::make_unique<CWLDataDeviceProtocol>(&wl_data_device_manager_interface, 3, "WLDataDevice");
PROTO::compositor = std::make_unique<CWLCompositorProtocol>(&wl_compositor_interface, 6, "WLCompositor");
PROTO::subcompositor = std::make_unique<CWLSubcompositorProtocol>(&wl_subcompositor_interface, 1, "WLSubcompositor");
PROTO::shm = std::make_unique<CWLSHMProtocol>(&wl_shm_interface, 1, "WLSHM");
// Extensions // Extensions
PROTO::viewport = std::make_unique<CViewporterProtocol>(&wp_viewporter_interface, 1, "Viewporter");
PROTO::tearing = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl"); PROTO::tearing = std::make_unique<CTearingControlProtocol>(&wp_tearing_control_manager_v1_interface, 1, "TearingControl");
PROTO::fractional = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale"); PROTO::fractional = std::make_unique<CFractionalScaleProtocol>(&wp_fractional_scale_manager_v1_interface, 1, "FractionalScale");
PROTO::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput"); PROTO::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
@ -75,6 +103,8 @@ CProtocolManager::CProtocolManager() {
PROTO::dataWlr = std::make_unique<CDataDeviceWLRProtocol>(&zwlr_data_control_manager_v1_interface, 2, "DataDeviceWlr"); PROTO::dataWlr = std::make_unique<CDataDeviceWLRProtocol>(&zwlr_data_control_manager_v1_interface, 2, "DataDeviceWlr");
PROTO::primarySelection = std::make_unique<CPrimarySelectionProtocol>(&zwp_primary_selection_device_manager_v1_interface, 1, "PrimarySelection"); PROTO::primarySelection = std::make_unique<CPrimarySelectionProtocol>(&zwp_primary_selection_device_manager_v1_interface, 1, "PrimarySelection");
PROTO::xwaylandShell = std::make_unique<CXWaylandShellProtocol>(&xwayland_shell_v1_interface, 1, "XWaylandShell"); PROTO::xwaylandShell = std::make_unique<CXWaylandShellProtocol>(&xwayland_shell_v1_interface, 1, "XWaylandShell");
PROTO::mesaDRM = std::make_unique<CMesaDRMProtocol>(&wl_drm_interface, 2, "MesaDRM");
PROTO::linuxDma = std::make_unique<CLinuxDMABufV1Protocol>(&zwp_linux_dmabuf_v1_interface, 5, "LinuxDMABUF");
// Old protocol implementations. // Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner. // TODO: rewrite them to use hyprwayland-scanner.

View file

@ -3,6 +3,7 @@
#include "../protocols/core/DataDevice.hpp" #include "../protocols/core/DataDevice.hpp"
#include "../protocols/DataDeviceWlr.hpp" #include "../protocols/DataDeviceWlr.hpp"
#include "../protocols/PrimarySelection.hpp" #include "../protocols/PrimarySelection.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include <algorithm> #include <algorithm>
@ -98,7 +99,7 @@ void CSeatManager::updateActiveKeyboardData() {
PROTO::seat->updateKeymap(); PROTO::seat->updateKeymap();
} }
void CSeatManager::setKeyboardFocus(wlr_surface* surf) { void CSeatManager::setKeyboardFocus(SP<CWLSurfaceResource> surf) {
if (state.keyboardFocus == surf) if (state.keyboardFocus == surf)
return; return;
@ -107,7 +108,7 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
return; return;
} }
hyprListener_keyboardSurfaceDestroy.removeCallback(); listeners.keyboardSurfaceDestroy.reset();
if (state.keyboardFocusResource) { if (state.keyboardFocusResource) {
auto client = state.keyboardFocusResource->client(); auto client = state.keyboardFocusResource->client();
@ -132,7 +133,7 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
return; return;
} }
auto client = wl_resource_get_client(surf->resource); auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) { for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client) if (r->resource->client() != client)
continue; continue;
@ -147,8 +148,7 @@ void CSeatManager::setKeyboardFocus(wlr_surface* surf) {
} }
} }
hyprListener_keyboardSurfaceDestroy.initCallback( listeners.keyboardSurfaceDestroy = surf->events.destroy.registerListener([this](std::any d) { setKeyboardFocus(nullptr); });
&surf->events.destroy, [this](void* owner, void* data) { setKeyboardFocus(nullptr); }, nullptr, "CSeatManager");
events.keyboardFocusChange.emit(); events.keyboardFocusChange.emit();
} }
@ -187,7 +187,7 @@ void CSeatManager::sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32
} }
} }
void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) { void CSeatManager::setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D& local) {
if (state.pointerFocus == surf) if (state.pointerFocus == surf)
return; return;
@ -196,7 +196,7 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
return; return;
} }
hyprListener_pointerSurfaceDestroy.removeCallback(); listeners.pointerSurfaceDestroy.reset();
if (state.pointerFocusResource) { if (state.pointerFocusResource) {
auto client = state.pointerFocusResource->client(); auto client = state.pointerFocusResource->client();
@ -224,7 +224,7 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
return; return;
} }
auto client = wl_resource_get_client(surf->resource); auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) { for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client) if (r->resource->client() != client)
continue; continue;
@ -243,8 +243,7 @@ void CSeatManager::setPointerFocus(wlr_surface* surf, const Vector2D& local) {
sendPointerFrame(); sendPointerFrame();
hyprListener_pointerSurfaceDestroy.initCallback( listeners.pointerSurfaceDestroy = surf->events.destroy.registerListener([this](std::any d) { setPointerFocus(nullptr, {}); });
&surf->events.destroy, [this](void* owner, void* data) { setPointerFocus(nullptr, {}); }, nullptr, "CSeatManager");
events.pointerFocusChange.emit(); events.pointerFocusChange.emit();
} }
@ -340,11 +339,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<CWLSurfaceResource> surf, uint32_t timeMs, int32_t id, const Vector2D& local) {
if (state.touchFocus == surf) if (state.touchFocus == surf)
return; return;
hyprListener_touchSurfaceDestroy.removeCallback(); listeners.touchSurfaceDestroy.reset();
if (state.touchFocusResource) { if (state.touchFocusResource) {
auto client = state.touchFocusResource->client(); auto client = state.touchFocusResource->client();
@ -369,7 +368,7 @@ void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id,
return; return;
} }
auto client = wl_resource_get_client(surf->resource); auto client = surf->client();
for (auto& r : seatResources | std::views::reverse) { for (auto& r : seatResources | std::views::reverse) {
if (r->resource->client() != client) if (r->resource->client() != client)
continue; continue;
@ -383,8 +382,7 @@ void CSeatManager::sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id,
} }
} }
hyprListener_touchSurfaceDestroy.initCallback( listeners.touchSurfaceDestroy = surf->events.destroy.registerListener([this, timeMs, id](std::any d) { sendTouchUp(timeMs + 10, id); });
&surf->events.destroy, [this, timeMs, id](void* owner, void* data) { sendTouchUp(timeMs + 10, id); }, nullptr, "CSeatManager");
events.touchFocusChange.emit(); events.touchFocusChange.emit();
} }
@ -486,7 +484,7 @@ void CSeatManager::refocusGrab() {
// try to find a surf in focus first // try to find a surf in focus first
const auto MOUSE = g_pInputManager->getMouseCoordsInternal(); const auto MOUSE = g_pInputManager->getMouseCoordsInternal();
for (auto& s : seatGrab->surfs) { for (auto& s : seatGrab->surfs) {
auto hlSurf = CWLSurface::surfaceFromWlr(s); auto hlSurf = CWLSurface::fromResource(s.lock());
if (!hlSurf) if (!hlSurf)
continue; continue;
@ -498,13 +496,13 @@ void CSeatManager::refocusGrab() {
continue; continue;
if (seatGrab->keyboard) if (seatGrab->keyboard)
setKeyboardFocus(s); setKeyboardFocus(s.lock());
if (seatGrab->pointer) if (seatGrab->pointer)
setPointerFocus(s, MOUSE - b->pos()); setPointerFocus(s.lock(), MOUSE - b->pos());
return; return;
} }
wlr_surface* surf = seatGrab->surfs.at(0); SP<CWLSurfaceResource> surf = seatGrab->surfs.at(0).lock();
if (seatGrab->keyboard) if (seatGrab->keyboard)
setKeyboardFocus(surf); setKeyboardFocus(surf);
if (seatGrab->pointer) if (seatGrab->pointer)
@ -512,7 +510,7 @@ void CSeatManager::refocusGrab() {
} }
} }
void CSeatManager::onSetCursor(SP<CWLSeatResource> seatResource, uint32_t serial, wlr_surface* surf, const Vector2D& hotspot) { void CSeatManager::onSetCursor(SP<CWLSeatResource> seatResource, uint32_t serial, SP<CWLSurfaceResource> surf, const Vector2D& hotspot) {
if (!state.pointerFocusResource || !seatResource || seatResource->client() != state.pointerFocusResource->client()) { if (!state.pointerFocusResource || !seatResource || seatResource->client() != state.pointerFocusResource->client()) {
Debug::log(LOG, "[seatmgr] Rejecting a setCursor because the client ain't in focus"); Debug::log(LOG, "[seatmgr] Rejecting a setCursor because the client ain't in focus");
return; return;
@ -599,8 +597,8 @@ void CSeatManager::setGrab(SP<CSeatGrab> grab) {
} }
void CSeatManager::resendEnterEvents() { void CSeatManager::resendEnterEvents() {
wlr_surface* kb = state.keyboardFocus; SP<CWLSurfaceResource> kb = state.keyboardFocus.lock();
wlr_surface* pt = state.pointerFocus; SP<CWLSurfaceResource> pt = state.pointerFocus.lock();
auto last = lastLocalCoords; auto last = lastLocalCoords;
@ -611,15 +609,15 @@ void CSeatManager::resendEnterEvents() {
setPointerFocus(pt, last); setPointerFocus(pt, last);
} }
bool CSeatGrab::accepts(wlr_surface* surf) { bool CSeatGrab::accepts(SP<CWLSurfaceResource> surf) {
return std::find(surfs.begin(), surfs.end(), surf) != surfs.end(); return std::find(surfs.begin(), surfs.end(), surf) != surfs.end();
} }
void CSeatGrab::add(wlr_surface* surf) { void CSeatGrab::add(SP<CWLSurfaceResource> surf) {
surfs.push_back(surf); surfs.push_back(surf);
} }
void CSeatGrab::remove(wlr_surface* surf) { void CSeatGrab::remove(SP<CWLSurfaceResource> surf) {
std::erase(surfs, surf); std::erase(surfs, surf);
if ((keyboard && g_pSeatManager->state.keyboardFocus == surf) || (pointer && g_pSeatManager->state.pointerFocus == surf)) if ((keyboard && g_pSeatManager->state.keyboardFocus == surf) || (pointer && g_pSeatManager->state.pointerFocus == surf))
g_pSeatManager->refocusGrab(); g_pSeatManager->refocusGrab();

View file

@ -11,7 +11,7 @@
constexpr size_t MAX_SERIAL_STORE_LEN = 100; constexpr size_t MAX_SERIAL_STORE_LEN = 100;
struct wlr_surface; class CWLSurfaceResource;
class CWLSeatResource; class CWLSeatResource;
class IPointer; class IPointer;
class IKeyboard; class IKeyboard;
@ -29,9 +29,9 @@ class IKeyboard;
*/ */
class CSeatGrab { class CSeatGrab {
public: public:
bool accepts(wlr_surface* surf); bool accepts(SP<CWLSurfaceResource> surf);
void add(wlr_surface* surf); void add(SP<CWLSurfaceResource> surf);
void remove(wlr_surface* surf); void remove(SP<CWLSurfaceResource> surf);
void setCallback(std::function<void()> onEnd_); void setCallback(std::function<void()> onEnd_);
void clear(); void clear();
@ -42,7 +42,7 @@ class CSeatGrab {
bool removeOnInput = true; // on hard input e.g. click outside, remove bool removeOnInput = true; // on hard input e.g. click outside, remove
private: private:
std::vector<wlr_surface*> surfs; // read-only std::vector<WP<CWLSurfaceResource>> surfs;
std::function<void()> onEnd; std::function<void()> onEnd;
friend class CSeatManager; friend class CSeatManager;
}; };
@ -57,11 +57,11 @@ class CSeatManager {
void setKeyboard(SP<IKeyboard> keeb); void setKeyboard(SP<IKeyboard> keeb);
void updateActiveKeyboardData(); // updates the clients with the keymap and repeat info void updateActiveKeyboardData(); // updates the clients with the keymap and repeat info
void setKeyboardFocus(wlr_surface* surf); void setKeyboardFocus(SP<CWLSurfaceResource> surf);
void sendKeyboardKey(uint32_t timeMs, uint32_t key, wl_keyboard_key_state state); 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 sendKeyboardMods(uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group);
void setPointerFocus(wlr_surface* surf, const Vector2D& local); void setPointerFocus(SP<CWLSurfaceResource> surf, const Vector2D& local);
void sendPointerMotion(uint32_t timeMs, 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 sendPointerButton(uint32_t timeMs, uint32_t key, wl_pointer_button_state state);
void sendPointerFrame(); 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, 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); wl_pointer_axis_relative_direction relative);
void sendTouchDown(wlr_surface* surf, uint32_t timeMs, int32_t id, const Vector2D& local); void sendTouchDown(SP<CWLSurfaceResource> surf, uint32_t timeMs, int32_t id, const Vector2D& local);
void sendTouchUp(uint32_t timeMs, int32_t id); void sendTouchUp(uint32_t timeMs, int32_t id);
void sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local); void sendTouchMotion(uint32_t timeMs, int32_t id, const Vector2D& local);
void sendTouchFrame(); void sendTouchFrame();
@ -83,23 +83,23 @@ class CSeatManager {
// pops the serial if it was valid, meaning it is consumed. // pops the serial if it was valid, meaning it is consumed.
bool serialValid(SP<CWLSeatResource> seatResource, uint32_t serial); bool serialValid(SP<CWLSeatResource> seatResource, uint32_t serial);
void onSetCursor(SP<CWLSeatResource> seatResource, uint32_t serial, wlr_surface* surf, const Vector2D& hotspot); void onSetCursor(SP<CWLSeatResource> seatResource, uint32_t serial, SP<CWLSurfaceResource> surf, const Vector2D& hotspot);
SP<CWLSeatResource> seatResourceForClient(wl_client* client); SP<CWLSeatResource> seatResourceForClient(wl_client* client);
struct { struct {
wlr_surface* keyboardFocus = nullptr; WP<CWLSurfaceResource> keyboardFocus;
WP<CWLSeatResource> keyboardFocusResource; WP<CWLSeatResource> keyboardFocusResource;
wlr_surface* pointerFocus = nullptr; WP<CWLSurfaceResource> pointerFocus;
WP<CWLSeatResource> pointerFocusResource; WP<CWLSeatResource> pointerFocusResource;
wlr_surface* touchFocus = nullptr; WP<CWLSurfaceResource> touchFocus;
WP<CWLSeatResource> touchFocusResource; WP<CWLSeatResource> touchFocusResource;
} state; } state;
struct SSetCursorEvent { struct SSetCursorEvent {
wlr_surface* surf = nullptr; SP<CWLSurfaceResource> surf = nullptr;
Vector2D hotspot; Vector2D hotspot;
}; };
@ -149,14 +149,13 @@ class CSeatManager {
struct { struct {
CHyprSignalListener newSeatResource; CHyprSignalListener newSeatResource;
CHyprSignalListener keyboardSurfaceDestroy;
CHyprSignalListener pointerSurfaceDestroy;
CHyprSignalListener touchSurfaceDestroy;
} listeners; } listeners;
Vector2D lastLocalCoords; Vector2D lastLocalCoords;
DYNLISTENER(keyboardSurfaceDestroy);
DYNLISTENER(pointerSurfaceDestroy);
DYNLISTENER(touchSurfaceDestroy);
friend struct SSeatResourceContainer; friend struct SSeatResourceContainer;
friend class CSeatGrab; friend class CSeatGrab;
}; };

View file

@ -20,7 +20,7 @@ SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : sur
listeners.destroy = surface_->events.destroy.registerListener([this](std::any data) { listeners.destroy = surface_->events.destroy.registerListener([this](std::any data) {
if (pWlrSurface == g_pCompositor->m_pLastFocus) if (pWlrSurface == g_pCompositor->m_pLastFocus)
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
g_pSessionLockManager->removeSessionLockSurface(this); g_pSessionLockManager->removeSessionLockSurface(this);
}); });
@ -70,7 +70,7 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
g_pHyprRenderer->damageMonitor(m.get()); g_pHyprRenderer->damageMonitor(m.get());
}); });
m_pSessionLock->listeners.destroy = pLock->events.destroyed.registerListener([this](std::any data) { m_pSessionLock->listeners.destroy = pLock->events.destroyed.registerListener([](std::any data) {
g_pCompositor->focusSurface(nullptr); g_pCompositor->focusSurface(nullptr);
for (auto& m : g_pCompositor->m_vMonitors) for (auto& m : g_pCompositor->m_vMonitors)
@ -117,7 +117,7 @@ float CSessionLockManager::getRedScreenAlphaForMonitor(uint64_t id) {
return std::clamp(NOMAPPEDSURFACETIMER->second.getSeconds() - /* delay for screencopy */ 0.5f, 0.f, 1.f); return std::clamp(NOMAPPEDSURFACETIMER->second.getSeconds() - /* delay for screencopy */ 0.5f, 0.f, 1.f);
} }
bool CSessionLockManager::isSurfaceSessionLock(wlr_surface* pSurface) { bool CSessionLockManager::isSurfaceSessionLock(SP<CWLSurfaceResource> pSurface) {
// TODO: this has some edge cases when it's wrong (e.g. destroyed lock but not yet surfaces) // TODO: this has some edge cases when it's wrong (e.g. destroyed lock but not yet surfaces)
// but can be easily fixed when I rewrite wlr_surface // but can be easily fixed when I rewrite wlr_surface

View file

@ -8,12 +8,13 @@
class CSessionLockSurface; class CSessionLockSurface;
class CSessionLock; class CSessionLock;
class CWLSurfaceResource;
struct SSessionLockSurface { struct SSessionLockSurface {
SSessionLockSurface(SP<CSessionLockSurface> surface_); SSessionLockSurface(SP<CSessionLockSurface> surface_);
WP<CSessionLockSurface> surface; WP<CSessionLockSurface> surface;
wlr_surface* pWlrSurface = nullptr; WP<CWLSurfaceResource> pWlrSurface;
uint64_t iMonitorID = -1; uint64_t iMonitorID = -1;
bool mapped = false; bool mapped = false;
@ -49,7 +50,7 @@ class CSessionLockManager {
bool isSessionLocked(); bool isSessionLocked();
bool isSessionLockPresent(); bool isSessionLockPresent();
bool isSurfaceSessionLock(wlr_surface*); bool isSurfaceSessionLock(SP<CWLSurfaceResource>);
void removeSessionLockSurface(SSessionLockSurface*); void removeSessionLockSurface(SSessionLockSurface*);

View file

@ -3,6 +3,7 @@
#include "../events/Events.hpp" #include "../events/Events.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../protocols/XDGShell.hpp" #include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../xwayland/XWayland.hpp" #include "../xwayland/XWayland.hpp"
#define OUTPUT_MANAGER_VERSION 3 #define OUTPUT_MANAGER_VERSION 3
@ -19,11 +20,11 @@ CHyprXWaylandManager::~CHyprXWaylandManager() {
#endif #endif
} }
wlr_surface* CHyprXWaylandManager::getWindowSurface(PHLWINDOW pWindow) { SP<CWLSurfaceResource> CHyprXWaylandManager::getWindowSurface(PHLWINDOW pWindow) {
return pWindow->m_pWLSurface.wlr(); return pWindow->m_pWLSurface->resource();
} }
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) { void CHyprXWaylandManager::activateSurface(SP<CWLSurfaceResource> pSurface, bool activate) {
if (!pSurface) if (!pSurface)
return; return;
@ -33,7 +34,7 @@ void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate)
if (!w->m_bIsMapped) if (!w->m_bIsMapped)
continue; continue;
if (w->m_pWLSurface.wlr() != pSurface) if (w->m_pWLSurface->resource() != pSurface)
continue; continue;
if (w->m_bIsX11) { if (w->m_bIsX11) {
@ -131,10 +132,6 @@ void CHyprXWaylandManager::setWindowSize(PHLWINDOW pWindow, Vector2D size, bool
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor())); pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(pWindow->m_pXDGSurface->toplevel->setSize(size), size.floor()));
} }
wlr_surface* CHyprXWaylandManager::surfaceAt(PHLWINDOW pWindow, const Vector2D& client, Vector2D& surface) {
return wlr_surface_surface_at(pWindow->m_pWLSurface.wlr(), client.x, client.y, &surface.x, &surface.y);
}
bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) { bool CHyprXWaylandManager::shouldBeFloated(PHLWINDOW pWindow, bool pending) {
if (pWindow->m_bIsX11) { if (pWindow->m_bIsX11) {
for (auto& a : pWindow->m_pXWaylandSurface->atoms) for (auto& a : pWindow->m_pXWaylandSurface->atoms)

View file

@ -5,20 +5,20 @@
class CWindow; // because clangd class CWindow; // because clangd
typedef SP<CWindow> PHLWINDOW; typedef SP<CWindow> PHLWINDOW;
class CWLSurfaceResource;
class CHyprXWaylandManager { class CHyprXWaylandManager {
public: public:
CHyprXWaylandManager(); CHyprXWaylandManager();
~CHyprXWaylandManager(); ~CHyprXWaylandManager();
wlr_surface* getWindowSurface(PHLWINDOW); SP<CWLSurfaceResource> getWindowSurface(PHLWINDOW);
void activateSurface(wlr_surface*, bool); void activateSurface(SP<CWLSurfaceResource>, bool);
void activateWindow(PHLWINDOW, bool); void activateWindow(PHLWINDOW, bool);
void getGeometryForWindow(PHLWINDOW, CBox*); void getGeometryForWindow(PHLWINDOW, CBox*);
void sendCloseWindow(PHLWINDOW); void sendCloseWindow(PHLWINDOW);
void setWindowSize(PHLWINDOW, Vector2D, bool force = false); void setWindowSize(PHLWINDOW, Vector2D, bool force = false);
void setWindowFullscreen(PHLWINDOW, bool); void setWindowFullscreen(PHLWINDOW, bool);
wlr_surface* surfaceAt(PHLWINDOW, const Vector2D&, Vector2D&);
bool shouldBeFloated(PHLWINDOW, bool pending = false); bool shouldBeFloated(PHLWINDOW, bool pending = false);
void checkBorders(PHLWINDOW); void checkBorders(PHLWINDOW);
Vector2D getMaxSizeForWindow(PHLWINDOW); Vector2D getMaxSizeForWindow(PHLWINDOW);

View file

@ -14,7 +14,7 @@ void CInputManager::newIdleInhibitor(std::any inhibitor) {
recheckIdleInhibitorStatus(); recheckIdleInhibitorStatus();
}); });
auto WLSurface = CWLSurface::surfaceFromWlr(PINHIBIT->inhibitor->surface); auto WLSurface = CWLSurface::fromResource(PINHIBIT->inhibitor->surface.lock());
if (!WLSurface) { if (!WLSurface) {
Debug::log(LOG, "Inhibitor has no HL Surface attached to it, likely meaning it's a non-desktop element. Assuming it's visible."); Debug::log(LOG, "Inhibitor has no HL Surface attached to it, likely meaning it's a non-desktop element. Assuming it's visible.");
@ -37,7 +37,7 @@ void CInputManager::recheckIdleInhibitorStatus() {
return; return;
} }
auto WLSurface = CWLSurface::surfaceFromWlr(ii->inhibitor->surface); auto WLSurface = CWLSurface::fromResource(ii->inhibitor->surface.lock());
if (!WLSurface) if (!WLSurface)
continue; continue;

View file

@ -43,7 +43,7 @@ CInputManager::CInputManager() {
Debug::log(LOG, "cursorImage request: shape {} -> {}", (uint32_t)event.shape, event.shapeName); Debug::log(LOG, "cursorImage request: shape {} -> {}", (uint32_t)event.shape, event.shapeName);
m_sCursorSurfaceInfo.wlSurface.unassign(); m_sCursorSurfaceInfo.wlSurface->unassign();
m_sCursorSurfaceInfo.vHotspot = {}; m_sCursorSurfaceInfo.vHotspot = {};
m_sCursorSurfaceInfo.name = event.shapeName; m_sCursorSurfaceInfo.name = event.shapeName;
m_sCursorSurfaceInfo.hidden = false; m_sCursorSurfaceInfo.hidden = false;
@ -58,6 +58,8 @@ CInputManager::CInputManager() {
m_sListeners.newVirtualMouse = m_sListeners.newVirtualMouse =
PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointerV1Resource>>(data)); }); PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointerV1Resource>>(data)); });
m_sListeners.setCursor = g_pSeatManager->events.setCursor.registerListener([this](std::any d) { this->processMouseRequest(d); }); m_sListeners.setCursor = g_pSeatManager->events.setCursor.registerListener([this](std::any d) { this->processMouseRequest(d); });
m_sCursorSurfaceInfo.wlSurface = CWLSurface::create();
} }
CInputManager::~CInputManager() { CInputManager::~CInputManager() {
@ -115,8 +117,8 @@ void CInputManager::sendMotionEventsToFocused() {
return; return;
// todo: this sucks ass // todo: this sucks ass
const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus); const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus.lock());
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus); const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus.lock());
timespec now; timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
@ -125,7 +127,7 @@ void CInputManager::sendMotionEventsToFocused() {
m_bEmptyFocusCursorSet = false; m_bEmptyFocusCursorSet = false;
g_pSeatManager->setPointerFocus(g_pCompositor->m_pLastFocus, LOCAL); g_pSeatManager->setPointerFocus(g_pCompositor->m_pLastFocus.lock(), LOCAL);
} }
void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) { void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
@ -141,10 +143,10 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
const auto FOLLOWMOUSE = *PFOLLOWONDND && PROTO::data->dndActive() ? 1 : *PFOLLOWMOUSE; const auto FOLLOWMOUSE = *PFOLLOWONDND && PROTO::data->dndActive() ? 1 : *PFOLLOWMOUSE;
m_pFoundSurfaceToFocus = nullptr; m_pFoundSurfaceToFocus.reset();
m_pFoundLSToFocus.reset(); m_pFoundLSToFocus.reset();
m_pFoundWindowToFocus.reset(); m_pFoundWindowToFocus.reset();
wlr_surface* foundSurface = nullptr; SP<CWLSurfaceResource> foundSurface;
Vector2D surfaceCoords; Vector2D surfaceCoords;
Vector2D surfacePos = Vector2D(-1337, -1337); Vector2D surfacePos = Vector2D(-1337, -1337);
PHLWINDOW pFoundWindow; PHLWINDOW pFoundWindow;
@ -191,12 +193,12 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (forcedFocus) { if (forcedFocus) {
pFoundWindow = forcedFocus; pFoundWindow = forcedFocus;
surfacePos = pFoundWindow->m_vRealPosition.value(); surfacePos = pFoundWindow->m_vRealPosition.value();
foundSurface = pFoundWindow->m_pWLSurface.wlr(); foundSurface = pFoundWindow->m_pWLSurface->resource();
} }
// constraints // constraints
if (!g_pSeatManager->mouse.expired() && isConstrained()) { if (!g_pSeatManager->mouse.expired() && isConstrained()) {
const auto SURF = CWLSurface::surfaceFromWlr(g_pCompositor->m_pLastFocus); const auto SURF = CWLSurface::fromResource(g_pCompositor->m_pLastFocus.lock());
const auto CONSTRAINT = SURF->constraint(); const auto CONSTRAINT = SURF->constraint();
if (SURF && CONSTRAINT) { if (SURF && CONSTRAINT) {
@ -223,7 +225,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
// if we are holding a pointer button, // if we are holding a pointer button,
// and we're not dnd-ing, don't refocus. Keep focus on last surface. // and we're not dnd-ing, don't refocus. Keep focus on last surface.
if (!PROTO::data->dndActive() && !m_lCurrentlyHeldButtons.empty() && g_pCompositor->m_pLastFocus && g_pSeatManager->state.pointerFocus && !m_bHardInput) { if (!PROTO::data->dndActive() && !m_lCurrentlyHeldButtons.empty() && g_pCompositor->m_pLastFocus && g_pSeatManager->state.pointerFocus && !m_bHardInput) {
foundSurface = g_pSeatManager->state.pointerFocus; foundSurface = g_pSeatManager->state.pointerFocus.lock();
// IME popups aren't desktop-like elements // IME popups aren't desktop-like elements
// TODO: make them. // TODO: make them.
@ -233,7 +235,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
m_bFocusHeldByButtons = true; m_bFocusHeldByButtons = true;
m_bRefocusHeldByButtons = refocus; m_bRefocusHeldByButtons = refocus;
} else { } else {
auto HLSurface = CWLSurface::surfaceFromWlr(foundSurface); auto HLSurface = CWLSurface::fromResource(foundSurface);
if (HLSurface) { if (HLSurface) {
const auto BOX = HLSurface->getSurfaceBoxGlobal(); const auto BOX = HLSurface->getSurfaceBoxGlobal();
@ -275,7 +277,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (!foundSurface) { if (!foundSurface) {
auto popup = g_pInputManager->m_sIMERelay.popupFromCoords(mouseCoords); auto popup = g_pInputManager->m_sIMERelay.popupFromCoords(mouseCoords);
if (popup) { if (popup) {
foundSurface = popup->getWlrSurface(); foundSurface = popup->getSurface();
surfacePos = popup->globalBox().pos(); surfacePos = popup->globalBox().pos();
} }
} }
@ -306,7 +308,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
surfacePos = Vector2D(-1337, -1337); surfacePos = Vector2D(-1337, -1337);
} else { } else {
foundSurface = pFoundWindow->m_pWLSurface.wlr(); foundSurface = pFoundWindow->m_pWLSurface->resource();
surfacePos = pFoundWindow->m_vRealPosition.value(); surfacePos = pFoundWindow->m_vRealPosition.value();
} }
} }
@ -345,7 +347,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
if (!pFoundWindow->m_bIsX11) { if (!pFoundWindow->m_bIsX11) {
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords); foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
} else { } else {
foundSurface = pFoundWindow->m_pWLSurface.wlr(); foundSurface = pFoundWindow->m_pWLSurface->resource();
surfacePos = pFoundWindow->m_vRealPosition.value(); surfacePos = pFoundWindow->m_vRealPosition.value();
} }
} }
@ -369,9 +371,9 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
return; // setGrab will refocus return; // setGrab will refocus
} else { } else {
// we need to grab the last surface. // we need to grab the last surface.
foundSurface = g_pSeatManager->state.pointerFocus; foundSurface = g_pSeatManager->state.pointerFocus.lock();
auto HLSurface = CWLSurface::surfaceFromWlr(foundSurface); auto HLSurface = CWLSurface::fromResource(foundSurface);
if (HLSurface) { if (HLSurface) {
const auto BOX = HLSurface->getSurfaceBoxGlobal(); const auto BOX = HLSurface->getSurfaceBoxGlobal();
@ -423,7 +425,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
bool allowKeyboardRefocus = true; bool allowKeyboardRefocus = true;
if (!refocus && g_pCompositor->m_pLastFocus) { if (!refocus && g_pCompositor->m_pLastFocus) {
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus); const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus.lock());
if (PLS && PLS->layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) if (PLS && PLS->layerSurface->current.interactivity == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
allowKeyboardRefocus = false; allowKeyboardRefocus = false;
@ -441,7 +443,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus) {
return; return;
} }
if (pFoundWindow && foundSurface == pFoundWindow->m_pWLSurface.wlr() && !m_bCursorImageOverridden) { if (pFoundWindow && foundSurface == pFoundWindow->m_pWLSurface->resource() && !m_bCursorImageOverridden) {
const auto BOX = pFoundWindow->getWindowMainSurfaceBox(); const auto BOX = pFoundWindow->getWindowMainSurfaceBox();
if (!VECINRECT(mouseCoords, BOX.x, BOX.y, BOX.x + BOX.width, BOX.y + BOX.height)) if (!VECINRECT(mouseCoords, BOX.x, BOX.y, BOX.x + BOX.width, BOX.y + BOX.height))
setCursorImageOverride("left_ptr"); setCursorImageOverride("left_ptr");
@ -555,11 +557,11 @@ void CInputManager::processMouseRequest(std::any E) {
Debug::log(LOG, "cursorImage request: surface {:x}", (uintptr_t)e.surf); Debug::log(LOG, "cursorImage request: surface {:x}", (uintptr_t)e.surf);
if (e.surf != m_sCursorSurfaceInfo.wlSurface.wlr()) { if (e.surf != m_sCursorSurfaceInfo.wlSurface->resource()) {
m_sCursorSurfaceInfo.wlSurface.unassign(); m_sCursorSurfaceInfo.wlSurface->unassign();
if (e.surf) if (e.surf)
m_sCursorSurfaceInfo.wlSurface.assign(e.surf); m_sCursorSurfaceInfo.wlSurface->assign(e.surf);
} }
if (e.surf) { if (e.surf) {
@ -573,7 +575,7 @@ void CInputManager::processMouseRequest(std::any E) {
m_sCursorSurfaceInfo.name = ""; m_sCursorSurfaceInfo.name = "";
m_sCursorSurfaceInfo.inUse = true; m_sCursorSurfaceInfo.inUse = true;
g_pHyprRenderer->setCursorSurface(&m_sCursorSurfaceInfo.wlSurface, e.hotspot.x, e.hotspot.y); g_pHyprRenderer->setCursorSurface(m_sCursorSurfaceInfo.wlSurface, e.hotspot.x, e.hotspot.y);
} }
void CInputManager::restoreCursorIconToApp() { void CInputManager::restoreCursorIconToApp() {
@ -586,8 +588,8 @@ void CInputManager::restoreCursorIconToApp() {
} }
if (m_sCursorSurfaceInfo.name.empty()) { if (m_sCursorSurfaceInfo.name.empty()) {
if (m_sCursorSurfaceInfo.wlSurface.exists()) if (m_sCursorSurfaceInfo.wlSurface->exists())
g_pHyprRenderer->setCursorSurface(&m_sCursorSurfaceInfo.wlSurface, m_sCursorSurfaceInfo.vHotspot.x, m_sCursorSurfaceInfo.vHotspot.y); g_pHyprRenderer->setCursorSurface(m_sCursorSurfaceInfo.wlSurface, m_sCursorSurfaceInfo.vHotspot.x, m_sCursorSurfaceInfo.vHotspot.y);
} else { } else {
g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name); g_pHyprRenderer->setCursorFromName(m_sCursorSurfaceInfo.name);
} }
@ -696,7 +698,7 @@ void CInputManager::processMouseDownNormal(const IPointer::SButtonEvent& e) {
if (!g_pSeatManager->state.pointerFocus) if (!g_pSeatManager->state.pointerFocus)
break; break;
auto HLSurf = CWLSurface::surfaceFromWlr(g_pSeatManager->state.pointerFocus); auto HLSurf = CWLSurface::fromResource(g_pSeatManager->state.pointerFocus.lock());
if (HLSurf && HLSurf->getWindow()) if (HLSurf && HLSurf->getWindow())
g_pCompositor->changeWindowZOrder(HLSurf->getWindow(), true); g_pCompositor->changeWindowZOrder(HLSurf->getWindow(), true);
@ -1399,7 +1401,7 @@ bool CInputManager::isConstrained() {
if (!C) if (!C)
continue; continue;
if (!C->isActive() || C->owner()->wlr() != g_pCompositor->m_pLastFocus) if (!C->isActive() || C->owner()->resource() != g_pCompositor->m_pLastFocus)
continue; continue;
return true; return true;

View file

@ -46,7 +46,7 @@ enum eBorderIconDirection {
struct STouchData { struct STouchData {
PHLWINDOWREF touchFocusWindow; PHLWINDOWREF touchFocusWindow;
PHLLSREF touchFocusLS; PHLLSREF touchFocusLS;
wlr_surface* touchFocusSurface = nullptr; WP<CWLSurfaceResource> touchFocusSurface;
Vector2D touchSurfaceOrigin; Vector2D touchSurfaceOrigin;
}; };
@ -236,7 +236,7 @@ class CInputManager {
void applyConfigToKeyboard(SP<IKeyboard>); void applyConfigToKeyboard(SP<IKeyboard>);
// this will be set after a refocus() // this will be set after a refocus()
wlr_surface* m_pFoundSurfaceToFocus = nullptr; WP<CWLSurfaceResource> m_pFoundSurfaceToFocus;
PHLLSREF m_pFoundLSToFocus; PHLLSREF m_pFoundLSToFocus;
PHLWINDOWREF m_pFoundWindowToFocus; PHLWINDOWREF m_pFoundWindowToFocus;
@ -269,7 +269,7 @@ class CInputManager {
// cursor surface // cursor surface
struct cursorSI { struct cursorSI {
bool hidden = false; // null surface = hidden bool hidden = false; // null surface = hidden
CWLSurface wlSurface; SP<CWLSurface> wlSurface;
Vector2D vHotspot; Vector2D vHotspot;
std::string name; // if not empty, means set by name. std::string name; // if not empty, means set by name.
bool inUse = false; bool inUse = false;

View file

@ -3,22 +3,24 @@
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../protocols/FractionalScale.hpp" #include "../../protocols/FractionalScale.hpp"
#include "../../protocols/InputMethodV2.hpp" #include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/core/Compositor.hpp"
CInputPopup::CInputPopup(SP<CInputMethodPopupV2> popup_) : popup(popup_) { CInputPopup::CInputPopup(SP<CInputMethodPopupV2> popup_) : popup(popup_) {
listeners.commit = popup_->events.commit.registerListener([this](std::any d) { onCommit(); }); listeners.commit = popup_->events.commit.registerListener([this](std::any d) { onCommit(); });
listeners.map = popup_->events.map.registerListener([this](std::any d) { onMap(); }); listeners.map = popup_->events.map.registerListener([this](std::any d) { onMap(); });
listeners.unmap = popup_->events.unmap.registerListener([this](std::any d) { onUnmap(); }); listeners.unmap = popup_->events.unmap.registerListener([this](std::any d) { onUnmap(); });
listeners.destroy = popup_->events.destroy.registerListener([this](std::any d) { onDestroy(); }); listeners.destroy = popup_->events.destroy.registerListener([this](std::any d) { onDestroy(); });
surface.assign(popup_->surface()); surface = CWLSurface::create();
surface->assign(popup_->surface());
} }
CWLSurface* CInputPopup::queryOwner() { SP<CWLSurface> CInputPopup::queryOwner() {
const auto FOCUSED = g_pInputManager->m_sIMERelay.getFocusedTextInput(); const auto FOCUSED = g_pInputManager->m_sIMERelay.getFocusedTextInput();
if (!FOCUSED) if (!FOCUSED)
return nullptr; return nullptr;
return CWLSurface::surfaceFromWlr(FOCUSED->focusedSurface()); return CWLSurface::fromResource(FOCUSED->focusedSurface());
} }
void CInputPopup::onDestroy() { void CInputPopup::onDestroy() {
@ -36,7 +38,7 @@ void CInputPopup::onMap() {
if (!PMONITOR) if (!PMONITOR)
return; return;
PROTO::fractional->sendScale(surface.wlr(), PMONITOR->scale); PROTO::fractional->sendScale(surface->resource(), PMONITOR->scale);
} }
void CInputPopup::onUnmap() { void CInputPopup::onUnmap() {
@ -69,7 +71,7 @@ void CInputPopup::damageSurface() {
} }
Vector2D pos = globalBox().pos(); Vector2D pos = globalBox().pos();
g_pHyprRenderer->damageSurface(surface.wlr(), pos.x, pos.y); g_pHyprRenderer->damageSurface(surface->resource(), pos.x, pos.y);
} }
void CInputPopup::updateBox() { void CInputPopup::updateBox() {
@ -98,7 +100,7 @@ void CInputPopup::updateBox() {
cursorBoxParent = {0, 0, (int)parentBox.w, (int)parentBox.h}; cursorBoxParent = {0, 0, (int)parentBox.w, (int)parentBox.h};
} }
Vector2D currentPopupSize = surface.getViewporterCorrectedSize(); Vector2D currentPopupSize = surface->getViewporterCorrectedSize();
CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle()); CMonitor* pMonitor = g_pCompositor->getMonitorFromVector(parentBox.middle());
@ -127,9 +129,9 @@ void CInputPopup::updateBox() {
const auto PML = g_pCompositor->getMonitorFromID(lastMonitor); const auto PML = g_pCompositor->getMonitorFromID(lastMonitor);
if (PML) if (PML)
wlr_surface_send_leave(surface.wlr(), PML->output); surface->resource()->leave(PML->self.lock());
wlr_surface_send_enter(surface.wlr(), PM->output); surface->resource()->enter(PM->self.lock());
lastMonitor = PM->ID; lastMonitor = PM->ID;
} }
@ -151,6 +153,6 @@ bool CInputPopup::isVecInPopup(const Vector2D& point) {
return globalBox().containsPoint(point); return globalBox().containsPoint(point);
} }
wlr_surface* CInputPopup::getWlrSurface() { SP<CWLSurfaceResource> CInputPopup::getSurface() {
return surface.wlr(); return surface->resource();
} }

View file

@ -18,12 +18,12 @@ class CInputPopup {
bool isVecInPopup(const Vector2D& point); bool isVecInPopup(const Vector2D& point);
CBox globalBox(); CBox globalBox();
wlr_surface* getWlrSurface(); SP<CWLSurfaceResource> getSurface();
void onCommit(); void onCommit();
private: private:
CWLSurface* queryOwner(); SP<CWLSurface> queryOwner();
void updateBox(); void updateBox();
void onDestroy(); void onDestroy();
@ -31,7 +31,7 @@ class CInputPopup {
void onUnmap(); void onUnmap();
WP<CInputMethodPopupV2> popup; WP<CInputMethodPopupV2> popup;
CWLSurface surface; SP<CWLSurface> surface;
CBox lastBoxLocal; CBox lastBoxLocal;
uint64_t lastMonitor = -1; uint64_t lastMonitor = -1;

View file

@ -3,9 +3,11 @@
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../protocols/TextInputV3.hpp" #include "../../protocols/TextInputV3.hpp"
#include "../../protocols/InputMethodV2.hpp" #include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/core/Compositor.hpp"
CInputMethodRelay::CInputMethodRelay() { CInputMethodRelay::CInputMethodRelay() {
static auto P = g_pHookSystem->hookDynamic("keyboardFocus", [&](void* self, SCallbackInfo& info, std::any param) { onKeyboardFocus(std::any_cast<wlr_surface*>(param)); }); static auto P =
g_pHookSystem->hookDynamic("keyboardFocus", [&](void* self, SCallbackInfo& info, std::any param) { onKeyboardFocus(std::any_cast<SP<CWLSurfaceResource>>(param)); });
listeners.newTIV3 = PROTO::textInputV3->events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(ti); }); listeners.newTIV3 = PROTO::textInputV3->events.newTextInput.registerListener([this](std::any ti) { onNewTextInput(ti); });
listeners.newIME = PROTO::ime->events.newIME.registerListener([this](std::any ime) { onNewIME(std::any_cast<SP<CInputMethodV2>>(ime)); }); listeners.newIME = PROTO::ime->events.newIME.registerListener([this](std::any ime) { onNewIME(std::any_cast<SP<CInputMethodV2>>(ime)); });
@ -54,17 +56,17 @@ void CInputMethodRelay::onNewIME(SP<CInputMethodV2> pIME) {
return; return;
for (auto& ti : m_vTextInputs) { for (auto& ti : m_vTextInputs) {
if (ti->client() != wl_resource_get_client(g_pCompositor->m_pLastFocus->resource)) if (ti->client() != g_pCompositor->m_pLastFocus->client())
continue; continue;
if (ti->isV3()) if (ti->isV3())
ti->enter(g_pCompositor->m_pLastFocus); ti->enter(g_pCompositor->m_pLastFocus.lock());
else else
ti->onEnabled(g_pCompositor->m_pLastFocus); ti->onEnabled(g_pCompositor->m_pLastFocus.lock());
} }
} }
void CInputMethodRelay::setIMEPopupFocus(CInputPopup* pPopup, wlr_surface* pSurface) { void CInputMethodRelay::setIMEPopupFocus(CInputPopup* pPopup, SP<CWLSurfaceResource> pSurface) {
pPopup->onCommit(); pPopup->onCommit();
} }
@ -125,7 +127,7 @@ void CInputMethodRelay::commitIMEState(CTextInput* pInput) {
pInput->commitStateToIME(m_pIME.lock()); pInput->commitStateToIME(m_pIME.lock());
} }
void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) { void CInputMethodRelay::onKeyboardFocus(SP<CWLSurfaceResource> pSurface) {
if (m_pIME.expired()) if (m_pIME.expired())
return; return;
@ -145,7 +147,7 @@ void CInputMethodRelay::onKeyboardFocus(wlr_surface* pSurface) {
if (!ti->isV3()) if (!ti->isV3())
continue; continue;
if (ti->client() != wl_resource_get_client(pSurface->resource)) if (ti->client() != pSurface->client())
continue; continue;
ti->enter(pSurface); ti->enter(pSurface);
@ -161,9 +163,9 @@ CInputPopup* CInputMethodRelay::popupFromCoords(const Vector2D& point) {
return nullptr; return nullptr;
} }
CInputPopup* CInputMethodRelay::popupFromSurface(const wlr_surface* surface) { CInputPopup* CInputMethodRelay::popupFromSurface(const SP<CWLSurfaceResource> surface) {
for (auto& p : m_vIMEPopups) { for (auto& p : m_vIMEPopups) {
if (p->getWlrSurface() == surface) if (p->getSurface() == surface)
return p.get(); return p.get();
} }

View file

@ -26,15 +26,15 @@ class CInputMethodRelay {
void commitIMEState(CTextInput* pInput); void commitIMEState(CTextInput* pInput);
void removeTextInput(CTextInput* pInput); void removeTextInput(CTextInput* pInput);
void onKeyboardFocus(wlr_surface*); void onKeyboardFocus(SP<CWLSurfaceResource>);
CTextInput* getFocusedTextInput(); CTextInput* getFocusedTextInput();
void setIMEPopupFocus(CInputPopup*, wlr_surface*); void setIMEPopupFocus(CInputPopup*, SP<CWLSurfaceResource>);
void removePopup(CInputPopup*); void removePopup(CInputPopup*);
CInputPopup* popupFromCoords(const Vector2D& point); CInputPopup* popupFromCoords(const Vector2D& point);
CInputPopup* popupFromSurface(const wlr_surface* surface); CInputPopup* popupFromSurface(const SP<CWLSurfaceResource> surface);
void updateAllPopups(); void updateAllPopups();
@ -44,7 +44,7 @@ class CInputMethodRelay {
std::vector<std::unique_ptr<CTextInput>> m_vTextInputs; std::vector<std::unique_ptr<CTextInput>> m_vTextInputs;
std::vector<std::unique_ptr<CInputPopup>> m_vIMEPopups; std::vector<std::unique_ptr<CInputPopup>> m_vIMEPopups;
wlr_surface* m_pLastKbFocus = nullptr; WP<CWLSurfaceResource> m_pLastKbFocus;
struct { struct {
CHyprSignalListener newTIV3; CHyprSignalListener newTIV3;
@ -57,6 +57,6 @@ class CInputMethodRelay {
friend class CHyprRenderer; friend class CHyprRenderer;
friend class CInputManager; friend class CInputManager;
friend class CTextInputV1ProtocolManager; friend class CTextInputV1ProtocolManager;
friend struct CTextInput; friend class CTextInput;
friend class CHyprRenderer; friend class CHyprRenderer;
}; };

View file

@ -20,7 +20,7 @@ static void unfocusTool(SP<CTabletTool> tool) {
PROTO::tablet->proximityOut(tool); PROTO::tablet->proximityOut(tool);
} }
static void focusTool(SP<CTabletTool> tool, SP<CTablet> tablet, wlr_surface* surf) { static void focusTool(SP<CTabletTool> tool, SP<CTablet> tablet, SP<CWLSurfaceResource> surf) {
if (tool->getSurface() == surf || !surf) if (tool->getSurface() == surf || !surf)
return; return;
@ -37,7 +37,7 @@ static void focusTool(SP<CTabletTool> tool, SP<CTablet> tablet, wlr_surface* sur
} }
static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = false) { static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = false) {
const auto LASTHLSURFACE = CWLSurface::surfaceFromWlr(g_pSeatManager->state.pointerFocus); const auto LASTHLSURFACE = CWLSurface::fromResource(g_pSeatManager->state.pointerFocus.lock());
if (!LASTHLSURFACE || !tool->active) { if (!LASTHLSURFACE || !tool->active) {
if (tool->getSurface()) if (tool->getSurface())
@ -57,7 +57,7 @@ static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = f
const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal(); const auto CURSORPOS = g_pInputManager->getMouseCoordsInternal();
focusTool(tool, tab, g_pSeatManager->state.pointerFocus); focusTool(tool, tab, g_pSeatManager->state.pointerFocus.lock());
if (!motion) if (!motion)
return; return;

View file

@ -5,6 +5,7 @@
#include "../../Compositor.hpp" #include "../../Compositor.hpp"
#include "../../protocols/TextInputV3.hpp" #include "../../protocols/TextInputV3.hpp"
#include "../../protocols/InputMethodV2.hpp" #include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/core/Compositor.hpp"
CTextInput::CTextInput(STextInputV1* ti) : pV1Input(ti) { CTextInput::CTextInput(STextInputV1* ti) : pV1Input(ti) {
ti->pTextInput = this; ti->pTextInput = this;
@ -56,8 +57,8 @@ void CTextInput::initCallbacks() {
hyprListener_textInputDestroy.removeCallback(); hyprListener_textInputDestroy.removeCallback();
hyprListener_textInputDisable.removeCallback(); hyprListener_textInputDisable.removeCallback();
hyprListener_textInputEnable.removeCallback(); hyprListener_textInputEnable.removeCallback();
hyprListener_surfaceDestroyed.removeCallback(); listeners.surfaceUnmap.reset();
hyprListener_surfaceUnmapped.removeCallback(); listeners.surfaceDestroy.reset();
g_pInputManager->m_sIMERelay.removeTextInput(this); g_pInputManager->m_sIMERelay.removeTextInput(this);
}, },
@ -65,7 +66,7 @@ void CTextInput::initCallbacks() {
} }
} }
void CTextInput::onEnabled(wlr_surface* surfV1) { void CTextInput::onEnabled(SP<CWLSurfaceResource> surfV1) {
Debug::log(LOG, "TI ENABLE"); Debug::log(LOG, "TI ENABLE");
if (g_pInputManager->m_sIMERelay.m_pIME.expired()) { if (g_pInputManager->m_sIMERelay.m_pIME.expired()) {
@ -75,7 +76,7 @@ void CTextInput::onEnabled(wlr_surface* surfV1) {
// v1 only, map surface to PTI // v1 only, map surface to PTI
if (!isV3()) { if (!isV3()) {
wlr_surface* pSurface = surfV1; SP<CWLSurfaceResource> pSurface = surfV1;
if (g_pCompositor->m_pLastFocus != pSurface || !pV1Input->active) if (g_pCompositor->m_pLastFocus != pSurface || !pV1Input->active)
return; return;
@ -97,8 +98,8 @@ void CTextInput::onDisabled() {
if (!isV3()) if (!isV3())
leave(); leave();
hyprListener_surfaceDestroyed.removeCallback(); listeners.surfaceUnmap.reset();
hyprListener_surfaceUnmapped.removeCallback(); listeners.surfaceDestroy.reset();
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
} }
@ -117,50 +118,44 @@ void CTextInput::onCommit() {
g_pInputManager->m_sIMERelay.commitIMEState(this); g_pInputManager->m_sIMERelay.commitIMEState(this);
} }
void CTextInput::setFocusedSurface(wlr_surface* pSurface) { void CTextInput::setFocusedSurface(SP<CWLSurfaceResource> pSurface) {
if (pSurface == pFocusedSurface) if (pSurface == pFocusedSurface)
return; return;
pFocusedSurface = pSurface; pFocusedSurface = pSurface;
hyprListener_surfaceUnmapped.removeCallback(); listeners.surfaceUnmap.reset();
hyprListener_surfaceDestroyed.removeCallback(); listeners.surfaceDestroy.reset();
if (!pSurface) if (!pSurface)
return; return;
hyprListener_surfaceUnmapped.initCallback( listeners.surfaceUnmap = pSurface->events.unmap.registerListener([this](std::any d) {
&pSurface->events.unmap,
[this](void* owner, void* data) {
Debug::log(LOG, "Unmap TI owner1"); Debug::log(LOG, "Unmap TI owner1");
if (enterLocks) if (enterLocks)
enterLocks--; enterLocks--;
pFocusedSurface = nullptr; pFocusedSurface.reset();
hyprListener_surfaceUnmapped.removeCallback(); listeners.surfaceUnmap.reset();
hyprListener_surfaceDestroyed.removeCallback(); listeners.surfaceDestroy.reset();
}, });
this, "CTextInput");
hyprListener_surfaceDestroyed.initCallback( listeners.surfaceDestroy = pSurface->events.destroy.registerListener([this](std::any d) {
&pSurface->events.destroy, Debug::log(LOG, "Destroy TI owner1");
[this](void* owner, void* data) {
Debug::log(LOG, "destroy TI owner1");
if (enterLocks) if (enterLocks)
enterLocks--; enterLocks--;
pFocusedSurface = nullptr; pFocusedSurface.reset();
hyprListener_surfaceUnmapped.removeCallback(); listeners.surfaceUnmap.reset();
hyprListener_surfaceDestroyed.removeCallback(); listeners.surfaceDestroy.reset();
}, });
this, "CTextInput");
} }
bool CTextInput::isV3() { bool CTextInput::isV3() {
return !pV1Input; return !pV1Input;
} }
void CTextInput::enter(wlr_surface* pSurface) { void CTextInput::enter(SP<CWLSurfaceResource> pSurface) {
if (!pSurface || !pSurface->mapped) if (!pSurface || !pSurface->mapped)
return; return;
@ -182,7 +177,7 @@ void CTextInput::enter(wlr_surface* pSurface) {
if (isV3()) if (isV3())
pV3Input->enter(pSurface); pV3Input->enter(pSurface);
else { else {
zwp_text_input_v1_send_enter(pV1Input->resourceImpl, pSurface->resource); zwp_text_input_v1_send_enter(pV1Input->resourceImpl, pSurface->getResource()->resource());
pV1Input->active = true; pV1Input->active = true;
} }
@ -211,8 +206,8 @@ void CTextInput::leave() {
g_pInputManager->m_sIMERelay.deactivateIME(this); g_pInputManager->m_sIMERelay.deactivateIME(this);
} }
wlr_surface* CTextInput::focusedSurface() { SP<CWLSurfaceResource> CTextInput::focusedSurface() {
return pFocusedSurface; return pFocusedSurface.lock();
} }
wl_client* CTextInput::client() { wl_client* CTextInput::client() {

View file

@ -6,12 +6,12 @@
#include "../../helpers/signal/Listener.hpp" #include "../../helpers/signal/Listener.hpp"
#include <memory> #include <memory>
struct wlr_surface;
struct wl_client; struct wl_client;
struct STextInputV1; struct STextInputV1;
class CTextInputV3; class CTextInputV3;
class CInputMethodV2; class CInputMethodV2;
class CWLSurfaceResource;
class CTextInput { class CTextInput {
public: public:
@ -20,27 +20,27 @@ class CTextInput {
~CTextInput(); ~CTextInput();
bool isV3(); bool isV3();
void enter(wlr_surface* pSurface); void enter(SP<CWLSurfaceResource> pSurface);
void leave(); void leave();
void tiV1Destroyed(); void tiV1Destroyed();
wl_client* client(); wl_client* client();
void commitStateToIME(SP<CInputMethodV2> ime); void commitStateToIME(SP<CInputMethodV2> ime);
void updateIMEState(SP<CInputMethodV2> ime); void updateIMEState(SP<CInputMethodV2> ime);
void onEnabled(wlr_surface* surfV1 = nullptr); void onEnabled(SP<CWLSurfaceResource> surfV1 = nullptr);
void onDisabled(); void onDisabled();
void onCommit(); void onCommit();
bool hasCursorRectangle(); bool hasCursorRectangle();
CBox cursorBox(); CBox cursorBox();
wlr_surface* focusedSurface(); SP<CWLSurfaceResource> focusedSurface();
private: private:
void setFocusedSurface(wlr_surface* pSurface); void setFocusedSurface(SP<CWLSurfaceResource> pSurface);
void initCallbacks(); void initCallbacks();
wlr_surface* pFocusedSurface = nullptr; WP<CWLSurfaceResource> pFocusedSurface;
int enterLocks = 0; int enterLocks = 0;
WP<CTextInputV3> pV3Input; WP<CTextInputV3> pV3Input;
STextInputV1* pV1Input = nullptr; STextInputV1* pV1Input = nullptr;
@ -49,13 +49,13 @@ class CTextInput {
DYNLISTENER(textInputDisable); DYNLISTENER(textInputDisable);
DYNLISTENER(textInputCommit); DYNLISTENER(textInputCommit);
DYNLISTENER(textInputDestroy); DYNLISTENER(textInputDestroy);
DYNLISTENER(surfaceUnmapped);
DYNLISTENER(surfaceDestroyed);
struct { struct {
CHyprSignalListener enable; CHyprSignalListener enable;
CHyprSignalListener disable; CHyprSignalListener disable;
CHyprSignalListener commit; CHyprSignalListener commit;
CHyprSignalListener destroy; CHyprSignalListener destroy;
CHyprSignalListener surfaceUnmap;
CHyprSignalListener surfaceDestroy;
} listeners; } listeners;
}; };

View file

@ -77,7 +77,7 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
} else } else
return; // oops, nothing found. return; // oops, nothing found.
g_pSeatManager->sendTouchDown(m_sTouchData.touchFocusSurface, e.timeMs, e.touchID, local); g_pSeatManager->sendTouchDown(m_sTouchData.touchFocusSurface.lock(), e.timeMs, e.touchID, local);
PROTO::idle->onActivity(); PROTO::idle->onActivity();
} }

View file

@ -2,10 +2,11 @@
#include <algorithm> #include <algorithm>
#include "../desktop/WLSurface.hpp" #include "../desktop/WLSurface.hpp"
#include "../render/Renderer.hpp" #include "../render/Renderer.hpp"
#include "core/Compositor.hpp"
#define LOGM PROTO::alphaModifier->protoLog #define LOGM PROTO::alphaModifier->protoLog
CAlphaModifier::CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, wlr_surface* surface_) : resource(resource_), pSurface(surface_) { CAlphaModifier::CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, SP<CWLSurfaceResource> surface_) : resource(resource_), pSurface(surface_) {
if (!resource->resource()) if (!resource->resource())
return; return;
@ -18,8 +19,7 @@ CAlphaModifier::CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, wlr_surf
setSurfaceAlpha(1.F); setSurfaceAlpha(1.F);
}); });
hyprListener_surfaceDestroy.initCallback( listeners.destroySurface = pSurface->events.destroy.registerListener([this](std::any d) { onSurfaceDestroy(); });
&surface_->events.destroy, [this](void* owner, void* data) { onSurfaceDestroy(); }, this, "CAlphaModifier");
resource->setSetMultiplier([this](CWpAlphaModifierSurfaceV1* mod, uint32_t alpha) { resource->setSetMultiplier([this](CWpAlphaModifierSurfaceV1* mod, uint32_t alpha) {
if (!pSurface) { if (!pSurface) {
@ -35,19 +35,19 @@ CAlphaModifier::CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, wlr_surf
} }
CAlphaModifier::~CAlphaModifier() { CAlphaModifier::~CAlphaModifier() {
hyprListener_surfaceDestroy.removeCallback(); ;
} }
bool CAlphaModifier::good() { bool CAlphaModifier::good() {
return resource->resource(); return resource->resource();
} }
wlr_surface* CAlphaModifier::getSurface() { SP<CWLSurfaceResource> CAlphaModifier::getSurface() {
return pSurface; return pSurface.lock();
} }
void CAlphaModifier::setSurfaceAlpha(float a) { void CAlphaModifier::setSurfaceAlpha(float a) {
CWLSurface* surf = CWLSurface::surfaceFromWlr(pSurface); auto surf = CWLSurface::fromResource(pSurface.lock());
if (!surf) { if (!surf) {
LOGM(ERR, "CAlphaModifier::setSurfaceAlpha: No CWLSurface for given surface??"); LOGM(ERR, "CAlphaModifier::setSurfaceAlpha: No CWLSurface for given surface??");
@ -62,8 +62,7 @@ void CAlphaModifier::setSurfaceAlpha(float a) {
} }
void CAlphaModifier::onSurfaceDestroy() { void CAlphaModifier::onSurfaceDestroy() {
hyprListener_surfaceDestroy.removeCallback(); pSurface.reset();
pSurface = nullptr;
} }
CAlphaModifierProtocol::CAlphaModifierProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { CAlphaModifierProtocol::CAlphaModifierProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
@ -75,7 +74,7 @@ void CAlphaModifierProtocol::bindManager(wl_client* client, void* data, uint32_t
RESOURCE->setOnDestroy([this](CWpAlphaModifierV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setOnDestroy([this](CWpAlphaModifierV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CWpAlphaModifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); RESOURCE->setDestroy([this](CWpAlphaModifierV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
RESOURCE->setGetSurface([this](CWpAlphaModifierV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetSurface(pMgr, id, wlr_surface_from_resource(surface)); }); RESOURCE->setGetSurface([this](CWpAlphaModifierV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetSurface(pMgr, id, CWLSurfaceResource::fromResource(surface)); });
} }
void CAlphaModifierProtocol::onManagerResourceDestroy(wl_resource* res) { void CAlphaModifierProtocol::onManagerResourceDestroy(wl_resource* res) {
@ -83,29 +82,11 @@ void CAlphaModifierProtocol::onManagerResourceDestroy(wl_resource* res) {
} }
void CAlphaModifierProtocol::destroyModifier(CAlphaModifier* modifier) { void CAlphaModifierProtocol::destroyModifier(CAlphaModifier* modifier) {
if (modifier->getSurface()) std::erase_if(m_mAlphaModifiers, [](const auto& e) { return e.first.expired(); });
m_mAlphaModifiers.erase(modifier->getSurface());
else {
// find it first
wlr_surface* deadptr = nullptr;
for (auto& [k, v] : m_mAlphaModifiers) {
if (v.get() == modifier) {
deadptr = k;
break;
}
} }
if (!deadptr) { void CAlphaModifierProtocol::onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface) {
LOGM(ERR, "CAlphaModifierProtocol::destroyModifier: dead resource but no deadptr???"); if (std::find_if(m_mAlphaModifiers.begin(), m_mAlphaModifiers.end(), [surface](const auto& e) { return e.first == surface; }) != m_mAlphaModifiers.end()) {
return;
}
m_mAlphaModifiers.erase(deadptr);
}
}
void CAlphaModifierProtocol::onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, wlr_surface* surface) {
if (m_mAlphaModifiers.contains(surface)) {
LOGM(ERR, "AlphaModifier already present for surface {:x}", (uintptr_t)surface); LOGM(ERR, "AlphaModifier already present for surface {:x}", (uintptr_t)surface);
pMgr->error(WP_ALPHA_MODIFIER_V1_ERROR_ALREADY_CONSTRUCTED, "AlphaModifier already present"); pMgr->error(WP_ALPHA_MODIFIER_V1_ERROR_ALREADY_CONSTRUCTED, "AlphaModifier already present");
return; return;

View file

@ -5,23 +5,28 @@
#include <unordered_map> #include <unordered_map>
#include "WaylandProtocol.hpp" #include "WaylandProtocol.hpp"
#include "alpha-modifier-v1.hpp" #include "alpha-modifier-v1.hpp"
#include "../helpers/signal/Listener.hpp"
class CWLSurfaceResource;
class CAlphaModifier { class CAlphaModifier {
public: public:
CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, wlr_surface* surface); CAlphaModifier(SP<CWpAlphaModifierSurfaceV1> resource_, SP<CWLSurfaceResource> surface);
~CAlphaModifier(); ~CAlphaModifier();
bool good(); bool good();
wlr_surface* getSurface(); SP<CWLSurfaceResource> getSurface();
void onSurfaceDestroy(); void onSurfaceDestroy();
private: private:
SP<CWpAlphaModifierSurfaceV1> resource; SP<CWpAlphaModifierSurfaceV1> resource;
wlr_surface* pSurface = nullptr; WP<CWLSurfaceResource> pSurface;
void setSurfaceAlpha(float a); void setSurfaceAlpha(float a);
DYNLISTENER(surfaceDestroy); struct {
CHyprSignalListener destroySurface;
} listeners;
}; };
class CAlphaModifierProtocol : public IWaylandProtocol { class CAlphaModifierProtocol : public IWaylandProtocol {
@ -33,11 +38,11 @@ class CAlphaModifierProtocol : public IWaylandProtocol {
private: private:
void onManagerResourceDestroy(wl_resource* res); void onManagerResourceDestroy(wl_resource* res);
void destroyModifier(CAlphaModifier* decoration); void destroyModifier(CAlphaModifier* decoration);
void onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, wlr_surface* surface); void onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface);
// //
std::vector<UP<CWpAlphaModifierV1>> m_vManagers; std::vector<UP<CWpAlphaModifierV1>> m_vManagers;
std::unordered_map<wlr_surface*, UP<CAlphaModifier>> m_mAlphaModifiers; // xdg_toplevel -> deco std::unordered_map<WP<CWLSurfaceResource>, UP<CAlphaModifier>> m_mAlphaModifiers; // xdg_toplevel -> deco
friend class CAlphaModifier; friend class CAlphaModifier;
}; };

View file

@ -1,21 +1,21 @@
#include "FocusGrab.hpp" #include "FocusGrab.hpp"
#include "Compositor.hpp" #include "../Compositor.hpp"
#include <hyprland-focus-grab-v1.hpp> #include <hyprland-focus-grab-v1.hpp>
#include "../managers/input/InputManager.hpp" #include "../managers/input/InputManager.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "core/Compositor.hpp"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <wayland-server.h> #include <wayland-server.h>
#define LOGM PROTO::focusGrab->protoLog #define LOGM PROTO::focusGrab->protoLog
CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface) { CFocusGrabSurfaceState::CFocusGrabSurfaceState(CFocusGrab* grab, SP<CWLSurfaceResource> surface) {
hyprListener_surfaceDestroy.initCallback( listeners.destroy = surface->events.destroy.registerListener([=](std::any d) { grab->eraseSurface(surface); });
&surface->events.destroy, [=](void*, void*) { grab->eraseSurface(surface); }, this, "CFocusGrab");
} }
CFocusGrabSurfaceState::~CFocusGrabSurfaceState() { CFocusGrabSurfaceState::~CFocusGrabSurfaceState() {
hyprListener_surfaceDestroy.removeCallback(); ;
} }
CFocusGrab::CFocusGrab(SP<CHyprlandFocusGrabV1> resource_) : resource(resource_) { CFocusGrab::CFocusGrab(SP<CHyprlandFocusGrabV1> resource_) : resource(resource_) {
@ -29,8 +29,8 @@ CFocusGrab::CFocusGrab(SP<CHyprlandFocusGrabV1> resource_) : resource(resource_)
resource->setDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); }); resource->setDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); });
resource->setOnDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); }); resource->setOnDestroy([this](CHyprlandFocusGrabV1* pMgr) { PROTO::focusGrab->destroyGrab(this); });
resource->setAddSurface([this](CHyprlandFocusGrabV1* pMgr, wl_resource* surface) { addSurface(wlr_surface_from_resource(surface)); }); resource->setAddSurface([this](CHyprlandFocusGrabV1* pMgr, wl_resource* surface) { addSurface(CWLSurfaceResource::fromResource(surface)); });
resource->setRemoveSurface([this](CHyprlandFocusGrabV1* pMgr, wl_resource* surface) { removeSurface(wlr_surface_from_resource(surface)); }); resource->setRemoveSurface([this](CHyprlandFocusGrabV1* pMgr, wl_resource* surface) { removeSurface(CWLSurfaceResource::fromResource(surface)); });
resource->setCommit([this](CHyprlandFocusGrabV1* pMgr) { commit(); }); resource->setCommit([this](CHyprlandFocusGrabV1* pMgr) { commit(); });
} }
@ -42,8 +42,8 @@ bool CFocusGrab::good() {
return resource->resource(); return resource->resource();
} }
bool CFocusGrab::isSurfaceComitted(wlr_surface* surface) { bool CFocusGrab::isSurfaceComitted(SP<CWLSurfaceResource> surface) {
auto iter = m_mSurfaces.find(surface); auto iter = std::find_if(m_mSurfaces.begin(), m_mSurfaces.end(), [surface](const auto& o) { return o.first == surface; });
if (iter == m_mSurfaces.end()) if (iter == m_mSurfaces.end())
return false; return false;
@ -77,14 +77,14 @@ void CFocusGrab::finish(bool sendCleared) {
} }
} }
void CFocusGrab::addSurface(wlr_surface* surface) { void CFocusGrab::addSurface(SP<CWLSurfaceResource> surface) {
auto iter = m_mSurfaces.find(surface); auto iter = std::find_if(m_mSurfaces.begin(), m_mSurfaces.end(), [surface](const auto& e) { return e.first == surface; });
if (iter == m_mSurfaces.end()) { if (iter == m_mSurfaces.end()) {
m_mSurfaces.emplace(surface, std::make_unique<CFocusGrabSurfaceState>(this, surface)); m_mSurfaces.emplace(surface, std::make_unique<CFocusGrabSurfaceState>(this, surface));
} }
} }
void CFocusGrab::removeSurface(wlr_surface* surface) { void CFocusGrab::removeSurface(SP<CWLSurfaceResource> surface) {
auto iter = m_mSurfaces.find(surface); auto iter = m_mSurfaces.find(surface);
if (iter != m_mSurfaces.end()) { if (iter != m_mSurfaces.end()) {
if (iter->second->state == CFocusGrabSurfaceState::PendingAddition) { if (iter->second->state == CFocusGrabSurfaceState::PendingAddition) {
@ -94,20 +94,20 @@ void CFocusGrab::removeSurface(wlr_surface* surface) {
} }
} }
void CFocusGrab::eraseSurface(wlr_surface* surface) { void CFocusGrab::eraseSurface(SP<CWLSurfaceResource> surface) {
removeSurface(surface); removeSurface(surface);
commit(true); commit(true);
} }
void CFocusGrab::refocusKeyboard() { void CFocusGrab::refocusKeyboard() {
auto keyboardSurface = g_pSeatManager->state.keyboardFocus; auto keyboardSurface = g_pSeatManager->state.keyboardFocus;
if (keyboardSurface != nullptr && isSurfaceComitted(keyboardSurface)) if (keyboardSurface && isSurfaceComitted(keyboardSurface.lock()))
return; return;
wlr_surface* surface = nullptr; SP<CWLSurfaceResource> surface = nullptr;
for (auto& [surf, state] : m_mSurfaces) { for (auto& [surf, state] : m_mSurfaces) {
if (state->state == CFocusGrabSurfaceState::Comitted) { if (state->state == CFocusGrabSurfaceState::Comitted) {
surface = surf; surface = surf.lock();
break; break;
} }
} }
@ -124,14 +124,14 @@ void CFocusGrab::commit(bool removeOnly) {
for (auto iter = m_mSurfaces.begin(); iter != m_mSurfaces.end();) { for (auto iter = m_mSurfaces.begin(); iter != m_mSurfaces.end();) {
switch (iter->second->state) { switch (iter->second->state) {
case CFocusGrabSurfaceState::PendingRemoval: case CFocusGrabSurfaceState::PendingRemoval:
grab->remove(iter->first); grab->remove(iter->first.lock());
iter = m_mSurfaces.erase(iter); iter = m_mSurfaces.erase(iter);
surfacesChanged = true; surfacesChanged = true;
continue; continue;
case CFocusGrabSurfaceState::PendingAddition: case CFocusGrabSurfaceState::PendingAddition:
if (!removeOnly) { if (!removeOnly) {
iter->second->state = CFocusGrabSurfaceState::Comitted; iter->second->state = CFocusGrabSurfaceState::Comitted;
grab->add(iter->first); grab->add(iter->first.lock());
surfacesChanged = true; surfacesChanged = true;
anyComitted = true; anyComitted = true;
} }

View file

@ -6,13 +6,15 @@
#include <cstdint> #include <cstdint>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "../helpers/signal/Listener.hpp"
class CFocusGrab; class CFocusGrab;
class CSeatGrab; class CSeatGrab;
class CWLSurfaceResource;
class CFocusGrabSurfaceState { class CFocusGrabSurfaceState {
public: public:
CFocusGrabSurfaceState(CFocusGrab* grab, wlr_surface* surface); CFocusGrabSurfaceState(CFocusGrab* grab, SP<CWLSurfaceResource> surface);
~CFocusGrabSurfaceState(); ~CFocusGrabSurfaceState();
enum State { enum State {
@ -22,7 +24,9 @@ class CFocusGrabSurfaceState {
} state = PendingAddition; } state = PendingAddition;
private: private:
DYNLISTENER(surfaceDestroy); struct {
CHyprSignalListener destroy;
} listeners;
}; };
class CFocusGrab { class CFocusGrab {
@ -31,20 +35,20 @@ class CFocusGrab {
~CFocusGrab(); ~CFocusGrab();
bool good(); bool good();
bool isSurfaceComitted(wlr_surface* surface); bool isSurfaceComitted(SP<CWLSurfaceResource> surface);
void start(); void start();
void finish(bool sendCleared); void finish(bool sendCleared);
private: private:
void addSurface(wlr_surface* surface); void addSurface(SP<CWLSurfaceResource> surface);
void removeSurface(wlr_surface* surface); void removeSurface(SP<CWLSurfaceResource> surface);
void eraseSurface(wlr_surface* surface); void eraseSurface(SP<CWLSurfaceResource> surface);
void refocusKeyboard(); void refocusKeyboard();
void commit(bool removeOnly = false); void commit(bool removeOnly = false);
SP<CHyprlandFocusGrabV1> resource; SP<CHyprlandFocusGrabV1> resource;
std::unordered_map<wlr_surface*, UP<CFocusGrabSurfaceState>> m_mSurfaces; std::unordered_map<WP<CWLSurfaceResource>, UP<CFocusGrabSurfaceState>> m_mSurfaces;
SP<CSeatGrab> grab; SP<CSeatGrab> grab;
bool m_bGrabActive = false; bool m_bGrabActive = false;

View file

@ -1,13 +1,9 @@
#include "FractionalScale.hpp" #include "FractionalScale.hpp"
#include <algorithm>
#include "core/Compositor.hpp"
#define LOGM PROTO::fractional->protoLog #define LOGM PROTO::fractional->protoLog
static void onWlrSurfaceDestroy(void* owner, void* data) {
const auto SURF = (wlr_surface*)owner;
PROTO::fractional->onSurfaceDestroy(SURF);
}
CFractionalScaleProtocol::CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { CFractionalScaleProtocol::CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
; ;
} }
@ -18,7 +14,7 @@ void CFractionalScaleProtocol::bindManager(wl_client* client, void* data, uint32
RESOURCE->setDestroy([this](CWpFractionalScaleManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); RESOURCE->setDestroy([this](CWpFractionalScaleManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
RESOURCE->setGetFractionalScale( RESOURCE->setGetFractionalScale(
[this](CWpFractionalScaleManagerV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetFractionalScale(pMgr, id, wlr_surface_from_resource(surface)); }); [this](CWpFractionalScaleManagerV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetFractionalScale(pMgr, id, CWLSurfaceResource::fromResource(surface)); });
} }
void CFractionalScaleProtocol::removeAddon(CFractionalScaleAddon* addon) { void CFractionalScaleProtocol::removeAddon(CFractionalScaleAddon* addon) {
@ -29,12 +25,14 @@ void CFractionalScaleProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [res](const auto& other) { return other->resource() == res; }); std::erase_if(m_vManagers, [res](const auto& other) { return other->resource() == res; });
} }
void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1* pMgr, uint32_t id, wlr_surface* surface) { void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface) {
if (m_mAddons.contains(surface)) { for (auto& [k, v] : m_mAddons) {
if (k == surface) {
LOGM(ERR, "Surface {:x} already has a fractionalScale addon", (uintptr_t)surface); LOGM(ERR, "Surface {:x} already has a fractionalScale addon", (uintptr_t)surface);
pMgr->error(WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS, "Fractional scale already exists"); pMgr->error(WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS, "Fractional scale already exists");
return; return;
} }
}
const auto PADDON = const auto PADDON =
m_mAddons.emplace(surface, std::make_unique<CFractionalScaleAddon>(makeShared<CWpFractionalScaleV1>(pMgr->client(), pMgr->version(), id), surface)).first->second.get(); m_mAddons.emplace(surface, std::make_unique<CFractionalScaleAddon>(makeShared<CWpFractionalScaleV1>(pMgr->client(), pMgr->version(), id), surface)).first->second.get();
@ -48,35 +46,22 @@ void CFractionalScaleProtocol::onGetFractionalScale(CWpFractionalScaleManagerV1*
PADDON->resource->setOnDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); }); PADDON->resource->setOnDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); });
PADDON->resource->setDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); }); PADDON->resource->setDestroy([this, PADDON](CWpFractionalScaleV1* self) { this->removeAddon(PADDON); });
if (!m_mSurfaceScales.contains(surface)) if (std::find_if(m_mSurfaceScales.begin(), m_mSurfaceScales.end(), [surface](const auto& e) { return e.first == surface; }) == m_mSurfaceScales.end())
m_mSurfaceScales[surface] = 1.F; m_mSurfaceScales.emplace(surface, 1.F);
PADDON->setScale(m_mSurfaceScales[surface]); PADDON->setScale(m_mSurfaceScales.at(surface));
registerSurface(surface);
// clean old
std::erase_if(m_mSurfaceScales, [](const auto& e) { return e.first.expired(); });
} }
void CFractionalScaleProtocol::sendScale(wlr_surface* surf, const float& scale) { void CFractionalScaleProtocol::sendScale(SP<CWLSurfaceResource> surf, const float& scale) {
m_mSurfaceScales[surf] = scale; m_mSurfaceScales[surf] = scale;
if (m_mAddons.contains(surf)) if (m_mAddons.contains(surf))
m_mAddons[surf]->setScale(scale); m_mAddons[surf]->setScale(scale);
registerSurface(surf);
} }
void CFractionalScaleProtocol::registerSurface(wlr_surface* surf) { CFractionalScaleAddon::CFractionalScaleAddon(SP<CWpFractionalScaleV1> resource_, SP<CWLSurfaceResource> surf_) : resource(resource_), surface(surf_) {
if (m_mSurfaceDestroyListeners.contains(surf))
return;
m_mSurfaceDestroyListeners[surf].hyprListener_surfaceDestroy.initCallback(&surf->events.destroy, ::onWlrSurfaceDestroy, surf, "FractionalScale");
}
void CFractionalScaleProtocol::onSurfaceDestroy(wlr_surface* surf) {
m_mSurfaceDestroyListeners.erase(surf);
m_mSurfaceScales.erase(surf);
if (m_mAddons.contains(surf))
m_mAddons[surf]->onSurfaceDestroy();
}
CFractionalScaleAddon::CFractionalScaleAddon(SP<CWpFractionalScaleV1> resource_, wlr_surface* surf_) : resource(resource_), surface(surf_) {
resource->setDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); }); resource->setDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); });
resource->setOnDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); }); resource->setOnDestroy([this](CWpFractionalScaleV1* self) { PROTO::fractional->removeAddon(this); });
} }
@ -93,6 +78,6 @@ bool CFractionalScaleAddon::good() {
return resource->resource(); return resource->resource();
} }
wlr_surface* CFractionalScaleAddon::surf() { SP<CWLSurfaceResource> CFractionalScaleAddon::surf() {
return surface; return surface.lock();
} }

View file

@ -6,17 +6,18 @@
#include "fractional-scale-v1.hpp" #include "fractional-scale-v1.hpp"
class CFractionalScaleProtocol; class CFractionalScaleProtocol;
class CWLSurfaceResource;
class CFractionalScaleAddon { class CFractionalScaleAddon {
public: public:
CFractionalScaleAddon(SP<CWpFractionalScaleV1> resource_, wlr_surface* surf_); CFractionalScaleAddon(SP<CWpFractionalScaleV1> resource_, SP<CWLSurfaceResource> surf_);
void setScale(const float& scale); void setScale(const float& scale);
void onSurfaceDestroy(); void onSurfaceDestroy();
bool good(); bool good();
wlr_surface* surf(); SP<CWLSurfaceResource> surf();
bool operator==(const wl_resource* other) const { bool operator==(const wl_resource* other) const {
return other == resource->resource(); return other == resource->resource();
@ -29,36 +30,30 @@ class CFractionalScaleAddon {
private: private:
SP<CWpFractionalScaleV1> resource; SP<CWpFractionalScaleV1> resource;
float scale = 1.F; float scale = 1.F;
wlr_surface* surface = nullptr; WP<CWLSurfaceResource> surface;
bool surfaceGone = false; bool surfaceGone = false;
friend class CFractionalScaleProtocol; friend class CFractionalScaleProtocol;
}; };
struct SSurfaceListener {
DYNLISTENER(surfaceDestroy);
};
class CFractionalScaleProtocol : public IWaylandProtocol { class CFractionalScaleProtocol : public IWaylandProtocol {
public: public:
CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name); CFractionalScaleProtocol(const wl_interface* iface, const int& ver, const std::string& name);
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id); virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
void onSurfaceDestroy(wlr_surface* surf); void onSurfaceDestroy(SP<CWLSurfaceResource> surf);
void sendScale(wlr_surface* surf, const float& scale); void sendScale(SP<CWLSurfaceResource> surf, const float& scale);
private: private:
void removeAddon(CFractionalScaleAddon*); void removeAddon(CFractionalScaleAddon*);
void registerSurface(wlr_surface*);
void onManagerResourceDestroy(wl_resource* res); void onManagerResourceDestroy(wl_resource* res);
void onGetFractionalScale(CWpFractionalScaleManagerV1* pMgr, uint32_t id, wlr_surface* surface); void onGetFractionalScale(CWpFractionalScaleManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface);
// //
std::unordered_map<wlr_surface*, SSurfaceListener> m_mSurfaceDestroyListeners;
std::unordered_map<wlr_surface*, float> m_mSurfaceScales; std::unordered_map<WP<CWLSurfaceResource>, float> m_mSurfaceScales;
std::unordered_map<wlr_surface*, UP<CFractionalScaleAddon>> m_mAddons; std::unordered_map<WP<CWLSurfaceResource>, UP<CFractionalScaleAddon>> m_mAddons;
std::vector<UP<CWpFractionalScaleManagerV1>> m_vManagers; std::vector<UP<CWpFractionalScaleManagerV1>> m_vManagers;
friend class CFractionalScaleAddon; friend class CFractionalScaleAddon;

View file

@ -3,6 +3,7 @@
#include <unistd.h> #include <unistd.h>
#include "../helpers/Monitor.hpp" #include "../helpers/Monitor.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../protocols/core/Output.hpp"
#define LOGM PROTO::gamma->protoLog #define LOGM PROTO::gamma->protoLog
@ -10,15 +11,15 @@ CGammaControl::CGammaControl(SP<CZwlrGammaControlV1> resource_, wl_resource* out
if (!resource_->resource()) if (!resource_->resource())
return; return;
wlr_output* wlrOutput = wlr_output_from_resource(output); auto OUTPUTRES = CWLOutputResource::fromResource(output);
if (!wlrOutput) { if (!OUTPUTRES) {
LOGM(ERR, "No wlr_output in CGammaControl"); LOGM(ERR, "No output in CGammaControl");
resource->sendFailed(); resource->sendFailed();
return; return;
} }
pMonitor = g_pCompositor->getRealMonitorFromOutput(wlrOutput); pMonitor = OUTPUTRES->monitor.get();
if (!pMonitor) { if (!pMonitor) {
LOGM(ERR, "No CMonitor"); LOGM(ERR, "No CMonitor");
@ -33,7 +34,7 @@ CGammaControl::CGammaControl(SP<CZwlrGammaControlV1> resource_, wl_resource* out
} }
} }
gammaSize = wlr_output_get_gamma_size(wlrOutput); gammaSize = wlr_output_get_gamma_size(pMonitor->output);
if (gammaSize <= 0) { if (gammaSize <= 0) {
LOGM(ERR, "Output {} doesn't support gamma", pMonitor->szName); LOGM(ERR, "Output {} doesn't support gamma", pMonitor->szName);

View file

@ -1,26 +1,23 @@
#include "IdleInhibit.hpp" #include "IdleInhibit.hpp"
#include "core/Compositor.hpp"
CIdleInhibitor::CIdleInhibitor(SP<CIdleInhibitorResource> resource_, wlr_surface* surf_) : resource(resource_), surface(surf_) { CIdleInhibitor::CIdleInhibitor(SP<CIdleInhibitorResource> resource_, SP<CWLSurfaceResource> surf_) : resource(resource_), surface(surf_) {
; ;
} }
CIdleInhibitorResource::CIdleInhibitorResource(SP<CZwpIdleInhibitorV1> resource_, wlr_surface* surface_) : resource(resource_), surface(surface_) { CIdleInhibitorResource::CIdleInhibitorResource(SP<CZwpIdleInhibitorV1> resource_, SP<CWLSurfaceResource> surface_) : resource(resource_), surface(surface_) {
hyprListener_surfaceDestroy.initCallback( listeners.destroySurface = surface->events.destroy.registerListener([this](std::any d) {
&surface->events.destroy, surface.reset();
[this](void* owner, void* data) { listeners.destroySurface.reset();
surface = nullptr;
hyprListener_surfaceDestroy.removeCallback();
destroySent = true; destroySent = true;
events.destroy.emit(); events.destroy.emit();
}, });
this, "CIdleInhibitorResource");
resource->setOnDestroy([this](CZwpIdleInhibitorV1* p) { PROTO::idleInhibit->removeInhibitor(this); }); resource->setOnDestroy([this](CZwpIdleInhibitorV1* p) { PROTO::idleInhibit->removeInhibitor(this); });
resource->setDestroy([this](CZwpIdleInhibitorV1* p) { PROTO::idleInhibit->removeInhibitor(this); }); resource->setDestroy([this](CZwpIdleInhibitorV1* p) { PROTO::idleInhibit->removeInhibitor(this); });
} }
CIdleInhibitorResource::~CIdleInhibitorResource() { CIdleInhibitorResource::~CIdleInhibitorResource() {
hyprListener_surfaceDestroy.removeCallback();
if (!destroySent) if (!destroySent)
events.destroy.emit(); events.destroy.emit();
} }
@ -39,14 +36,14 @@ void CIdleInhibitProtocol::bindManager(wl_client* client, void* data, uint32_t v
RESOURCE->setDestroy([this](CZwpIdleInhibitManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); RESOURCE->setDestroy([this](CZwpIdleInhibitManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
RESOURCE->setCreateInhibitor( RESOURCE->setCreateInhibitor(
[this](CZwpIdleInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface) { this->onCreateInhibitor(pMgr, id, wlr_surface_from_resource(surface)); }); [this](CZwpIdleInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface) { this->onCreateInhibitor(pMgr, id, CWLSurfaceResource::fromResource(surface)); });
} }
void CIdleInhibitProtocol::removeInhibitor(CIdleInhibitorResource* resource) { void CIdleInhibitProtocol::removeInhibitor(CIdleInhibitorResource* resource) {
std::erase_if(m_vInhibitors, [resource](const auto& el) { return el.get() == resource; }); std::erase_if(m_vInhibitors, [resource](const auto& el) { return el.get() == resource; });
} }
void CIdleInhibitProtocol::onCreateInhibitor(CZwpIdleInhibitManagerV1* pMgr, uint32_t id, wlr_surface* surface) { void CIdleInhibitProtocol::onCreateInhibitor(CZwpIdleInhibitManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vInhibitors.emplace_back(makeShared<CIdleInhibitorResource>(makeShared<CZwpIdleInhibitorV1>(CLIENT, pMgr->version(), id), surface)); const auto RESOURCE = m_vInhibitors.emplace_back(makeShared<CIdleInhibitorResource>(makeShared<CZwpIdleInhibitorV1>(CLIENT, pMgr->version(), id), surface));

View file

@ -7,22 +7,23 @@
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
class CIdleInhibitorResource; class CIdleInhibitorResource;
class CWLSurfaceResource;
class CIdleInhibitor { class CIdleInhibitor {
public: public:
CIdleInhibitor(SP<CIdleInhibitorResource> resource_, wlr_surface* surf_); CIdleInhibitor(SP<CIdleInhibitorResource> resource_, SP<CWLSurfaceResource> surf_);
struct { struct {
CHyprSignalListener destroy; CHyprSignalListener destroy;
} listeners; } listeners;
WP<CIdleInhibitorResource> resource; WP<CIdleInhibitorResource> resource;
wlr_surface* surface = nullptr; WP<CWLSurfaceResource> surface;
}; };
class CIdleInhibitorResource { class CIdleInhibitorResource {
public: public:
CIdleInhibitorResource(SP<CZwpIdleInhibitorV1> resource_, wlr_surface* surface_); CIdleInhibitorResource(SP<CZwpIdleInhibitorV1> resource_, SP<CWLSurfaceResource> surface_);
~CIdleInhibitorResource(); ~CIdleInhibitorResource();
SP<CIdleInhibitor> inhibitor; SP<CIdleInhibitor> inhibitor;
@ -33,10 +34,12 @@ class CIdleInhibitorResource {
private: private:
SP<CZwpIdleInhibitorV1> resource; SP<CZwpIdleInhibitorV1> resource;
wlr_surface* surface = nullptr; WP<CWLSurfaceResource> surface;
bool destroySent = false; bool destroySent = false;
DYNLISTENER(surfaceDestroy); struct {
CHyprSignalListener destroySurface;
} listeners;
}; };
class CIdleInhibitProtocol : public IWaylandProtocol { class CIdleInhibitProtocol : public IWaylandProtocol {
@ -51,7 +54,7 @@ class CIdleInhibitProtocol : public IWaylandProtocol {
private: private:
void onManagerResourceDestroy(wl_resource* res); void onManagerResourceDestroy(wl_resource* res);
void onCreateInhibitor(CZwpIdleInhibitManagerV1* pMgr, uint32_t id, wlr_surface* surface); void onCreateInhibitor(CZwpIdleInhibitManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface);
void removeInhibitor(CIdleInhibitorResource*); void removeInhibitor(CIdleInhibitorResource*);

View file

@ -3,6 +3,7 @@
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "../devices/IKeyboard.hpp" #include "../devices/IKeyboard.hpp"
#include <sys/mman.h> #include <sys/mman.h>
#include "core/Compositor.hpp"
#define LOGM PROTO::ime->protoLog #define LOGM PROTO::ime->protoLog
@ -83,51 +84,45 @@ wl_client* CInputMethodKeyboardGrabV2::client() {
return resource->client(); return resource->client();
} }
CInputMethodPopupV2::CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_, SP<CInputMethodV2> owner_, wlr_surface* wlrSurface) : resource(resource_), owner(owner_) { CInputMethodPopupV2::CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_, SP<CInputMethodV2> owner_, SP<CWLSurfaceResource> surface) : resource(resource_), owner(owner_) {
if (!resource->resource()) if (!resource->resource())
return; return;
resource->setDestroy([this](CZwpInputPopupSurfaceV2* r) { PROTO::ime->destroyResource(this); }); resource->setDestroy([this](CZwpInputPopupSurfaceV2* r) { PROTO::ime->destroyResource(this); });
resource->setOnDestroy([this](CZwpInputPopupSurfaceV2* r) { PROTO::ime->destroyResource(this); }); resource->setOnDestroy([this](CZwpInputPopupSurfaceV2* r) { PROTO::ime->destroyResource(this); });
pSurface = wlrSurface; pSurface = surface;
hyprListener_destroySurface.initCallback( listeners.destroySurface = surface->events.destroy.registerListener([this](std::any d) {
&wlrSurface->events.destroy,
[this](void* owner, void* data) {
if (mapped) if (mapped)
events.unmap.emit(); events.unmap.emit();
hyprListener_commitSurface.removeCallback(); listeners.destroySurface.reset();
hyprListener_destroySurface.removeCallback(); listeners.commitSurface.reset();
if (g_pCompositor->m_pLastFocus == pSurface) if (g_pCompositor->m_pLastFocus == pSurface)
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
pSurface = nullptr; pSurface.reset();
}, });
this, "IMEPopup");
hyprListener_commitSurface.initCallback( listeners.commitSurface = surface->events.commit.registerListener([this](std::any d) {
&wlrSurface->events.commit, if (pSurface->current.buffer && !mapped) {
[this](void* owner, void* data) {
if (pSurface->pending.buffer_width > 0 && pSurface->pending.buffer_height > 0 && !mapped) {
mapped = true; mapped = true;
wlr_surface_map(pSurface); pSurface->map();
events.map.emit(); events.map.emit();
return; return;
} }
if (pSurface->pending.buffer_width <= 0 && pSurface->pending.buffer_height <= 0 && mapped) { if (!pSurface->current.buffer && mapped) {
mapped = false; mapped = false;
wlr_surface_unmap(pSurface); pSurface->unmap();
events.unmap.emit(); events.unmap.emit();
return; return;
} }
events.commit.emit(); events.commit.emit();
}, });
this, "IMEPopup");
} }
CInputMethodPopupV2::~CInputMethodPopupV2() { CInputMethodPopupV2::~CInputMethodPopupV2() {
@ -145,8 +140,8 @@ void CInputMethodPopupV2::sendInputRectangle(const CBox& box) {
resource->sendTextInputRectangle(box.x, box.y, box.w, box.h); resource->sendTextInputRectangle(box.x, box.y, box.w, box.h);
} }
wlr_surface* CInputMethodPopupV2::surface() { SP<CWLSurfaceResource> CInputMethodPopupV2::surface() {
return pSurface; return pSurface.lock();
} }
void CInputMethodV2::SState::reset() { void CInputMethodV2::SState::reset() {
@ -194,7 +189,7 @@ CInputMethodV2::CInputMethodV2(SP<CZwpInputMethodV2> resource_) : resource(resou
resource->setGetInputPopupSurface([this](CZwpInputMethodV2* r, uint32_t id, wl_resource* surface) { resource->setGetInputPopupSurface([this](CZwpInputMethodV2* r, uint32_t id, wl_resource* surface) {
const auto RESOURCE = PROTO::ime->m_vPopups.emplace_back( const auto RESOURCE = PROTO::ime->m_vPopups.emplace_back(
makeShared<CInputMethodPopupV2>(makeShared<CZwpInputPopupSurfaceV2>(r->client(), r->version(), id), self.lock(), wlr_surface_from_resource(surface))); makeShared<CInputMethodPopupV2>(makeShared<CZwpInputPopupSurfaceV2>(r->client(), r->version(), id), self.lock(), CWLSurfaceResource::fromResource(surface)));
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
r->noMemory(); r->noMemory();

View file

@ -101,12 +101,12 @@ class CInputMethodKeyboardGrabV2 {
class CInputMethodPopupV2 { class CInputMethodPopupV2 {
public: public:
CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_, SP<CInputMethodV2> owner_, wlr_surface* surface); CInputMethodPopupV2(SP<CZwpInputPopupSurfaceV2> resource_, SP<CInputMethodV2> owner_, SP<CWLSurfaceResource> surface);
~CInputMethodPopupV2(); ~CInputMethodPopupV2();
bool good(); bool good();
void sendInputRectangle(const CBox& box); void sendInputRectangle(const CBox& box);
wlr_surface* surface(); SP<CWLSurfaceResource> surface();
struct { struct {
CSignal map; CSignal map;
@ -120,10 +120,12 @@ class CInputMethodPopupV2 {
private: private:
SP<CZwpInputPopupSurfaceV2> resource; SP<CZwpInputPopupSurfaceV2> resource;
WP<CInputMethodV2> owner; WP<CInputMethodV2> owner;
wlr_surface* pSurface = nullptr; WP<CWLSurfaceResource> pSurface;
DYNLISTENER(commitSurface); struct {
DYNLISTENER(destroySurface); CHyprSignalListener destroySurface;
CHyprSignalListener commitSurface;
} listeners;
}; };
class CInputMethodV2Protocol : public IWaylandProtocol { class CInputMethodV2Protocol : public IWaylandProtocol {

View file

@ -1,6 +1,8 @@
#include "LayerShell.hpp" #include "LayerShell.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "XDGShell.hpp" #include "XDGShell.hpp"
#include "core/Compositor.hpp"
#include "core/Output.hpp"
#define LOGM PROTO::layerShell->protoLog #define LOGM PROTO::layerShell->protoLog
@ -14,7 +16,7 @@ void CLayerShellResource::SState::reset() {
margin = {0, 0, 0, 0}; margin = {0, 0, 0, 0};
} }
CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, wlr_surface* surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer) : CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer) :
layerNamespace(namespace_), surface(surf_), resource(resource_) { layerNamespace(namespace_), surface(surf_), resource(resource_) {
if (!good()) if (!good())
return; return;
@ -31,24 +33,19 @@ CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, wlr_
PROTO::layerShell->destroyResource(this); PROTO::layerShell->destroyResource(this);
}); });
hyprListener_destroySurface.initCallback( listeners.destroySurface = surf_->events.destroy.registerListener([this](std::any d) {
&surf_->events.destroy,
[this](void* owner, void* data) {
events.destroy.emit(); events.destroy.emit();
PROTO::layerShell->destroyResource(this); PROTO::layerShell->destroyResource(this);
}, });
this, "CLayerShellResource");
hyprListener_commitSurface.initCallback( listeners.commitSurface = surf_->events.commit.registerListener([this](std::any d) {
&surf_->events.commit,
[this](void* owner, void* data) {
current = pending; current = pending;
pending.committed = 0; pending.committed = 0;
bool attachedBuffer = surface->pending.buffer_width > 0 && surface->pending.buffer_height > 0; bool attachedBuffer = surface->current.buffer;
if (attachedBuffer && !configured) { if (attachedBuffer && !configured) {
wlr_surface_reject_pending(surface, resource->resource(), -1, "layerSurface was not configured, but a buffer was attached"); surface->error(-1, "layerSurface was not configured, but a buffer was attached");
return; return;
} }
@ -56,32 +53,32 @@ CLayerShellResource::CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, wlr_
constexpr uint32_t vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; constexpr uint32_t vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
if (current.desiredSize.x <= 0 && (current.anchor & horiz) != horiz) { if (current.desiredSize.x <= 0 && (current.anchor & horiz) != horiz) {
wlr_surface_reject_pending(surface, resource->resource(), -1, "x == 0 but anchor doesn't have left and right"); surface->error(-1, "x == 0 but anchor doesn't have left and right");
return; return;
} }
if (current.desiredSize.y <= 0 && (current.anchor & vert) != vert) { if (current.desiredSize.y <= 0 && (current.anchor & vert) != vert) {
wlr_surface_reject_pending(surface, resource->resource(), -1, "y == 0 but anchor doesn't have top and bottom"); surface->error(-1, "y == 0 but anchor doesn't have top and bottom");
return; return;
} }
if (attachedBuffer && !mapped) { if (attachedBuffer && !mapped) {
mapped = true; mapped = true;
wlr_surface_map(surface); surface->map();
events.map.emit(); events.map.emit();
return; return;
} }
if (!attachedBuffer && mapped) { if (!attachedBuffer && mapped) {
mapped = false; mapped = false;
wlr_surface_unmap(surface); surface->unmap();
events.unmap.emit(); events.unmap.emit();
configured = false;
return; return;
} }
events.commit.emit(); events.commit.emit();
}, });
this, "CLayerShellResource");
resource->setSetSize([this](CZwlrLayerSurfaceV1* r, uint32_t x, uint32_t y) { resource->setSetSize([this](CZwlrLayerSurfaceV1* r, uint32_t x, uint32_t y) {
pending.committed |= STATE_SIZE; pending.committed |= STATE_SIZE;
@ -209,9 +206,9 @@ void CLayerShellProtocol::destroyResource(CLayerShellResource* surf) {
void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* output, zwlrLayerShellV1Layer layer, std::string namespace_) { void CLayerShellProtocol::onGetLayerSurface(CZwlrLayerShellV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* output, zwlrLayerShellV1Layer layer, std::string namespace_) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto PMONITOR = output ? g_pCompositor->getMonitorFromOutput(wlr_output_from_resource(output)) : nullptr; const auto PMONITOR = output ? CWLOutputResource::fromResource(output)->monitor.get() : nullptr;
const auto RESOURCE = m_vLayers.emplace_back( const auto RESOURCE = m_vLayers.emplace_back(
makeShared<CLayerShellResource>(makeShared<CZwlrLayerSurfaceV1>(CLIENT, pMgr->version(), id), wlr_surface_from_resource(surface), namespace_, PMONITOR, layer)); makeShared<CLayerShellResource>(makeShared<CZwlrLayerSurfaceV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), namespace_, PMONITOR, layer));
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();

View file

@ -10,10 +10,11 @@
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
class CMonitor; class CMonitor;
class CWLSurfaceResource;
class CLayerShellResource { class CLayerShellResource {
public: public:
CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, wlr_surface* surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer); CLayerShellResource(SP<CZwlrLayerSurfaceV1> resource_, SP<CWLSurfaceResource> surf_, std::string namespace_, CMonitor* pMonitor, zwlrLayerShellV1Layer layer);
~CLayerShellResource(); ~CLayerShellResource();
bool good(); bool good();
@ -57,15 +58,17 @@ class CLayerShellResource {
Vector2D size; Vector2D size;
std::string layerNamespace; std::string layerNamespace;
std::string monitor = ""; std::string monitor = "";
wlr_surface* surface = nullptr; WP<CWLSurfaceResource> surface;
bool mapped = false; bool mapped = false;
bool configured = false; bool configured = false;
private: private:
SP<CZwlrLayerSurfaceV1> resource; SP<CZwlrLayerSurfaceV1> resource;
DYNLISTENER(destroySurface); struct {
DYNLISTENER(commitSurface); CHyprSignalListener commitSurface;
CHyprSignalListener destroySurface;
} listeners;
bool closed = false; bool closed = false;

View file

@ -0,0 +1,454 @@
#include "LinuxDMABUF.hpp"
#include <algorithm>
#include <set>
#include <tuple>
#include "../helpers/MiscFunctions.hpp"
#include <sys/mman.h>
#include <xf86drm.h>
#include <fcntl.h>
#include "core/Compositor.hpp"
#include "types/DMABuffer.hpp"
#include "types/WLBuffer.hpp"
#include "../managers/HookSystemManager.hpp"
#include "../render/OpenGL.hpp"
#include "../Compositor.hpp"
#define LOGM PROTO::linuxDma->protoLog
static std::optional<dev_t> devIDFromFD(int fd) {
struct stat stat;
if (fstat(fd, &stat) != 0)
return {};
return stat.st_rdev;
}
CCompiledDMABUFFeedback::CCompiledDMABUFFeedback(dev_t device, std::vector<SDMABufTranche> tranches_) {
std::set<std::pair<uint32_t, uint64_t>> formats;
for (auto& t : tranches_) {
for (auto& fmt : t.formats) {
for (auto& mod : fmt.mods) {
formats.insert(std::make_pair<>(fmt.format, mod));
}
}
}
tableLen = formats.size() * sizeof(SDMABUFFeedbackTableEntry);
int fds[2] = {0};
allocateSHMFilePair(tableLen, &fds[0], &fds[1]);
auto arr = (SDMABUFFeedbackTableEntry*)mmap(nullptr, tableLen, PROT_READ | PROT_WRITE, MAP_SHARED, fds[0], 0);
if (!arr) {
LOGM(ERR, "mmap failed");
close(fds[0]);
close(fds[1]);
return;
}
close(fds[0]);
std::vector<std::pair<uint32_t, uint64_t>> formatsVec;
for (auto& f : formats) {
formatsVec.push_back(f);
}
size_t i = 0;
for (auto& [fmt, mod] : formatsVec) {
arr[i++] = SDMABUFFeedbackTableEntry{
.fmt = fmt,
.modifier = mod,
};
}
munmap(arr, tableLen);
mainDevice = device;
tableFD = fds[1];
tranches = formatsVec;
// TODO: maybe calculate indices? currently we send all as available which could be wrong? I ain't no kernel dev tho.
}
CCompiledDMABUFFeedback::~CCompiledDMABUFFeedback() {
close(tableFD);
}
CLinuxDMABuffer::CLinuxDMABuffer(uint32_t id, wl_client* client, SDMABUFAttrs attrs) {
buffer = makeShared<CDMABuffer>(id, client, attrs);
buffer->resource->buffer = buffer;
listeners.bufferResourceDestroy = buffer->events.destroy.registerListener([this](std::any d) {
listeners.bufferResourceDestroy.reset();
PROTO::linuxDma->destroyResource(this);
});
if (!buffer->success)
LOGM(ERR, "Possibly compositor bug: buffer failed to create");
}
CLinuxDMABuffer::~CLinuxDMABuffer() {
buffer.reset();
listeners.bufferResourceDestroy.reset();
}
bool CLinuxDMABuffer::good() {
return buffer && buffer->good();
}
CLinuxDMABBUFParamsResource::CLinuxDMABBUFParamsResource(SP<CZwpLinuxBufferParamsV1> resource_) : resource(resource_) {
if (!good())
return;
resource->setOnDestroy([this](CZwpLinuxBufferParamsV1* r) { PROTO::linuxDma->destroyResource(this); });
resource->setDestroy([this](CZwpLinuxBufferParamsV1* r) { PROTO::linuxDma->destroyResource(this); });
attrs = makeShared<SDMABUFAttrs>();
attrs->success = true;
resource->setAdd([this](CZwpLinuxBufferParamsV1* r, int32_t fd, uint32_t plane, uint32_t offset, uint32_t stride, uint32_t modHi, uint32_t modLo) {
if (used) {
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED, "Already used");
return;
}
if (plane > 3) {
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX, "plane > 3");
return;
}
if (attrs->fds.at(plane) != -1) {
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX, "plane used");
return;
}
attrs->fds[plane] = fd;
attrs->strides[plane] = stride;
attrs->offsets[plane] = offset;
attrs->modifier = ((uint64_t)modHi << 32) | modLo;
});
resource->setCreate([this](CZwpLinuxBufferParamsV1* r, int32_t w, int32_t h, uint32_t fmt, zwpLinuxBufferParamsV1Flags flags) {
if (used) {
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED, "Already used");
return;
}
if (flags > 0) {
r->sendFailed();
LOGM(ERR, "DMABUF flags are not supported");
return;
}
attrs->size = {w, h};
attrs->format = fmt;
attrs->planes = 4 - std::count(attrs->fds.begin(), attrs->fds.end(), -1);
create(0);
});
resource->setCreateImmed([this](CZwpLinuxBufferParamsV1* r, uint32_t id, int32_t w, int32_t h, uint32_t fmt, zwpLinuxBufferParamsV1Flags flags) {
if (used) {
r->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_ALREADY_USED, "Already used");
return;
}
if (flags > 0) {
r->sendFailed();
LOGM(ERR, "DMABUF flags are not supported");
return;
}
attrs->size = {w, h};
attrs->format = fmt;
attrs->planes = 4 - std::count(attrs->fds.begin(), attrs->fds.end(), -1);
create(id);
});
}
CLinuxDMABBUFParamsResource::~CLinuxDMABBUFParamsResource() {
;
}
bool CLinuxDMABBUFParamsResource::good() {
return resource->resource();
}
void CLinuxDMABBUFParamsResource::create(uint32_t id) {
used = true;
if (!verify()) {
LOGM(ERR, "Failed creating a dmabuf: verify() said no");
return; // if verify failed, we errored the resource.
}
if (!commence()) {
LOGM(ERR, "Failed creating a dmabuf: commence() said no");
resource->sendFailed();
return;
}
LOGM(LOG, "Creating a dmabuf, with id {}: size {}, fmt {}, planes {}", id, attrs->size, attrs->format, attrs->planes);
for (int i = 0; i < attrs->planes; ++i) {
LOGM(LOG, " | plane {}: mod {} fd {} stride {} offset {}", i, attrs->modifier, attrs->fds[i], attrs->strides[i], attrs->offsets[i]);
}
auto buf = PROTO::linuxDma->m_vBuffers.emplace_back(makeShared<CLinuxDMABuffer>(id, resource->client(), *attrs));
if (!buf->good() || !buf->buffer->success) {
resource->sendFailed();
return;
}
if (!id)
resource->sendCreated(PROTO::linuxDma->m_vBuffers.back()->buffer->resource->getResource());
createdBuffer = buf;
}
bool CLinuxDMABBUFParamsResource::commence() {
if (PROTO::linuxDma->mainDeviceFD < 0)
return true;
for (int i = 0; i < attrs->planes; i++) {
uint32_t handle = 0;
if (drmPrimeFDToHandle(PROTO::linuxDma->mainDeviceFD, attrs->fds.at(i), &handle)) {
LOGM(ERR, "Failed to import dmabuf fd");
return false;
}
if (drmCloseBufferHandle(PROTO::linuxDma->mainDeviceFD, handle)) {
LOGM(ERR, "Failed to close dmabuf handle");
return false;
}
}
return true;
}
bool CLinuxDMABBUFParamsResource::verify() {
if (attrs->planes <= 0) {
resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "No planes added");
return false;
}
if (attrs->fds.at(0) < 0) {
resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, "No plane 0");
return false;
}
bool empty = false;
for (auto& plane : attrs->fds) {
if (empty && plane != -1) {
resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT, "Gap in planes");
return false;
}
if (plane == -1) {
empty = true;
continue;
}
}
if (attrs->size.x < 1 || attrs->size.y < 1) {
resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS, "x/y < 1");
return false;
}
for (size_t i = 0; i < (size_t)attrs->planes; ++i) {
if ((uint64_t)attrs->offsets.at(i) + (uint64_t)attrs->strides.at(i) * attrs->size.y > UINT32_MAX) {
resource->error(ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
std::format("size overflow on plane {}: offset {} + stride {} * height {} = {}, overflows UINT32_MAX", i, (uint64_t)attrs->offsets.at(i),
(uint64_t)attrs->strides.at(i), attrs->size.y, (uint64_t)attrs->offsets.at(i) + (uint64_t)attrs->strides.at(i)));
return false;
}
}
return true;
}
CLinuxDMABUFFeedbackResource::CLinuxDMABUFFeedbackResource(SP<CZwpLinuxDmabufFeedbackV1> resource_, SP<CWLSurfaceResource> surface_) : surface(surface_), resource(resource_) {
if (!good())
return;
resource->setOnDestroy([this](CZwpLinuxDmabufFeedbackV1* r) { PROTO::linuxDma->destroyResource(this); });
resource->setDestroy([this](CZwpLinuxDmabufFeedbackV1* r) { PROTO::linuxDma->destroyResource(this); });
if (surface)
LOGM(ERR, "FIXME: surface feedback stub");
auto* feedback = PROTO::linuxDma->defaultFeedback.get();
resource->sendFormatTable(feedback->tableFD, feedback->tableLen);
// send default feedback
struct wl_array deviceArr = {
.size = sizeof(feedback->mainDevice),
.data = (void*)&feedback->mainDevice,
};
resource->sendMainDevice(&deviceArr);
resource->sendTrancheTargetDevice(&deviceArr);
resource->sendTrancheFlags((zwpLinuxDmabufFeedbackV1TrancheFlags)0);
wl_array indices;
wl_array_init(&indices);
for (size_t i = 0; i < feedback->tranches.size(); ++i) {
*((uint16_t*)wl_array_add(&indices, sizeof(uint16_t))) = i;
}
resource->sendTrancheFormats(&indices);
wl_array_release(&indices);
resource->sendTrancheDone();
resource->sendDone();
}
CLinuxDMABUFFeedbackResource::~CLinuxDMABUFFeedbackResource() {
;
}
bool CLinuxDMABUFFeedbackResource::good() {
return resource->resource();
}
CLinuxDMABUFResource::CLinuxDMABUFResource(SP<CZwpLinuxDmabufV1> resource_) : resource(resource_) {
if (!good())
return;
resource->setOnDestroy([this](CZwpLinuxDmabufV1* r) { PROTO::linuxDma->destroyResource(this); });
resource->setDestroy([this](CZwpLinuxDmabufV1* r) { PROTO::linuxDma->destroyResource(this); });
resource->setGetDefaultFeedback([](CZwpLinuxDmabufV1* r, uint32_t id) {
const auto RESOURCE =
PROTO::linuxDma->m_vFeedbacks.emplace_back(makeShared<CLinuxDMABUFFeedbackResource>(makeShared<CZwpLinuxDmabufFeedbackV1>(r->client(), r->version(), id), nullptr));
if (!RESOURCE->good()) {
r->noMemory();
PROTO::linuxDma->m_vFeedbacks.pop_back();
return;
}
});
resource->setGetSurfaceFeedback([](CZwpLinuxDmabufV1* r, uint32_t id, wl_resource* surf) {
const auto RESOURCE = PROTO::linuxDma->m_vFeedbacks.emplace_back(
makeShared<CLinuxDMABUFFeedbackResource>(makeShared<CZwpLinuxDmabufFeedbackV1>(r->client(), r->version(), id), CWLSurfaceResource::fromResource(surf)));
if (!RESOURCE->good()) {
r->noMemory();
PROTO::linuxDma->m_vFeedbacks.pop_back();
return;
}
});
resource->setCreateParams([](CZwpLinuxDmabufV1* r, uint32_t id) {
const auto RESOURCE = PROTO::linuxDma->m_vParams.emplace_back(makeShared<CLinuxDMABBUFParamsResource>(makeShared<CZwpLinuxBufferParamsV1>(r->client(), r->version(), id)));
if (!RESOURCE->good()) {
r->noMemory();
PROTO::linuxDma->m_vParams.pop_back();
return;
}
});
if (resource->version() < 4)
sendMods();
}
bool CLinuxDMABUFResource::good() {
return resource->resource();
}
void CLinuxDMABUFResource::sendMods() {
for (auto& [fmt, mod] : PROTO::linuxDma->defaultFeedback->tranches) {
if (resource->version() < 3) {
if (mod == DRM_FORMAT_MOD_INVALID)
resource->sendFormat(fmt);
continue;
}
// TODO: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1166
resource->sendModifier(fmt, mod >> 32, mod & 0xFFFFFFFF);
}
}
CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
static auto P = g_pHookSystem->hookDynamic("ready", [this](void* self, SCallbackInfo& info, std::any d) {
int rendererFD = wlr_renderer_get_drm_fd(g_pCompositor->m_sWLRRenderer);
auto dev = devIDFromFD(rendererFD);
if (!dev.has_value()) {
LOGM(ERR, "failed to get drm dev");
PROTO::linuxDma.reset();
return;
}
mainDevice = *dev;
auto fmts = g_pHyprOpenGL->getDRMFormats();
SDMABufTranche tranche = {
.device = *dev,
.formats = fmts,
};
std::vector<SDMABufTranche> tches;
tches.push_back(tranche);
defaultFeedback = std::make_unique<CCompiledDMABUFFeedback>(*dev, tches);
drmDevice* device = nullptr;
if (drmGetDeviceFromDevId(mainDevice, 0, &device) != 0) {
LOGM(ERR, "failed to get drm dev");
PROTO::linuxDma.reset();
return;
}
if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
const char* name = device->nodes[DRM_NODE_RENDER];
mainDeviceFD = open(name, O_RDWR | O_CLOEXEC);
drmFreeDevice(&device);
if (mainDeviceFD < 0) {
LOGM(ERR, "failed to open drm dev");
PROTO::linuxDma.reset();
return;
}
} else {
LOGM(ERR, "DRM device {} has no render node!!", device->nodes[DRM_NODE_PRIMARY]);
drmFreeDevice(&device);
}
});
}
CLinuxDMABufV1Protocol::~CLinuxDMABufV1Protocol() {
if (mainDeviceFD >= 0)
close(mainDeviceFD);
}
void CLinuxDMABufV1Protocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CLinuxDMABUFResource>(makeShared<CZwpLinuxDmabufV1>(client, ver, id)));
if (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
return;
}
}
void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABUFResource* resource) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; });
}
void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABUFFeedbackResource* resource) {
std::erase_if(m_vFeedbacks, [&](const auto& other) { return other.get() == resource; });
}
void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABBUFParamsResource* resource) {
std::erase_if(m_vParams, [&](const auto& other) { return other.get() == resource; });
}
void CLinuxDMABufV1Protocol::destroyResource(CLinuxDMABuffer* resource) {
std::erase_if(m_vBuffers, [&](const auto& other) { return other.get() == resource; });
}

View file

@ -0,0 +1,138 @@
#pragma once
#include <memory>
#include <vector>
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "wayland.hpp"
#include "linux-dmabuf-v1.hpp"
#include "../helpers/signal/Signal.hpp"
class CDMABuffer;
struct SDRMFormat;
struct SDMABUFAttrs;
class CWLSurfaceResource;
class CLinuxDMABuffer {
public:
CLinuxDMABuffer(uint32_t id, wl_client* client, SDMABUFAttrs attrs);
~CLinuxDMABuffer();
bool good();
private:
SP<CDMABuffer> buffer;
struct {
CHyprSignalListener bufferResourceDestroy;
} listeners;
friend class CLinuxDMABBUFParamsResource;
};
#pragma pack(push, 1)
struct SDMABUFFeedbackTableEntry {
uint32_t fmt = 0;
char pad[4];
uint64_t modifier = 0;
};
#pragma pack(pop)
class SCompiledDMABUFTranche {
dev_t device = 0;
uint32_t flags = 0;
std::vector<uint16_t> indices;
};
struct SDMABufTranche {
dev_t device = 0;
uint32_t flags = 0;
std::vector<SDRMFormat> formats;
};
class CCompiledDMABUFFeedback {
public:
CCompiledDMABUFFeedback(dev_t device, std::vector<SDMABufTranche> tranches);
~CCompiledDMABUFFeedback();
dev_t mainDevice = 0;
int tableFD = -1;
size_t tableLen = 0;
std::vector<std::pair<uint32_t, uint64_t>> tranches;
};
class CLinuxDMABBUFParamsResource {
public:
CLinuxDMABBUFParamsResource(SP<CZwpLinuxBufferParamsV1> resource_);
~CLinuxDMABBUFParamsResource();
bool good();
void create(uint32_t id); // 0 means not immed
SP<SDMABUFAttrs> attrs;
WP<CLinuxDMABuffer> createdBuffer;
bool used = false;
private:
SP<CZwpLinuxBufferParamsV1> resource;
bool verify();
bool commence();
};
class CLinuxDMABUFFeedbackResource {
public:
CLinuxDMABUFFeedbackResource(SP<CZwpLinuxDmabufFeedbackV1> resource_, SP<CWLSurfaceResource> surface_);
~CLinuxDMABUFFeedbackResource();
bool good();
SP<CWLSurfaceResource> surface; // optional, for surface feedbacks
private:
SP<CZwpLinuxDmabufFeedbackV1> resource;
};
class CLinuxDMABUFResource {
public:
CLinuxDMABUFResource(SP<CZwpLinuxDmabufV1> resource_);
bool good();
void sendMods();
private:
SP<CZwpLinuxDmabufV1> resource;
};
class CLinuxDMABufV1Protocol : public IWaylandProtocol {
public:
CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name);
~CLinuxDMABufV1Protocol();
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
private:
void destroyResource(CLinuxDMABUFResource* resource);
void destroyResource(CLinuxDMABUFFeedbackResource* resource);
void destroyResource(CLinuxDMABBUFParamsResource* resource);
void destroyResource(CLinuxDMABuffer* resource);
//
std::vector<SP<CLinuxDMABUFResource>> m_vManagers;
std::vector<SP<CLinuxDMABUFFeedbackResource>> m_vFeedbacks;
std::vector<SP<CLinuxDMABBUFParamsResource>> m_vParams;
std::vector<SP<CLinuxDMABuffer>> m_vBuffers;
UP<CCompiledDMABUFFeedback> defaultFeedback;
dev_t mainDevice;
int mainDeviceFD = -1;
friend class CLinuxDMABUFResource;
friend class CLinuxDMABUFFeedbackResource;
friend class CLinuxDMABBUFParamsResource;
friend class CLinuxDMABuffer;
};
namespace PROTO {
inline UP<CLinuxDMABufV1Protocol> linuxDma;
};

133
src/protocols/MesaDRM.cpp Normal file
View file

@ -0,0 +1,133 @@
#include "MesaDRM.hpp"
#include <algorithm>
#include <xf86drm.h>
#include "../Compositor.hpp"
#include <wlr/render/drm_format_set.h>
#include "types/WLBuffer.hpp"
#define LOGM PROTO::mesaDRM->protoLog
CMesaDRMBufferResource::CMesaDRMBufferResource(uint32_t id, wl_client* client, SDMABUFAttrs attrs_) {
LOGM(LOG, "Creating a Mesa dmabuf, with id {}: size {}, fmt {}, planes {}", id, attrs_.size, attrs_.format, attrs_.planes);
for (int i = 0; i < attrs_.planes; ++i) {
LOGM(LOG, " | plane {}: mod {} fd {} stride {} offset {}", i, attrs_.modifier, attrs_.fds[i], attrs_.strides[i], attrs_.offsets[i]);
}
buffer = makeShared<CDMABuffer>(id, client, attrs_);
buffer->resource->buffer = buffer;
listeners.bufferResourceDestroy = buffer->events.destroy.registerListener([this](std::any d) {
listeners.bufferResourceDestroy.reset();
PROTO::mesaDRM->destroyResource(this);
});
if (!buffer->success)
LOGM(ERR, "Possibly compositor bug: buffer failed to create");
}
CMesaDRMBufferResource::~CMesaDRMBufferResource() {
if (buffer && buffer->resource)
buffer->resource->sendRelease();
buffer.reset();
listeners.bufferResourceDestroy.reset();
}
bool CMesaDRMBufferResource::good() {
return buffer && buffer->good();
}
CMesaDRMResource::CMesaDRMResource(SP<CWlDrm> resource_) : resource(resource_) {
if (!good())
return;
resource->setOnDestroy([this](CWlDrm* r) { PROTO::mesaDRM->destroyResource(this); });
resource->setAuthenticate([this](CWlDrm* r, uint32_t token) {
// we don't need this
resource->sendAuthenticated();
});
resource->setCreateBuffer([](CWlDrm* r, uint32_t, uint32_t, int32_t, int32_t, uint32_t, uint32_t) { r->error(WL_DRM_ERROR_INVALID_NAME, "Not supported, use prime instead"); });
resource->setCreatePlanarBuffer([](CWlDrm* r, uint32_t, uint32_t, int32_t, int32_t, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) {
r->error(WL_DRM_ERROR_INVALID_NAME, "Not supported, use prime instead");
});
resource->setCreatePrimeBuffer(
[this](CWlDrm* r, uint32_t id, int32_t nameFd, int32_t w, int32_t h, uint32_t fmt, int32_t off0, int32_t str0, int32_t off1, int32_t str1, int32_t off2, int32_t str2) {
if (off0 < 0 || w <= 0 || h <= 0) {
r->error(WL_DRM_ERROR_INVALID_FORMAT, "Invalid w, h, or offset");
return;
}
SDMABUFAttrs attrs;
attrs.success = true;
attrs.size = {w, h};
attrs.modifier = DRM_FORMAT_MOD_INVALID;
attrs.planes = 1;
attrs.offsets[0] = off0;
attrs.strides[0] = str0;
attrs.fds[0] = nameFd;
attrs.format = fmt;
const auto RESOURCE = PROTO::mesaDRM->m_vBuffers.emplace_back(makeShared<CMesaDRMBufferResource>(id, resource->client(), attrs));
if (!RESOURCE->good()) {
r->noMemory();
PROTO::mesaDRM->m_vBuffers.pop_back();
return;
}
// append instance so that buffer knows its owner
RESOURCE->buffer->resource->buffer = RESOURCE->buffer;
});
resource->sendDevice(PROTO::mesaDRM->nodeName.c_str());
resource->sendCapabilities(WL_DRM_CAPABILITY_PRIME);
auto fmts = g_pHyprOpenGL->getDRMFormats();
for (auto& fmt : fmts) {
resource->sendFormat(fmt.format);
}
}
bool CMesaDRMResource::good() {
return resource->resource();
}
CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
drmDevice* dev = nullptr;
int drmFD = wlr_renderer_get_drm_fd(g_pCompositor->m_sWLRRenderer);
if (drmGetDevice2(drmFD, 0, &dev) != 0) {
LOGM(ERR, "Failed to get device");
PROTO::mesaDRM.reset();
return;
}
if (dev->available_nodes & (1 << DRM_NODE_RENDER)) {
nodeName = dev->nodes[DRM_NODE_RENDER];
} else {
ASSERT(dev->available_nodes & (1 << DRM_NODE_PRIMARY));
LOGM(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]);
nodeName = dev->nodes[DRM_NODE_PRIMARY];
}
drmFreeDevice(&dev);
}
void CMesaDRMProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CMesaDRMResource>(makeShared<CWlDrm>(client, ver, id)));
if (!RESOURCE->good()) {
wl_client_post_no_memory(client);
m_vManagers.pop_back();
return;
}
}
void CMesaDRMProtocol::destroyResource(CMesaDRMResource* resource) {
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; });
}
void CMesaDRMProtocol::destroyResource(CMesaDRMBufferResource* resource) {
std::erase_if(m_vBuffers, [&](const auto& other) { return other.get() == resource; });
}

60
src/protocols/MesaDRM.hpp Normal file
View file

@ -0,0 +1,60 @@
#pragma once
#include <memory>
#include <vector>
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "wayland-drm.hpp"
#include "types/Buffer.hpp"
#include "types/DMABuffer.hpp"
class CMesaDRMBufferResource {
public:
CMesaDRMBufferResource(uint32_t id, wl_client* client, SDMABUFAttrs attrs);
~CMesaDRMBufferResource();
bool good();
private:
SP<CDMABuffer> buffer;
struct {
CHyprSignalListener bufferResourceDestroy;
} listeners;
friend class CMesaDRMResource;
};
class CMesaDRMResource {
public:
CMesaDRMResource(SP<CWlDrm> resource_);
bool good();
private:
SP<CWlDrm> resource;
};
class CMesaDRMProtocol : public IWaylandProtocol {
public:
CMesaDRMProtocol(const wl_interface* iface, const int& ver, const std::string& name);
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
private:
void destroyResource(CMesaDRMResource* resource);
void destroyResource(CMesaDRMBufferResource* resource);
//
std::vector<SP<CMesaDRMResource>> m_vManagers;
std::vector<SP<CMesaDRMBufferResource>> m_vBuffers;
std::string nodeName = "";
friend class CMesaDRMResource;
friend class CMesaDRMBufferResource;
};
namespace PROTO {
inline UP<CMesaDRMProtocol> mesaDRM;
};

View file

@ -1,5 +1,6 @@
#include "OutputPower.hpp" #include "OutputPower.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "core/Output.hpp"
#define LOGM PROTO::outputPower->protoLog #define LOGM PROTO::outputPower->protoLog
@ -61,15 +62,15 @@ void COutputPowerProtocol::destroyOutputPower(COutputPower* power) {
void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uint32_t id, wl_resource* output) { void COutputPowerProtocol::onGetOutputPower(CZwlrOutputPowerManagerV1* pMgr, uint32_t id, wl_resource* output) {
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(wlr_output_from_resource(output)); const auto OUTPUT = CWLOutputResource::fromResource(output);
if (!PMONITOR) { if (!OUTPUT) {
pMgr->error(0, "Invalid output resource"); pMgr->error(0, "Invalid output resource");
return; return;
} }
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vOutputPowers.emplace_back(std::make_unique<COutputPower>(makeShared<CZwlrOutputPowerV1>(CLIENT, pMgr->version(), id), PMONITOR)).get(); const auto RESOURCE = m_vOutputPowers.emplace_back(std::make_unique<COutputPower>(makeShared<CZwlrOutputPowerV1>(CLIENT, pMgr->version(), id), OUTPUT->monitor.get())).get();
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();

View file

@ -3,10 +3,11 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../config/ConfigValue.hpp" #include "../config/ConfigValue.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "core/Compositor.hpp"
#define LOGM PROTO::constraints->protoLog #define LOGM PROTO::constraints->protoLog
CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, wlr_surface* surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime) : CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime) :
resourceL(resource_), locked(true) { resourceL(resource_), locked(true) {
if (!resource_->resource()) if (!resource_->resource())
return; return;
@ -14,13 +15,13 @@ CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, wlr_su
resource_->setOnDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); }); resource_->setOnDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
resource_->setDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); }); resource_->setDestroy([this](CZwpLockedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
pHLSurface = CWLSurface::surfaceFromWlr(surf); pHLSurface = CWLSurface::fromResource(surf);
if (!pHLSurface) if (!pHLSurface)
return; return;
if (region_) if (region_)
region.set(wlr_region_from_resource(region_)); region.set(CWLRegionResource::fromResource(region_)->region);
resource_->setSetRegion([this](CZwpLockedPointerV1* p, wl_resource* region) { onSetRegion(region); }); resource_->setSetRegion([this](CZwpLockedPointerV1* p, wl_resource* region) { onSetRegion(region); });
resource_->setSetCursorPositionHint([this](CZwpLockedPointerV1* p, wl_fixed_t x, wl_fixed_t y) { resource_->setSetCursorPositionHint([this](CZwpLockedPointerV1* p, wl_fixed_t x, wl_fixed_t y) {
@ -45,7 +46,7 @@ CPointerConstraint::CPointerConstraint(SP<CZwpLockedPointerV1> resource_, wlr_su
sharedConstructions(); sharedConstructions();
} }
CPointerConstraint::CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, wlr_surface* surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime) : CPointerConstraint::CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region_, zwpPointerConstraintsV1Lifetime lifetime) :
resourceC(resource_), locked(false) { resourceC(resource_), locked(false) {
if (!resource_->resource()) if (!resource_->resource())
return; return;
@ -53,13 +54,13 @@ CPointerConstraint::CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, wlr_
resource_->setOnDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); }); resource_->setOnDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
resource_->setDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); }); resource_->setDestroy([this](CZwpConfinedPointerV1* p) { PROTO::constraints->destroyPointerConstraint(this); });
pHLSurface = CWLSurface::surfaceFromWlr(surf); pHLSurface = CWLSurface::fromResource(surf);
if (!pHLSurface) if (!pHLSurface)
return; return;
if (region_) if (region_)
region.set(wlr_region_from_resource(region_)); region.set(CWLRegionResource::fromResource(region_)->region);
resource_->setSetRegion([this](CZwpConfinedPointerV1* p, wl_resource* region) { onSetRegion(region); }); resource_->setSetRegion([this](CZwpConfinedPointerV1* p, wl_resource* region) { onSetRegion(region); });
@ -79,7 +80,7 @@ CPointerConstraint::~CPointerConstraint() {
void CPointerConstraint::sharedConstructions() { void CPointerConstraint::sharedConstructions() {
if (pHLSurface) { if (pHLSurface) {
listeners.destroySurface = pHLSurface->events.destroy.registerListener([this](std::any d) { listeners.destroySurface = pHLSurface->events.destroy.registerListener([this](std::any d) {
pHLSurface = nullptr; pHLSurface.reset();
if (active) if (active)
deactivate(); deactivate();
@ -92,7 +93,7 @@ void CPointerConstraint::sharedConstructions() {
cursorPosOnActivate = g_pInputManager->getMouseCoordsInternal(); cursorPosOnActivate = g_pInputManager->getMouseCoordsInternal();
if (g_pCompositor->m_pLastFocus == pHLSurface->wlr()) if (g_pCompositor->m_pLastFocus == pHLSurface->resource())
activate(); activate();
} }
@ -126,10 +127,10 @@ void CPointerConstraint::activate() {
return; return;
// TODO: hack, probably not a super duper great idea // TODO: hack, probably not a super duper great idea
if (g_pSeatManager->state.pointerFocus != pHLSurface->wlr()) { if (g_pSeatManager->state.pointerFocus != pHLSurface->resource()) {
const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal(); const auto SURFBOX = pHLSurface->getSurfaceBoxGlobal();
const auto LOCAL = SURFBOX.has_value() ? logicPositionHint() - SURFBOX->pos() : Vector2D{}; const auto LOCAL = SURFBOX.has_value() ? logicPositionHint() - SURFBOX->pos() : Vector2D{};
g_pSeatManager->setPointerFocus(pHLSurface->wlr(), LOCAL); g_pSeatManager->setPointerFocus(pHLSurface->resource(), LOCAL);
} }
if (locked) if (locked)
@ -152,15 +153,15 @@ void CPointerConstraint::onSetRegion(wl_resource* wlRegion) {
return; return;
} }
const auto REGION = wlr_region_from_resource(wlRegion); const auto REGION = region.set(CWLRegionResource::fromResource(wlRegion)->region);
region.set(REGION); region.set(REGION);
positionHint = region.closestPoint(positionHint); positionHint = region.closestPoint(positionHint);
g_pInputManager->simulateMouseMovement(); // to warp the cursor if anything's amiss g_pInputManager->simulateMouseMovement(); // to warp the cursor if anything's amiss
} }
CWLSurface* CPointerConstraint::owner() { SP<CWLSurface> CPointerConstraint::owner() {
return pHLSurface; return pHLSurface.lock();
} }
CRegion CPointerConstraint::logicConstraintRegion() { CRegion CPointerConstraint::logicConstraintRegion() {
@ -241,7 +242,7 @@ void CPointerConstraintsProtocol::onLockPointer(CZwpPointerConstraintsV1* pMgr,
zwpPointerConstraintsV1Lifetime lifetime) { zwpPointerConstraintsV1Lifetime lifetime) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vConstraints.emplace_back( const auto RESOURCE = m_vConstraints.emplace_back(
makeShared<CPointerConstraint>(makeShared<CZwpLockedPointerV1>(CLIENT, pMgr->version(), id), wlr_surface_from_resource(surface), region, lifetime)); makeShared<CPointerConstraint>(makeShared<CZwpLockedPointerV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), region, lifetime));
onNewConstraint(RESOURCE, pMgr); onNewConstraint(RESOURCE, pMgr);
} }
@ -250,7 +251,7 @@ void CPointerConstraintsProtocol::onConfinePointer(CZwpPointerConstraintsV1* pMg
zwpPointerConstraintsV1Lifetime lifetime) { zwpPointerConstraintsV1Lifetime lifetime) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto RESOURCE = m_vConstraints.emplace_back( const auto RESOURCE = m_vConstraints.emplace_back(
makeShared<CPointerConstraint>(makeShared<CZwpConfinedPointerV1>(CLIENT, pMgr->version(), id), wlr_surface_from_resource(surface), region, lifetime)); makeShared<CPointerConstraint>(makeShared<CZwpConfinedPointerV1>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surface), region, lifetime));
onNewConstraint(RESOURCE, pMgr); onNewConstraint(RESOURCE, pMgr);
} }

View file

@ -12,11 +12,12 @@
#include "../helpers/signal/Listener.hpp" #include "../helpers/signal/Listener.hpp"
class CWLSurface; class CWLSurface;
class CWLSurfaceResource;
class CPointerConstraint { class CPointerConstraint {
public: public:
CPointerConstraint(SP<CZwpLockedPointerV1> resource_, wlr_surface* surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime); CPointerConstraint(SP<CZwpLockedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime);
CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, wlr_surface* surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime); CPointerConstraint(SP<CZwpConfinedPointerV1> resource_, SP<CWLSurfaceResource> surf, wl_resource* region, zwpPointerConstraintsV1Lifetime lifetime);
~CPointerConstraint(); ~CPointerConstraint();
bool good(); bool good();
@ -25,7 +26,7 @@ class CPointerConstraint {
void activate(); void activate();
bool isActive(); bool isActive();
CWLSurface* owner(); SP<CWLSurface> owner();
CRegion logicConstraintRegion(); CRegion logicConstraintRegion();
bool isLocked(); bool isLocked();
@ -36,7 +37,7 @@ class CPointerConstraint {
SP<CZwpConfinedPointerV1> resourceC; SP<CZwpConfinedPointerV1> resourceC;
wl_client* pClient = nullptr; wl_client* pClient = nullptr;
CWLSurface* pHLSurface = nullptr; WP<CWLSurface> pHLSurface;
CRegion region; CRegion region;
bool hintSet = false; bool hintSet = false;

View file

@ -2,6 +2,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "core/Seat.hpp" #include "core/Seat.hpp"
#include "core/Compositor.hpp"
#define LOGM PROTO::pointerGestures->protoLog #define LOGM PROTO::pointerGestures->protoLog
@ -116,7 +117,7 @@ void CPointerGesturesProtocol::swipeBegin(uint32_t timeMs, uint32_t fingers) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)
continue; continue;
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->resource, fingers); sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->getResource()->resource(), fingers);
} }
} }
@ -162,7 +163,7 @@ void CPointerGesturesProtocol::pinchBegin(uint32_t timeMs, uint32_t fingers) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)
continue; continue;
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->resource, fingers); sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->getResource()->resource(), fingers);
} }
} }
@ -208,7 +209,7 @@ void CPointerGesturesProtocol::holdBegin(uint32_t timeMs, uint32_t fingers) {
if (sw->resource->client() != FOCUSEDCLIENT) if (sw->resource->client() != FOCUSEDCLIENT)
continue; continue;
sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->resource, fingers); sw->resource->sendBegin(SERIAL, timeMs, g_pSeatManager->state.pointerFocus->getResource()->resource(), fingers);
} }
} }

View file

@ -2,10 +2,11 @@
#include <algorithm> #include <algorithm>
#include "../helpers/Monitor.hpp" #include "../helpers/Monitor.hpp"
#include "../managers/HookSystemManager.hpp" #include "../managers/HookSystemManager.hpp"
#include "core/Compositor.hpp"
#define LOGM PROTO::presentation->protoLog #define LOGM PROTO::presentation->protoLog
CQueuedPresentationData::CQueuedPresentationData(wlr_surface* surf) : surface(surf) { CQueuedPresentationData::CQueuedPresentationData(SP<CWLSurfaceResource> surf) : surface(surf) {
; ;
} }
@ -25,7 +26,7 @@ void CQueuedPresentationData::discarded() {
wasPresented = false; wasPresented = false;
} }
CPresentationFeedback::CPresentationFeedback(SP<CWpPresentationFeedback> resource_, wlr_surface* surf) : resource(resource_), surface(surf) { CPresentationFeedback::CPresentationFeedback(SP<CWpPresentationFeedback> resource_, SP<CWLSurfaceResource> surf) : resource(resource_), surface(surf) {
if (!good()) if (!good())
return; return;
@ -69,7 +70,7 @@ void CPresentationFeedback::sendQueued(SP<CQueuedPresentationData> data, timespe
CPresentationProtocol::CPresentationProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { CPresentationProtocol::CPresentationProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
static auto P = g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, SCallbackInfo& info, std::any param) { static auto P = g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, SCallbackInfo& info, std::any param) {
const auto PMONITOR = std::any_cast<CMonitor*>(param); const auto PMONITOR = std::any_cast<CMonitor*>(param);
std::erase_if(m_vQueue, [PMONITOR, this](const auto& other) { return !other->surface || other->pMonitor == PMONITOR; }); std::erase_if(m_vQueue, [PMONITOR](const auto& other) { return !other->surface || other->pMonitor == PMONITOR; });
}); });
} }
@ -92,7 +93,8 @@ void CPresentationProtocol::destroyResource(CPresentationFeedback* feedback) {
void CPresentationProtocol::onGetFeedback(CWpPresentation* pMgr, wl_resource* surf, uint32_t id) { void CPresentationProtocol::onGetFeedback(CWpPresentation* pMgr, wl_resource* surf, uint32_t id) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto RESOURCE = const auto RESOURCE =
m_vFeedbacks.emplace_back(makeShared<CPresentationFeedback>(makeShared<CWpPresentationFeedback>(CLIENT, pMgr->version(), id), wlr_surface_from_resource(surf))).get(); m_vFeedbacks.emplace_back(makeShared<CPresentationFeedback>(makeShared<CWpPresentationFeedback>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf)))
.get();
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();
@ -116,8 +118,8 @@ void CPresentationProtocol::onPresented(CMonitor* pMonitor, timespec* when, uint
} }
} }
std::erase_if(m_vFeedbacks, [pMonitor, this](const auto& other) { return !other->surface || other->done; }); std::erase_if(m_vFeedbacks, [](const auto& other) { return !other->surface || other->done; });
std::erase_if(m_vQueue, [pMonitor, this](const auto& other) { return !other->surface || other->pMonitor == pMonitor || !other->pMonitor; }); std::erase_if(m_vQueue, [pMonitor](const auto& other) { return !other->surface || other->pMonitor == pMonitor || !other->pMonitor; });
} }
void CPresentationProtocol::queueData(SP<CQueuedPresentationData> data) { void CPresentationProtocol::queueData(SP<CQueuedPresentationData> data) {

View file

@ -7,10 +7,11 @@
#include "presentation-time.hpp" #include "presentation-time.hpp"
class CMonitor; class CMonitor;
class CWLSurfaceResource;
class CQueuedPresentationData { class CQueuedPresentationData {
public: public:
CQueuedPresentationData(wlr_surface* surf); CQueuedPresentationData(SP<CWLSurfaceResource> surf);
void setPresentationType(bool zeroCopy); void setPresentationType(bool zeroCopy);
void attachMonitor(CMonitor* pMonitor); void attachMonitor(CMonitor* pMonitor);
@ -22,7 +23,7 @@ class CQueuedPresentationData {
bool wasPresented = false; bool wasPresented = false;
bool zeroCopy = false; bool zeroCopy = false;
CMonitor* pMonitor = nullptr; CMonitor* pMonitor = nullptr;
wlr_surface* surface = nullptr; // READ-ONLY WP<CWLSurfaceResource> surface;
DYNLISTENER(destroySurface); DYNLISTENER(destroySurface);
@ -32,7 +33,7 @@ class CQueuedPresentationData {
class CPresentationFeedback { class CPresentationFeedback {
public: public:
CPresentationFeedback(SP<CWpPresentationFeedback> resource_, wlr_surface* surf); CPresentationFeedback(SP<CWpPresentationFeedback> resource_, SP<CWLSurfaceResource> surf);
bool good(); bool good();
@ -40,7 +41,7 @@ class CPresentationFeedback {
private: private:
SP<CWpPresentationFeedback> resource; SP<CWpPresentationFeedback> resource;
wlr_surface* surface = nullptr; // READ-ONLY WP<CWLSurfaceResource> surface;
bool done = false; bool done = false;
friend class CPresentationProtocol; friend class CPresentationProtocol;

View file

@ -2,11 +2,13 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/eventLoop/EventLoopManager.hpp" #include "../managers/eventLoop/EventLoopManager.hpp"
#include "../managers/PointerManager.hpp" #include "../managers/PointerManager.hpp"
#include "core/Output.hpp"
#include "types/WLBuffer.hpp"
#include "types/Buffer.hpp"
#include "../helpers/Format.hpp"
#include <algorithm> #include <algorithm>
#include "ToplevelExportWlrFuncs.hpp"
#define SCREENCOPY_VERSION 3 #define SCREENCOPY_VERSION 3
static void bindManagerInt(wl_client* client, void* data, uint32_t version, uint32_t id) { static void bindManagerInt(wl_client* client, void* data, uint32_t version, uint32_t id) {
@ -202,8 +204,8 @@ void CScreencopyProtocolManager::removeFrame(SScreencopyFrame* frame, bool force
std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return other == frame; }); std::erase_if(m_vFramesAwaitingWrite, [&](const auto& other) { return other == frame; });
wl_resource_set_user_data(frame->resource, nullptr); wl_resource_set_user_data(frame->resource, nullptr);
if (frame->buffer && frame->buffer->n_locks > 0) if (frame->buffer && frame->buffer->locked())
wlr_buffer_unlock(frame->buffer); frame->buffer->unlock();
removeClient(frame->client, force); removeClient(frame->client, force);
m_lFrames.remove(*frame); m_lFrames.remove(*frame);
} }
@ -214,7 +216,7 @@ void CScreencopyProtocolManager::captureOutput(wl_client* client, wl_resource* r
const auto PFRAME = &m_lFrames.emplace_back(); const auto PFRAME = &m_lFrames.emplace_back();
PFRAME->overlayCursor = !!overlay_cursor; PFRAME->overlayCursor = !!overlay_cursor;
PFRAME->resource = wl_resource_create(client, &zwlr_screencopy_frame_v1_interface, wl_resource_get_version(resource), frame); PFRAME->resource = wl_resource_create(client, &zwlr_screencopy_frame_v1_interface, wl_resource_get_version(resource), frame);
PFRAME->pMonitor = g_pCompositor->getMonitorFromOutput(wlr_output_from_resource(output)); PFRAME->pMonitor = CWLOutputResource::fromResource(output)->monitor.get();
if (!PFRAME->pMonitor) { if (!PFRAME->pMonitor) {
Debug::log(ERR, "client requested sharing of a monitor that doesnt exist"); Debug::log(ERR, "client requested sharing of a monitor that doesnt exist");
@ -256,7 +258,7 @@ void CScreencopyProtocolManager::captureOutput(wl_client* client, wl_resource* r
return; return;
} }
const auto PSHMINFO = drm_get_pixel_format_info(PFRAME->shmFormat); const auto PSHMINFO = FormatUtils::getPixelFormatFromDRM(PFRAME->shmFormat);
if (!PSHMINFO) { if (!PSHMINFO) {
Debug::log(ERR, "No pixel format supported by renderer in capture output"); Debug::log(ERR, "No pixel format supported by renderer in capture output");
zwlr_screencopy_frame_v1_send_failed(PFRAME->resource); zwlr_screencopy_frame_v1_send_failed(PFRAME->resource);
@ -279,9 +281,9 @@ void CScreencopyProtocolManager::captureOutput(wl_client* client, wl_resource* r
wlr_output_effective_resolution(PFRAME->pMonitor->output, &ow, &oh); wlr_output_effective_resolution(PFRAME->pMonitor->output, &ow, &oh);
PFRAME->box.transform(PFRAME->pMonitor->transform, ow, oh).scale(PFRAME->pMonitor->scale).round(); PFRAME->box.transform(PFRAME->pMonitor->transform, ow, oh).scale(PFRAME->pMonitor->scale).round();
PFRAME->shmStride = pixel_format_info_min_stride(PSHMINFO, PFRAME->box.w); PFRAME->shmStride = FormatUtils::minStride(PSHMINFO, PFRAME->box.w);
zwlr_screencopy_frame_v1_send_buffer(PFRAME->resource, convert_drm_format_to_wl_shm(PFRAME->shmFormat), PFRAME->box.width, PFRAME->box.height, PFRAME->shmStride); zwlr_screencopy_frame_v1_send_buffer(PFRAME->resource, FormatUtils::drmToShm(PFRAME->shmFormat), PFRAME->box.width, PFRAME->box.height, PFRAME->shmStride);
if (wl_resource_get_version(resource) >= 3) { if (wl_resource_get_version(resource) >= 3) {
if (PFRAME->dmabufFormat != DRM_FORMAT_INVALID) { if (PFRAME->dmabufFormat != DRM_FORMAT_INVALID) {
@ -307,7 +309,7 @@ void CScreencopyProtocolManager::copyFrame(wl_client* client, wl_resource* resou
return; return;
} }
const auto PBUFFER = wlr_buffer_try_from_resource(buffer); const auto PBUFFER = CWLBufferResource::fromResource(buffer);
if (!PBUFFER) { if (!PBUFFER) {
Debug::log(ERR, "[sc] invalid buffer in {:x}", (uintptr_t)PFRAME); Debug::log(ERR, "[sc] invalid buffer in {:x}", (uintptr_t)PFRAME);
wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer"); wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer");
@ -315,7 +317,9 @@ void CScreencopyProtocolManager::copyFrame(wl_client* client, wl_resource* resou
return; return;
} }
if (PBUFFER->width != PFRAME->box.width || PBUFFER->height != PFRAME->box.height) { PBUFFER->buffer->lock();
if (PBUFFER->buffer->size != PFRAME->box.size()) {
Debug::log(ERR, "[sc] invalid dimensions in {:x}", (uintptr_t)PFRAME); Debug::log(ERR, "[sc] invalid dimensions in {:x}", (uintptr_t)PFRAME);
wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions"); wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer dimensions");
removeFrame(PFRAME); removeFrame(PFRAME);
@ -329,28 +333,22 @@ void CScreencopyProtocolManager::copyFrame(wl_client* client, wl_resource* resou
return; return;
} }
wlr_dmabuf_attributes dmabufAttrs; if (auto attrs = PBUFFER->buffer->dmabuf(); attrs.success) {
void* wlrBufferAccessData; PFRAME->bufferDMA = true;
uint32_t wlrBufferAccessFormat;
size_t wlrBufferAccessStride;
if (wlr_buffer_get_dmabuf(PBUFFER, &dmabufAttrs)) {
PFRAME->bufferCap = WLR_BUFFER_CAP_DMABUF;
if (dmabufAttrs.format != PFRAME->dmabufFormat) { if (attrs.format != PFRAME->dmabufFormat) {
Debug::log(ERR, "[sc] invalid buffer dma format in {:x}", (uintptr_t)PFRAME); Debug::log(ERR, "[sc] invalid buffer dma format in {:x}", (uintptr_t)PFRAME);
wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format"); wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
removeFrame(PFRAME); removeFrame(PFRAME);
return; return;
} }
} else if (wlr_buffer_begin_data_ptr_access(PBUFFER, WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &wlrBufferAccessData, &wlrBufferAccessFormat, &wlrBufferAccessStride)) { } else if (auto attrs = PBUFFER->buffer->shm(); attrs.success) {
wlr_buffer_end_data_ptr_access(PBUFFER); if (attrs.format != PFRAME->shmFormat) {
if (wlrBufferAccessFormat != PFRAME->shmFormat) {
Debug::log(ERR, "[sc] invalid buffer shm format in {:x}", (uintptr_t)PFRAME); Debug::log(ERR, "[sc] invalid buffer shm format in {:x}", (uintptr_t)PFRAME);
wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format"); wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer format");
removeFrame(PFRAME); removeFrame(PFRAME);
return; return;
} else if ((int)wlrBufferAccessStride != PFRAME->shmStride) { } else if ((int)attrs.stride != PFRAME->shmStride) {
Debug::log(ERR, "[sc] invalid buffer shm stride in {:x}", (uintptr_t)PFRAME); Debug::log(ERR, "[sc] invalid buffer shm stride in {:x}", (uintptr_t)PFRAME);
wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride"); wl_resource_post_error(PFRAME->resource, ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, "invalid buffer stride");
removeFrame(PFRAME); removeFrame(PFRAME);
@ -363,7 +361,7 @@ void CScreencopyProtocolManager::copyFrame(wl_client* client, wl_resource* resou
return; return;
} }
PFRAME->buffer = PBUFFER; PFRAME->buffer = PBUFFER->buffer;
m_vFramesAwaitingWrite.emplace_back(PFRAME); m_vFramesAwaitingWrite.emplace_back(PFRAME);
@ -432,7 +430,7 @@ void CScreencopyProtocolManager::shareFrame(SScreencopyFrame* frame) {
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
uint32_t flags = 0; uint32_t flags = 0;
if (frame->bufferCap == WLR_BUFFER_CAP_DMABUF) { if (frame->bufferDMA) {
if (!copyFrameDmabuf(frame)) { if (!copyFrameDmabuf(frame)) {
Debug::log(ERR, "[sc] dmabuf copy failed in {:x}", (uintptr_t)frame); Debug::log(ERR, "[sc] dmabuf copy failed in {:x}", (uintptr_t)frame);
zwlr_screencopy_frame_v1_send_failed(frame->resource); zwlr_screencopy_frame_v1_send_failed(frame->resource);
@ -471,7 +469,7 @@ void CScreencopyProtocolManager::sendFrameDamage(SScreencopyFrame* frame) {
// std::clamp(RECT.x2 - RECT.x1, 0, frame->buffer->width - RECT.x1), std::clamp(RECT.y2 - RECT.y1, 0, frame->buffer->height - RECT.y1)); // std::clamp(RECT.x2 - RECT.x1, 0, frame->buffer->width - RECT.x1), std::clamp(RECT.y2 - RECT.y1, 0, frame->buffer->height - RECT.y1));
// } // }
zwlr_screencopy_frame_v1_send_damage(frame->resource, 0, 0, frame->buffer->width, frame->buffer->height); zwlr_screencopy_frame_v1_send_damage(frame->resource, 0, 0, frame->buffer->size.x, frame->buffer->size.y);
} }
bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec* now) { bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec* now) {
@ -479,13 +477,10 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
if (!sourceTex) if (!sourceTex)
return false; return false;
void* data; auto TEXTURE = makeShared<CTexture>(sourceTex);
uint32_t format;
size_t stride; auto shm = frame->buffer->shm();
if (!wlr_buffer_begin_data_ptr_access(frame->buffer, WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &data, &format, &stride)) { auto [pixelData, fmt, bufLen] = frame->buffer->beginDataPtr(0); // no need for end, cuz it's shm
wlr_texture_destroy(sourceTex);
return false;
}
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX}; CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
@ -496,14 +491,13 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &fb, true)) { if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &fb, true)) {
wlr_texture_destroy(sourceTex); wlr_texture_destroy(sourceTex);
wlr_buffer_end_data_ptr_access(frame->buffer);
return false; return false;
} }
CBox monbox = CBox{0, 0, frame->pMonitor->vecTransformedSize.x, frame->pMonitor->vecTransformedSize.y}.translate({-frame->box.x, -frame->box.y}); CBox monbox = CBox{0, 0, frame->pMonitor->vecTransformedSize.x, frame->pMonitor->vecTransformedSize.y}.translate({-frame->box.x, -frame->box.y});
g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->setRenderModifEnabled(false);
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1); g_pHyprOpenGL->renderTexture(TEXTURE, &monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false); g_pHyprOpenGL->setMonitorTransformEnabled(false);
@ -513,14 +507,15 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
glBindFramebuffer(GL_FRAMEBUFFER, fb.m_iFb); glBindFramebuffer(GL_FRAMEBUFFER, fb.m_iFb);
#endif #endif
const auto PFORMAT = g_pHyprOpenGL->getPixelFormatFromDRM(format); const auto PFORMAT = FormatUtils::getPixelFormatFromDRM(shm.format);
if (!PFORMAT) { if (!PFORMAT) {
g_pHyprRenderer->endRender(); g_pHyprRenderer->endRender();
wlr_texture_destroy(sourceTex); wlr_texture_destroy(sourceTex);
wlr_buffer_end_data_ptr_access(frame->buffer);
return false; return false;
} }
auto glFormat = PFORMAT->flipRB ? GL_BGRA_EXT : GL_RGBA;
g_pHyprOpenGL->m_RenderData.blockScreenShader = true; g_pHyprOpenGL->m_RenderData.blockScreenShader = true;
g_pHyprRenderer->endRender(); g_pHyprRenderer->endRender();
@ -530,21 +525,20 @@ bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec*
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
const wlr_pixel_format_info* drmFmtWlr = drm_get_pixel_format_info(format); const auto drmFmt = FormatUtils::getPixelFormatFromDRM(shm.format);
uint32_t packStride = pixel_format_info_min_stride(drmFmtWlr, frame->box.w); uint32_t packStride = FormatUtils::minStride(drmFmt, frame->box.w);
if (packStride == stride) { if (packStride == (uint32_t)shm.stride) {
glReadPixels(0, 0, frame->box.w, frame->box.h, PFORMAT->glFormat, PFORMAT->glType, data); glReadPixels(0, 0, frame->box.w, frame->box.h, glFormat, PFORMAT->glType, pixelData);
} else { } else {
for (size_t i = 0; i < frame->box.h; ++i) { for (size_t i = 0; i < frame->box.h; ++i) {
uint32_t y = i; uint32_t y = i;
glReadPixels(0, y, frame->box.w, 1, PFORMAT->glFormat, PFORMAT->glType, ((unsigned char*)data) + i * stride); glReadPixels(0, y, frame->box.w, 1, glFormat, PFORMAT->glType, ((unsigned char*)pixelData) + i * shm.stride);
} }
} }
g_pHyprOpenGL->m_RenderData.pMonitor = nullptr; g_pHyprOpenGL->m_RenderData.pMonitor = nullptr;
wlr_buffer_end_data_ptr_access(frame->buffer);
wlr_texture_destroy(sourceTex); wlr_texture_destroy(sourceTex);
return true; return true;
@ -555,9 +549,11 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) {
if (!sourceTex) if (!sourceTex)
return false; return false;
auto TEXTURE = makeShared<CTexture>(sourceTex);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX}; CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer, nullptr, true)) if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_TO_BUFFER, frame->buffer.lock(), nullptr, true))
return false; return false;
CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y} CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y}
@ -565,7 +561,7 @@ bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) {
.transform(wlr_output_transform_invert(frame->pMonitor->output->transform), frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y); .transform(wlr_output_transform_invert(frame->pMonitor->output->transform), frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y);
g_pHyprOpenGL->setMonitorTransformEnabled(true); g_pHyprOpenGL->setMonitorTransformEnabled(true);
g_pHyprOpenGL->setRenderModifEnabled(false); g_pHyprOpenGL->setRenderModifEnabled(false);
g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1); g_pHyprOpenGL->renderTexture(TEXTURE, &monbox, 1);
g_pHyprOpenGL->setRenderModifEnabled(true); g_pHyprOpenGL->setRenderModifEnabled(true);
g_pHyprOpenGL->setMonitorTransformEnabled(false); g_pHyprOpenGL->setMonitorTransformEnabled(false);

View file

@ -10,6 +10,7 @@
#include "../managers/eventLoop/EventLoopTimer.hpp" #include "../managers/eventLoop/EventLoopTimer.hpp"
class CMonitor; class CMonitor;
class IWLBuffer;
enum eClientOwners { enum eClientOwners {
CLIENT_SCREENCOPY = 0, CLIENT_SCREENCOPY = 0,
@ -53,9 +54,9 @@ struct SScreencopyFrame {
bool withDamage = false; bool withDamage = false;
bool lockedSWCursors = false; bool lockedSWCursors = false;
wlr_buffer_cap bufferCap = WLR_BUFFER_CAP_SHM; bool bufferDMA = false;
wlr_buffer* buffer = nullptr; WP<IWLBuffer> buffer;
CMonitor* pMonitor = nullptr; CMonitor* pMonitor = nullptr;
PHLWINDOWREF pWindow; PHLWINDOWREF pWindow;

View file

@ -1,8 +1,9 @@
#include "ServerDecorationKDE.hpp" #include "ServerDecorationKDE.hpp"
#include "core/Compositor.hpp"
#define LOGM PROTO::serverDecorationKDE->protoLog #define LOGM PROTO::serverDecorationKDE->protoLog
CServerDecorationKDE::CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, wlr_surface* surf) : resource(resource_) { CServerDecorationKDE::CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, SP<CWLSurfaceResource> surf) : resource(resource_) {
if (!good()) if (!good())
return; return;
@ -42,7 +43,8 @@ void CServerDecorationKDEProtocol::destroyResource(CServerDecorationKDE* hayperl
void CServerDecorationKDEProtocol::createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf) { void CServerDecorationKDEProtocol::createDecoration(COrgKdeKwinServerDecorationManager* pMgr, uint32_t id, wl_resource* surf) {
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
const auto RESOURCE = const auto RESOURCE =
m_vDecos.emplace_back(std::make_unique<CServerDecorationKDE>(makeShared<COrgKdeKwinServerDecoration>(CLIENT, pMgr->version(), id), wlr_surface_from_resource(surf))).get(); m_vDecos.emplace_back(std::make_unique<CServerDecorationKDE>(makeShared<COrgKdeKwinServerDecoration>(CLIENT, pMgr->version(), id), CWLSurfaceResource::fromResource(surf)))
.get();
if (!RESOURCE->good()) { if (!RESOURCE->good()) {
pMgr->noMemory(); pMgr->noMemory();

View file

@ -6,9 +6,11 @@
#include "WaylandProtocol.hpp" #include "WaylandProtocol.hpp"
#include "kde-server-decoration.hpp" #include "kde-server-decoration.hpp"
class CWLSurfaceResource;
class CServerDecorationKDE { class CServerDecorationKDE {
public: public:
CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, wlr_surface* surf); CServerDecorationKDE(SP<COrgKdeKwinServerDecoration> resource_, SP<CWLSurfaceResource> surf);
bool good(); bool good();

View file

@ -2,10 +2,12 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "FractionalScale.hpp" #include "FractionalScale.hpp"
#include "core/Compositor.hpp"
#include "core/Output.hpp"
#define LOGM PROTO::sessionLock->protoLog #define LOGM PROTO::sessionLock->protoLog
CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, wlr_surface* surface_, CMonitor* pMonitor_, WP<CSessionLock> owner_) : CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, SP<CWLSurfaceResource> surface_, CMonitor* pMonitor_, WP<CSessionLock> owner_) :
resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) { resource(resource_), sessionLock(owner_), pSurface(surface_), pMonitor(pMonitor_) {
if (!resource->resource()) if (!resource->resource())
return; return;
@ -21,10 +23,8 @@ CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_,
resource->setAckConfigure([this](CExtSessionLockSurfaceV1* r, uint32_t serial) { ackdConfigure = true; }); resource->setAckConfigure([this](CExtSessionLockSurfaceV1* r, uint32_t serial) { ackdConfigure = true; });
hyprListener_surfaceCommit.initCallback( listeners.surfaceCommit = pSurface->events.commit.registerListener([this](std::any d) {
&pSurface->events.commit, if (!pSurface->current.buffer) {
[this](void* owner, void* data) {
if (pSurface->pending.buffer_width <= 0 || pSurface->pending.buffer_height <= 0) {
LOGM(ERR, "SessionLock attached a null buffer"); LOGM(ERR, "SessionLock attached a null buffer");
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER, "Null buffer attached"); resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER, "Null buffer attached");
return; return;
@ -39,27 +39,22 @@ CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_,
if (committed) if (committed)
events.commit.emit(); events.commit.emit();
else { else {
wlr_surface_map(pSurface); pSurface->map();
events.map.emit(); events.map.emit();
} }
committed = true; committed = true;
}, });
this, "SessionLockSurface");
hyprListener_surfaceDestroy.initCallback( listeners.surfaceDestroy = pSurface->events.destroy.registerListener([this](std::any d) {
&pSurface->events.destroy,
[this](void* owner, void* data) {
LOGM(WARN, "SessionLockSurface object remains but surface is being destroyed???"); LOGM(WARN, "SessionLockSurface object remains but surface is being destroyed???");
wlr_surface_unmap(pSurface); pSurface->unmap();
hyprListener_surfaceCommit.removeCallback(); listeners.surfaceCommit.reset();
hyprListener_surfaceDestroy.removeCallback(); listeners.surfaceDestroy.reset();
if (g_pCompositor->m_pLastFocus == pSurface) if (g_pCompositor->m_pLastFocus == pSurface)
g_pCompositor->m_pLastFocus = nullptr; g_pCompositor->m_pLastFocus.reset();
pSurface = nullptr; pSurface.reset();
}, });
this, "SessionLockSurface");
PROTO::fractional->sendScale(surface_, pMonitor_->scale); PROTO::fractional->sendScale(surface_, pMonitor_->scale);
@ -70,9 +65,9 @@ CSessionLockSurface::CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_,
CSessionLockSurface::~CSessionLockSurface() { CSessionLockSurface::~CSessionLockSurface() {
if (pSurface && pSurface->mapped) if (pSurface && pSurface->mapped)
wlr_surface_unmap(pSurface); pSurface->unmap();
hyprListener_surfaceCommit.removeCallback(); listeners.surfaceCommit.reset();
hyprListener_surfaceDestroy.removeCallback(); listeners.surfaceDestroy.reset();
events.destroy.emit(); // just in case. events.destroy.emit(); // just in case.
} }
@ -93,8 +88,8 @@ CMonitor* CSessionLockSurface::monitor() {
return pMonitor; return pMonitor;
} }
wlr_surface* CSessionLockSurface::surface() { SP<CWLSurfaceResource> CSessionLockSurface::surface() {
return pSurface; return pSurface.lock();
} }
CSessionLock::CSessionLock(SP<CExtSessionLockV1> resource_) : resource(resource_) { CSessionLock::CSessionLock(SP<CExtSessionLockV1> resource_) : resource(resource_) {
@ -195,8 +190,8 @@ void CSessionLockProtocol::onLock(CExtSessionLockManagerV1* pMgr, uint32_t id) {
void CSessionLockProtocol::onGetLockSurface(CExtSessionLockV1* lock, uint32_t id, wl_resource* surface, wl_resource* output) { void CSessionLockProtocol::onGetLockSurface(CExtSessionLockV1* lock, uint32_t id, wl_resource* surface, wl_resource* output) {
LOGM(LOG, "New sessionLockSurface with id {}", id); LOGM(LOG, "New sessionLockSurface with id {}", id);
auto PSURFACE = wlr_surface_from_resource(surface); auto PSURFACE = CWLSurfaceResource::fromResource(surface);
auto PMONITOR = g_pCompositor->getMonitorFromOutput(wlr_output_from_resource(output)); auto PMONITOR = CWLOutputResource::fromResource(output)->monitor.get();
SP<CSessionLock> sessionLock; SP<CSessionLock> sessionLock;
for (auto& l : m_vLocks) { for (auto& l : m_vLocks) {

View file

@ -9,16 +9,17 @@
class CMonitor; class CMonitor;
class CSessionLock; class CSessionLock;
class CWLSurfaceResource;
class CSessionLockSurface { class CSessionLockSurface {
public: public:
CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, wlr_surface* surface_, CMonitor* pMonitor_, WP<CSessionLock> owner_); CSessionLockSurface(SP<CExtSessionLockSurfaceV1> resource_, SP<CWLSurfaceResource> surface_, CMonitor* pMonitor_, WP<CSessionLock> owner_);
~CSessionLockSurface(); ~CSessionLockSurface();
bool good(); bool good();
bool inert(); bool inert();
CMonitor* monitor(); CMonitor* monitor();
wlr_surface* surface(); SP<CWLSurfaceResource> surface();
struct { struct {
CSignal map; CSignal map;
@ -29,7 +30,7 @@ class CSessionLockSurface {
private: private:
SP<CExtSessionLockSurfaceV1> resource; SP<CExtSessionLockSurfaceV1> resource;
WP<CSessionLock> sessionLock; WP<CSessionLock> sessionLock;
wlr_surface* pSurface = nullptr; WP<CWLSurfaceResource> pSurface;
CMonitor* pMonitor = nullptr; CMonitor* pMonitor = nullptr;
bool ackdConfigure = false; bool ackdConfigure = false;
@ -37,11 +38,10 @@ class CSessionLockSurface {
void sendConfigure(); void sendConfigure();
DYNLISTENER(surfaceCommit);
DYNLISTENER(surfaceDestroy);
struct { struct {
CHyprSignalListener monitorMode; CHyprSignalListener monitorMode;
CHyprSignalListener surfaceCommit;
CHyprSignalListener surfaceDestroy;
} listeners; } listeners;
}; };

View file

@ -1,10 +1,11 @@
#include "ShortcutsInhibit.hpp" #include "ShortcutsInhibit.hpp"
#include <algorithm> #include <algorithm>
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "core/Compositor.hpp"
#define LOGM PROTO::shortcutsInhibit->protoLog #define LOGM PROTO::shortcutsInhibit->protoLog
CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, wlr_surface* surf) : resource(resource_), pSurface(surf) { CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf) : resource(resource_), pSurface(surf) {
if (!resource->resource()) if (!resource->resource())
return; return;
@ -16,8 +17,8 @@ CKeyboardShortcutsInhibitor::CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcut
resource->sendActive(); resource->sendActive();
} }
wlr_surface* CKeyboardShortcutsInhibitor::surface() { SP<CWLSurfaceResource> CKeyboardShortcutsInhibitor::surface() {
return pSurface; return pSurface.lock();
} }
bool CKeyboardShortcutsInhibitor::good() { bool CKeyboardShortcutsInhibitor::good() {
@ -46,7 +47,7 @@ void CKeyboardShortcutsInhibitProtocol::destroyInhibitor(CKeyboardShortcutsInhib
} }
void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat) { void CKeyboardShortcutsInhibitProtocol::onInhibit(CZwpKeyboardShortcutsInhibitManagerV1* pMgr, uint32_t id, wl_resource* surface, wl_resource* seat) {
wlr_surface* surf = wlr_surface_from_resource(surface); SP<CWLSurfaceResource> surf = CWLSurfaceResource::fromResource(surface);
const auto CLIENT = pMgr->client(); const auto CLIENT = pMgr->client();
for (auto& in : m_vInhibitors) { for (auto& in : m_vInhibitors) {

View file

@ -6,17 +6,19 @@
#include "WaylandProtocol.hpp" #include "WaylandProtocol.hpp"
#include "keyboard-shortcuts-inhibit-unstable-v1.hpp" #include "keyboard-shortcuts-inhibit-unstable-v1.hpp"
class CWLSurfaceResource;
class CKeyboardShortcutsInhibitor { class CKeyboardShortcutsInhibitor {
public: public:
CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, wlr_surface* surf); CKeyboardShortcutsInhibitor(SP<CZwpKeyboardShortcutsInhibitorV1> resource_, SP<CWLSurfaceResource> surf);
// read-only pointer, may be invalid // read-only pointer, may be invalid
wlr_surface* surface(); SP<CWLSurfaceResource> surface();
bool good(); bool good();
private: private:
SP<CZwpKeyboardShortcutsInhibitorV1> resource; SP<CZwpKeyboardShortcutsInhibitorV1> resource;
wlr_surface* pSurface = nullptr; WP<CWLSurfaceResource> pSurface;
}; };
class CKeyboardShortcutsInhibitProtocol : public IWaylandProtocol { class CKeyboardShortcutsInhibitProtocol : public IWaylandProtocol {

View file

@ -3,6 +3,7 @@
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "../managers/SeatManager.hpp" #include "../managers/SeatManager.hpp"
#include "core/Seat.hpp" #include "core/Seat.hpp"
#include "core/Compositor.hpp"
#include <algorithm> #include <algorithm>
#define LOGM PROTO::tablet->protoLog #define LOGM PROTO::tablet->protoLog
@ -160,11 +161,11 @@ CTabletToolV2Resource::CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<
resource->setDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); }); resource->setDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
resource->setOnDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); }); resource->setOnDestroy([this](CZwpTabletToolV2* r) { PROTO::tablet->destroyResource(this); });
resource->setSetCursor([this](CZwpTabletToolV2* r, uint32_t serial, wl_resource* surf, int32_t hot_x, int32_t hot_y) { resource->setSetCursor([](CZwpTabletToolV2* r, uint32_t serial, wl_resource* surf, int32_t hot_x, int32_t hot_y) {
if (!g_pSeatManager->state.pointerFocusResource || g_pSeatManager->state.pointerFocusResource->client() != r->client()) if (!g_pSeatManager->state.pointerFocusResource || g_pSeatManager->state.pointerFocusResource->client() != r->client())
return; return;
g_pInputManager->processMouseRequest(CSeatManager::SSetCursorEvent{surf ? wlr_surface_from_resource(surf) : nullptr, {hot_x, hot_y}}); g_pInputManager->processMouseRequest(CSeatManager::SSetCursorEvent{surf ? CWLSurfaceResource::fromResource(surf) : nullptr, {hot_x, hot_y}});
}); });
} }
@ -448,7 +449,7 @@ void CTabletV2Protocol::recheckRegisteredDevices() {
if (t->current) { if (t->current) {
t->resource->sendProximityOut(); t->resource->sendProximityOut();
t->sendFrame(); t->sendFrame();
t->lastSurf = nullptr; t->lastSurf.reset();
} }
t->resource->sendRemoved(); t->resource->sendRemoved();
@ -545,9 +546,9 @@ void CTabletV2Protocol::down(SP<CTabletTool> tool) {
} }
} }
void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, wlr_surface* surf) { void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, SP<CWLSurfaceResource> surf) {
proximityOut(tool); proximityOut(tool);
const auto CLIENT = wl_resource_get_client(surf->resource); const auto CLIENT = surf->client();
SP<CTabletToolV2Resource> toolResource; SP<CTabletToolV2Resource> toolResource;
SP<CTabletV2Resource> tabletResource; SP<CTabletV2Resource> tabletResource;
@ -587,7 +588,7 @@ void CTabletV2Protocol::proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, wl
toolResource->lastSurf = surf; toolResource->lastSurf = surf;
auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(toolResource->resource->client())); auto serial = g_pSeatManager->nextSerial(g_pSeatManager->seatResourceForClient(toolResource->resource->client()));
toolResource->resource->sendProximityIn(serial, tabletResource->resource.get(), surf->resource); toolResource->resource->sendProximityIn(serial, tabletResource->resource.get(), surf->getResource()->resource());
toolResource->queueFrame(); toolResource->queueFrame();
LOGM(ERR, "proximityIn: found no resource to send enter"); LOGM(ERR, "proximityIn: found no resource to send enter");
@ -599,7 +600,7 @@ void CTabletV2Protocol::proximityOut(SP<CTabletTool> tool) {
continue; continue;
t->current = false; t->current = false;
t->lastSurf = nullptr; t->lastSurf.reset();
t->resource->sendProximityOut(); t->resource->sendProximityOut();
t->sendFrame(); t->sendFrame();
} }

View file

@ -12,6 +12,7 @@ class CTabletTool;
class CTabletPad; class CTabletPad;
class CEventLoopTimer; class CEventLoopTimer;
class CTabletSeat; class CTabletSeat;
class CWLSurfaceResource;
class CTabletPadStripV2Resource { class CTabletPadStripV2Resource {
public: public:
@ -118,7 +119,7 @@ class CTabletToolV2Resource {
void sendFrame(bool removeSource = true); void sendFrame(bool removeSource = true);
bool current = false; bool current = false;
wlr_surface* lastSurf = nullptr; // READ-ONLY WP<CWLSurfaceResource> lastSurf;
WP<CTabletTool> tool; WP<CTabletTool> tool;
WP<CTabletSeat> seat; WP<CTabletSeat> seat;
@ -180,7 +181,7 @@ class CTabletV2Protocol : public IWaylandProtocol {
void tilt(SP<CTabletTool> tool, const Vector2D& value); void tilt(SP<CTabletTool> tool, const Vector2D& value);
void up(SP<CTabletTool> tool); void up(SP<CTabletTool> tool);
void down(SP<CTabletTool> tool); void down(SP<CTabletTool> tool);
void proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, wlr_surface* surf); void proximityIn(SP<CTabletTool> tool, SP<CTablet> tablet, SP<CWLSurfaceResource> surf);
void proximityOut(SP<CTabletTool> tool); void proximityOut(SP<CTabletTool> tool);
void buttonTool(SP<CTabletTool> tool, uint32_t button, uint32_t state); void buttonTool(SP<CTabletTool> tool, uint32_t button, uint32_t state);
void motion(SP<CTabletTool> tool, const Vector2D& value); void motion(SP<CTabletTool> tool, const Vector2D& value);

View file

@ -2,6 +2,7 @@
#include "../managers/ProtocolManager.hpp" #include "../managers/ProtocolManager.hpp"
#include "../desktop/Window.hpp" #include "../desktop/Window.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "core/Compositor.hpp"
CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) { CTearingControlProtocol::CTearingControlProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
static auto P = static auto P =
@ -13,15 +14,16 @@ void CTearingControlProtocol::bindManager(wl_client* client, void* data, uint32_
RESOURCE->setOnDestroy([this](CWpTearingControlManagerV1* p) { this->onManagerResourceDestroy(p->resource()); }); RESOURCE->setOnDestroy([this](CWpTearingControlManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
RESOURCE->setDestroy([this](CWpTearingControlManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); }); RESOURCE->setDestroy([this](CWpTearingControlManagerV1* pMgr) { this->onManagerResourceDestroy(pMgr->resource()); });
RESOURCE->setGetTearingControl( RESOURCE->setGetTearingControl([this](CWpTearingControlManagerV1* pMgr, uint32_t id, wl_resource* surface) {
[this](CWpTearingControlManagerV1* pMgr, uint32_t id, wl_resource* surface) { this->onGetController(pMgr->client(), pMgr, id, wlr_surface_from_resource(surface)); }); this->onGetController(pMgr->client(), pMgr, id, CWLSurfaceResource::fromResource(surface));
});
} }
void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) { void CTearingControlProtocol::onManagerResourceDestroy(wl_resource* res) {
std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; }); std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
} }
void CTearingControlProtocol::onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, wlr_surface* surf) { void CTearingControlProtocol::onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surf) {
const auto CONTROLLER = m_vTearingControllers.emplace_back(std::make_unique<CTearingControl>(makeShared<CWpTearingControlV1>(client, pMgr->version(), id), surf)).get(); const auto CONTROLLER = m_vTearingControllers.emplace_back(std::make_unique<CTearingControl>(makeShared<CWpTearingControlV1>(client, pMgr->version(), id), surf)).get();
if (!CONTROLLER->good()) { if (!CONTROLLER->good()) {
@ -44,14 +46,14 @@ void CTearingControlProtocol::onWindowDestroy(PHLWINDOW pWindow) {
// //
CTearingControl::CTearingControl(SP<CWpTearingControlV1> resource_, wlr_surface* surf_) : resource(resource_) { CTearingControl::CTearingControl(SP<CWpTearingControlV1> resource_, SP<CWLSurfaceResource> surf_) : resource(resource_) {
resource->setData(this); resource->setData(this);
resource->setOnDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); }); resource->setOnDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); });
resource->setDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); }); resource->setDestroy([this](CWpTearingControlV1* res) { PROTO::tearing->onControllerDestroy(this); });
resource->setSetPresentationHint([this](CWpTearingControlV1* res, wpTearingControlV1PresentationHint hint) { this->onHint(hint); }); resource->setSetPresentationHint([this](CWpTearingControlV1* res, wpTearingControlV1PresentationHint hint) { this->onHint(hint); });
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_pWLSurface.wlr() == surf_) { if (w->m_pWLSurface->resource() == surf_) {
pWindow = w; pWindow = w;
break; break;
} }

View file

@ -6,10 +6,11 @@
class CWindow; class CWindow;
class CTearingControlProtocol; class CTearingControlProtocol;
class CWLSurfaceResource;
class CTearingControl { class CTearingControl {
public: public:
CTearingControl(SP<CWpTearingControlV1> resource_, wlr_surface* surf_); CTearingControl(SP<CWpTearingControlV1> resource_, SP<CWLSurfaceResource> surf_);
void onHint(wpTearingControlV1PresentationHint hint_); void onHint(wpTearingControlV1PresentationHint hint_);
@ -42,7 +43,7 @@ class CTearingControlProtocol : public IWaylandProtocol {
private: private:
void onManagerResourceDestroy(wl_resource* res); void onManagerResourceDestroy(wl_resource* res);
void onControllerDestroy(CTearingControl* control); void onControllerDestroy(CTearingControl* control);
void onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, wlr_surface* surf); void onGetController(wl_client* client, CWpTearingControlManagerV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surf);
void onWindowDestroy(PHLWINDOW pWindow); void onWindowDestroy(PHLWINDOW pWindow);
// //

View file

@ -1,6 +1,7 @@
#include "TextInputV1.hpp" #include "TextInputV1.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "core/Compositor.hpp"
#define TEXT_INPUT_VERSION 1 #define TEXT_INPUT_VERSION 1
@ -168,7 +169,7 @@ void CTextInputV1ProtocolManager::handleActivate(wl_client* client, wl_resource*
return; return;
} }
PTI->active = true; PTI->active = true;
PTI->pTextInput->onEnabled(wlr_surface_from_resource(surface)); PTI->pTextInput->onEnabled(CWLSurfaceResource::fromResource(surface));
} }
void CTextInputV1ProtocolManager::handleDeactivate(wl_client* client, wl_resource* resource, wl_resource* seat) { void CTextInputV1ProtocolManager::handleDeactivate(wl_client* client, wl_resource* resource, wl_resource* seat) {

View file

@ -1,5 +1,6 @@
#include "TextInputV3.hpp" #include "TextInputV3.hpp"
#include <algorithm> #include <algorithm>
#include "core/Compositor.hpp"
#define LOGM PROTO::textInputV3->protoLog #define LOGM PROTO::textInputV3->protoLog
@ -66,12 +67,12 @@ CTextInputV3::~CTextInputV3() {
events.destroy.emit(); events.destroy.emit();
} }
void CTextInputV3::enter(wlr_surface* surf) { void CTextInputV3::enter(SP<CWLSurfaceResource> surf) {
resource->sendEnter(surf->resource); resource->sendEnter(surf->getResource()->resource());
} }
void CTextInputV3::leave(wlr_surface* surf) { void CTextInputV3::leave(SP<CWLSurfaceResource> surf) {
resource->sendLeave(surf->resource); resource->sendLeave(surf->getResource()->resource());
} }
void CTextInputV3::preeditString(const std::string& text, int32_t cursorBegin, int32_t cursorEnd) { void CTextInputV3::preeditString(const std::string& text, int32_t cursorBegin, int32_t cursorEnd) {

View file

@ -9,13 +9,15 @@
#include "../helpers/signal/Signal.hpp" #include "../helpers/signal/Signal.hpp"
#include "../helpers/Box.hpp" #include "../helpers/Box.hpp"
class CWLSurfaceResource;
class CTextInputV3 { class CTextInputV3 {
public: public:
CTextInputV3(SP<CZwpTextInputV3> resource_); CTextInputV3(SP<CZwpTextInputV3> resource_);
~CTextInputV3(); ~CTextInputV3();
void enter(wlr_surface* surf); void enter(SP<CWLSurfaceResource> surf);
void leave(wlr_surface* surf); void leave(SP<CWLSurfaceResource> surf);
void preeditString(const std::string& text, int32_t cursorBegin, int32_t cursorEnd); void preeditString(const std::string& text, int32_t cursorBegin, int32_t cursorEnd);
void commitString(const std::string& text); void commitString(const std::string& text);
void deleteSurroundingText(uint32_t beforeLength, uint32_t afterLength); void deleteSurroundingText(uint32_t beforeLength, uint32_t afterLength);

Some files were not shown because too many files have changed in this diff Show more