mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-22 22:09:49 +01:00
XDG-Output: move to hyprwayland-scanner
This commit is contained in:
parent
a945346064
commit
84ee839ca6
7 changed files with 93 additions and 101 deletions
|
@ -260,11 +260,11 @@ protocol("subprojects/hyprland-protocols/protocols/hyprland-global-shortcuts-v1.
|
|||
protocol("subprojects/hyprland-protocols/protocols/hyprland-toplevel-export-v1.xml" "hyprland-toplevel-export-v1" true)
|
||||
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
|
||||
protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-v1" false)
|
||||
protocol("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
|
||||
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
|
||||
protocol("staging/cursor-shape/cursor-shape-v1.xml" "cursor-shape-v1" false)
|
||||
protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
|
||||
protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
||||
protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
|
||||
|
||||
# tools
|
||||
add_subdirectory(hyprctl)
|
||||
|
|
|
@ -27,7 +27,6 @@ protocols = [
|
|||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||
[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/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
|
||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||
['wlr-layer-shell-unstable-v1.xml'],
|
||||
|
@ -43,6 +42,7 @@ protocols = [
|
|||
new_protocols = [
|
||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
]
|
||||
|
||||
wl_protos_src = []
|
||||
|
|
|
@ -2,18 +2,22 @@
|
|||
|
||||
#include "../protocols/TearingControl.hpp"
|
||||
#include "../protocols/FractionalScale.hpp"
|
||||
#include "../protocols/XDGOutput.hpp"
|
||||
|
||||
#include "xdg-output-unstable-v1-protocol.h"
|
||||
#include "tearing-control-v1.hpp"
|
||||
#include "fractional-scale-v1.hpp"
|
||||
#include "xdg-output-unstable-v1.hpp"
|
||||
|
||||
CProtocolManager::CProtocolManager() {
|
||||
|
||||
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::xdgOutput = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
|
||||
|
||||
// Old protocol implementations.
|
||||
// TODO: rewrite them to use hyprwayland-scanner.
|
||||
m_pToplevelExportProtocolManager = std::make_unique<CToplevelExportProtocolManager>();
|
||||
m_pTextInputV1ProtocolManager = std::make_unique<CTextInputV1ProtocolManager>();
|
||||
m_pGlobalShortcutsProtocolManager = std::make_unique<CGlobalShortcutsProtocolManager>();
|
||||
m_pScreencopyProtocolManager = std::make_unique<CScreencopyProtocolManager>();
|
||||
|
||||
m_pXDGOutputProtocol = std::make_unique<CXDGOutputProtocol>(&zxdg_output_manager_v1_interface, 3, "XDGOutput");
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "../protocols/TextInputV1.hpp"
|
||||
#include "../protocols/GlobalShortcuts.hpp"
|
||||
#include "../protocols/Screencopy.hpp"
|
||||
#include "../protocols/XDGOutput.hpp"
|
||||
|
||||
class CProtocolManager {
|
||||
public:
|
||||
|
@ -16,9 +15,6 @@ class CProtocolManager {
|
|||
std::unique_ptr<CTextInputV1ProtocolManager> m_pTextInputV1ProtocolManager;
|
||||
std::unique_ptr<CGlobalShortcutsProtocolManager> m_pGlobalShortcutsProtocolManager;
|
||||
std::unique_ptr<CScreencopyProtocolManager> m_pScreencopyProtocolManager;
|
||||
|
||||
// New protocols
|
||||
std::unique_ptr<CXDGOutputProtocol> m_pXDGOutputProtocol;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CProtocolManager> g_pProtocolManager;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "XWaylandManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
#include "xdg-output-unstable-v1-protocol.h"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
|
||||
#define OUTPUT_MANAGER_VERSION 3
|
||||
|
|
|
@ -2,60 +2,34 @@
|
|||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
|
||||
#include "xdg-output-unstable-v1-protocol.h"
|
||||
|
||||
#define OUTPUT_MANAGER_VERSION 3
|
||||
#define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3
|
||||
#define OUTPUT_DESCRIPTION_MUTABLE_SINCE_VERSION 3
|
||||
|
||||
static void destroyManagerResource(wl_client* client, wl_resource* resource) {
|
||||
RESOURCE_OR_BAIL(PRESOURCE);
|
||||
reinterpret_cast<CXDGOutputProtocol*>(PRESOURCE->data())->onManagerResourceDestroy(resource);
|
||||
}
|
||||
|
||||
static void destroyOutputResource(wl_client* client, wl_resource* resource) {
|
||||
RESOURCE_OR_BAIL(PRESOURCE);
|
||||
reinterpret_cast<CXDGOutputProtocol*>(PRESOURCE->data())->onOutputResourceDestroy(resource);
|
||||
}
|
||||
|
||||
static void getXDGOutput(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* outputResource) {
|
||||
RESOURCE_OR_BAIL(PRESOURCE);
|
||||
reinterpret_cast<CXDGOutputProtocol*>(PRESOURCE->data())->onManagerGetXDGOutput(client, resource, id, outputResource);
|
||||
}
|
||||
#define OUTPUT_NAME_SINCE_VERSION 2
|
||||
#define OUTPUT_DESCRIPTION_SINCE_VERSION 2
|
||||
|
||||
//
|
||||
|
||||
static const struct zxdg_output_manager_v1_interface MANAGER_IMPL = {
|
||||
.destroy = destroyManagerResource,
|
||||
.get_xdg_output = getXDGOutput,
|
||||
};
|
||||
|
||||
static const struct zxdg_output_v1_interface OUTPUT_IMPL = {
|
||||
.destroy = destroyOutputResource,
|
||||
};
|
||||
|
||||
void CXDGOutputProtocol::onManagerResourceDestroy(wl_resource* res) {
|
||||
std::erase_if(m_vManagerResources, [&](const auto& other) { return other->resource() == res; });
|
||||
}
|
||||
|
||||
void CXDGOutputProtocol::onOutputResourceDestroy(wl_resource* res) {
|
||||
std::erase_if(m_vXDGOutputs, [&](const auto& other) {
|
||||
if (!other->resource)
|
||||
return false; // ???
|
||||
return other->resource->resource() == res;
|
||||
});
|
||||
std::erase_if(m_vXDGOutputs, [&](const auto& other) { return other->resource->resource() == res; });
|
||||
}
|
||||
|
||||
void CXDGOutputProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||
const auto RESOURCE = m_vManagerResources.emplace_back(std::make_unique<CWaylandResource>(client, &zxdg_output_manager_v1_interface, ver, id)).get();
|
||||
const auto RESOURCE = m_vManagerResources.emplace_back(std::make_unique<CZxdgOutputManagerV1>(client, ver, id)).get();
|
||||
|
||||
if (!RESOURCE->good()) {
|
||||
if (!RESOURCE->resource()) {
|
||||
Debug::log(LOG, "Couldn't bind XDGOutputMgr");
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
RESOURCE->setImplementation(&MANAGER_IMPL, nullptr);
|
||||
RESOURCE->setData(this);
|
||||
RESOURCE->setDestroy([this](CZxdgOutputManagerV1* res) { this->onManagerResourceDestroy(res->resource()); });
|
||||
RESOURCE->setOnDestroy([this](CZxdgOutputManagerV1* res) { this->onManagerResourceDestroy(res->resource()); });
|
||||
RESOURCE->setGetXdgOutput([this](CZxdgOutputManagerV1* mgr, uint32_t id, wl_resource* output) { this->onManagerGetXDGOutput(mgr, id, output); });
|
||||
}
|
||||
|
||||
CXDGOutputProtocol::CXDGOutputProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||
|
@ -63,81 +37,87 @@ CXDGOutputProtocol::CXDGOutputProtocol(const wl_interface* iface, const int& ver
|
|||
g_pHookSystem->hookDynamic("configReloaded", [this](void* self, SCallbackInfo& info, std::any param) { this->updateAllOutputs(); });
|
||||
g_pHookSystem->hookDynamic("monitorRemoved", [this](void* self, SCallbackInfo& info, std::any param) {
|
||||
const auto PMONITOR = std::any_cast<CMonitor*>(param);
|
||||
std::erase_if(m_vXDGOutputs, [&](const auto& other) {
|
||||
const auto REMOVE = other->monitor == PMONITOR;
|
||||
if (REMOVE)
|
||||
other->resource->markDefunct(); // so that wl_resource_destroy is not sent
|
||||
return REMOVE;
|
||||
});
|
||||
for (auto& o : m_vXDGOutputs) {
|
||||
if (o->monitor == PMONITOR)
|
||||
o->monitor = nullptr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* outputResource) {
|
||||
void CXDGOutputProtocol::onManagerGetXDGOutput(CZxdgOutputManagerV1* mgr, uint32_t id, wl_resource* outputResource) {
|
||||
const auto OUTPUT = wlr_output_from_resource(outputResource);
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromOutput(OUTPUT);
|
||||
|
||||
SXDGOutput* pXDGOutput = m_vXDGOutputs.emplace_back(std::make_unique<SXDGOutput>(PMONITOR)).get();
|
||||
const auto CLIENT = wl_resource_get_client(mgr->resource());
|
||||
|
||||
CXDGOutput* pXDGOutput =
|
||||
m_vXDGOutputs.emplace_back(std::make_unique<CXDGOutput>(std::make_shared<CZxdgOutputV1>(CLIENT, wl_resource_get_version(mgr->resource()), id), PMONITOR)).get();
|
||||
#ifndef NO_XWAYLAND
|
||||
if (g_pXWaylandManager->m_sWLRXWayland && g_pXWaylandManager->m_sWLRXWayland->server && g_pXWaylandManager->m_sWLRXWayland->server->client == client)
|
||||
if (g_pXWaylandManager->m_sWLRXWayland && g_pXWaylandManager->m_sWLRXWayland->server && g_pXWaylandManager->m_sWLRXWayland->server->client == CLIENT)
|
||||
pXDGOutput->isXWayland = true;
|
||||
#endif
|
||||
pXDGOutput->client = client;
|
||||
pXDGOutput->client = CLIENT;
|
||||
|
||||
pXDGOutput->resource = std::make_unique<CWaylandResource>(client, &zxdg_output_v1_interface, wl_resource_get_version(resource), id);
|
||||
|
||||
if (!pXDGOutput->resource->good()) {
|
||||
pXDGOutput->resource.release();
|
||||
if (!pXDGOutput->resource->resource()) {
|
||||
m_vXDGOutputs.pop_back();
|
||||
wl_resource_post_no_memory(mgr->resource());
|
||||
return;
|
||||
}
|
||||
|
||||
pXDGOutput->resource->setImplementation(&OUTPUT_IMPL, nullptr);
|
||||
pXDGOutput->resource->setData(this);
|
||||
|
||||
if (!PMONITOR)
|
||||
return;
|
||||
|
||||
const auto XDGVER = pXDGOutput->resource->version();
|
||||
const auto XDGVER = wl_resource_get_version(pXDGOutput->resource->resource());
|
||||
|
||||
if (XDGVER >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
|
||||
zxdg_output_v1_send_name(pXDGOutput->resource->resource(), PMONITOR->szName.c_str());
|
||||
if (XDGVER >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION && PMONITOR->output->description)
|
||||
zxdg_output_v1_send_description(pXDGOutput->resource->resource(), PMONITOR->output->description);
|
||||
if (XDGVER >= OUTPUT_NAME_SINCE_VERSION)
|
||||
pXDGOutput->resource->sendName(PMONITOR->szName.c_str());
|
||||
if (XDGVER >= OUTPUT_DESCRIPTION_SINCE_VERSION && PMONITOR->output->description)
|
||||
pXDGOutput->resource->sendDescription(PMONITOR->output->description);
|
||||
|
||||
updateOutputDetails(pXDGOutput);
|
||||
pXDGOutput->sendDetails();
|
||||
|
||||
const auto OUTPUTVER = wl_resource_get_version(outputResource);
|
||||
if (OUTPUTVER >= WL_OUTPUT_DONE_SINCE_VERSION && XDGVER >= OUTPUT_DONE_DEPRECATED_SINCE_VERSION)
|
||||
wl_output_send_done(outputResource);
|
||||
}
|
||||
|
||||
void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
|
||||
if (!pOutput->resource->good() || !pOutput->monitor)
|
||||
return;
|
||||
|
||||
const auto POS = pOutput->isXWayland ? pOutput->monitor->vecXWaylandPosition : pOutput->monitor->vecPosition;
|
||||
zxdg_output_v1_send_logical_position(pOutput->resource->resource(), POS.x, POS.y);
|
||||
|
||||
if (*PXWLFORCESCALEZERO && pOutput->isXWayland)
|
||||
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecTransformedSize.x, pOutput->monitor->vecTransformedSize.y);
|
||||
else
|
||||
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecSize.x, pOutput->monitor->vecSize.y);
|
||||
|
||||
if (wl_resource_get_version(pOutput->resource->resource()) < OUTPUT_DONE_DEPRECATED_SINCE_VERSION)
|
||||
zxdg_output_v1_send_done(pOutput->resource->resource());
|
||||
}
|
||||
|
||||
void CXDGOutputProtocol::updateAllOutputs() {
|
||||
for (auto& o : m_vXDGOutputs) {
|
||||
|
||||
if (!o->monitor)
|
||||
continue;
|
||||
|
||||
updateOutputDetails(o.get());
|
||||
o->sendDetails();
|
||||
|
||||
wlr_output_schedule_done(o->monitor->output);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
CXDGOutput::CXDGOutput(SP<CZxdgOutputV1> resource_, CMonitor* monitor_) : monitor(monitor_), resource(resource_) {
|
||||
if (!resource->resource())
|
||||
return;
|
||||
|
||||
resource->setDestroy([](CZxdgOutputV1* pMgr) { PROTO::xdgOutput->onOutputResourceDestroy(pMgr->resource()); });
|
||||
resource->setOnDestroy([](CZxdgOutputV1* pMgr) { PROTO::xdgOutput->onOutputResourceDestroy(pMgr->resource()); });
|
||||
}
|
||||
|
||||
void CXDGOutput::sendDetails() {
|
||||
static auto PXWLFORCESCALEZERO = CConfigValue<Hyprlang::INT>("xwayland:force_zero_scaling");
|
||||
|
||||
if (!monitor)
|
||||
return;
|
||||
|
||||
const auto POS = isXWayland ? monitor->vecXWaylandPosition : monitor->vecPosition;
|
||||
resource->sendLogicalPosition(POS.x, POS.y);
|
||||
|
||||
if (*PXWLFORCESCALEZERO && isXWayland)
|
||||
resource->sendLogicalSize(monitor->vecTransformedSize.x, monitor->vecTransformedSize.y);
|
||||
else
|
||||
resource->sendLogicalSize(monitor->vecSize.x, monitor->vecSize.y);
|
||||
|
||||
if (wl_resource_get_version(resource->resource()) < OUTPUT_DONE_DEPRECATED_SINCE_VERSION)
|
||||
resource->sendDone();
|
||||
}
|
|
@ -1,18 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include "xdg-output-unstable-v1.hpp"
|
||||
#include "WaylandProtocol.hpp"
|
||||
#include <optional>
|
||||
|
||||
class CMonitor;
|
||||
class CXDGOutputProtocol;
|
||||
|
||||
struct SXDGOutput {
|
||||
CMonitor* monitor = nullptr;
|
||||
std::unique_ptr<CWaylandResource> resource;
|
||||
class CXDGOutput {
|
||||
public:
|
||||
CXDGOutput(SP<CZxdgOutputV1> resource, CMonitor* monitor_);
|
||||
|
||||
std::optional<Vector2D> overridePosition;
|
||||
void sendDetails();
|
||||
|
||||
wl_client* client = nullptr;
|
||||
bool isXWayland = false;
|
||||
private:
|
||||
CMonitor* monitor = nullptr;
|
||||
SP<CZxdgOutputV1> resource;
|
||||
|
||||
std::optional<Vector2D> overridePosition;
|
||||
|
||||
wl_client* client = nullptr;
|
||||
bool isXWayland = false;
|
||||
|
||||
friend class CXDGOutputProtocol;
|
||||
};
|
||||
|
||||
class CXDGOutputProtocol : public IWaylandProtocol {
|
||||
|
@ -23,12 +33,15 @@ class CXDGOutputProtocol : public IWaylandProtocol {
|
|||
|
||||
void onManagerResourceDestroy(wl_resource* res);
|
||||
void onOutputResourceDestroy(wl_resource* res);
|
||||
void onManagerGetXDGOutput(wl_client* client, wl_resource* resource, uint32_t id, wl_resource* outputResource);
|
||||
void onManagerGetXDGOutput(CZxdgOutputManagerV1* mgr, uint32_t id, wl_resource* outputResource);
|
||||
|
||||
private:
|
||||
void updateOutputDetails(SXDGOutput* pOutput);
|
||||
void updateAllOutputs();
|
||||
void updateAllOutputs();
|
||||
|
||||
std::vector<std::unique_ptr<CWaylandResource>> m_vManagerResources;
|
||||
std::vector<std::unique_ptr<SXDGOutput>> m_vXDGOutputs;
|
||||
};
|
||||
std::vector<UP<CZxdgOutputManagerV1>> m_vManagerResources;
|
||||
std::vector<UP<CXDGOutput>> m_vXDGOutputs;
|
||||
};
|
||||
|
||||
namespace PROTO {
|
||||
inline UP<CXDGOutputProtocol> xdgOutput;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue