mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 07:05:58 +01:00
wayland/core: move to new impl (#6268)
* wayland/core/dmabuf: move to new impl it's the final countdown
This commit is contained in:
parent
c31d9ef417
commit
6967a31450
147 changed files with 5388 additions and 2226 deletions
|
@ -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()
|
||||||
|
|
||||||
|
|
18
flake.lock
18
flake.lock
|
@ -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": {
|
||||||
|
|
|
@ -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
189
protocols/wayland-drm.xml
Normal 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>
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -96,86 +99,86 @@ class CCompositor {
|
||||||
|
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
|
||||||
CMonitor* getMonitorFromID(const int&);
|
CMonitor* getMonitorFromID(const int&);
|
||||||
CMonitor* getMonitorFromName(const std::string&);
|
CMonitor* getMonitorFromName(const std::string&);
|
||||||
CMonitor* getMonitorFromDesc(const std::string&);
|
CMonitor* getMonitorFromDesc(const std::string&);
|
||||||
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&);
|
||||||
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
||||||
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
PHLWORKSPACE getWorkspaceByString(const std::string&);
|
||||||
void sanityCheckWorkspaces();
|
void sanityCheckWorkspaces();
|
||||||
void updateWorkspaceWindowDecos(const int&);
|
void updateWorkspaceWindowDecos(const int&);
|
||||||
void updateWorkspaceSpecialRenderData(const int&);
|
void updateWorkspaceSpecialRenderData(const int&);
|
||||||
int getWindowsOnWorkspace(const int& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
int getWindowsOnWorkspace(const int& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||||
int getGroupsOnWorkspace(const int& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
int getGroupsOnWorkspace(const int& id, std::optional<bool> onlyTiled = {}, std::optional<bool> onlyVisible = {});
|
||||||
PHLWINDOW getUrgentWindow();
|
PHLWINDOW getUrgentWindow();
|
||||||
bool hasUrgentWindowOnWorkspace(const int&);
|
bool hasUrgentWindowOnWorkspace(const int&);
|
||||||
PHLWINDOW getFirstWindowOnWorkspace(const int&);
|
PHLWINDOW getFirstWindowOnWorkspace(const int&);
|
||||||
PHLWINDOW getTopLeftWindowOnWorkspace(const int&);
|
PHLWINDOW getTopLeftWindowOnWorkspace(const int&);
|
||||||
PHLWINDOW getFullscreenWindowOnWorkspace(const int&);
|
PHLWINDOW getFullscreenWindowOnWorkspace(const int&);
|
||||||
bool isWindowActive(PHLWINDOW);
|
bool isWindowActive(PHLWINDOW);
|
||||||
void changeWindowZOrder(PHLWINDOW, bool);
|
void changeWindowZOrder(PHLWINDOW, bool);
|
||||||
void cleanupFadingOut(const int& monid);
|
void cleanupFadingOut(const int& monid);
|
||||||
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
PHLWINDOW getWindowInDirection(PHLWINDOW, char);
|
||||||
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
PHLWINDOW getNextWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||||
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
PHLWINDOW getPrevWindowOnWorkspace(PHLWINDOW, bool focusableOnly = false, std::optional<bool> floating = {});
|
||||||
int getNextAvailableNamedWorkspace();
|
int getNextAvailableNamedWorkspace();
|
||||||
bool isPointOnAnyMonitor(const Vector2D&);
|
bool isPointOnAnyMonitor(const Vector2D&);
|
||||||
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
bool isPointOnReservedArea(const Vector2D& point, const CMonitor* monitor = nullptr);
|
||||||
CMonitor* getMonitorInDirection(const char&);
|
CMonitor* getMonitorInDirection(const char&);
|
||||||
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
CMonitor* getMonitorInDirection(CMonitor*, const char&);
|
||||||
void updateAllWindowsAnimatedDecorationValues();
|
void updateAllWindowsAnimatedDecorationValues();
|
||||||
void updateWorkspaceWindows(const int64_t& id);
|
void updateWorkspaceWindows(const int64_t& id);
|
||||||
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
void updateWindowAnimatedDecorationValues(PHLWINDOW);
|
||||||
int getNextAvailableMonitorID(std::string const& name);
|
int getNextAvailableMonitorID(std::string const& name);
|
||||||
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
void moveWorkspaceToMonitor(PHLWORKSPACE, CMonitor*, bool noWarpCursor = false);
|
||||||
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
void swapActiveWorkspaces(CMonitor*, CMonitor*);
|
||||||
CMonitor* getMonitorFromString(const std::string&);
|
CMonitor* getMonitorFromString(const std::string&);
|
||||||
bool workspaceIDOutOfBounds(const int64_t&);
|
bool workspaceIDOutOfBounds(const int64_t&);
|
||||||
void setWindowFullscreen(PHLWINDOW, bool, eFullscreenMode mode = FULLSCREEN_INVALID);
|
void setWindowFullscreen(PHLWINDOW, bool, eFullscreenMode mode = FULLSCREEN_INVALID);
|
||||||
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
||||||
PHLWINDOW getX11Parent(PHLWINDOW);
|
PHLWINDOW getX11Parent(PHLWINDOW);
|
||||||
void scheduleFrameForMonitor(CMonitor*);
|
void scheduleFrameForMonitor(CMonitor*);
|
||||||
void addToFadingOutSafe(PHLLS);
|
void addToFadingOutSafe(PHLLS);
|
||||||
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&);
|
||||||
PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
|
PHLWORKSPACE createNewWorkspace(const int&, const int&, const std::string& name = "", bool isEmtpy = true); // will be deleted next frame if left empty and unfocused!
|
||||||
void renameWorkspace(const int&, const std::string& name = "");
|
void renameWorkspace(const int&, const std::string& name = "");
|
||||||
void setActiveMonitor(CMonitor*);
|
void setActiveMonitor(CMonitor*);
|
||||||
bool isWorkspaceSpecial(const int&);
|
bool isWorkspaceSpecial(const int&);
|
||||||
int getNewSpecialID();
|
int getNewSpecialID();
|
||||||
void performUserChecks();
|
void performUserChecks();
|
||||||
void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
|
void moveWindowToWorkspaceSafe(PHLWINDOW pWindow, PHLWORKSPACE pWorkspace);
|
||||||
PHLWINDOW getForceFocus();
|
PHLWINDOW getForceFocus();
|
||||||
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*);
|
||||||
|
|
||||||
std::string explicitConfigPath;
|
std::string explicitConfigPath;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initAllSignals();
|
void initAllSignals();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -208,11 +213,11 @@ void CLayerSurface::onUnmap() {
|
||||||
if (WASLASTFOCUS) {
|
if (WASLASTFOCUS) {
|
||||||
g_pInputManager->releaseAllMouseButtons();
|
g_pInputManager->releaseAllMouseButtons();
|
||||||
|
|
||||||
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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
@ -69,14 +72,14 @@ void CPopup::onMap() {
|
||||||
if (m_bMapped)
|
if (m_bMapped)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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,12 +38,18 @@ 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;
|
||||||
Vector2D m_vLastSize = {};
|
CHyprSignalListener commitSubsurface;
|
||||||
|
CHyprSignalListener mapSubsurface;
|
||||||
|
CHyprSignalListener unmapSubsurface;
|
||||||
|
CHyprSignalListener newSubsurface;
|
||||||
|
} listeners;
|
||||||
|
|
||||||
|
WP<CWLSubsurfaceResource> m_pSubsurface;
|
||||||
|
SP<CWLSurface> m_pWLSurface;
|
||||||
|
Vector2D m_vLastSize = {};
|
||||||
|
|
||||||
// if nullptr, means it's a dummy node
|
// if nullptr, means it's a dummy node
|
||||||
CSubsurface* m_pParent = nullptr;
|
CSubsurface* m_pParent = nullptr;
|
||||||
|
@ -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();
|
||||||
};
|
};
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -7,33 +7,37 @@
|
||||||
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;
|
||||||
CWLSurface(CWLSurface&&) = delete;
|
CWLSurface(CWLSurface&&) = delete;
|
||||||
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.
|
||||||
PHLWINDOW getWindow();
|
PHLWINDOW getWindow();
|
||||||
|
@ -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,15 +88,19 @@ class CWLSurface {
|
||||||
CSignal destroy;
|
CSignal destroy;
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
|
WP<CWLSurface> self;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_bInert = true;
|
CWLSurface() = default;
|
||||||
|
|
||||||
wlr_surface* m_pWLRSurface = nullptr;
|
bool m_bInert = true;
|
||||||
|
|
||||||
PHLWINDOWREF m_pWindowOwner;
|
WP<CWLSurfaceResource> m_pResource;
|
||||||
PHLLSREF m_pLayerOwner;
|
|
||||||
CPopup* m_pPopupOwner = nullptr;
|
PHLWINDOWREF m_pWindowOwner;
|
||||||
CSubsurface* m_pSubsurfaceOwner = nullptr;
|
PHLLSREF m_pLayerOwner;
|
||||||
|
CPopup* m_pPopupOwner = nullptr;
|
||||||
|
CSubsurface* m_pSubsurfaceOwner = nullptr;
|
||||||
|
|
||||||
//
|
//
|
||||||
WP<CPointerConstraint> m_pConstraint;
|
WP<CPointerConstraint> m_pConstraint;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
|
@ -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)
|
if (!m_pWLSurface->resource() || !m_pWLSurface->resource()->current.buffer)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: this is wrong
|
||||||
|
const auto EXTENTS = m_pXDGSurface->surface->current.opaque.getExtents();
|
||||||
|
if (EXTENTS.w >= m_pXDGSurface->surface->current.buffer->size.x && EXTENTS.h >= m_pXDGSurface->surface->current.buffer->size.y)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const auto EXTENTS = pixman_region32_extents(&m_pXDGSurface->surface->opaque_region);
|
return m_pWLSurface->resource()->current.buffer->opaque;
|
||||||
if (EXTENTS->x2 - EXTENTS->x1 >= m_pXDGSurface->surface->current.buffer_width && EXTENTS->y2 - EXTENTS->y1 >= m_pXDGSurface->surface->current.buffer_height)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,
|
PROTO::tablet->proximityOut(self.lock());
|
||||||
[this](void* owner, void* data) {
|
pSurface.reset();
|
||||||
PROTO::tablet->proximityOut(self.lock());
|
listeners.destroySurface.reset();
|
||||||
pSurface = nullptr;
|
});
|
||||||
hyprListener_destroySurface.removeCallback();
|
|
||||||
},
|
|
||||||
this, "CTabletTool");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct wlr_tablet_pad;
|
||||||
|
|
||||||
class CTabletTool;
|
class CTabletTool;
|
||||||
class CTabletPad;
|
class CTabletPad;
|
||||||
|
class CWLSurfaceResource;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A tablet device
|
A tablet device
|
||||||
|
@ -197,32 +198,35 @@ class CTabletTool : public IHID {
|
||||||
HID_TABLET_TOOL_CAPABILITY_WHEEL = (1 << 5),
|
HID_TABLET_TOOL_CAPABILITY_WHEEL = (1 << 5),
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
bool active = false; // true if in proximity
|
bool active = false; // true if in proximity
|
||||||
uint32_t toolCapabilities = 0;
|
uint32_t toolCapabilities = 0;
|
||||||
|
|
||||||
bool isDown = false;
|
bool isDown = false;
|
||||||
std::vector<uint32_t> buttonsDown;
|
std::vector<uint32_t> buttonsDown;
|
||||||
Vector2D absolutePos; // last known absolute position.
|
Vector2D absolutePos; // last known absolute position.
|
||||||
|
|
||||||
std::string hlName;
|
std::string hlName;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CTabletTool(wlr_tablet_tool* tool);
|
CTabletTool(wlr_tablet_tool* tool);
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
|
@ -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
271
src/helpers/Format.cpp
Normal 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
37
src/helpers/Format.hpp
Normal 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);
|
||||||
|
};
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -20,9 +21,9 @@ struct SRenderData {
|
||||||
double x, y;
|
double x, y;
|
||||||
|
|
||||||
// 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
|
||||||
bool dontRound = true;
|
bool dontRound = true;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,19 +2,40 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
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(); });
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -89,4 +89,14 @@
|
||||||
}
|
}
|
||||||
#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); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
damageIfSoftware();
|
||||||
[this](void* owner, void* data) {
|
currentCursorImage.size = currentCursorImage.surface->resource()->current.buffer ? currentCursorImage.surface->resource()->current.buffer->size : Vector2D{};
|
||||||
damageIfSoftware();
|
currentCursorImage.scale = currentCursorImage.surface ? currentCursorImage.surface->resource()->current.scale : 1.F;
|
||||||
currentCursorImage.size = {currentCursorImage.surface->wlr()->current.buffer_width, currentCursorImage.surface->wlr()->current.buffer_height};
|
recheckEnteredOutputs();
|
||||||
currentCursorImage.scale = currentCursorImage.surface && currentCursorImage.surface->wlr() ? currentCursorImage.surface->wlr()->current.scale : 1.F;
|
updateCursorBackend();
|
||||||
recheckEnteredOutputs();
|
damageIfSoftware();
|
||||||
updateCursorBackend();
|
});
|
||||||
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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -129,8 +130,9 @@ class CPointerManager {
|
||||||
} currentMonitorLayout;
|
} currentMonitorLayout;
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,10 +597,10 @@ 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;
|
||||||
|
|
||||||
setKeyboardFocus(nullptr);
|
setKeyboardFocus(nullptr);
|
||||||
setPointerFocus(nullptr, {});
|
setPointerFocus(nullptr, {});
|
||||||
|
@ -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();
|
||||||
|
|
|
@ -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,8 +42,8 @@ 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,24 +83,24 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,14 @@
|
||||||
|
|
||||||
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*);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -5,25 +5,25 @@
|
||||||
|
|
||||||
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);
|
Vector2D getMinSizeForWindow(PHLWINDOW);
|
||||||
Vector2D getMinSizeForWindow(PHLWINDOW);
|
Vector2D xwaylandToWaylandCoords(const Vector2D&);
|
||||||
Vector2D xwaylandToWaylandCoords(const Vector2D&);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CHyprXWaylandManager> g_pXWaylandManager;
|
inline std::unique_ptr<CHyprXWaylandManager> g_pXWaylandManager;
|
|
@ -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;
|
||||||
|
|
|
@ -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,14 +143,14 @@ 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;
|
||||||
PHLLS pFoundLayerSurface;
|
PHLLS pFoundLayerSurface;
|
||||||
|
|
||||||
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
|
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
|
||||||
return;
|
return;
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -44,10 +44,10 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The third row is always 0 0 1 and is not expected by `libinput_device_config_calibration_set_matrix`
|
// The third row is always 0 0 1 and is not expected by `libinput_device_config_calibration_set_matrix`
|
||||||
|
@ -236,9 +236,9 @@ 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;
|
||||||
|
|
||||||
// for holding focus on buttons held
|
// for holding focus on buttons held
|
||||||
bool m_bFocusHeldByButtons = false;
|
bool m_bFocusHeldByButtons = false;
|
||||||
|
@ -268,11 +268,11 @@ 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;
|
||||||
} m_sCursorSurfaceInfo;
|
} m_sCursorSurfaceInfo;
|
||||||
|
|
||||||
void restoreCursorIconToApp(); // no-op if restored
|
void restoreCursorIconToApp(); // no-op if restored
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,18 +12,18 @@ class CInputPopup {
|
||||||
public:
|
public:
|
||||||
CInputPopup(SP<CInputMethodPopupV2> popup);
|
CInputPopup(SP<CInputMethodPopupV2> popup);
|
||||||
|
|
||||||
void damageEntire();
|
void damageEntire();
|
||||||
void damageSurface();
|
void damageSurface();
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
Debug::log(LOG, "Unmap TI owner1");
|
||||||
[this](void* owner, void* data) {
|
|
||||||
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() {
|
||||||
|
|
|
@ -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:
|
||||||
|
@ -19,43 +19,43 @@ class CTextInput {
|
||||||
CTextInput(STextInputV1* ti);
|
CTextInput(STextInputV1* ti);
|
||||||
~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;
|
||||||
|
|
||||||
DYNLISTENER(textInputEnable);
|
DYNLISTENER(textInputEnable);
|
||||||
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;
|
||||||
};
|
};
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
|
||||||
LOGM(ERR, "CAlphaModifierProtocol::destroyModifier: dead resource but no deadptr???");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mAlphaModifiers.erase(deadptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAlphaModifierProtocol::onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, wlr_surface* surface) {
|
void CAlphaModifierProtocol::onGetSurface(CWpAlphaModifierV1* pMgr, uint32_t id, SP<CWLSurfaceResource> surface) {
|
||||||
if (m_mAlphaModifiers.contains(surface)) {
|
if (std::find_if(m_mAlphaModifiers.begin(), m_mAlphaModifiers.end(), [surface](const auto& e) { return e.first == surface; }) != m_mAlphaModifiers.end()) {
|
||||||
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;
|
||||||
|
|
|
@ -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,15 +38,15 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PROTO {
|
namespace PROTO {
|
||||||
inline UP<CAlphaModifierProtocol> alphaModifier;
|
inline UP<CAlphaModifierProtocol> alphaModifier;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,23 +35,23 @@ 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;
|
||||||
|
|
||||||
DYNLISTENER(pointerGrabStarted);
|
DYNLISTENER(pointerGrabStarted);
|
||||||
DYNLISTENER(keyboardGrabStarted);
|
DYNLISTENER(keyboardGrabStarted);
|
||||||
|
|
|
@ -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,11 +25,13 @@ 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) {
|
||||||
LOGM(ERR, "Surface {:x} already has a fractionalScale addon", (uintptr_t)surface);
|
if (k == surface) {
|
||||||
pMgr->error(WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS, "Fractional scale already exists");
|
LOGM(ERR, "Surface {:x} already has a fractionalScale addon", (uintptr_t)surface);
|
||||||
return;
|
pMgr->error(WP_FRACTIONAL_SCALE_MANAGER_V1_ERROR_FRACTIONAL_SCALE_EXISTS, "Fractional scale already exists");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto PADDON =
|
const auto PADDON =
|
||||||
|
@ -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();
|
||||||
}
|
}
|
|
@ -6,19 +6,20 @@
|
||||||
#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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,42 +29,36 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PROTO {
|
namespace PROTO {
|
||||||
inline UP<CFractionalScaleProtocol> fractional;
|
inline UP<CFractionalScaleProtocol> fractional;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
destroySent = true;
|
||||||
hyprListener_surfaceDestroy.removeCallback();
|
events.destroy.emit();
|
||||||
destroySent = true;
|
});
|
||||||
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));
|
||||||
|
|
||||||
|
|
|
@ -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*);
|
||||||
|
|
||||||
|
@ -64,4 +67,4 @@ class CIdleInhibitProtocol : public IWaylandProtocol {
|
||||||
|
|
||||||
namespace PROTO {
|
namespace PROTO {
|
||||||
inline UP<CIdleInhibitProtocol> idleInhibit;
|
inline UP<CIdleInhibitProtocol> idleInhibit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
if (mapped)
|
||||||
[this](void* owner, void* data) {
|
events.unmap.emit();
|
||||||
if (mapped)
|
|
||||||
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) {
|
mapped = true;
|
||||||
if (pSurface->pending.buffer_width > 0 && pSurface->pending.buffer_height > 0 && !mapped) {
|
pSurface->map();
|
||||||
mapped = true;
|
events.map.emit();
|
||||||
wlr_surface_map(pSurface);
|
return;
|
||||||
events.map.emit();
|
}
|
||||||
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();
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,57 +33,52 @@ 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,
|
events.destroy.emit();
|
||||||
[this](void* owner, void* data) {
|
PROTO::layerShell->destroyResource(this);
|
||||||
events.destroy.emit();
|
});
|
||||||
PROTO::layerShell->destroyResource(this);
|
|
||||||
},
|
|
||||||
this, "CLayerShellResource");
|
|
||||||
|
|
||||||
hyprListener_commitSurface.initCallback(
|
listeners.commitSurface = surf_->events.commit.registerListener([this](std::any d) {
|
||||||
&surf_->events.commit,
|
current = pending;
|
||||||
[this](void* owner, void* data) {
|
pending.committed = 0;
|
||||||
current = pending;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
constexpr uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
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();
|
||||||
return;
|
configured = false;
|
||||||
}
|
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();
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -54,18 +55,20 @@ class CLayerShellResource {
|
||||||
void reset();
|
void reset();
|
||||||
} current, pending;
|
} current, pending;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|
454
src/protocols/LinuxDMABUF.cpp
Normal file
454
src/protocols/LinuxDMABUF.cpp
Normal 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; });
|
||||||
|
}
|
138
src/protocols/LinuxDMABUF.hpp
Normal file
138
src/protocols/LinuxDMABUF.hpp
Normal 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
133
src/protocols/MesaDRM.cpp
Normal 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
60
src/protocols/MesaDRM.hpp
Normal 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;
|
||||||
|
};
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,31 +12,32 @@
|
||||||
#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();
|
||||||
|
|
||||||
void deactivate();
|
void deactivate();
|
||||||
void activate();
|
void activate();
|
||||||
bool isActive();
|
bool isActive();
|
||||||
|
|
||||||
CWLSurface* owner();
|
SP<CWLSurface> owner();
|
||||||
|
|
||||||
CRegion logicConstraintRegion();
|
CRegion logicConstraintRegion();
|
||||||
bool isLocked();
|
bool isLocked();
|
||||||
Vector2D logicPositionHint();
|
Vector2D logicPositionHint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SP<CZwpLockedPointerV1> resourceL;
|
SP<CZwpLockedPointerV1> resourceL;
|
||||||
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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -19,10 +20,10 @@ class CQueuedPresentationData {
|
||||||
void discarded();
|
void discarded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
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,8 +41,8 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,45 +23,38 @@ 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) {
|
LOGM(ERR, "SessionLock attached a null buffer");
|
||||||
if (pSurface->pending.buffer_width <= 0 || pSurface->pending.buffer_height <= 0) {
|
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER, "Null buffer attached");
|
||||||
LOGM(ERR, "SessionLock attached a null buffer");
|
return;
|
||||||
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_NULL_BUFFER, "Null buffer attached");
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ackdConfigure) {
|
if (!ackdConfigure) {
|
||||||
LOGM(ERR, "SessionLock committed without an ack");
|
LOGM(ERR, "SessionLock committed without an ack");
|
||||||
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_COMMIT_BEFORE_FIRST_ACK, "Committed surface before first ack");
|
resource->error(EXT_SESSION_LOCK_SURFACE_V1_ERROR_COMMIT_BEFORE_FIRST_ACK, "Committed surface before first ack");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
LOGM(WARN, "SessionLockSurface object remains but surface is being destroyed???");
|
||||||
[this](void* owner, void* data) {
|
pSurface->unmap();
|
||||||
LOGM(WARN, "SessionLockSurface object remains but surface is being destroyed???");
|
listeners.surfaceCommit.reset();
|
||||||
wlr_surface_unmap(pSurface);
|
listeners.surfaceDestroy.reset();
|
||||||
hyprListener_surfaceCommit.removeCallback();
|
if (g_pCompositor->m_pLastFocus == pSurface)
|
||||||
hyprListener_surfaceDestroy.removeCallback();
|
g_pCompositor->m_pLastFocus.reset();
|
||||||
|
|
||||||
if (g_pCompositor->m_pLastFocus == pSurface)
|
pSurface.reset();
|
||||||
g_pCompositor->m_pLastFocus = nullptr;
|
});
|
||||||
|
|
||||||
pSurface = nullptr;
|
|
||||||
},
|
|
||||||
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) {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,8 +47,8 @@ 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) {
|
||||||
if (in->surface() != surf)
|
if (in->surface() != surf)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
|
@ -598,8 +599,8 @@ void CTabletV2Protocol::proximityOut(SP<CTabletTool> tool) {
|
||||||
if (t->tool != tool || !t->current)
|
if (t->tool != tool || !t->current)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
t->current = false;
|
t->current = false;
|
||||||
t->lastSurf = nullptr;
|
t->lastSurf.reset();
|
||||||
t->resource->sendProximityOut();
|
t->resource->sendProximityOut();
|
||||||
t->sendFrame();
|
t->sendFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
@ -112,19 +113,19 @@ class CTabletToolV2Resource {
|
||||||
CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<CTabletTool> tool_, SP<CTabletSeat> seat_);
|
CTabletToolV2Resource(SP<CZwpTabletToolV2> resource_, SP<CTabletTool> tool_, SP<CTabletSeat> seat_);
|
||||||
~CTabletToolV2Resource();
|
~CTabletToolV2Resource();
|
||||||
|
|
||||||
bool good();
|
bool good();
|
||||||
void sendData();
|
void sendData();
|
||||||
void queueFrame();
|
void queueFrame();
|
||||||
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;
|
||||||
wl_event_source* frameSource = nullptr;
|
wl_event_source* frameSource = nullptr;
|
||||||
|
|
||||||
bool inert = false; // removed was sent
|
bool inert = false; // removed was sent
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SP<CZwpTabletToolV2> resource;
|
SP<CZwpTabletToolV2> resource;
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue