Added toplevel handle sharing Rev2 (#1203)

* Added toplevel handle sharing

* nix: fix build

* update hyprland-protocols

Co-authored-by: Mihai Fufezan <fufexan@protonmail.com>
This commit is contained in:
Vaxry
2022-12-12 14:56:42 +00:00
committed by GitHub
parent b45a213413
commit 111d209bff
10 changed files with 331 additions and 22 deletions

View File

@@ -6,7 +6,7 @@
#include "ToplevelExportWlrFuncs.hpp"
#define TOPLEVEL_EXPORT_VERSION 1
#define TOPLEVEL_EXPORT_VERSION 2
static void bindManagerInt(wl_client* client, void* data, uint32_t version, uint32_t id) {
g_pProtocolManager->m_pToplevelExportProtocolManager->bindManager(client, data, version, id);
@@ -41,8 +41,17 @@ CToplevelExportProtocolManager::CToplevelExportProtocolManager() {
Debug::log(LOG, "ToplevelExportManager started successfully!");
}
wlr_foreign_toplevel_handle_v1* zwlrHandleFromResource(wl_resource* resource) {
// we can't assert here, but it doesnt matter.
return (wlr_foreign_toplevel_handle_v1*)wl_resource_get_user_data(resource);
}
void handleCaptureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, handle);
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromHandle(handle));
}
void handleCaptureToplevelWithWlr(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, wl_resource* handle) {
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromZWLRHandle(handle));
}
void handleDestroy(wl_client* client, wl_resource* resource) {
@@ -59,7 +68,8 @@ void handleDestroyFrame(wl_client* client, wl_resource* resource) {
static const struct hyprland_toplevel_export_manager_v1_interface toplevelExportManagerImpl = {
.capture_toplevel = handleCaptureToplevel,
.destroy = handleDestroy
.destroy = handleDestroy,
.capture_toplevel_with_wlr_toplevel_handle = handleCaptureToplevelWithWlr,
};
static const struct hyprland_toplevel_export_frame_v1_interface toplevelFrameImpl = {
@@ -133,26 +143,24 @@ void CToplevelExportProtocolManager::removeFrame(SToplevelFrame* frame, bool for
m_lFrames.remove(*frame);
}
void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, CWindow* pWindow) {
const auto PCLIENT = clientFromResource(resource);
const auto PWINDOW = g_pCompositor->getWindowFromHandle(handle);
// create a frame
const auto PFRAME = &m_lFrames.emplace_back();
PFRAME->overlayCursor = !!overlay_cursor;
PFRAME->resource = wl_resource_create(client, &hyprland_toplevel_export_frame_v1_interface, wl_resource_get_version(resource), frame);
PFRAME->pWindow = PWINDOW;
PFRAME->pWindow = pWindow;
if (!PWINDOW) {
Debug::log(ERR, "Client requested sharing of window handle %x which does not exist!", handle);
if (!PFRAME->pWindow) {
Debug::log(ERR, "Client requested sharing of window handle %x which does not exist!", PFRAME->pWindow);
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
removeFrame(PFRAME);
return;
}
if (!PWINDOW->m_bIsMapped || PWINDOW->isHidden()) {
Debug::log(ERR, "Client requested sharing of window handle %x which is not shareable!", handle);
if (!PFRAME->pWindow->m_bIsMapped || PFRAME->pWindow->isHidden()) {
Debug::log(ERR, "Client requested sharing of window handle %x which is not shareable!", PFRAME->pWindow);
hyprland_toplevel_export_frame_v1_send_failed(PFRAME->resource);
removeFrame(PFRAME);
return;
@@ -170,7 +178,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
PFRAME->client = PCLIENT;
PCLIENT->ref++;
const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
const auto PMONITOR = g_pCompositor->getMonitorFromID(PFRAME->pWindow->m_iMonitorID);
PFRAME->shmFormat = wlr_output_preferred_read_format(PMONITOR->output);
if (PFRAME->shmFormat == DRM_FORMAT_INVALID) {
@@ -194,7 +202,7 @@ void CToplevelExportProtocolManager::captureToplevel(wl_client* client, wl_resou
PFRAME->dmabufFormat = DRM_FORMAT_INVALID;
}
PFRAME->box = { 0, 0, (int)(PWINDOW->m_vRealSize.vec().x * PMONITOR->scale), (int)(PWINDOW->m_vRealSize.vec().y * PMONITOR->scale) };
PFRAME->box = { 0, 0, (int)(PFRAME->pWindow->m_vRealSize.vec().x * PMONITOR->scale), (int)(PFRAME->pWindow->m_vRealSize.vec().y * PMONITOR->scale) };
int ow, oh;
wlr_output_effective_resolution(PMONITOR->output, &ow, &oh);
wlr_box_transform(&PFRAME->box, &PFRAME->box, PMONITOR->transform, ow, oh);